| Index: third_party/twisted_8_1/twisted/internet/_sslverify.py | 
| diff --git a/third_party/twisted_8_1/twisted/internet/_sslverify.py b/third_party/twisted_8_1/twisted/internet/_sslverify.py | 
| deleted file mode 100644 | 
| index cde31f74df3649981a912ba04fd55084634ec390..0000000000000000000000000000000000000000 | 
| --- a/third_party/twisted_8_1/twisted/internet/_sslverify.py | 
| +++ /dev/null | 
| @@ -1,949 +0,0 @@ | 
| -# -*- test-case-name: twisted.test.test_sslverify -*- | 
| -# Copyright 2005 Divmod, Inc.  See LICENSE file for details | 
| - | 
| -import hashlib | 
| -import itertools | 
| -from OpenSSL import SSL, crypto | 
| - | 
| -from twisted.python import reflect, util | 
| -from twisted.internet.defer import Deferred | 
| -from twisted.internet.error import VerifyError, CertificateError | 
| - | 
| -# Private - shared between all OpenSSLCertificateOptions, counts up to provide | 
| -# a unique session id for each context | 
| -_sessionCounter = itertools.count().next | 
| - | 
| -class _SSLApplicationData(object): | 
| -    def __init__(self): | 
| -        self.problems = [] | 
| - | 
| -class OpenSSLVerifyError(VerifyError): | 
| - | 
| -    _errorCodes = {0: ('X509_V_OK', | 
| -                       'ok', | 
| -                       'the operation was successful. >'), | 
| - | 
| -                   2: ('X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT', | 
| -                       'unable to get issuer certificate', | 
| -                       "The issuer certificate could not be found.  This " | 
| -                       "occurs if the issuer certificate of an untrusted " | 
| -                       "certificate cannot be found."), | 
| - | 
| -                   3: ('X509_V_ERR_UNABLE_TO_GET_CRL', | 
| -                       'unable to get certificate CRL', | 
| -                       "The CRL of a certificate could not be found. " | 
| -                       "Unused."), | 
| - | 
| -                   4: ('X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE', | 
| -                       "unable to decrypt certificate's signature", | 
| -                       "The certificate signature could not be decrypted.  " | 
| -                       "This means that the actual signature value could not " | 
| -                       "be determined rather than it not matching the " | 
| -                       "expected value, this is only meaningful for RSA " | 
| -                       "keys."), | 
| - | 
| -                   5: ('X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE', | 
| -                       "unable to decrypt CRL's signature", | 
| -                       "The CRL signature could not be decrypted.  This " | 
| -                       "means that the actual signature value could not be " | 
| -                       "determined rather than it not matching the expected " | 
| -                       "value. Unused."), | 
| - | 
| -                   6: ('X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY', | 
| -                       'unable to decode issuer', | 
| -                       "Public key the public key in the certificate " | 
| -                       "SubjectPublicKeyInfo could not be read."), | 
| - | 
| -                   7: ('X509_V_ERR_CERT_SIGNATURE_FAILURE', | 
| -                       'certificate signature failure', | 
| -                       'The signature of the certificate is invalid.'), | 
| - | 
| -                   8: ('X509_V_ERR_CRL_SIGNATURE_FAILURE', | 
| -                       'CRL signature failure', | 
| -                       'The signature of the certificate is invalid. Unused.'), | 
| - | 
| -                   9: ('X509_V_ERR_CERT_NOT_YET_VALID', | 
| -                       'certificate is not yet valid', | 
| -                       "The certificate is not yet valid.  The notBefore " | 
| -                       "date is after the current time."), | 
| - | 
| -                   10: ('X509_V_ERR_CERT_HAS_EXPIRED', | 
| -                        'certificate has expired', | 
| -                        "The certificate has expired.  The notAfter date " | 
| -                        "is before the current time."), | 
| - | 
| -                   11: ('X509_V_ERR_CRL_NOT_YET_VALID', | 
| -                        'CRL is not yet valid', | 
| -                        'The CRL is not yet valid. Unused.'), | 
| - | 
| -                   12: ('X509_V_ERR_CRL_HAS_EXPIRED', | 
| -                        'CRL has expired', | 
| -                        'The CRL has expired. Unused.'), | 
| - | 
| -                   13: ('X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD', | 
| -                        "format error in certificate's notBefore field", | 
| -                        "The certificate's notBefore field contains an " | 
| -                        "invalid time."), | 
| - | 
| -                   14: ('X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD', | 
| -                        "format error in certificate's notAfter field.", | 
| -                        "The certificate's notAfter field contains an " | 
| -                        "invalid time."), | 
| - | 
| -                   15: ('X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD', | 
| -                        "format error in CRL's lastUpdate field", | 
| -                        "The CRL lastUpdate field contains an invalid " | 
| -                        "time. Unused."), | 
| - | 
| -                   16: ('X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD', | 
| -                        "format error in CRL's nextUpdate field", | 
| -                        "The CRL nextUpdate field contains an invalid " | 
| -                        "time. Unused."), | 
| - | 
| -                   17: ('X509_V_ERR_OUT_OF_MEM', | 
| -                        'out of memory', | 
| -                        'An error occurred trying to allocate memory. ' | 
| -                        'This should never happen.'), | 
| - | 
| -                   18: ('X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT', | 
| -                        'self signed certificate', | 
| -                        'The passed certificate is self signed and the same ' | 
| -                        'certificate cannot be found in the list of trusted ' | 
| -                        'certificates.'), | 
| - | 
| -                   19: ('X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN', | 
| -                        'self signed certificate in certificate chain', | 
| -                        'The certificate chain could be built up using the ' | 
| -                        'untrusted certificates but the root could not be ' | 
| -                        'found locally.'), | 
| - | 
| -                   20: ('X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY', | 
| -                        'unable to get local issuer certificate', | 
| -                        'The issuer certificate of a locally looked up ' | 
| -                        'certificate could not be found. This normally ' | 
| -                        'means the list of trusted certificates is not ' | 
| -                        'complete.'), | 
| - | 
| -                   21: ('X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE', | 
| -                        'unable to verify the first certificate', | 
| -                        'No signatures could be verified because the chain ' | 
| -                        'contains only one certificate and it is not self ' | 
| -                        'signed.'), | 
| - | 
| -                   22: ('X509_V_ERR_CERT_CHAIN_TOO_LONG', | 
| -                        'certificate chain too long', | 
| -                        'The certificate chain length is greater than the ' | 
| -                        'supplied maximum depth. Unused.'), | 
| - | 
| -                   23: ('X509_V_ERR_CERT_REVOKED', | 
| -                        'certificate revoked', | 
| -                        'The certificate has been revoked. Unused.'), | 
| - | 
| -                   24: ('X509_V_ERR_INVALID_CA', | 
| -                        'invalid CA certificate', | 
| -                        'A CA certificate is invalid. Either it is not a CA ' | 
| -                        'or its extensions are not consistent with the ' | 
| -                        'supplied purpose.'), | 
| - | 
| -                   25: ('X509_V_ERR_PATH_LENGTH_EXCEEDED', | 
| -                        'path length constraint exceeded', | 
| -                        'The basicConstraints pathlength parameter has been ' | 
| -                        'exceeded.'), | 
| - | 
| -                   26: ('X509_V_ERR_INVALID_PURPOSE', | 
| -                        'unsupported certificate purpose', | 
| -                        'The supplied certificate cannot be used for the ' | 
| -                        'specified purpose.'), | 
| - | 
| -                   27: ('X509_V_ERR_CERT_UNTRUSTED', | 
| -                        'certificate not trusted', | 
| -                        'The root CA is not marked as trusted for the ' | 
| -                        'specified purpose.'), | 
| - | 
| -                   28: ('X509_V_ERR_CERT_REJECTED', | 
| -                        'certificate rejected', | 
| -                        'The root CA is marked to reject the specified ' | 
| -                        'purpose.'), | 
| - | 
| -                   29: ('X509_V_ERR_SUBJECT_ISSUER_MISMATCH', | 
| -                        'subject issuer mismatch', | 
| -                        'The current candidate issuer certificate was ' | 
| -                        'rejected because its subject name did not match ' | 
| -                        'the issuer name of the current certificate. Only ' | 
| -                        'displayed when the issuer_checks option is set.'), | 
| - | 
| -                   30: ('X509_V_ERR_AKID_SKID_MISMATCH', | 
| -                        'authority and subject key identifier mismatch', | 
| -                        'The current candidate issuer certificate was ' | 
| -                        'rejected because its subject key identifier was ' | 
| -                        'present and did not match the authority key ' | 
| -                        'identifier current certificate. Only displayed ' | 
| -                        'when the issuer_checks option is set.'), | 
| - | 
| -                   31: ('X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH', | 
| -                        'authority and issuer serial number mismatch', | 
| -                        'The current candidate issuer certificate was ' | 
| -                        'rejected because its issuer name and serial ' | 
| -                        'number was present and did not match the ' | 
| -                        'authority key identifier of the current ' | 
| -                        'certificate. Only displayed when the issuer_checks ' | 
| -                        'option is set.'), | 
| - | 
| -                   32: ('X509_V_ERR_KEYUSAGE_NO_CERTSIGN', | 
| -                        'key usage does not include certificate', | 
| -                        'Signing the current candidate issuer certificate was ' | 
| -                        'rejected because its keyUsage extension does not ' | 
| -                        'permit certificate signing.'), | 
| - | 
| -                   50: ('X509_V_ERR_APPLICATION_VERIFICATION', | 
| -                        'application verification failure', | 
| -                        'an application specific error. Unused.')} | 
| - | 
| - | 
| -    def __init__(self, cert, errno, depth): | 
| -        VerifyError.__init__(self, cert, errno, depth) | 
| -        self.cert = cert | 
| -        self.errno = errno | 
| -        self.depth = depth | 
| - | 
| -    def __repr__(self): | 
| -        x = self._errorCodes.get(self.errno) | 
| -        if x is not None: | 
| -            name, short, long = x | 
| -            return 'Peer Certificate Verification Failed: %s (error code: %d)' % ( | 
| -                long, self.errno | 
| -                ) | 
| -        return "Peer Certificate Verification Failed for Unknown Reason" | 
| - | 
| -    __str__ = __repr__ | 
| - | 
| - | 
| -_x509names = { | 
| -    'CN': 'commonName', | 
| -    'commonName': 'commonName', | 
| - | 
| -    'O': 'organizationName', | 
| -    'organizationName': 'organizationName', | 
| - | 
| -    'OU': 'organizationalUnitName', | 
| -    'organizationalUnitName': 'organizationalUnitName', | 
| - | 
| -    'L': 'localityName', | 
| -    'localityName': 'localityName', | 
| - | 
| -    'ST': 'stateOrProvinceName', | 
| -    'stateOrProvinceName': 'stateOrProvinceName', | 
| - | 
| -    'C': 'countryName', | 
| -    'countryName': 'countryName', | 
| - | 
| -    'emailAddress': 'emailAddress'} | 
| - | 
| - | 
| -class DistinguishedName(dict): | 
| -    """ | 
| -    Identify and describe an entity. | 
| - | 
| -    Distinguished names are used to provide a minimal amount of identifying | 
| -    information about a certificate issuer or subject.  They are commonly | 
| -    created with one or more of the following fields:: | 
| - | 
| -        commonName (CN) | 
| -        organizationName (O) | 
| -        organizationalUnitName (OU) | 
| -        localityName (L) | 
| -        stateOrProvinceName (ST) | 
| -        countryName (C) | 
| -        emailAddress | 
| -    """ | 
| -    __slots__ = () | 
| - | 
| -    def __init__(self, **kw): | 
| -        for k, v in kw.iteritems(): | 
| -            setattr(self, k, v) | 
| - | 
| - | 
| -    def _copyFrom(self, x509name): | 
| -        d = {} | 
| -        for name in _x509names: | 
| -            value = getattr(x509name, name, None) | 
| -            if value is not None: | 
| -                setattr(self, name, value) | 
| - | 
| - | 
| -    def _copyInto(self, x509name): | 
| -        for k, v in self.iteritems(): | 
| -            setattr(x509name, k, v) | 
| - | 
| - | 
| -    def __repr__(self): | 
| -        return '<DN %s>' % (dict.__repr__(self)[1:-1]) | 
| - | 
| - | 
| -    def __getattr__(self, attr): | 
| -        try: | 
| -            return self[_x509names[attr]] | 
| -        except KeyError: | 
| -            raise AttributeError(attr) | 
| - | 
| - | 
| -    def __setattr__(self, attr, value): | 
| -        assert type(attr) is str | 
| -        if not attr in _x509names: | 
| -            raise AttributeError("%s is not a valid OpenSSL X509 name field" % (attr,)) | 
| -        realAttr = _x509names[attr] | 
| -        value = value.encode('ascii') | 
| -        assert type(value) is str | 
| -        self[realAttr] = value | 
| - | 
| - | 
| -    def inspect(self): | 
| -        """ | 
| -        Return a multi-line, human-readable representation of this DN. | 
| -        """ | 
| -        l = [] | 
| -        lablen = 0 | 
| -        def uniqueValues(mapping): | 
| -            return dict.fromkeys(mapping.itervalues()).keys() | 
| -        for k in uniqueValues(_x509names): | 
| -            label = util.nameToLabel(k) | 
| -            lablen = max(len(label), lablen) | 
| -            v = getattr(self, k, None) | 
| -            if v is not None: | 
| -                l.append((label, v)) | 
| -        lablen += 2 | 
| -        for n, (label, attr) in enumerate(l): | 
| -            l[n] = (label.rjust(lablen)+': '+ attr) | 
| -        return '\n'.join(l) | 
| - | 
| -DN = DistinguishedName | 
| - | 
| - | 
| -class CertBase: | 
| -    def __init__(self, original): | 
| -        self.original = original | 
| - | 
| -    def _copyName(self, suffix): | 
| -        dn = DistinguishedName() | 
| -        dn._copyFrom(getattr(self.original, 'get_'+suffix)()) | 
| -        return dn | 
| - | 
| -    def getSubject(self): | 
| -        """ | 
| -        Retrieve the subject of this certificate. | 
| - | 
| -        @rtype: L{DistinguishedName} | 
| -        @return: A copy of the subject of this certificate. | 
| -        """ | 
| -        return self._copyName('subject') | 
| - | 
| - | 
| - | 
| -def problemsFromTransport(tpt): | 
| -    """ | 
| -    Retrieve the SSL errors associated with the given transport. | 
| - | 
| -    @type tpt: L{ISystemHandle} provider wrapper around an SSL connection. | 
| -    @rtype: C{list} of L{OpenSSLVerifyError}. | 
| -    """ | 
| -    return tpt.getHandle().get_context().get_app_data().problems | 
| - | 
| - | 
| -def _handleattrhelper(Class, transport, methodName): | 
| -    """ | 
| -    (private) Helper for L{Certificate.peerFromTransport} and | 
| -    L{Certificate.hostFromTransport} which checks for incompatible handle types | 
| -    and null certificates and raises the appropriate exception or returns the | 
| -    appropriate certificate object. | 
| -    """ | 
| -    method = getattr(transport.getHandle(), | 
| -                     "get_%s_certificate" % (methodName,), None) | 
| -    if method is None: | 
| -        raise CertificateError( | 
| -            "non-TLS transport %r did not have %s certificate" % (transport, methodName)) | 
| -    cert = method() | 
| -    if cert is None: | 
| -        raise CertificateError( | 
| -            "TLS transport %r did not have %s certificate" % (transport, methodName)) | 
| -    return Class(cert) | 
| - | 
| - | 
| -class Certificate(CertBase): | 
| -    """ | 
| -    An x509 certificate. | 
| -    """ | 
| -    def __repr__(self): | 
| -        return '<%s Subject=%s Issuer=%s>' % (self.__class__.__name__, | 
| -                                              self.getSubject().commonName, | 
| -                                              self.getIssuer().commonName) | 
| - | 
| -    def __eq__(self, other): | 
| -        if isinstance(other, Certificate): | 
| -            return self.dump() == other.dump() | 
| -        return False | 
| - | 
| - | 
| -    def __ne__(self, other): | 
| -        return not self.__eq__(other) | 
| - | 
| - | 
| -    def load(Class, requestData, format=crypto.FILETYPE_ASN1, args=()): | 
| -        """ | 
| -        Load a certificate from an ASN.1- or PEM-format string. | 
| - | 
| -        @rtype: C{Class} | 
| -        """ | 
| -        return Class(crypto.load_certificate(format, requestData), *args) | 
| -    load = classmethod(load) | 
| -    _load = load | 
| - | 
| - | 
| -    def dumpPEM(self): | 
| -        """ | 
| -        Dump this certificate to a PEM-format data string. | 
| - | 
| -        @rtype: C{str} | 
| -        """ | 
| -        return self.dump(crypto.FILETYPE_PEM) | 
| - | 
| - | 
| -    def loadPEM(Class, data): | 
| -        """ | 
| -        Load a certificate from a PEM-format data string. | 
| - | 
| -        @rtype: C{Class} | 
| -        """ | 
| -        return Class.load(data, crypto.FILETYPE_PEM) | 
| -    loadPEM = classmethod(loadPEM) | 
| - | 
| - | 
| -    def peerFromTransport(Class, transport): | 
| -        """ | 
| -        Get the certificate for the remote end of the given transport. | 
| - | 
| -        @type: L{ISystemHandle} | 
| -        @rtype: C{Class} | 
| - | 
| -        @raise: L{CertificateError}, if the given transport does not have a peer | 
| -        certificate. | 
| -        """ | 
| -        return _handleattrhelper(Class, transport, 'peer') | 
| -    peerFromTransport = classmethod(peerFromTransport) | 
| - | 
| - | 
| -    def hostFromTransport(Class, transport): | 
| -        """ | 
| -        Get the certificate for the local end of the given transport. | 
| - | 
| -        @param transport: an L{ISystemHandle} provider; the transport we will | 
| - | 
| -        @rtype: C{Class} | 
| - | 
| -        @raise: L{CertificateError}, if the given transport does not have a host | 
| -        certificate. | 
| -        """ | 
| -        return _handleattrhelper(Class, transport, 'host') | 
| -    hostFromTransport = classmethod(hostFromTransport) | 
| - | 
| - | 
| -    def getPublicKey(self): | 
| -        """ | 
| -        Get the public key for this certificate. | 
| - | 
| -        @rtype: L{PublicKey} | 
| -        """ | 
| -        return PublicKey(self.original.get_pubkey()) | 
| - | 
| - | 
| -    def dump(self, format=crypto.FILETYPE_ASN1): | 
| -        return crypto.dump_certificate(format, self.original) | 
| - | 
| - | 
| -    def serialNumber(self): | 
| -        """ | 
| -        Retrieve the serial number of this certificate. | 
| - | 
| -        @rtype: C{int} | 
| -        """ | 
| -        return self.original.get_serial_number() | 
| - | 
| - | 
| -    def digest(self, method='md5'): | 
| -        """ | 
| -        Return a digest hash of this certificate using the specified hash | 
| -        algorithm. | 
| - | 
| -        @param method: One of C{'md5'} or C{'sha'}. | 
| -        @rtype: C{str} | 
| -        """ | 
| -        return self.original.digest(method) | 
| - | 
| - | 
| -    def _inspect(self): | 
| -        return '\n'.join(['Certificate For Subject:', | 
| -                          self.getSubject().inspect(), | 
| -                          '\nIssuer:', | 
| -                          self.getIssuer().inspect(), | 
| -                          '\nSerial Number: %d' % self.serialNumber(), | 
| -                          'Digest: %s' % self.digest()]) | 
| - | 
| - | 
| -    def inspect(self): | 
| -        """ | 
| -        Return a multi-line, human-readable representation of this | 
| -        Certificate, including information about the subject, issuer, and | 
| -        public key. | 
| -        """ | 
| -        return '\n'.join((self._inspect(), self.getPublicKey().inspect())) | 
| - | 
| - | 
| -    def getIssuer(self): | 
| -        """ | 
| -        Retrieve the issuer of this certificate. | 
| - | 
| -        @rtype: L{DistinguishedName} | 
| -        @return: A copy of the issuer of this certificate. | 
| -        """ | 
| -        return self._copyName('issuer') | 
| - | 
| - | 
| -    def options(self, *authorities): | 
| -        raise NotImplementedError('Possible, but doubtful we need this yet') | 
| - | 
| - | 
| - | 
| -class CertificateRequest(CertBase): | 
| -    """ | 
| -    An x509 certificate request. | 
| - | 
| -    Certificate requests are given to certificate authorities to be signed and | 
| -    returned resulting in an actual certificate. | 
| -    """ | 
| -    def load(Class, requestData, requestFormat=crypto.FILETYPE_ASN1): | 
| -        req = crypto.load_certificate_request(requestFormat, requestData) | 
| -        dn = DistinguishedName() | 
| -        dn._copyFrom(req.get_subject()) | 
| -        if not req.verify(req.get_pubkey()): | 
| -            raise VerifyError("Can't verify that request for %r is self-signed." % (dn,)) | 
| -        return Class(req) | 
| -    load = classmethod(load) | 
| - | 
| - | 
| -    def dump(self, format=crypto.FILETYPE_ASN1): | 
| -        return crypto.dump_certificate_request(format, self.original) | 
| - | 
| - | 
| - | 
| -class PrivateCertificate(Certificate): | 
| -    """ | 
| -    An x509 certificate and private key. | 
| -    """ | 
| -    def __repr__(self): | 
| -        return Certificate.__repr__(self) + ' with ' + repr(self.privateKey) | 
| - | 
| - | 
| -    def _setPrivateKey(self, privateKey): | 
| -        if not privateKey.matches(self.getPublicKey()): | 
| -            raise VerifyError( | 
| -                "Sanity check failed: Your certificate was not properly signed.") | 
| -        self.privateKey = privateKey | 
| -        return self | 
| - | 
| - | 
| -    def newCertificate(self, newCertData, format=crypto.FILETYPE_ASN1): | 
| -        """ | 
| -        Create a new L{PrivateCertificate} from the given certificate data and | 
| -        this instance's private key. | 
| -        """ | 
| -        return self.load(newCertData, self.privateKey, format) | 
| - | 
| - | 
| -    def load(Class, data, privateKey, format=crypto.FILETYPE_ASN1): | 
| -        return Class._load(data, format)._setPrivateKey(privateKey) | 
| -    load = classmethod(load) | 
| - | 
| - | 
| -    def inspect(self): | 
| -        return '\n'.join([Certificate._inspect(self), | 
| -                          self.privateKey.inspect()]) | 
| - | 
| - | 
| -    def dumpPEM(self): | 
| -        """ | 
| -        Dump both public and private parts of a private certificate to | 
| -        PEM-format data. | 
| -        """ | 
| -        return self.dump(crypto.FILETYPE_PEM) + self.privateKey.dump(crypto.FILETYPE_PEM) | 
| - | 
| - | 
| -    def loadPEM(Class, data): | 
| -        """ | 
| -        Load both private and public parts of a private certificate from a | 
| -        chunk of PEM-format data. | 
| -        """ | 
| -        return Class.load(data, KeyPair.load(data, crypto.FILETYPE_PEM), | 
| -                          crypto.FILETYPE_PEM) | 
| -    loadPEM = classmethod(loadPEM) | 
| - | 
| - | 
| -    def fromCertificateAndKeyPair(Class, certificateInstance, privateKey): | 
| -        privcert = Class(certificateInstance.original) | 
| -        return privcert._setPrivateKey(privateKey) | 
| -    fromCertificateAndKeyPair = classmethod(fromCertificateAndKeyPair) | 
| - | 
| - | 
| -    def options(self, *authorities): | 
| -        options = dict(privateKey=self.privateKey.original, | 
| -                       certificate=self.original) | 
| -        if authorities: | 
| -            options.update(dict(verify=True, | 
| -                                requireCertificate=True, | 
| -                                caCerts=[auth.original for auth in authorities])) | 
| -        return OpenSSLCertificateOptions(**options) | 
| - | 
| - | 
| -    def certificateRequest(self, format=crypto.FILETYPE_ASN1, | 
| -                           digestAlgorithm='md5'): | 
| -        return self.privateKey.certificateRequest( | 
| -            self.getSubject(), | 
| -            format, | 
| -            digestAlgorithm) | 
| - | 
| - | 
| -    def signCertificateRequest(self, | 
| -                               requestData, | 
| -                               verifyDNCallback, | 
| -                               serialNumber, | 
| -                               requestFormat=crypto.FILETYPE_ASN1, | 
| -                               certificateFormat=crypto.FILETYPE_ASN1): | 
| -        issuer = self.getSubject() | 
| -        return self.privateKey.signCertificateRequest( | 
| -            issuer, | 
| -            requestData, | 
| -            verifyDNCallback, | 
| -            serialNumber, | 
| -            requestFormat, | 
| -            certificateFormat) | 
| - | 
| - | 
| -    def signRequestObject(self, certificateRequest, serialNumber, | 
| -                          secondsToExpiry=60 * 60 * 24 * 365, # One year | 
| -                          digestAlgorithm='md5'): | 
| -        return self.privateKey.signRequestObject(self.getSubject(), | 
| -                                                 certificateRequest, | 
| -                                                 serialNumber, | 
| -                                                 secondsToExpiry, | 
| -                                                 digestAlgorithm) | 
| - | 
| - | 
| -class PublicKey: | 
| -    def __init__(self, osslpkey): | 
| -        self.original = osslpkey | 
| -        req1 = crypto.X509Req() | 
| -        req1.set_pubkey(osslpkey) | 
| -        self._emptyReq = crypto.dump_certificate_request(crypto.FILETYPE_ASN1, req1) | 
| - | 
| - | 
| -    def matches(self, otherKey): | 
| -        return self._emptyReq == otherKey._emptyReq | 
| - | 
| - | 
| -    # XXX This could be a useful method, but sometimes it triggers a segfault, | 
| -    # so we'll steer clear for now. | 
| -#     def verifyCertificate(self, certificate): | 
| -#         """ | 
| -#         returns None, or raises a VerifyError exception if the certificate | 
| -#         could not be verified. | 
| -#         """ | 
| -#         if not certificate.original.verify(self.original): | 
| -#             raise VerifyError("We didn't sign that certificate.") | 
| - | 
| -    def __repr__(self): | 
| -        return '<%s %s>' % (self.__class__.__name__, self.keyHash()) | 
| - | 
| - | 
| -    def keyHash(self): | 
| -        """ | 
| -        MD5 hex digest of signature on an empty certificate request with this | 
| -        key. | 
| -        """ | 
| -        return hashlib.md5(self._emptyReq).hexdigest() | 
| - | 
| - | 
| -    def inspect(self): | 
| -        return 'Public Key with Hash: %s' % (self.keyHash(),) | 
| - | 
| - | 
| - | 
| -class KeyPair(PublicKey): | 
| - | 
| -    def load(Class, data, format=crypto.FILETYPE_ASN1): | 
| -        return Class(crypto.load_privatekey(format, data)) | 
| -    load = classmethod(load) | 
| - | 
| - | 
| -    def dump(self, format=crypto.FILETYPE_ASN1): | 
| -        return crypto.dump_privatekey(format, self.original) | 
| - | 
| - | 
| -    def __getstate__(self): | 
| -        return self.dump() | 
| - | 
| - | 
| -    def __setstate__(self, state): | 
| -        self.__init__(crypto.load_privatekey(crypto.FILETYPE_ASN1, state)) | 
| - | 
| - | 
| -    def inspect(self): | 
| -        t = self.original.type() | 
| -        if t == crypto.TYPE_RSA: | 
| -            ts = 'RSA' | 
| -        elif t == crypto.TYPE_DSA: | 
| -            ts = 'DSA' | 
| -        else: | 
| -            ts = '(Unknown Type!)' | 
| -        L = (self.original.bits(), ts, self.keyHash()) | 
| -        return '%s-bit %s Key Pair with Hash: %s' % L | 
| - | 
| - | 
| -    def generate(Class, kind=crypto.TYPE_RSA, size=1024): | 
| -        pkey = crypto.PKey() | 
| -        pkey.generate_key(kind, size) | 
| -        return Class(pkey) | 
| - | 
| - | 
| -    def newCertificate(self, newCertData, format=crypto.FILETYPE_ASN1): | 
| -        return PrivateCertificate.load(newCertData, self, format) | 
| -    generate = classmethod(generate) | 
| - | 
| - | 
| -    def requestObject(self, distinguishedName, digestAlgorithm='md5'): | 
| -        req = crypto.X509Req() | 
| -        req.set_pubkey(self.original) | 
| -        distinguishedName._copyInto(req.get_subject()) | 
| -        req.sign(self.original, digestAlgorithm) | 
| -        return CertificateRequest(req) | 
| - | 
| - | 
| -    def certificateRequest(self, distinguishedName, | 
| -                           format=crypto.FILETYPE_ASN1, | 
| -                           digestAlgorithm='md5'): | 
| -        """Create a certificate request signed with this key. | 
| - | 
| -        @return: a string, formatted according to the 'format' argument. | 
| -        """ | 
| -        return self.requestObject(distinguishedName, digestAlgorithm).dump(format) | 
| - | 
| - | 
| -    def signCertificateRequest(self, | 
| -                               issuerDistinguishedName, | 
| -                               requestData, | 
| -                               verifyDNCallback, | 
| -                               serialNumber, | 
| -                               requestFormat=crypto.FILETYPE_ASN1, | 
| -                               certificateFormat=crypto.FILETYPE_ASN1, | 
| -                               secondsToExpiry=60 * 60 * 24 * 365, # One year | 
| -                               digestAlgorithm='md5'): | 
| -        """ | 
| -        Given a blob of certificate request data and a certificate authority's | 
| -        DistinguishedName, return a blob of signed certificate data. | 
| - | 
| -        If verifyDNCallback returns a Deferred, I will return a Deferred which | 
| -        fires the data when that Deferred has completed. | 
| -        """ | 
| -        hlreq = CertificateRequest.load(requestData, requestFormat) | 
| - | 
| -        dn = hlreq.getSubject() | 
| -        vval = verifyDNCallback(dn) | 
| - | 
| -        def verified(value): | 
| -            if not value: | 
| -                raise VerifyError("DN callback %r rejected request DN %r" % (verifyDNCallback, dn)) | 
| -            return self.signRequestObject(issuerDistinguishedName, hlreq, | 
| -                                          serialNumber, secondsToExpiry, digestAlgorithm).dump(certificateFormat) | 
| - | 
| -        if isinstance(vval, Deferred): | 
| -            return vval.addCallback(verified) | 
| -        else: | 
| -            return verified(vval) | 
| - | 
| - | 
| -    def signRequestObject(self, | 
| -                          issuerDistinguishedName, | 
| -                          requestObject, | 
| -                          serialNumber, | 
| -                          secondsToExpiry=60 * 60 * 24 * 365, # One year | 
| -                          digestAlgorithm='md5'): | 
| -        """ | 
| -        Sign a CertificateRequest instance, returning a Certificate instance. | 
| -        """ | 
| -        req = requestObject.original | 
| -        dn = requestObject.getSubject() | 
| -        cert = crypto.X509() | 
| -        issuerDistinguishedName._copyInto(cert.get_issuer()) | 
| -        cert.set_subject(req.get_subject()) | 
| -        cert.set_pubkey(req.get_pubkey()) | 
| -        cert.gmtime_adj_notBefore(0) | 
| -        cert.gmtime_adj_notAfter(secondsToExpiry) | 
| -        cert.set_serial_number(serialNumber) | 
| -        cert.sign(self.original, digestAlgorithm) | 
| -        return Certificate(cert) | 
| - | 
| - | 
| -    def selfSignedCert(self, serialNumber, **kw): | 
| -        dn = DN(**kw) | 
| -        return PrivateCertificate.fromCertificateAndKeyPair( | 
| -            self.signRequestObject(dn, self.requestObject(dn), serialNumber), | 
| -            self) | 
| - | 
| - | 
| - | 
| -class OpenSSLCertificateOptions(object): | 
| -    """ | 
| -    A factory for SSL context objects for both SSL servers and clients. | 
| -    """ | 
| - | 
| -    _context = None | 
| -    # Older versions of PyOpenSSL didn't provide OP_ALL.  Fudge it here, just in case. | 
| -    _OP_ALL = getattr(SSL, 'OP_ALL', 0x0000FFFF) | 
| - | 
| -    method = SSL.TLSv1_METHOD | 
| - | 
| -    def __init__(self, | 
| -                 privateKey=None, | 
| -                 certificate=None, | 
| -                 method=None, | 
| -                 verify=False, | 
| -                 caCerts=None, | 
| -                 verifyDepth=9, | 
| -                 requireCertificate=True, | 
| -                 verifyOnce=True, | 
| -                 enableSingleUseKeys=True, | 
| -                 enableSessions=True, | 
| -                 fixBrokenPeers=False): | 
| -        """ | 
| -        Create an OpenSSL context SSL connection context factory. | 
| - | 
| -        @param privateKey: A PKey object holding the private key. | 
| - | 
| -        @param certificate: An X509 object holding the certificate. | 
| - | 
| -        @param method: The SSL protocol to use, one of SSLv23_METHOD, | 
| -        SSLv2_METHOD, SSLv3_METHOD, TLSv1_METHOD.  Defaults to TLSv1_METHOD. | 
| - | 
| -        @param verify: If True, verify certificates received from the peer and | 
| -        fail the handshake if verification fails.  Otherwise, allow anonymous | 
| -        sessions and sessions with certificates which fail validation.  By | 
| -        default this is False. | 
| - | 
| -        @param caCerts: List of certificate authority certificates to | 
| -        send to the client when requesting a certificate.  Only used if verify | 
| -        is True, and if verify is True, either this must be specified or | 
| -        caCertsFile must be given.  Since verify is False by default, | 
| -        this is None by default. | 
| - | 
| -        @param verifyDepth: Depth in certificate chain down to which to verify. | 
| -        If unspecified, use the underlying default (9). | 
| - | 
| -        @param requireCertificate: If True, do not allow anonymous sessions. | 
| - | 
| -        @param verifyOnce: If True, do not re-verify the certificate | 
| -        on session resumption. | 
| - | 
| -        @param enableSingleUseKeys: If True, generate a new key whenever | 
| -        ephemeral DH parameters are used to prevent small subgroup attacks. | 
| - | 
| -        @param enableSessions: If True, set a session ID on each context.  This | 
| -        allows a shortened handshake to be used when a known client reconnects. | 
| - | 
| -        @param fixBrokenPeers: If True, enable various non-spec protocol fixes | 
| -        for broken SSL implementations.  This should be entirely safe, | 
| -        according to the OpenSSL documentation, but YMMV.  This option is now | 
| -        off by default, because it causes problems with connections between | 
| -        peers using OpenSSL 0.9.8a. | 
| -        """ | 
| - | 
| -        assert (privateKey is None) == (certificate is None), "Specify neither or both of privateKey and certificate" | 
| -        self.privateKey = privateKey | 
| -        self.certificate = certificate | 
| -        if method is not None: | 
| -            self.method = method | 
| - | 
| -        self.verify = verify | 
| -        assert ((verify and caCerts) or | 
| -                (not verify)), "Specify client CA certificate information if and only if enabling certificate verification" | 
| - | 
| -        self.caCerts = caCerts | 
| -        self.verifyDepth = verifyDepth | 
| -        self.requireCertificate = requireCertificate | 
| -        self.verifyOnce = verifyOnce | 
| -        self.enableSingleUseKeys = enableSingleUseKeys | 
| -        self.enableSessions = enableSessions | 
| -        self.fixBrokenPeers = fixBrokenPeers | 
| - | 
| - | 
| -    def __getstate__(self): | 
| -        d = self.__dict__.copy() | 
| -        try: | 
| -            del d['_context'] | 
| -        except KeyError: | 
| -            pass | 
| -        return d | 
| - | 
| - | 
| -    def __setstate__(self, state): | 
| -        self.__dict__ = state | 
| - | 
| - | 
| -    def getContext(self): | 
| -        """Return a SSL.Context object. | 
| -        """ | 
| -        if self._context is None: | 
| -            self._context = self._makeContext() | 
| -        return self._context | 
| - | 
| - | 
| -    def _makeContext(self): | 
| -        ctx = SSL.Context(self.method) | 
| -        ctx.set_app_data(_SSLApplicationData()) | 
| - | 
| -        if self.certificate is not None and self.privateKey is not None: | 
| -            ctx.use_certificate(self.certificate) | 
| -            ctx.use_privatekey(self.privateKey) | 
| -            # Sanity check | 
| -            ctx.check_privatekey() | 
| - | 
| -        verifyFlags = SSL.VERIFY_NONE | 
| -        if self.verify: | 
| -            verifyFlags = SSL.VERIFY_PEER | 
| -            if self.requireCertificate: | 
| -                verifyFlags |= SSL.VERIFY_FAIL_IF_NO_PEER_CERT | 
| -            if self.verifyOnce: | 
| -                verifyFlags |= SSL.VERIFY_CLIENT_ONCE | 
| -            if self.caCerts: | 
| -                store = ctx.get_cert_store() | 
| -                for cert in self.caCerts: | 
| -                    store.add_cert(cert) | 
| - | 
| -        def _trackVerificationProblems(conn,cert,errno,depth,preverify_ok): | 
| -            # retcode is the answer OpenSSL's default verifier would have | 
| -            # given, had we allowed it to run. | 
| -            if not preverify_ok: | 
| -                ctx.get_app_data().problems.append(OpenSSLVerifyError(cert, errno, depth)) | 
| -            return preverify_ok | 
| -        ctx.set_verify(verifyFlags, _trackVerificationProblems) | 
| - | 
| -        if self.verifyDepth is not None: | 
| -            ctx.set_verify_depth(self.verifyDepth) | 
| - | 
| -        if self.enableSingleUseKeys: | 
| -            ctx.set_options(SSL.OP_SINGLE_DH_USE) | 
| - | 
| -        if self.fixBrokenPeers: | 
| -            ctx.set_options(self._OP_ALL) | 
| - | 
| -        if self.enableSessions: | 
| -            sessionName = hashlib.md5("%s-%d" % (reflect.qual(self.__class__), _sessionCounter())).hexdigest() | 
| -            ctx.set_session_id(sessionName) | 
| - | 
| -        return ctx | 
|  |