def get_nodes_from_csv() -> List[Node]: """ Reads the predetermined CSV and then returns the list of nodes including the client node itself :return: A list of nodes, including the client node itself """ node_container = [] try: with open(BASE_PROJECT_DIR+'/node_directory_service'+'/tor_nodes_list.csv') as f: data = csv.reader(f) for i, row in enumerate(data): id_pub = CoreCryptoRSA.load_public_key_from_disc( BASE_PROJECT_DIR + '/node_directory_service' + '/keyfiles' + '/' + row[2]+'.pub') onion_pub = CoreCryptoRSA.load_public_key_from_disc( BASE_PROJECT_DIR + '/node_directory_service' + '/keyfiles' + '/' + row[3]+'.pub') node = Node(row[0], int(row[1]), None, id_pub, None, onion_pub) # Only for the client node we load its private keys. Other nodes we can't # if i == 0: id_priv = CoreCryptoRSA.load_private_key_from_disc( BASE_PROJECT_DIR + '/node_directory_service' + '/keyfiles' + '/' + row[2]) node.identity_key_pri = id_priv onion_priv = CoreCryptoRSA.load_private_key_from_disc( BASE_PROJECT_DIR + '/node_directory_service' + '/keyfiles' + '/' + row[3]) node.onion_key_pri = onion_priv node_container.append(node) return node_container except: print("Trying to read from CSV. Something went wrong!") return list()
def process_create_cell(cell: Cell, private_onion_key, y_bytes: bytes) -> (bytes, Dict): """ Process the create cell and return the g^x (public key of sender) :param y_bytes: The private DH key generated by the router node in bytes :param cell: The Create Cell Object :param private_onion_key: The private key of the receiver which will be used in hybrid decrypt :return: g^x as bytes object """ create_cell_payload = cell.PAYLOAD gx_bytes = CoreCryptoRSA.hybrid_decrypt(create_cell_payload.HDATA, private_onion_key) gxy = CoreCryptoDH.compute_dh_shared_key(gx_bytes, y_bytes) kdf_dict = CoreCryptoRSA.kdf_tor(gxy) return gx_bytes, kdf_dict
def build_extended_cell(y, gy, streamID: int, circ_id: int, gx: str, recognized) -> Cell: """ The method to build the extended Cell object :param y: :param gy: :param streamID: :param circ_id: :param gx: :param recognized: :return: The Extended Cell """ gxy = CoreCryptoDH.compute_dh_shared_key(y, gx) kdf_dict = CoreCryptoRSA.kdf_tor(gxy) server_h_data = TapSHData(gy, kdf_dict['KH']) # Construct extended2 payload extended_cell_payload_relay = RelayExtendedPayload(RelayExtendedPayload.TAP_S_HANDSHAKE_LEN, server_h_data) # Calculate digest from the extended2 payload payload_dict = { 'HLEN': extended_cell_payload_relay.HLEN, 'HDATA': extended_cell_payload_relay.HDATA } digest = CoreCryptoMisc.calculate_digest(payload_dict) # Construct the Relay cell with extended2 payload which is the payload for the Cell class extended_cell_payload = RelayCellPayload(RelayCellPayload.RELAY_CMD_ENUM['EXTENDED2'], recognized, streamID, digest, Cell.PAYLOAD_LEN - 11, extended_cell_payload_relay) # Construct the actual cell extended_cell = Cell(circ_id, Cell.CMD_ENUM['RELAY'], Cell.PAYLOAD_LEN, extended_cell_payload) return extended_cell
def build_extend_cell(handshake_type: str, x_bytes: bytes, gx_bytes: bytes, circ_id: int, onion_key, hop2_ip, hop2_port) -> Cell: """ The method used to build a Extend/Extend2 cell :param handshake_type: The handshake type. TAP or ntor. :param x_bytes: The diffie hellman private key as a bytes object :param gx_bytes: The diffie hellman public key as a bytes object :param circ_id: The circuit ID :param onion_key: The onion key of the next hop used in hybrid_encrypt method :param lspec: The link specifier as a string :return: The extend Cell object """ client_h_data = CoreCryptoRSA.hybrid_encrypt(gx_bytes, onion_key) nspec = 1 # Always keep this 1 to avoid going to hell lspec = bytearray(IPv4Address(hop2_ip).packed) + pack('!H', int(hop2_port)) extend_cell_payload = RelayExtendPayload(nspec, RelayExtendPayload.LSTYPE_ENUM['TLS_TCP_IPV4'], RelayExtendPayload.LSTYPE_LSLEN_ENUM['TLS_TCP_IPV4'], lspec, CreateCellPayload.CREATE_HANDSHAKE_TYPE[handshake_type], CreateCellPayload.CREATE_HANDSHAKE_LEN[handshake_type], client_h_data) relay_cell_payload = RelayCellPayload(RelayCellPayload.RELAY_CMD_ENUM['RELAY_EXTEND2'], 0, 0, b'', Cell.PAYLOAD_LEN - 11, extend_cell_payload) relay_extend_cell = Cell(circ_id, Cell.CMD_ENUM['RELAY'], Cell.PAYLOAD_LEN, relay_cell_payload) return relay_extend_cell
def build_create_cell(handshake_type: str, x_bytes: bytes, gx_bytes: bytes, circ_id: int, onion_key) -> Cell: """ The method used to build a Create/Create2 cell :param x_bytes: The diffie hellman private key as a bytes object :param gx_bytes: The diffie hellman public key as a bytes object :param circ_id: The circuit ID :param onion_key: The onion key of the next hop used in hybrid_encrypt method :return: The create Cell object """ client_h_data = CoreCryptoRSA.hybrid_encrypt(gx_bytes, onion_key) create_cell_payload = CreateCellPayload(CreateCellPayload.CREATE_HANDSHAKE_TYPE[handshake_type], CreateCellPayload.CREATE_HANDSHAKE_LEN[handshake_type], client_h_data) create_cell = Cell(circ_id, Cell.CMD_ENUM['CREATE2'], Cell.PAYLOAD_LEN, create_cell_payload) return create_cell
def build_created_cell(y_bytes: bytes, gy_bytes: bytes, circ_id: int, gx_bytes: bytes) -> Cell: """ The method used to build a created/created2 cell object :param y_bytes: The diffie hellman private key bytes of the receiver :param gy_bytes: The diffie hellman public key bytes of the receiver :param circ_id: The circuit ID :param gx_bytes: The diffie hellman public key bytes of the sender :return: The created Cell object """ gxy = CoreCryptoDH.compute_dh_shared_key(gx_bytes, y_bytes) kdf_dict = CoreCryptoRSA.kdf_tor(gxy) server_h_data = TapSHData(gy_bytes, kdf_dict['KH']) created_cell_payload = CreatedCellPayload(CreatedCellPayload.TAP_S_HANDSHAKE_LEN, server_h_data) created_cell = Cell(circ_id, Cell.CMD_ENUM['CREATED2'], Cell.PAYLOAD_LEN, created_cell_payload) return created_cell
def process_created_cell(cell: Cell, required_circ_id: int, x_bytes: bytes): """ The method to process a created cell and return the kdf_dict that will be used after DH handshake :param cell: The Created Cell Object :param required_circ_id: The circuit ID that is expected :param x_bytes: The private key of the sender in bytes :return: The KDF Dict """ if cell.CIRCID == required_circ_id: created_h_data = cell.PAYLOAD.HDATA gy_bytes = created_h_data.GY gxy = CoreCryptoDH.compute_dh_shared_key(gy_bytes, x_bytes) kdf_dict = CoreCryptoRSA.kdf_tor(gxy) if created_h_data.KH == kdf_dict['KH']: print("Handshake successful!") return kdf_dict else: return None else: return None
def process_extended_cell(cell: Cell, required_circ_id: int, x_bytes: bytes): """ The processing functions for created and extended cells return dictionaries created by kdf_tor() function. For verifying KH, the kdf_dict has to be accessed. This is added to the 'extended' cell handling and similar changes have been made in the parsing and processing of 'created' cells """ if cell.CIRCID == required_circ_id: extended_h_data = cell.PAYLOAD.Data.HDATA gy_bytes = extended_h_data.GY gxy = CoreCryptoDH.compute_dh_shared_key(gy_bytes, x_bytes) kdf_dict = CoreCryptoRSA.kdf_tor(gxy) if extended_h_data.KH == kdf_dict['KH']: print("Handshake successful!") return kdf_dict else: return None else: return None