def build_relay_connected_cell(CIRCID: int, StreamID, kdf_dict, IPv4_address : str,TTL : int) -> Cell: """ :param CIRCID: The Circuit ID :param StreamID: The Stream ID :param kdf_dict: A dictionary (key) to encrypt data :param IPv4_address: The IPv4 address to which the connection was made [4 octets] :param TTL: A number of seconds (TTL) for which the address may be cached [4 octets] :return: """ # Encrypt the values by packing and unpacking enc_StreamID = unpack('!H', CoreCryptoSymmetric.encrypt_for_hop(pack('!H', StreamID), kdf_dict))[0] enc_relay_payload_len = unpack('!H',CoreCryptoSymmetric.encrypt_for_hop(pack('!H', Cell.PAYLOAD_LEN - 11),kdf_dict))[0] enc_IPv4_address = unpack('!I', CoreCryptoSymmetric.encrypt_for_hop(pack('!I', int(IPv4Address(IPv4_address))), kdf_dict))[0] enc_TTL = unpack('!I',CoreCryptoSymmetric.encrypt_for_hop(pack('!I', TTL), kdf_dict))[0] # enc_digest = CoreCryptoSymmetric.encrypt_for_hop(digest, kdf_dict) relay_connected_cell_payload = RelayConnectedPayload(enc_IPv4_address, enc_TTL) relay_cell_payload = RelayCellPayload(RelayCellPayload.RELAY_CMD_ENUM['RELAY_CONNECTED'], 0, enc_StreamID, b'', enc_relay_payload_len, relay_connected_cell_payload) # Construct the actual cell relay_cell = Cell(CIRCID, Cell.CMD_ENUM['RELAY'], Cell.PAYLOAD_LEN, relay_cell_payload) return relay_cell
def build_relay_data_cell(CIRCID: int, StreamID, kdf_dict1, kdf_dict2, kdf_dict3, http_req: str): enc_StreamID = unpack( '!H', CoreCryptoSymmetric.encrypt_from_origin(pack('!H', StreamID), kdf_dict1, kdf_dict2, kdf_dict3))[0] enc_relay_data_len = unpack( '!H', CoreCryptoSymmetric.encrypt_from_origin( pack('!H', Cell.PAYLOAD_LEN - 3), kdf_dict1, kdf_dict2, kdf_dict3))[0] #encrypting the http_req encoded_http_req = http_req.encode() http_req_len = len(http_req) enc_http_req = unpack( '!http_req_lenc', CoreCryptoSymmetric.encrypt_from_origin( pack('!http_req_lenc', StreamID), kdf_dict1, kdf_dict2, kdf_dict3))[0] #creating the relay cell payload with http_req as payload relay_cell_payload = RelayCellPayload( RelayCellPayload.RELAY_CMD_ENUM['RELAY_DATA'], 0, enc_StreamID, b'', enc_relay_data_len, http_req) #creating the complete cell relay_data_cell = Cell(CIRCID, Cell.CMD_ENUM['RELAY'], Cell.PAYLOAD_LEN, relay_cell_payload) return relay_data_cell
def process_relay_data_cell(cell: Cell, kdf_dict: Dict): """ Function for processing a relay data cell when it arrives in a router :param cell: The cell object for the relay data cell :param kdf_dict: The key derivative function dictionary for the session key """ # Take values to be encrypted from the cell enc_recognized = cell.PAYLOAD.RECOGNIZED enc_stream_id = cell.PAYLOAD.StreamID enc_digest = cell.PAYLOAD.Digest enc_length = cell.PAYLOAD.Length enc_bytestring = cell.PAYLOAD.Data # Add one layer of onion skin dec_recognized = unpack( '!H', CoreCryptoSymmetric.decrypt_for_hop(pack('!H', enc_recognized), kdf_dict))[0] dec_stream_id = unpack( '!H', CoreCryptoSymmetric.decrypt_for_hop(pack('!H', enc_stream_id), kdf_dict))[0] dec_digest = CoreCryptoSymmetric.decrypt_for_hop(enc_digest, kdf_dict) dec_length = unpack( '!H', CoreCryptoSymmetric.decrypt_for_hop(pack('!H', enc_length), kdf_dict))[0] dec_bytestring = CoreCryptoSymmetric.decrypt_for_hop( enc_bytestring, kdf_dict)[0] # Adding encrypted values to the cell cell.PAYLOAD.RECOGNIZED = dec_recognized cell.PAYLOAD.StreamID = dec_stream_id cell.PAYLOAD.Digest = dec_digest cell.PAYLOAD.Length = dec_length cell.PAYLOAD.Data = dec_bytestring if dec_recognized == 0: http = dec_bytestring.decode("utf-8") method = http.split(" ")[0] url = http.split(" ")[1] http_dict = {"method": method, "url": url} return dec_recognized, http_dict, cell else: return dec_recognized, None, cell
def process_connected_cell_proxy(cell: Cell, kdf_dict1: Dict, kdf_dict2: Dict, kdf_dict3: Dict) -> Cell: """ Function for processing a connected cell when it arrives in a router :param cell: The cell object for the connected cell :param kdf_dict1, kdf_dict2, kdf_dict3: The key derivative function dictionaries for the three session keys """ # Take values from the cell enc_recognized = cell.PAYLOAD.RECOGNIZED enc_stream_id = cell.PAYLOAD.StreamID enc_digest = cell.PAYLOAD.Digest enc_length = cell.PAYLOAD.Length enc_IPv4 = cell.PAYLOAD.Data.IPv4 enc_TTL = cell.PAYLOAD.Data.TTL # Decrypt all onion layers dec_recognized = unpack('!H', CoreCryptoSymmetric.decrypt_from_origin(pack('!H', enc_recognized), kdf_dict1, kdf_dict2, kdf_dict3))[0] dec_stream_id = unpack('!H', CoreCryptoSymmetric.decrypt_from_origin(pack('!H', enc_stream_id), kdf_dict1, kdf_dict2, kdf_dict3))[0] dec_digest = CoreCryptoSymmetric.decrypt_from_origin(enc_digest, kdf_dict1, kdf_dict2, kdf_dict3) dec_length = unpack('!H', CoreCryptoSymmetric.decrypt_from_origin(pack('!H', enc_length), kdf_dict1, kdf_dict2, kdf_dict3))[0] dec_IPv4 = unpack('!I', CoreCryptoSymmetric.decrypt_from_origin(pack('!I', enc_IPv4), kdf_dict1, kdf_dict2, kdf_dict3))[0] dec_TTL = unpack('!I', CoreCryptoSymmetric.decrypt_from_origin(pack('!I', enc_TTL), kdf_dict1, kdf_dict2, kdf_dict3))[0] # Adding decrypted values to the cell cell.PAYLOAD.RECOGNIZED = dec_recognized cell.PAYLOAD.StreamID = dec_stream_id cell.PAYLOAD.Digest = dec_digest cell.PAYLOAD.Length = dec_length cell.PAYLOAD.Data.IPv4 = dec_IPv4 cell.PAYLOAD.Data.TTL = dec_TTL return cell
def process_connected_cell_router(cell: Cell, kdf_dict: Dict) -> Cell: """ Function for processing a connected cell when it arrives in a router :param cell: The cell object for the connected cell :param kdf_dict: The key derivative function dictionary for the session key """ # Take values to be encrypted from the cell dec_recognized = cell.PAYLOAD.RECOGNIZED dec_stream_id = cell.PAYLOAD.StreamID dec_digest = cell.PAYLOAD.Digest dec_length = cell.PAYLOAD.Length dec_IPv4 = cell.PAYLOAD.Data.IPv4 dec_TTL = cell.PAYLOAD.Data.TTL # Add one layer of onion skin enc_recognized = unpack('!H', CoreCryptoSymmetric.encrypt_for_hop(pack('!H', dec_recognized), kdf_dict))[0] enc_stream_id = unpack('!H', CoreCryptoSymmetric.encrypt_for_hop(pack('!H', dec_stream_id), kdf_dict))[0] enc_digest = CoreCryptoSymmetric.encrypt_for_hop(dec_digest, kdf_dict) enc_length = unpack('!H', CoreCryptoSymmetric.encrypt_for_hop(pack('!H', dec_length), kdf_dict))[0] enc_IPv4 = unpack('!I', CoreCryptoSymmetric.encrypt_for_hop(pack('!I', dec_IPv4), kdf_dict))[0] enc_TTL = unpack('!I', CoreCryptoSymmetric.encrypt_for_hop(pack('!I', dec_TTL), kdf_dict))[0] # Adding encrypted values to the cell cell.PAYLOAD.RECOGNIZED = enc_recognized cell.PAYLOAD.StreamID = enc_stream_id cell.PAYLOAD.Digest = enc_digest cell.PAYLOAD.Length = enc_length cell.PAYLOAD.Data.IPv4 = enc_IPv4 cell.PAYLOAD.Data.TTL = enc_TTL return cell
def process_begin_cell(cell: Cell, kdf_dict: Dict) -> Tuple: # Take the encrypted values from the cell enc_recognized = cell.PAYLOAD.RECOGNIZED enc_stream_id = cell.PAYLOAD.StreamID enc_digest = cell.PAYLOAD.Digest enc_length = cell.PAYLOAD.Length enc_addrport = cell.PAYLOAD.Data.ADDRPORT enc_flags = cell.PAYLOAD.Data.FLAGS # Remove one layer of onion skin dec_recognized = unpack('!H', CoreCryptoSymmetric.decrypt_for_hop(pack('!H', enc_recognized), kdf_dict))[0] dec_stream_id = unpack('!H', CoreCryptoSymmetric.decrypt_for_hop(pack('!H', enc_stream_id), kdf_dict))[0] dec_digest = CoreCryptoSymmetric.decrypt_for_hop(enc_digest, kdf_dict) dec_length = unpack('!H', CoreCryptoSymmetric.decrypt_for_hop(pack('!H', enc_length), kdf_dict))[0] dec_addrport = CoreCryptoSymmetric.decrypt_for_hop(enc_addrport, kdf_dict) dec_flags = unpack('!I', CoreCryptoSymmetric.decrypt_for_hop(pack('!I', enc_flags), kdf_dict))[0] # Set the decrypted values cell.PAYLOAD.RECOGNIZED = dec_recognized cell.PAYLOAD.StreamID = dec_stream_id cell.PAYLOAD.Digest = dec_digest cell.PAYLOAD.Length = dec_length cell.PAYLOAD.Data = RelayBeginPayload(dec_addrport, dec_flags) # Return return dec_recognized, cell
def build_begin_cell(addrport: bytes, flag_dict, circ_id: int, recognized: int, streamID: int, kdf_dict1: Dict, kdf_dict2: Dict, kdf_dict3: Dict) -> Cell: """ The method to build a Begin Cell :param addrport: :param flag_dict: :param circ_id: :param recognized: :param streamID: :return: The Begin Cell object """ flags = int(0) flags |= flag_dict['IPV6_PREF'] flags |= (flag_dict['IPV4_NOT_OK'] << 1) flags |= (flag_dict['IPV6_OK'] << 2) digest_dict = { 'addrPort': addrport, 'flags': flags, 'relayCMD': RelayCellPayload.RELAY_CMD_ENUM['RELAY_BEGIN'], 'recognized': recognized, 'streamID': streamID, 'relayPayloadLen': Cell.PAYLOAD_LEN - 11 } digest = b'' # CoreCryptoMisc.calculate_digest(digest_dict) # Encrypt the values by packing and unpacking enc_addrport = CoreCryptoSymmetric.encrypt_from_origin(addrport, kdf_dict1, kdf_dict2, kdf_dict3) enc_flags = unpack('!I', CoreCryptoSymmetric.encrypt_from_origin(pack('!I', flags), kdf_dict1, kdf_dict2, kdf_dict3))[0] enc_relay_cmd = RelayCellPayload.RELAY_CMD_ENUM['RELAY_BEGIN'] # unpack('!B', CoreCryptoSymmetric.encrypt_from_origin(pack('!B', RelayCellPayload.RELAY_CMD_ENUM['RELAY_BEGIN']), kdf_dict1, kdf_dict2, kdf_dict3))[0] enc_recognized = unpack('!H', CoreCryptoSymmetric.encrypt_from_origin(pack('!H', recognized), kdf_dict1, kdf_dict2, kdf_dict3))[0] enc_stream_id = unpack('!H', CoreCryptoSymmetric.encrypt_from_origin(pack('!H', streamID), kdf_dict1, kdf_dict2, kdf_dict3))[0] enc_relay_payload_len = unpack('!H', CoreCryptoSymmetric.encrypt_from_origin(pack('!H', Cell.PAYLOAD_LEN - 11), kdf_dict1, kdf_dict2, kdf_dict3))[0] enc_digest = CoreCryptoSymmetric.encrypt_from_origin(digest, kdf_dict1, kdf_dict2, kdf_dict3) relay_begin_payload = RelayBeginPayload(enc_addrport, enc_flags) relay_cell_payload = RelayCellPayload(enc_relay_cmd, enc_recognized, enc_stream_id, enc_digest, enc_relay_payload_len, relay_begin_payload) begin_cell = Cell(circ_id, Cell.CMD_ENUM['RELAY'], Cell.PAYLOAD_LEN, relay_cell_payload) return begin_cell