def key_request(IP: str, port: int) -> Optional[RSA_key]: """Request the TTP's public key. PARAMETERS ========== IP: A string containing the IP address of the TTP. port: The port the TTP is listening on, as an integer. RETURNS ======= On success, return an RSA_key object. If there was a communications error, return None. """ sock = create_socket(IP, port) if sock is None: return None count = send(sock, b'k') if count != 1: return close_sock(sock) ttp_N = receive(sock, 128) if len(ttp_N) != 128: return close_sock(sock) ttp_d = receive(sock, 128) if len(ttp_d) != 128: return close_sock(sock) close_sock(sock) return RSA_key(pubkey=(bytes_to_int(ttp_N), bytes_to_int(ttp_d)))
def key_request(IP: str, port: int) -> Optional[RSA_key]: """Request the TTP's public key. PARAMETERS ========== IP: A string containing the IP address of the TTP. port: The port the TTP is listening on, as an integer. RETURNS ======= On success, return an RSA_key object. If there was a communications error, return None. """ sock = create_socket(IP, port) k_byte = 'k'.encode('utf-8') sentlen = send(sock, k_byte) if sentlen != 1: sock.close() return None ttp_n = receive(sock, 128) ttp_d = receive(sock, 128) if (len(ttp_d) != 128) or len(ttp_n) != 128: sock.close() return None sock.close() rsakey = RSA_key(pubkey=(bytes_to_int(ttp_n), bytes_to_int(ttp_d))) return rsakey
def sign_request( IP: str, port: int, server_name: str, server_key: RSA_key ) -> \ Optional[tuple[int,int]]: """Sign the server's public key, via the TTP. PARAMETERS ========== IP: A string containing the IP address of the TTP. port: The port the TTP is listening on, as an integer. server_name: The server's name, as a string. server_key: The server's RSA key, as an RSA_key object. RETURNS ======= On success, return (ttp_N, ttp_sig) as integers; the former is the TTP's RSA modulus, the latter the TTP's signature of the public key. If the TTP could not be contacted, or any other error occurred, return None. """ sock = create_socket(IP, port) if sock == None: return None sentlen = send(sock, b's') if sentlen != 1: sock.close() return None name = server_name.encode('utf-8') nameLength = len(name) nameLengthByte = int_to_bytes(nameLength, 1) sentlen = send(sock, nameLengthByte) if sentlen != 1: sock.close() return None sentlen = send(sock, name) if sentlen != len(name): sock.close() return None if server_key.N == None or server_key.e == None: sock.close() return None N_bytes = int_to_bytes(server_key.N, 128) sentlen = send(sock, N_bytes) if sentlen != 128: sock.close() return None e_bytes = int_to_bytes(server_key.e, 128) sentlen = send(sock, e_bytes) if sentlen != 128: sock.close() return None ttp_n = receive(sock, 128) ttp_sig = receive(sock, 128) if (len(ttp_sig) != 128) or len(ttp_n) != 128: sock.close() return None return (bytes_to_int(ttp_n), bytes_to_int(ttp_sig))
def sign_request( IP: str, port: int, server_name: str, server_key: RSA_key ) -> \ Optional[tuple[int,int]]: """Sign the server's public key, via the TTP. PARAMETERS ========== IP: A string containing the IP address of the TTP. port: The port the TTP is listening on, as an integer. server_name: The server's name, as a string. server_key: The server's RSA key, as an RSA_key object. RETURNS ======= On success, return (ttp_N, ttp_sig) as integers; the former is the TTP's RSA modulus, the latter the TTP's signature of the public key. If the TTP could not be contacted, or any other error occurred, return None. """ sock = create_socket(IP, port) if sock is None: return None count = send(sock, b's') if count != 1: return close_sock(sock) server_name_length = len(server_name.encode()) server_name_length_bytes = int_to_bytes(server_name_length, 1) count = send(sock, server_name_length_bytes) if count != 1: return close_sock(sock) count = send(sock, server_name.encode()) if count != server_name_length: return close_sock(sock) N_bytes = int_to_bytes(server_key.N, 128) count = send(sock, N_bytes) if count != 128: return close_sock(sock) e_bytes = int_to_bytes(server_key.e, 128) count = send(sock, e_bytes) if count != 128: return close_sock(sock) ttp_N = receive(sock, 128) if len(ttp_N) != 128: return close_sock(sock) ttp_sig = receive(sock, 128) if len(ttp_sig) != 128: return close_sock(sock) close_sock(sock) return (bytes_to_int(ttp_N), bytes_to_int(ttp_sig))
def client_protocol( ip: str, port: int, dh: DH_params, ttp_key: RSA_key, \ username: str, pw: str, s: bytes, file_bytes: bytes ) -> \ Optional[tuple[int,int]]: """Generate the shared key and send the file, from the client side. IMPORTANT: don't forget to send 'p'! PARAMETERS ========== ip: The IP address to connect to, as a string. port: The port to connect to, as an int. dh: A DH_params object. ttp_key: An RSA_key object. username: The username to register, as a string. pw: The password, as a string. s: The salt, a bytes object 16 bytes long. Must match what the server sends back. file_bytes: The plaintext to send to the server, as a bytes object. RETURNS ======= If successful, return a tuple of the form (a, K_client), where both a and K_client are integers. If not, return None. """ sock = create_socket(ip, port) if sock is None: return None count = send(sock, b'p') if count != 1: return close_sock(sock) encoded_username = username.encode() encoded_username_length = len(encoded_username) count = send(sock, int_to_bytes(encoded_username_length, 1)) if count != 1: return close_sock(sock) count = send(sock, encoded_username) if count != encoded_username_length: return close_sock(sock) encoded_server_name_length_bytes = receive(sock, 1) if len(encoded_server_name_length_bytes) != 1: return close_sock(sock) encoded_server_name_length = bytes_to_int(encoded_server_name_length_bytes) server_cert = receive(sock, (encoded_server_name_length + 384)) if len(server_cert) != (encoded_server_name_length + 384): return close_sock(sock) ttp_sig_rec = server_cert[-128:] server_cert = server_cert[:-128] server_name_bytes = server_cert[:-256] server_N_bytes = server_cert[-256:-128] server_e_bytes = server_cert[-128:] server_N = bytes_to_int(server_N_bytes) server_e = bytes_to_int(server_e_bytes) server_name = server_name_bytes.decode() server_key = RSA_key(pubkey=(server_N, server_e)) digest = hashes.Hash(hashes.SHA3_512()) digest.update(server_cert) t = digest.finalize() digest = hashes.Hash(hashes.SHA3_512()) digest.update(t) t_prime = digest.finalize() S = bytes_to_int(t + t_prime) - ttp_key.N ttp_sig = ttp_key.sign(S) if ttp_sig_rec != ttp_sig: return close_sock(sock) #COPIED FROM A2 BELOW a = int.from_bytes(os.urandom(63), byteorder="big") A = calc_A(dh.N, dh.g, a) #A = int_to_bytes(A, 64) enc_A = server_key.encrypt(A) enc_A_bytes = int_to_bytes(A, 128) send(sock, enc_A_bytes) #3 print("Client: A = " + str(bytes_to_int(A))) s = receive(sock, 16) #4 print("Client: Recieved " + s.hex()) B = receive(sock, 64) #5 print("Client: Recieved " + s.hex()) u = calc_u(A, B) x = calc_x(s, pw) v = calc_A(dh.N, dh.g, x) #where is k? I already calculated it....... byteN = dh.N byteG = dh.g if type(byteN) == int: byteN = int_to_bytes(byteN, 64) if type(byteG) == int: byteG = int_to_bytes(byteG, 64) byteK = hash_bytes(byteN + byteG) k = int.from_bytes(byteK, "big") K_client = calc_K_client(N, B, k, v, a, u, x) M1 = calc_M1(A, B, K_client) send(sock, M1) #6 print("Client: M1 = " + M1.hex()) M2 = receive(sock, 32) #7 print("Client: Recieved " + M2.hex()) M2check = calc_M2(A, M1, K_client) if M2 != M2check: return close_sock(sock) K_client_bytes = int_to_bytes(K_client, 64) AES_key = K_client_bytes[:32] HMAC_key = K_client_bytes[32:] encrypted_file_bytes = pad_encrypt_then_HMAC( file_bytes, AES_key, HMAC_key ) #this might now work, might need to break up file and only pad final block encrypted_file_bytes_length = len(encrypted_file_bytes) encrypted_file_bytes_length_bytes = int_to_bytes( encrypted_file_bytes_length, 4) count = send(sock, encrypted_file_bytes_length_bytes) if count != 4: return close_sock(sock) count = send(sock, encrypted_file_bytes) if count != encrypted_file_bytes_length: return close_sock(sock) close_sock(sock) return (a, K_client)
def server_protocol( sock: socket.socket, dh: DH_params, server_key: RSA_key, \ server_name: str, ttp_sig: int, database: Mapping[str,tuple[bytes,int]] ) -> \ Optional[ tuple[str,int,bytes,bytes,bytes] ]: """Carry out the protocol and file transfer as per the assignment. IMPORTANT: 'p' has already been sent! PARAMETERS ========== sock: A socket connected to the client. dh: A DH_params object. server_key: An RSA_key object. server_name: The server's name, as a string. ttp_sig: The signature returned by the TTP, as an int. database: A dict containing the user database, as per A2. RETURNS ======= If the protocol was successful, return the tuple ( username, b, AES_key, HMAC_key, plaintext ), which are (in order) the username supplied by the client, as a string; the server's randomly-chosen value for b, as an integer; the key used to encrypt the file transfer, as a bytes object; the key used for message authentication, as a bytes object; and the plaintext version of the file, as a bytes object. If the protocol failed, return None. """ encoded_username_length = receive(sock, 1) if len(encoded_username_length) != 1: return close_sock(sock) username_length = bytes_to_int(encoded_username_length) encoded_username = receive(sock, username_length) if len(encoded_username) != username_length: return close_sock(sock) username = encoded_username.decode() encoded_server_name = server_name.encode() encoded_server_name_length = len(encoded_server_name) count = send(sock, int_to_bytes(encoded_server_name_length, 1)) if count != 1: return close_sock(sock) data = encoded_server_name + int_to_bytes(server_key.N, 128) + int_to_bytes(server_key.e, 128) \ + int_to_bytes(ttp_sig, 128) count = send(sock, data) if count != (384 + encoded_server_name_length): return close_sock(sock) #copied from Assignment 2 Below b = int.from_bytes(os.urandom(63), byteorder="big") enc_A_bytes = receive(sock, 128) #3 print("Server: Recieved " + enc_A_bytes.hex()) enc_A = bytes_to_int(enc_A_bytes) A = server_key.decrypt(enc_A) if A % dh.N == 0: return close_sock(sock) if username in database: s, v = database[username] else: return close_sock(sock) #where is k? I already calculated it....... byteN = dh.N byteG = dh.g if type(byteN) == int: byteN = int_to_bytes(byteN, 64) if type(byteG) == int: byteG = int_to_bytes(byteG, 64) byteK = hash_bytes(byteN + byteG) k = int.from_bytes(byteK, "big") B = calc_B(dh.N, dh.g, b, k, v) send(sock, bytes(s)) #4 print("Server: salt = " + s.hex()) send(sock, int_to_bytes(B, 64)) #5 print("Server: B = " + str(B)) u = calc_u(A, B) K_server = calc_K_server(dh.N, A, b, v, u) M1 = receive(sock, 32) #6 print("Server: Recieved " + M1.hex()) M1check = calc_M1(A, B, K_server) if M1 != M1check: return close_sock(sock) M2 = calc_M2(A, M1, K_server) send(sock, M2) #7 print("Server: M2 = " + M2.hex()) encrypted_file_bytes_length_bytes = receive(sock, 4) if len(encrypted_file_bytes_length_bytes) != 4: return close_sock(sock) encrypted_file_bytes_length = bytes_to_int( encrypted_file_bytes_length_bytes) encrypted_file_bytes = receive(sock, encrypted_file_bytes_length) if len(encrypted_file_bytes) != encrypted_file_bytes_length: return close_sock(sock) K_server_bytes = int_to_bytes(K_server, 64) AES_key = K_server_bytes[:32] HMAC_key = K_server_bytes[32:] decrypted_file = decrypt_and_verify(encrypted_file_bytes, AES_key, HMAC_key) if decrypted_file == None: return close_sock(sock) close_sock(sock) return (username, b, decrypted_file, AES_key, HMAC_key)
def ttp_sign( sock: socket.socket, ttp_key: RSA_key, \ database: Mapping[str,RSA_key] ) -> Optional[Mapping[str,RSA_key]]: """Carry out the TTP's signing procedure. IMPORTANT: 's' has already been read! PARAMETERS ========== sock: The communication socket to send/receive data over. Must be closed before the function exits. ttp_key: An RSA_key object. database: A dictionary of all signatures generated, of the form database[server_name] = key, where server_name is a string and key is an RSA_key object. RETURNS ======= If the server has not requested a signature before, and the values can be signed, return an updated version of the database. If the server has already requested a signature but with different information, return None. If the information was the same, return the database unmodified. If a socket error occurs, return None. """ assert type(sock) is socket.socket assert type(database) == dict length_name = receive(sock, 1) if len(length_name) != 1: return close_sock(sock) length_name = bytes_to_int(length_name) varprint(length_name, 'length_name', "TTP") name = receive(sock, length_name) if len(name) != length_name: return close_sock(sock) varprint(name.decode("utf-8"), 'name', "name") serv_N = receive(sock, 128) if len(serv_N) != 128: return close_sock(sock) serv_e = receive(sock, 128) if len(serv_e) != 128: return close_sock(sock) serv_key = (bytes_to_int(serv_N), bytes_to_int(serv_e)) varprint(serv_key, 'serv_key', "TTP") db_index = name.decode("utf-8") if db_index in database: db_serv_key = database[db_index] if db_serv_key.N != serv_key[0] or db_serv_key.e != serv_key[1]: print("Server name exists with different information. Quitting...") return close_sock(sock) digest = hashes.Hash(hashes.SHA3_512()) digest.update(name + serv_N + serv_e) t = digest.finalize() digest = hashes.Hash(hashes.SHA3_512()) digest.update(t) t_prime = digest.finalize() S = bytes_to_int(t + t_prime) - ttp_key.N ttp_sig = ttp_key.sign(S) N_bytes = int_to_bytes(ttp_key.N, byte_length_of_int(ttp_key.N)) count = send(sock, N_bytes) if count != len(N_bytes): return close_sock(sock) ttp_sig_bytes = int_to_bytes(ttp_sig, byte_length_of_int(ttp_sig)) count = send(sock, ttp_sig_bytes) if count != len(ttp_sig_bytes): return close_sock(sock) if db_index not in database: database[db_index] = RSA_key(pubkey=serv_key) close_sock(sock) return database
def server_loop(IP, port, dh, key, server_name, output_file, verbose=False): database = dict() # for tracking registered users if verbose: print(f"Server: Retrieving a signature of our key.", flush=True) result = sign_request(*ttp_addr, server_name, key) if result is None: print(f"Server: Could not get a signature. Quitting.", flush=True) return ttp_N, ttp_sig = result if verbose: print(f"Server: Finished all preparations, ready to listen.", flush=True) sock = create_socket(IP, port, listen=True) if sock is None: if verbose: print(f"Server: Could not create socket, exiting.", flush=True) return if verbose: print(f"Server: Beginning connection loop.", flush=True) while True: (client, client_address) = sock.accept() if verbose: print(f"Server: Got connection from {client_address}.", flush=True) mode = receive(client, 1) if len(mode) != 1: if verbose: print( f"Server: Socket error with client, closing it and waiting for another connection.", flush=True) client.shutdown(socket.SHUT_RDWR) client.close() continue if mode == b'q': if verbose: print(f"Server: Asked to quit. Shutting down.", flush=True) client.shutdown(socket.SHUT_RDWR) client.close() sock.shutdown(socket.SHUT_RDWR) sock.close() return elif mode == b'r': if verbose: print(f"Server: Asked to register by the Client.", flush=True) temp = server_register(client, dh.N, dh.g, database) if (temp is None) and verbose: print( f"Server: Registration failed, closing socket and waiting for another connection.", flush=True) elif temp is not None: if verbose: print( f"Server: Registration complete, current users: {[x for x in temp]}.", flush=True) database = temp elif mode == b'p': if verbose: print(f"Server: Asked to share a file by a Client.", flush=True) temp = server_protocol(client, dh, key, server_name, ttp_sig, database) if (temp is None) and verbose: print( f"Server: Protocol failed, closing socket and waiting for another connection.", flush=True) elif (type(temp) == tuple) and (len(temp) == 5): if verbose: print( f"Server: Protocol complete, negotiated shared key for {temp[0]}.", flush=True) print( f"Server: AES key is {temp[2].hex()}, HMAC key is {temp[3].hex()}.", flush=True) # write out the file output_file.write(temp[4]) output_file.close()
def ttp_loop(IP, port, key, verbose=False): database = dict() # for tracking signed keys sock = create_socket(IP, port, listen=True) if sock is None: if verbose: print(f"TTP: Could not create socket, exiting.", flush=True) return if verbose: print(f"TTP: Beginning connection loop.", flush=True) while True: (client, client_address) = sock.accept() if verbose: print(f"TTP: Got connection from {client_address}.", flush=True) mode = receive(client, 1) if len(mode) != 1: if verbose: print( f"TTP: Socket error with client, closing it and waiting for another connection.", flush=True) client.shutdown(socket.SHUT_RDWR) client.close() continue if mode == b'q': if verbose: print(f"TTP: Asked to quit by client. Shutting down.", flush=True) client.shutdown(socket.SHUT_RDWR) client.close() sock.shutdown(socket.SHUT_RDWR) sock.close() return elif mode == b's': if verbose: print(f"TTP: Asked to sign by a Server.", flush=True) temp = ttp_sign(client, key, database) if (temp is None) and verbose: print( f"TTP: Signing failed, closing socket and waiting for another connection.", flush=True) elif type(temp) is dict: if verbose: print( f"TTP: Signing complete, current Servers: {[x for x in temp]}.", flush=True) database = temp elif mode == b'k': if verbose: print(f"TTP: Asked for our public key.", flush=True) ttp_sendkey(client, key)
def client_protocol( ip: str, port: int, dh: DH_params, ttp_key: RSA_key, \ username: str, pw: str, s: bytes, file_bytes: bytes ) -> \ Optional[tuple[int,int]]: """Generate the shared key and send the file, from the client side. IMPORTANT: don't forget to send 'p'! PARAMETERS ========== ip: The IP address to connect to, as a string. port: The port to connect to, as an int. dh: A DH_params object. ttp_key: An RSA_key object. username: The username to register, as a string. pw: The password, as a string. s: The salt, a bytes object 16 bytes long. Must match what the server sends back. file_bytes: The plaintext to send to the server, as a bytes object. RETURNS ======= If successful, return a tuple of the form (a, K_client), where both a and K_client are integers. If not, return None. """ try: sock = create_socket(ip, port) # if sock==None: # return None p = 'p'.encode('utf-8') send(sock, p) usernameUTF = username.encode('utf-8') send(sock, int_to_bytes(len(usernameUTF), 1)) send(sock, usernameUTF) serverNameLen1 = receive(sock, 1) serverNameLen = bytes_to_int(serverNameLen1) serverNameBytes = receive(sock, serverNameLen) serverName = serverNameBytes.decode('utf-8') servN_bytes = receive(sock, 128) serve_bytes = receive(sock, 128) servN = bytes_to_int(servN_bytes) serve = bytes_to_int(serve_bytes) server_key = RSA_key(pubkey=(servN, serve)) ttpSig_bytes = receive(sock, 128) NameNe = serverNameBytes + servN_bytes + serve_bytes ttpSign = bytes_to_int(ttpSig_bytes) digest = hashes.Hash(hashes.SHA3_512()) digest.update(NameNe) t = digest.finalize() digest = hashes.Hash(hashes.SHA3_512()) digest.update(t) tdash = digest.finalize() tFinal = bytes_to_int(t + tdash) verSig = pow(tFinal, ttp_key.d, ttp_key.N) # verify if (verSig != ttpSign): sock.close() return None N = dh.N g = dh.g a = random.randint(0, N - 1) A = calc_A(N, g, a) encA = server_key.encrypt(A) encABytes = int_to_bytes(encA, 128) sentLen = send(sock, encABytes) salt = receive(sock, 16) if salt != s: sock.close() return None B = receive(sock, 64) # calc u u = calc_u(A, B) k = calc_u(N, g) # calc x x = calc_x(s, pw) # calc v v = pow(g, x, N) # calc K_client k_client = calc_K_client(N, B, k, v, a, u, x) # calc M1 and send M1 = calc_M1(A, B, k_client) sentLen = send(sock, M1) if sentLen < len(M1): sock.close() return None M2 = receive(sock, 32) clientM2 = calc_M2(A, M1, k_client) if (M2 == clientM2): k_client_bytes = int_to_bytes(k_client, 64) aesKey = k_client_bytes[:32] hmacKey = k_client_bytes[32:] cyphertext = pad_encrypt_then_HMAC(file_bytes, aesKey, hmacKey) cypherLen = int_to_bytes(len(cyphertext), 4) send(sock, cypherLen) send(sock, cyphertext) sock.close() return (A, k_client) sock.close() return None except: return None
def server_protocol( sock: socket.socket, dh: DH_params, server_key: RSA_key, \ server_name: str, ttp_sig: int, database: Mapping[str,tuple[bytes,int]] ) -> \ Optional[ tuple[str,int,bytes,bytes,bytes] ]: """Carry out the protocol and file transfer as per the assignment. IMPORTANT: 'p' has already been sent! PARAMETERS ========== sock: A socket connected to the client. dh: A DH_params object. server_key: An RSA_key object. server_name: The server's name, as a string. ttp_sig: The signature returned by the TTP, as an int. database: A dict containing the user database, as per A2. RETURNS ======= If the protocol was successful, return the tuple ( username, b, AES_key, HMAC_key, plaintext ), which are (in order) the username supplied by the client, as a string; the server's randomly-chosen value for b, as an integer; the key used to encrypt the file transfer, as a bytes object; the key used for message authentication, as a bytes object; and the plaintext version of the file, as a bytes object. If the protocol failed, return None. """ clientUsernameLength = receive(sock, 1) clientUsernameUTF = receive(sock, bytes_to_int(clientUsernameLength)) clientUsername = clientUsernameUTF.decode("utf-8") server_nameUTF = server_name.encode("utf-8") server_nameLen = len(server_nameUTF) sentLen = send(sock, int_to_bytes(server_nameLen, 1)) sentLen = send(sock, server_nameUTF) Nbytes = int_to_bytes(server_key.N, 128) ebytes = int_to_bytes(server_key.e, 128) ttpsignbytes = int_to_bytes(ttp_sig, 128) sentLen = send(sock, Nbytes) sentLen = send(sock, ebytes) sentLen = send(sock, ttpsignbytes) encA = receive(sock, 128) A = server_key.decrypt(encA) if (A % dh.N == 0): sock.close() return None A_bytes = int_to_bytes(A, 64) N = dh.N g = dh.g k = calc_u(N, g) reply = database.get(clientUsername) if reply == None: database = ttp_sign(sock, server_key, database) reply = database.get(clientUsername) s = reply[0] v = reply[1] b = random.randint(0, N - 1) B = calc_B(N, g, b, k, v) B_bytes = int_to_bytes(B, 64) concat = s + B_bytes lenSent = send(sock, concat) '''s and b sent''' u = calc_u(A_bytes, B_bytes) k_server = calc_K_server(N, A_bytes, b, v, u) k_server_bytes = int_to_bytes(k_server, 64) M1 = receive(sock, 32) m1serv = calc_M1(A_bytes, B_bytes, k_server) M2 = calc_M2(A, M1, k_server) lenSent = send(sock, M2) if (M1 == m1serv): aesKey = k_server_bytes[:32] hmacKey = k_server_bytes[32:] cyphertextLen = receive(sock, 4) cypher = receive(sock, bytes_to_int(cyphertextLen)) plaintext = decrypt_and_verify(cypher, aesKey, hmacKey) sock.close() if plaintext == None: return None return (clientUsername, b, aesKey, hmacKey, plaintext) else: sock.close() return None
def ttp_sign( sock: socket.socket, ttp_key: RSA_key, \ database: Mapping[str,RSA_key] ) -> Optional[Mapping[str,RSA_key]]: """Carry out the TTP's signing procedure. IMPORTANT: 's' has already been read! PARAMETERS ========== sock: The communication socket to send/receive data over. Must be closed before the function exits. ttp_key: An RSA_key object. database: A dictionary of all signatures generated, of the form database[server_name] = key, where server_name is a string and key is an RSA_key object. RETURNS ======= If the server has not requested a signature before, and the values can be signed, return an updated version of the database. If the server has already requested a signature but with different information, return None. If the information was the same, return the database unmodified. If a socket error occurs, return None. """ assert type(sock) is socket.socket assert type(database) == dict nameLengthBytes = receive(sock, 1) nameLength = bytes_to_int(nameLengthBytes) nameBytes = receive(sock, nameLength) N_bytes = receive(sock, 128) e_bytes = receive(sock, 128) if (len(N_bytes) != 128) or (len(e_bytes) != 128): sock.close() return None hash = hashes.Hash(hashes.SHA3_512()) hash.update(nameBytes + N_bytes + e_bytes) t = hash.finalize() hash1 = hashes.Hash(hashes.SHA3_512()) hash1.update(t) tDash = hash1.finalize() tAndtdash = bytes_to_int(t + tDash) N = bytes_to_int(N_bytes) e = bytes_to_int(e_bytes) S = tAndtdash % ttp_key.N if database.get(nameBytes.decode('utf-8')) == None: key = RSA_key(pubkey=(N, e)) sig = ttp_key.sign(S) database[nameBytes.decode('utf-8')] = key newNbytes = int_to_bytes(ttp_key.N, 128) if (sig == None): sock.close() return database sentLength = send(sock, newNbytes) if sentLength != 128: sock.close() return database sig_bytes = int_to_bytes(sig, 128) sentLength = send(sock, sig_bytes) if sentLength != 256: sock.close() return database sock.close() return database else: key = database[nameBytes.decode('utf-8')] if key.N == N and key.e == e: #send(sock,N_bytes) sig = ttp_key.sign(S) newNbytes = int_to_bytes(ttp_key.N, 128) if (sig == None): sock.close() return database sentLength = send(sock, newNbytes) if sentLength != 128: sock.close() return database sig_bytes = int_to_bytes(sig, 128) sentLength = send(sock, sig_bytes) if sentLength != 256: sock.close() return database sock.close() return database sock.close() return None