def send_handshake_finished( self, handshake_keys: HandshakeKeys, handshake_hash: bytes ): hh_payload = HandshakeFinishedHandshakePayload.generate( handshake_keys.client_handshake_traffic_secret, handshake_hash ) hh_header = HandshakeHeader( HandshakeFinishedHandshakePayload.default_htype(), len(hh_payload.verify_data), ) plaintext_payload = b"".join( [hh_header.serialize(), hh_payload.verify_data, b"\x16"] ) record_header = RecordHeader(rtype=0x17, size=len(plaintext_payload) + 16) encryptor = AES.new( handshake_keys.client_key, AES.MODE_GCM, handshake_keys.client_iv ) encryptor.update(record_header.serialize()) ciphertext_payload = encryptor.encrypt(plaintext_payload) tag = encryptor.digest() w = Wrapper(record_header=record_header, payload=ciphertext_payload + tag) self.socket.send(w.serialize())
def send(self, data: bytes): send_data = data + b"\x17" record_header = RecordHeader(rtype=0x17, size=len(send_data) + 16) encryptor = AES.new( self.application_keys.client_key, AES.MODE_GCM, xor_iv(self.application_keys.client_iv, self.application_send_counter), ) encryptor.update(record_header.serialize()) ciphertext_payload = encryptor.encrypt(send_data) tag = encryptor.digest() w = Wrapper(record_header=record_header, payload=ciphertext_payload + tag) self.socket.send(w.serialize()) self.application_send_counter += 1
def __recv(self, bytes_buffer): # print("_recv", bytes_buffer.peek()) # raise Exception("Need more data!!!") wrapper = Wrapper.deserialize(bytes_buffer) while wrapper.record_header.size > len(wrapper.payload): # print("Wrapper read", wrapper.record_header.size - len(wrapper.payload)) wrapper.payload += self.socket.recv( wrapper.record_header.size - len(wrapper.payload) ) recdata = wrapper.record_header.serialize() authtag = wrapper.auth_tag ciphertext = wrapper.encrypted_data decryptor = AES.new( self.application_keys.server_key, AES.MODE_GCM, xor_iv(self.application_keys.server_iv, self.application_recv_counter), ) decryptor.update(recdata) plaintext = decryptor.decrypt(bytes(ciphertext)) decryptor.verify(authtag) self.application_recv_counter += 1 return plaintext
def parse_wrapper(bytes_buffer): wrapper = Wrapper.deserialize(bytes_buffer) while wrapper.record_header.size > len(wrapper.payload): wrapper.payload += self.socket.recv( wrapper.record_header.size - len(wrapper.payload) ) recdata = wrapper.record_header.serialize() authtag = wrapper.auth_tag ciphertext = wrapper.encrypted_data decryptor = AES.new( self.handshake_keys.server_key, AES.MODE_GCM, xor_iv(self.handshake_keys.server_iv, self.handshake_recv_counter), ) decryptor.update(recdata) plaintext = decryptor.decrypt(bytes(ciphertext)) self.handshake_recv_counter += 1 decryptor.verify(authtag) return plaintext[:-1]
def resume(self) -> None: if self.application_keys is None: raise Exception("Can't Resume TLS1.3 Session") session_ticket = self.session_tickets[0] print("keys", self.application_keys) resumption_master_secret = self.application_keys.resumption_master_secret( hashlib.sha256(self.hello_hash_bytes).digest()) print("resumption_master_secret", hexlify(resumption_master_secret)) self.resumption_keys = self.key_pair.derive_early_keys( session_ticket.psk(resumption_master_secret), b"") print("binder_key", hexlify(self.resumption_keys.binder_key)) finished_key = HKDF_Expand_Label( key=self.resumption_keys.binder_key, label="finished", context=b"", length=32, ) verify_data = hmac.new(finished_key, msg=b"", digestmod=hashlib.sha256).digest() psk_binders = verify_data print("finished_key", hexlify(finished_key)) offset = len(ExtensionPreSharedKey.serialize_binders(psk_binders)) pre_share_key_ext = ExtensionPreSharedKey( identity=session_ticket.session_ticket, obfuscated_ticket_age=session_ticket.obfuscated_ticket_age, binders=psk_binders) ch = ClientHello(self.host, self.key_pair.public) # ch.extensions = [ex for ex in ch.extensions if type(ex) is not ExtensionServerName] ch.add_extension(ExtensionEarlyData()) ch.add_extension(pre_share_key_ext) ch_bytes = ch.serialize() my_hello_hash = hashlib.sha256(ch_bytes[5:-offset]).digest() print("my_hash", hexlify(my_hello_hash)) print("my_hash_offset", hexlify(ch_bytes[5:-offset])) finished_key = HKDF_Expand_Label( key=self.resumption_keys.binder_key, label="finished", context=b"", length=32, ) verify_data = hmac.new(finished_key, msg=my_hello_hash, digestmod=hashlib.sha256).digest() print("finished_key", hexlify(finished_key)) psk_binders = verify_data print("psk_binders", hexlify(psk_binders)) final_hash = hashlib.sha256(ch_bytes[5:]).digest() print("final_hash", hexlify(final_hash)) self.resumption_keys = self.key_pair.derive_early_keys( session_ticket.psk(resumption_master_secret), final_hash) pre_share_key_ext = ExtensionPreSharedKey( identity=session_ticket.session_ticket, obfuscated_ticket_age=session_ticket.obfuscated_ticket_age, binders=psk_binders) ch.extensions = [ ex for ex in ch.extensions if type(ex) is not ExtensionPreSharedKey ] # ch.extensions = [ex for ex in ch.extensions if type(ex) is not ExtensionServerName] ch.add_extension(pre_share_key_ext) ch_bytes_final = ch.serialize() # print(len(ch_bytes_final), ch_bytes_final) final_hash = hashlib.sha256(ch_bytes_final[5:]).digest() print("final_hash", hexlify(final_hash)) self.resumption_keys = self.key_pair.derive_early_keys( session_ticket.psk(resumption_master_secret), final_hash) self.socket = socket() self.socket.connect((self.host, self.port)) data = f"HEAD /img.jpg HTTP/1.1\r\nHost: {self.host.decode()}\r\nUser-Agent: curl/7.54.0\r\nAccept: */*\r\n\r\n".encode( ) send_data = data + b"\x17" record_header = RecordHeader(rtype=0x17, size=len(send_data) + 16) print("client_early_traffic_secret", hexlify(self.resumption_keys.client_early_traffic_secret)) print("client_early_key", hexlify(self.resumption_keys.client_early_key)) print("client_early_iv", hexlify(self.resumption_keys.client_early_iv)) encryptor = AES.new( self.resumption_keys.client_early_key, AES.MODE_GCM, xor_iv(self.resumption_keys.client_early_iv, 0), ) encryptor.update(record_header.serialize()) ciphertext_payload = encryptor.encrypt(send_data) tag = encryptor.digest() w = Wrapper(record_header=record_header, payload=ciphertext_payload + tag) self.socket.send(ch_bytes_final + bytes.fromhex("140303000101") + w.serialize()) print("res", self.socket.recv(4096)) print("res", self.socket.recv(4096))