def _handshake(self, renegotiate=False):
in_buffers = None<EOL>out_buffers = None<EOL>new_context_handle_pointer = None<EOL>try:<EOL><INDENT>if renegotiate:<EOL><INDENT>temp_context_handle_pointer = self._context_handle_pointer<EOL><DEDENT>else:<EOL><INDENT>new_context_handle_pointer = new(secur32, '<STR_LIT>')<EOL>temp_context_handle_pointer = new_context_handle_pointer<EOL><DEDENT>requested_flags = {<EOL>Secur32Const.ISC_REQ_REPLAY_DETECT: '<STR_LIT>',<EOL>Secur32Const.ISC_REQ_SEQUENCE_DETECT: '<STR_LIT>',<EOL>Secur32Const.ISC_REQ_CONFIDENTIALITY: '<STR_LIT>',<EOL>Secur32Const.ISC_REQ_ALLOCATE_MEMORY: '<STR_LIT>',<EOL>Secur32Const.ISC_REQ_INTEGRITY: '<STR_LIT>',<EOL>Secur32Const.ISC_REQ_STREAM: '<STR_LIT>',<EOL>Secur32Const.ISC_REQ_USE_SUPPLIED_CREDS: '<STR_LIT>',<EOL>}<EOL>self._context_flags = <NUM_LIT:0><EOL>for flag in requested_flags:<EOL><INDENT>self._context_flags |= flag<EOL><DEDENT>in_sec_buffer_desc_pointer, in_buffers = self._create_buffers(<NUM_LIT:2>)<EOL>in_buffers[<NUM_LIT:0>].BufferType = Secur32Const.SECBUFFER_TOKEN<EOL>out_sec_buffer_desc_pointer, out_buffers = self._create_buffers(<NUM_LIT:2>)<EOL>out_buffers[<NUM_LIT:0>].BufferType = Secur32Const.SECBUFFER_TOKEN<EOL>out_buffers[<NUM_LIT:1>].BufferType = Secur32Const.SECBUFFER_ALERT<EOL>output_context_flags_pointer = new(secur32, '<STR_LIT>')<EOL>if renegotiate:<EOL><INDENT>first_handle = temp_context_handle_pointer<EOL>second_handle = null()<EOL><DEDENT>else:<EOL><INDENT>first_handle = null()<EOL>second_handle = temp_context_handle_pointer<EOL><DEDENT>result = secur32.InitializeSecurityContextW(<EOL>self._session._credentials_handle,<EOL>first_handle,<EOL>self._hostname,<EOL>self._context_flags,<EOL><NUM_LIT:0>,<EOL><NUM_LIT:0>,<EOL>null(),<EOL><NUM_LIT:0>,<EOL>second_handle,<EOL>out_sec_buffer_desc_pointer,<EOL>output_context_flags_pointer,<EOL>null()<EOL>)<EOL>if result not in set([Secur32Const.SEC_E_OK, Secur32Const.SEC_I_CONTINUE_NEEDED]):<EOL><INDENT>handle_error(result, TLSError)<EOL><DEDENT>if not renegotiate:<EOL><INDENT>temp_context_handle_pointer = second_handle<EOL><DEDENT>else:<EOL><INDENT>temp_context_handle_pointer = first_handle<EOL><DEDENT>handshake_server_bytes = b'<STR_LIT>'<EOL>handshake_client_bytes = b'<STR_LIT>'<EOL>if out_buffers[<NUM_LIT:0>].cbBuffer > <NUM_LIT:0>:<EOL><INDENT>token = bytes_from_buffer(out_buffers[<NUM_LIT:0>].pvBuffer, out_buffers[<NUM_LIT:0>].cbBuffer)<EOL>handshake_client_bytes += token<EOL>self._socket.send(token)<EOL>out_buffers[<NUM_LIT:0>].cbBuffer = <NUM_LIT:0><EOL>secur32.FreeContextBuffer(out_buffers[<NUM_LIT:0>].pvBuffer)<EOL>out_buffers[<NUM_LIT:0>].pvBuffer = null()<EOL><DEDENT>in_data_buffer = buffer_from_bytes(<NUM_LIT>)<EOL>in_buffers[<NUM_LIT:0>].pvBuffer = cast(secur32, '<STR_LIT>', in_data_buffer)<EOL>bytes_read = b'<STR_LIT>'<EOL>while result != Secur32Const.SEC_E_OK:<EOL><INDENT>try:<EOL><INDENT>fail_late = False<EOL>bytes_read = self._socket.recv(<NUM_LIT>)<EOL>if bytes_read == b'<STR_LIT>':<EOL><INDENT>raise_disconnection()<EOL><DEDENT><DEDENT>except (socket_error_cls):<EOL><INDENT>fail_late = True<EOL><DEDENT>handshake_server_bytes += bytes_read<EOL>self._received_bytes += bytes_read<EOL>in_buffers[<NUM_LIT:0>].cbBuffer = len(self._received_bytes)<EOL>write_to_buffer(in_data_buffer, self._received_bytes)<EOL>result = secur32.InitializeSecurityContextW(<EOL>self._session._credentials_handle,<EOL>temp_context_handle_pointer,<EOL>self._hostname,<EOL>self._context_flags,<EOL><NUM_LIT:0>,<EOL><NUM_LIT:0>,<EOL>in_sec_buffer_desc_pointer,<EOL><NUM_LIT:0>,<EOL>null(),<EOL>out_sec_buffer_desc_pointer,<EOL>output_context_flags_pointer,<EOL>null()<EOL>)<EOL>if result == Secur32Const.SEC_E_INCOMPLETE_MESSAGE:<EOL><INDENT>in_buffers[<NUM_LIT:0>].BufferType = Secur32Const.SECBUFFER_TOKEN<EOL>if in_buffers[<NUM_LIT:1>].BufferType != Secur32Const.SECBUFFER_EMPTY:<EOL><INDENT>in_buffers[<NUM_LIT:1>].BufferType = Secur32Const.SECBUFFER_EMPTY<EOL>in_buffers[<NUM_LIT:1>].cbBuffer = <NUM_LIT:0><EOL>if not is_null(in_buffers[<NUM_LIT:1>].pvBuffer):<EOL><INDENT>secur32.FreeContextBuffer(in_buffers[<NUM_LIT:1>].pvBuffer)<EOL>in_buffers[<NUM_LIT:1>].pvBuffer = null()<EOL><DEDENT><DEDENT>if fail_late:<EOL><INDENT>raise_disconnection()<EOL><DEDENT>continue<EOL><DEDENT>if result == Secur32Const.SEC_E_ILLEGAL_MESSAGE:<EOL><INDENT>if detect_client_auth_request(handshake_server_bytes):<EOL><INDENT>raise_client_auth()<EOL><DEDENT>alert_info = parse_alert(handshake_server_bytes)<EOL>if alert_info and alert_info == (<NUM_LIT:2>, <NUM_LIT>):<EOL><INDENT>raise_protocol_version()<EOL><DEDENT>raise_handshake()<EOL><DEDENT>if result == Secur32Const.SEC_E_WRONG_PRINCIPAL:<EOL><INDENT>chain = extract_chain(handshake_server_bytes)<EOL>raise_hostname(chain[<NUM_LIT:0>], self._hostname)<EOL><DEDENT>if result == Secur32Const.SEC_E_CERT_EXPIRED:<EOL><INDENT>chain = extract_chain(handshake_server_bytes)<EOL>raise_expired_not_yet_valid(chain[<NUM_LIT:0>])<EOL><DEDENT>if result == Secur32Const.SEC_E_UNTRUSTED_ROOT:<EOL><INDENT>chain = extract_chain(handshake_server_bytes)<EOL>cert = chain[<NUM_LIT:0>]<EOL>oscrypto_cert = load_certificate(cert)<EOL>if not oscrypto_cert.self_signed:<EOL><INDENT>raise_no_issuer(cert)<EOL><DEDENT>raise_self_signed(cert)<EOL><DEDENT>if result == Secur32Const.SEC_E_INTERNAL_ERROR:<EOL><INDENT>if get_dh_params_length(handshake_server_bytes) < <NUM_LIT>:<EOL><INDENT>raise_dh_params()<EOL><DEDENT><DEDENT>if result == Secur32Const.SEC_I_INCOMPLETE_CREDENTIALS:<EOL><INDENT>raise_client_auth()<EOL><DEDENT>if result == Crypt32Const.TRUST_E_CERT_SIGNATURE:<EOL><INDENT>raise_weak_signature(cert)<EOL><DEDENT>if result == Secur32Const.SEC_E_INVALID_TOKEN:<EOL><INDENT>if out_buffers[<NUM_LIT:1>].cbBuffer > <NUM_LIT:0>:<EOL><INDENT>alert_bytes = bytes_from_buffer(out_buffers[<NUM_LIT:1>].pvBuffer, out_buffers[<NUM_LIT:1>].cbBuffer)<EOL>handshake_client_bytes += alert_bytes<EOL>alert_number = alert_bytes[<NUM_LIT:6>:<NUM_LIT:7>]<EOL>if alert_number == b'<STR_LIT>' or alert_number == b'<STR_LIT>':<EOL><INDENT>if '<STR_LIT>' in self._session._protocols and len(self._session._protocols) > <NUM_LIT:1>:<EOL><INDENT>chain = extract_chain(handshake_server_bytes)<EOL>raise _TLSDowngradeError(<EOL>'<STR_LIT>',<EOL>chain[<NUM_LIT:0>]<EOL>)<EOL><DEDENT><DEDENT><DEDENT>if detect_client_auth_request(handshake_server_bytes):<EOL><INDENT>raise_client_auth()<EOL><DEDENT>if detect_other_protocol(handshake_server_bytes):<EOL><INDENT>raise_protocol_error(handshake_server_bytes)<EOL><DEDENT>raise_handshake()<EOL><DEDENT>if result == Secur32Const.SEC_E_BUFFER_TOO_SMALL or result == Secur32Const.SEC_E_MESSAGE_ALTERED:<EOL><INDENT>if '<STR_LIT>' in self._session._protocols:<EOL><INDENT>raise _TLSRetryError('<STR_LIT>')<EOL><DEDENT><DEDENT>if fail_late:<EOL><INDENT>raise_disconnection()<EOL><DEDENT>if result == Secur32Const.SEC_E_INVALID_PARAMETER:<EOL><INDENT>if get_dh_params_length(handshake_server_bytes) < <NUM_LIT>:<EOL><INDENT>raise_dh_params()<EOL><DEDENT><DEDENT>if result not in set([Secur32Const.SEC_E_OK, Secur32Const.SEC_I_CONTINUE_NEEDED]):<EOL><INDENT>handle_error(result, TLSError)<EOL><DEDENT>if out_buffers[<NUM_LIT:0>].cbBuffer > <NUM_LIT:0>:<EOL><INDENT>token = bytes_from_buffer(out_buffers[<NUM_LIT:0>].pvBuffer, out_buffers[<NUM_LIT:0>].cbBuffer)<EOL>handshake_client_bytes += token<EOL>self._socket.send(token)<EOL>out_buffers[<NUM_LIT:0>].cbBuffer = <NUM_LIT:0><EOL>secur32.FreeContextBuffer(out_buffers[<NUM_LIT:0>].pvBuffer)<EOL>out_buffers[<NUM_LIT:0>].pvBuffer = null()<EOL><DEDENT>if in_buffers[<NUM_LIT:1>].BufferType == Secur32Const.SECBUFFER_EXTRA:<EOL><INDENT>extra_amount = in_buffers[<NUM_LIT:1>].cbBuffer<EOL>self._received_bytes = self._received_bytes[-extra_amount:]<EOL>in_buffers[<NUM_LIT:1>].BufferType = Secur32Const.SECBUFFER_EMPTY<EOL>in_buffers[<NUM_LIT:1>].cbBuffer = <NUM_LIT:0><EOL>secur32.FreeContextBuffer(in_buffers[<NUM_LIT:1>].pvBuffer)<EOL>in_buffers[<NUM_LIT:1>].pvBuffer = null()<EOL>if result == Secur32Const.SEC_E_OK:<EOL><INDENT>handshake_server_bytes = handshake_server_bytes[-extra_amount:]<EOL><DEDENT><DEDENT>else:<EOL><INDENT>self._received_bytes = b'<STR_LIT>'<EOL><DEDENT><DEDENT>connection_info_pointer = struct(secur32, '<STR_LIT>')<EOL>result = secur32.QueryContextAttributesW(<EOL>temp_context_handle_pointer,<EOL>Secur32Const.SECPKG_ATTR_CONNECTION_INFO,<EOL>connection_info_pointer<EOL>)<EOL>handle_error(result, TLSError)<EOL>connection_info = unwrap(connection_info_pointer)<EOL>self._protocol = {<EOL>Secur32Const.SP_PROT_SSL2_CLIENT: '<STR_LIT>',<EOL>Secur32Const.SP_PROT_SSL3_CLIENT: '<STR_LIT>',<EOL>Secur32Const.SP_PROT_TLS1_CLIENT: '<STR_LIT>',<EOL>Secur32Const.SP_PROT_TLS1_1_CLIENT: '<STR_LIT>',<EOL>Secur32Const.SP_PROT_TLS1_2_CLIENT: '<STR_LIT>',<EOL>}.get(native(int, connection_info.dwProtocol), str_cls(connection_info.dwProtocol))<EOL>if self._protocol in set(['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>']):<EOL><INDENT>session_info = parse_session_info(handshake_server_bytes, handshake_client_bytes)<EOL>self._cipher_suite = session_info['<STR_LIT>']<EOL>self._compression = session_info['<STR_LIT>']<EOL>self._session_id = session_info['<STR_LIT>']<EOL>self._session_ticket = session_info['<STR_LIT>']<EOL><DEDENT>output_context_flags = deref(output_context_flags_pointer)<EOL>for flag in requested_flags:<EOL><INDENT>if (flag | output_context_flags) == <NUM_LIT:0>:<EOL><INDENT>raise OSError(pretty_message(<EOL>'''<STR_LIT>''',<EOL>requested_flags[flag]<EOL>))<EOL><DEDENT><DEDENT>if not renegotiate:<EOL><INDENT>self._context_handle_pointer = temp_context_handle_pointer<EOL>new_context_handle_pointer = None<EOL>stream_sizes_pointer = struct(secur32, '<STR_LIT>')<EOL>result = secur32.QueryContextAttributesW(<EOL>self._context_handle_pointer,<EOL>Secur32Const.SECPKG_ATTR_STREAM_SIZES,<EOL>stream_sizes_pointer<EOL>)<EOL>handle_error(result)<EOL>stream_sizes = unwrap(stream_sizes_pointer)<EOL>self._header_size = native(int, stream_sizes.cbHeader)<EOL>self._message_size = native(int, stream_sizes.cbMaximumMessage)<EOL>self._trailer_size = native(int, stream_sizes.cbTrailer)<EOL>self._buffer_size = self._header_size + self._message_size + self._trailer_size<EOL><DEDENT>if self._session._extra_trust_roots:<EOL><INDENT>self._extra_trust_root_validation()<EOL><DEDENT><DEDENT>except (OSError, socket_.error):<EOL><INDENT>self.close()<EOL>raise<EOL><DEDENT>finally:<EOL><INDENT>if out_buffers:<EOL><INDENT>if not is_null(out_buffers[<NUM_LIT:0>].pvBuffer):<EOL><INDENT>secur32.FreeContextBuffer(out_buffers[<NUM_LIT:0>].pvBuffer)<EOL><DEDENT>if not is_null(out_buffers[<NUM_LIT:1>].pvBuffer):<EOL><INDENT>secur32.FreeContextBuffer(out_buffers[<NUM_LIT:1>].pvBuffer)<EOL><DEDENT><DEDENT>if new_context_handle_pointer:<EOL><INDENT>secur32.DeleteSecurityContext(new_context_handle_pointer)<EOL><DEDENT><DEDENT>
Perform an initial TLS handshake, or a renegotiation

:param renegotiate:
    If the handshake is for a renegotiation