Exemplo n.º 1
0
    def connect(self):
        """
        Create the SecureTransport SSLContextRef object and initialize it.
        """

        self.ctx = security.SSLCreateContext(ffi.NULL, security.kSSLClientSide if self.is_client else security.kSSLServerSide, security.kSSLStreamType)

        minVersion = None
        for option, minValue in (
            (OP_NO_SSLv2, security.kSSLProtocol3),
            (OP_NO_SSLv3, security.kTLSProtocol1),
            (OP_NO_TLSv1, security.kTLSProtocol11),
            (OP_NO_TLSv1_1, security.kTLSProtocol12),
            (OP_NO_TLSv1_2, security.kTLSProtocol12),   # TLS1.2 is the highest supported right now
        ):
            if option in self.context.options:
                minVersion = minValue
        if minVersion is not None:
            security.SSLSetProtocolVersionMin(self.ctx, minVersion)

        # Make sure we have a reference back to this L{Connection} in the SecureTransport callbacks
        self.connref = ffi.new("int *", self.engine_id)
        err = security.SSLSetConnection(self.ctx, ffi.cast("SSLConnectionRef", self.connref))
        if err:
            self.shutdown()
            raise Error(err)

        # Setup the actual SecureTransport callbacks
        err = security.SSLSetIOFuncs(self.ctx, self._read, self._write)
        if err:
            self.shutdown()
            raise Error(err)

        # Must have a certificate identity if we are a server
        if not self.is_client and self.context.identity is None:
            self.shutdown()
            raise Error("No certificate")

        # Must have a peer name if we are a client
        if self.is_client and not self.context.peerName:
            self.shutdown()
            raise Error("No peer name set with client connection.")
        elif self.is_client:
            # Always set the client peer name for proper certificate validation
            err = security.SSLSetPeerDomainName(self.ctx, self.context.peerName, len(self.context.peerName))
            if err:
                self.shutdown()
                raise Error(err)

        # Add the certificate
        if self.context.identity is not None:
            certs = CFArrayRef.fromList([self.context.identity])
            err = security.SSLSetCertificate(self.ctx, certs.ref())
            if err:
                self.shutdown()
                raise Error(err)
Exemplo n.º 2
0
    def get_subject(self):
        """
        Use Security.framework to extract the componentized SubjectName field and map OID
        values to strings and store in an L{X509Name} object.
        """
        keys = CFArrayRef.fromList(
            [CFStringRef.fromRef(security.kSecOIDX509V1SubjectName)])
        error = ffi.new("CFErrorRef *")
        values = security.SecCertificateCopyValues(self._x509.ref(),
                                                   keys.ref(), error)
        if values == ffi.NULL:
            error = CFErrorRef(error[0])
            raise Error("Unable to get certificate subject")
        values = CFDictionaryRef(values).toDict()
        value = values[str(
            CFStringRef.fromRef(security.kSecOIDX509V1SubjectName))]

        components = {}
        if value[str(CFStringRef.fromRef(
                security.kSecPropertyKeyType))] == str(
                    CFStringRef.fromRef(security.kSecPropertyTypeSection)):
            for item in value[str(
                    CFStringRef.fromRef(security.kSecPropertyKeyValue))]:
                if item[str(CFStringRef.fromRef(
                        security.kSecPropertyKeyType))] == str(
                            CFStringRef.fromRef(
                                security.kSecPropertyTypeString)):
                    v = item[str(
                        CFStringRef.fromRef(security.kSecPropertyKeyValue))]
                    k = OID2STR.get(
                        item[str(
                            CFStringRef.fromRef(
                                security.kSecPropertyKeyLabel))], "Unknown")
                    components[k] = v

        return X509Name("Subject Name", components)