(self,
                  server_hostname,
                  verify,
                  trust_bundle,
                  min_version,
                  max_version,
                  client_cert,
                  client_key,
                  client_key_passphrase)
Actually performs the TLS handshake. This is run automatically by
        wrapped socket, and shouldn't be needed in user code.
Actually performs the TLS handshake. This is run automatically by
        wrapped socket, and shouldn't be needed in user code.
Actually performs the TLS handshake . This is run automatically by wrapped socket and shouldn t be needed in user code .
def handshake(self,
                  server_hostname,
                  verify,
                  trust_bundle,
                  min_version,
                  max_version,
                  client_cert,
                  client_key,
                  client_key_passphrase):
        """
        Actually performs the TLS handshake. This is run automatically by
        wrapped socket, and shouldn't be needed in user code.
        """
        # First, we do the initial bits of connection setup. We need to create
        # a context, set its I/O funcs, and set the connection reference.
        self.context = Security.SSLCreateContext(
            None, SecurityConst.kSSLClientSide, SecurityConst.kSSLStreamType
        )
        result = Security.SSLSetIOFuncs(
            self.context, _read_callback_pointer, _write_callback_pointer
        )
        _assert_no_error(result)

        # Here we need to compute the handle to use. We do this by taking the
        # id of self modulo 2**31 - 1. If this is already in the dictionary, we
        # just keep incrementing by one until we find a free space.
        with _connection_ref_lock:
            handle = id(self) % 2147483647
            while handle in _connection_refs:
                handle = (handle + 1) % 2147483647
            _connection_refs[handle] = self

        result = Security.SSLSetConnection(self.context, handle)
        _assert_no_error(result)

        # If we have a server hostname, we should set that too.
        if server_hostname:
            if not isinstance(server_hostname, bytes):
                server_hostname = server_hostname.encode('utf-8')

            result = Security.SSLSetPeerDomainName(
                self.context, server_hostname, len(server_hostname)
            )
            _assert_no_error(result)

        # Setup the ciphers.
        self._set_ciphers()

        # Set the minimum and maximum TLS versions.
        result = Security.SSLSetProtocolVersionMin(self.context, min_version)
        _assert_no_error(result)

        # TLS 1.3 isn't necessarily enabled by the OS
        # so we have to detect when we error out and try
        # setting TLS 1.3 if it's allowed. kTLSProtocolMaxSupported
        # was added in macOS 10.13 along with kTLSProtocol13.
        result = Security.SSLSetProtocolVersionMax(self.context, max_version)
        if result != 0 and max_version == SecurityConst.kTLSProtocolMaxSupported:
            result = Security.SSLSetProtocolVersionMax(self.context, SecurityConst.kTLSProtocol12)
        _assert_no_error(result)

        # If there's a trust DB, we need to use it. We do that by telling
        # SecureTransport to break on server auth. We also do that if we don't
        # want to validate the certs at all: we just won't actually do any
        # authing in that case.
        if not verify or trust_bundle is not None:
            result = Security.SSLSetSessionOption(
                self.context,
                SecurityConst.kSSLSessionOptionBreakOnServerAuth,
                True
            )
            _assert_no_error(result)

        # If there's a client cert, we need to use it.
        if client_cert:
            self._keychain, self._keychain_dir = _temporary_keychain()
            self._client_cert_chain = _load_client_cert_chain(
                self._keychain, client_cert, client_key
            )
            result = Security.SSLSetCertificate(
                self.context, self._client_cert_chain
            )
            _assert_no_error(result)

        while True:
            with self._raise_on_error():
                result = Security.SSLHandshake(self.context)

                if result == SecurityConst.errSSLWouldBlock:
                    raise socket.timeout("handshake timed out")
                elif result == SecurityConst.errSSLServerAuthCompleted:
                    self._custom_validate(verify, trust_bundle)
                    continue
                else:
                    _assert_no_error(result)
                    break
def handshake ( self , server_hostname , verify , trust_bundle , min_version , max_version , client_cert , client_key , client_key_passphrase ) : # First, we do the initial bits of connection setup. We need to create # a context, set its I/O funcs, and set the connection reference. self . context = Security . SSLCreateContext ( None , SecurityConst . kSSLClientSide , SecurityConst . kSSLStreamType ) result = Security . SSLSetIOFuncs ( self . context , _read_callback_pointer , _write_callback_pointer ) _assert_no_error ( result ) # Here we need to compute the handle to use. We do this by taking the # id of self modulo 2**31 - 1. If this is already in the dictionary, we # just keep incrementing by one until we find a free space. with _connection_ref_lock : handle = id ( self ) % 2147483647 while handle in _connection_refs : handle = ( handle + 1 ) % 2147483647 _connection_refs [ handle ] = self result = Security . SSLSetConnection ( self . context , handle ) _assert_no_error ( result ) # If we have a server hostname, we should set that too. if server_hostname : if not isinstance ( server_hostname , bytes ) : server_hostname = server_hostname . encode ( 'utf-8' ) result = Security . SSLSetPeerDomainName ( self . context , server_hostname , len ( server_hostname ) ) _assert_no_error ( result ) # Setup the ciphers. self . _set_ciphers ( ) # Set the minimum and maximum TLS versions. result = Security . SSLSetProtocolVersionMin ( self . context , min_version ) _assert_no_error ( result ) # TLS 1.3 isn't necessarily enabled by the OS # so we have to detect when we error out and try # setting TLS 1.3 if it's allowed. kTLSProtocolMaxSupported # was added in macOS 10.13 along with kTLSProtocol13. result = Security . SSLSetProtocolVersionMax ( self . context , max_version ) if result != 0 and max_version == SecurityConst . kTLSProtocolMaxSupported : result = Security . SSLSetProtocolVersionMax ( self . context , SecurityConst . kTLSProtocol12 ) _assert_no_error ( result ) # If there's a trust DB, we need to use it. We do that by telling # SecureTransport to break on server auth. We also do that if we don't # want to validate the certs at all: we just won't actually do any # authing in that case. if not verify or trust_bundle is not None : result = Security . SSLSetSessionOption ( self . context , SecurityConst . kSSLSessionOptionBreakOnServerAuth , True ) _assert_no_error ( result ) # If there's a client cert, we need to use it. if client_cert : self . _keychain , self . _keychain_dir = _temporary_keychain ( ) self . _client_cert_chain = _load_client_cert_chain ( self . _keychain , client_cert , client_key ) result = Security . SSLSetCertificate ( self . context , self . _client_cert_chain ) _assert_no_error ( result ) while True : with self . _raise_on_error ( ) : result = Security . SSLHandshake ( self . context ) if result == SecurityConst . errSSLWouldBlock : raise socket . timeout ( "handshake timed out" ) elif result == SecurityConst . errSSLServerAuthCompleted : self . _custom_validate ( verify , trust_bundle ) continue else : _assert_no_error ( result ) break