/usr/lib/python2.7/dist-packages/foolscap/crypto.py is in python-foolscap 0.6.5-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | # -*- test-case-name: foolscap.test.test_crypto -*-
available = False # hack to deal with half-broken imports in python <2.4
from OpenSSL import SSL
# we try to use ssl support classes from Twisted, if it is new enough. If
# not, we pull them from a local copy of sslverify. The funny '_ssl' import
# stuff is used to appease pyflakes, which otherwise complains that we're
# redefining an imported name.
from twisted.internet import ssl
if hasattr(ssl, "DistinguishedName"):
# Twisted-2.5 will contain these names
_ssl = ssl
CertificateOptions = ssl.CertificateOptions
else:
# but it hasn't been released yet (as of 16-Sep-2006). Without them, we
# cannot use any encrypted Tubs. We fall back to using a private copy of
# sslverify.py, copied from the Divmod tree.
import sslverify
_ssl = sslverify
from sslverify import OpenSSLCertificateOptions as CertificateOptions
DistinguishedName = _ssl.DistinguishedName
KeyPair = _ssl.KeyPair
Certificate = _ssl.Certificate
PrivateCertificate = _ssl.PrivateCertificate
from twisted.internet import error
if hasattr(error, "CertificateError"):
# Twisted-2.4 contains this, and it is used by twisted.internet.ssl
CertificateError = error.CertificateError
else:
class CertificateError(Exception):
"""
We did not find a certificate where we expected to find one.
"""
from foolscap import base32
peerFromTransport = Certificate.peerFromTransport
class MyOptions(CertificateOptions):
def _makeContext(self):
ctx = CertificateOptions._makeContext(self)
def alwaysValidate(conn, cert, errno, depth, preverify_ok):
# This function is called to validate the certificate received by
# the other end. OpenSSL calls it multiple times, each time it
# see something funny, to ask if it should proceed.
# We do not care about certificate authorities or revocation
# lists, we just want to know that the certificate has a valid
# signature and follow the chain back to one which is
# self-signed. The TubID will be the digest of one of these
# certificates. We need to protect against forged signatures, but
# not the usual SSL concerns about invalid CAs or revoked
# certificates.
# these constants are from openssl-0.9.7g/crypto/x509/x509_vfy.h
# and do not appear to be exposed by pyopenssl. Ick. TODO. We
# could just always return '1' here (ignoring all errors), but I
# think that would ignore forged signatures too, which would
# obviously be a security hole.
things_are_ok = (0, # X509_V_OK
9, # X509_V_ERR_CERT_NOT_YET_VALID
10, # X509_V_ERR_CERT_HAS_EXPIRED
18, # X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
19, # X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN
)
if errno in things_are_ok:
return 1
# TODO: log the details of the error, because otherwise they get
# lost in the PyOpenSSL exception that will eventually be raised
# (possibly OpenSSL.SSL.Error: certificate verify failed)
# I think that X509_V_ERR_CERT_SIGNATURE_FAILURE is the most
# obvious sign of hostile attack.
return 0
# VERIFY_PEER means we ask the the other end for their certificate.
# not adding VERIFY_FAIL_IF_NO_PEER_CERT means it's ok if they don't
# give us one (i.e. if an anonymous client connects to an
# authenticated server). I don't know what VERIFY_CLIENT_ONCE does.
ctx.set_verify(SSL.VERIFY_PEER |
#SSL.VERIFY_FAIL_IF_NO_PEER_CERT |
SSL.VERIFY_CLIENT_ONCE,
alwaysValidate)
return ctx
def digest32(colondigest):
digest = "".join([chr(int(c,16)) for c in colondigest.split(":")])
digest = base32.encode(digest)
return digest
available = True
|