Exemple #1
0
    def create_circuit_hop2(self) -> int:
        """
		The function to setup circuit with the second hop in the circuit. Creates the EXTEND/EXTEND2 cell and sends it
		down the socket. It assumes that the open_connection was called on the first node and the socket is connected
		to the first node, and that to the second node
		:return: Returns a status code. 0 --> Success DH Handshake and -1 --> Means error in processing the cell or the DH Handshake.
		On error it closes the socket to node 2.
		"""
        # First create a EXTEND2 Cell.
        x, x_bytes, gx, gx_bytes = CoreCryptoDH.generate_dh_priv_key()

        # For hop2 we get its IP:port for LSPEC ==> Link specifier
        hop2_ip = self.node_container[2].host
        hop2_port = self.node_container[2].port
        extend_cell = Builder.build_extend_cell(
            'TAP', x_bytes, gx_bytes, self.circ_id,
            self.node_container[2].onion_key_pub, hop2_ip, hop2_port)

        print(extend_cell)

        # Sending a JSON String down the socket
        self.skt.client_send_data(ComplexStructEncoder.encode(extend_cell))

        # Get the extended cell in response and convert it to python Cell Object
        cell_bytes = self.skt.client_recv_data()
        extended_cell = Parser.parse_encoded_extended_cell(cell_bytes)

        self.session_key02 = Processor.process_extended_cell(
            extended_cell, self.circ_id, x_bytes)
        if self.session_key02 is None:
            self.skt.close()
            return -1

        return 0
Exemple #2
0
	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
Exemple #3
0
    def create_circuit_hop1(self) -> int:
        """
		The function to setup circuit with the first hop in the circuit. Creates the CREATE/CREATE2 cell and sends it
		down the socket. It assumes that the open_connection was called on the first node and the socket is connected
		to the first node
		:return: Returns a status code. 0 --> Success DH Handshake and -1 --> Means error in processing the cell or the DH Handshake.
		On error it closes the socket to node 1
		"""
        # First create a CREATE2 Cell.
        x, x_bytes, gx, gx_bytes = CoreCryptoDH.generate_dh_priv_key()
        create_cell = Builder.build_create_cell(
            'TAP', x_bytes, gx_bytes, self.circ_id,
            self.node_container[1].onion_key_pub)

        # Sending a JSON String down the socket
        self.skt.client_send_data(ComplexStructEncoder.encode(create_cell))
        # self.skt.client_send_data(Serialize.obj_to_json(create_cell).encode('utf-8'))

        # Get the created cell in response and convert it to python Cell Object
        cell_bytes = self.skt.client_recv_data()
        created_cell = Parser.parse_encoded_created_cell(cell_bytes)

        self.session_key01 = Processor.process_created_cell(
            created_cell, self.circ_id, x_bytes)
        if self.session_key01 is None:
            self.skt.close()
            return -1

        return 0
Exemple #4
0
	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
Exemple #5
0
	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 handle_create_cell(self, cell_bytes, direction):
			# Call the Parser for create cell
			create_cell = Parser.parse_encoded_create_cell(cell_bytes)

			# Process the create cell
			y, y_bytes, gy, gy_bytes = CoreCryptoDH.generate_dh_priv_key()
			gx_bytes, kdf_dict = Processor.process_create_cell(create_cell, self.node.onion_key_pri, y_bytes)

			# After processing the create cell, we make a created cell
			# and send it down the socket
			created_cell = Builder.build_created_cell(y_bytes, gy_bytes, self.circ_id, gx_bytes)
			print(created_cell)
			self.conn.sendall(ComplexStructEncoder.encode(created_cell))
			print("Created cell sent")

			self.session_key = kdf_dict
			return 0
Exemple #7
0
	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
Exemple #8
0
	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