Пример #1
0
    async def receive_handshake_response(
        self,
        packet: HandshakeResponse,
    ) -> Tuple[SessionKeys, keys.PublicKey]:
        if not isinstance(packet, HandshakeResponse):
            raise Exception(f"Unhandled packet type: {type(packet)}")
        if not secrets.compare_digest(packet.token,
                                      self._initiating_packet.auth_tag):
            raise ValidationError("Mismatch between token")

        self.logger.debug('%s: receiving handshake response', self)

        # compute session keys
        ephemeral_private_key = keys.PrivateKey(secrets.token_bytes(32))

        self.remote_public_key = packet.public_key
        expected_remote_node_id = public_key_to_node_id(self.remote_public_key)
        if expected_remote_node_id != self.remote_node_id:
            raise ValidationError(
                f"Remote node ids does not match expected node id: "
                f"{self.remote_node_id} != {self.remote_node_id}")

        session_keys = compute_session_keys(
            local_private_key=ephemeral_private_key,
            remote_public_key=packet.public_key,
            local_node_id=self.local_node_id,
            remote_node_id=self.remote_node_id,
            id_nonce=packet.id_nonce,
            is_initiator=True,
        )
        return session_keys, ephemeral_private_key.public_key
Пример #2
0
class NodeFactory(factory.Factory):  # type: ignore
    class Meta:
        model = Node

    node_id = factory.LazyFunction(
        lambda: public_key_to_node_id(PublicKeyFactory()))
    endpoint = factory.SubFactory(EndpointFactory)
Пример #3
0
    def __init__(self,
                 private_key: keys.PrivateKey,
                 listen_on: Endpoint,
                 ) -> None:
        self._private_key = private_key
        self.public_key = private_key.public_key

        self.local_node_id = public_key_to_node_id(self.public_key)
        self.listen_on = listen_on
        self.local_node = Node(self.local_node_id, self.listen_on)

        # Datagrams
        (
            self._outbound_datagram_send_channel,
            self._outbound_datagram_receive_channel,
        ) = trio.open_memory_channel[Datagram](0)
        (
            self._inbound_datagram_send_channel,
            self._inbound_datagram_receive_channel,
        ) = trio.open_memory_channel[Datagram](0)

        # Packets
        (
            self._outbound_packet_send_channel,
            self._outbound_packet_receive_channel,
        ) = trio.open_memory_channel[NetworkPacket](0)
        (
            self._inbound_packet_send_channel,
            self._inbound_packet_receive_channel,
        ) = trio.open_memory_channel[NetworkPacket](0)

        # Messages
        (
            self._outbound_message_send_channel,
            self._outbound_message_receive_channel,
        ) = trio.open_memory_channel[MessageAPI[sedes.Serializable]](0)
        (
            self._inbound_message_send_channel,
            self._inbound_message_receive_channel,
        ) = trio.open_memory_channel[MessageAPI[sedes.Serializable]](0)

        self.events = Events()
        self.pool = Pool(
            private_key=self._private_key,
            events=self.events,
            outbound_packet_send_channel=self._outbound_packet_send_channel,
            inbound_message_send_channel=self._inbound_message_send_channel,
        )

        self.message_dispatcher = MessageDispatcher(
            self._outbound_message_send_channel,
            self._inbound_message_receive_channel,
        )

        self._ready = trio.Event()
Пример #4
0
    def __init__(
        self,
        private_key: keys.PrivateKey,
        events: EventsAPI,
        outbound_packet_send_channel: trio.abc.SendChannel[NetworkPacket],
        inbound_message_send_channel: trio.abc.SendChannel[MessageAPI[
            sedes.Serializable]],
    ) -> None:
        self._private_key = private_key
        self.public_key = private_key.public_key
        self.local_node_id = public_key_to_node_id(self.public_key)
        self._sessions = {}

        self._events = events
        self._outbound_packet_send_channel = outbound_packet_send_channel
        self._inbound_message_send_channel = inbound_message_send_channel
Пример #5
0
    async def receive_handshake_completion(
            self, packet: CompleteHandshakePacket) -> SessionKeys:
        self.logger.debug('%s: received handshake completion', self)
        remote_node_id = recover_source_id_from_tag(
            packet.tag,
            self.local_node_id,
        )
        if remote_node_id != self.remote_node_id:
            raise ValidationError(
                f"Remote node ids do not match: {remote_node_id} != {self.remote_node_id}"
            )

        self.remote_public_key = packet.header.public_key
        expected_remote_node_id = public_key_to_node_id(self.remote_public_key)
        if expected_remote_node_id != remote_node_id:
            raise ValidationError(
                f"Remote node ids does not match expected node id: "
                f"{remote_node_id} != {self.remote_node_id}")

        ephemeral_public_key = packet.header.ephemeral_public_key

        session_keys = compute_session_keys(
            local_private_key=self.private_key,
            remote_public_key=ephemeral_public_key,
            local_node_id=self.local_node_id,
            remote_node_id=self.remote_node_id,
            id_nonce=self.handshake_response_packet.id_nonce,
            is_initiator=False,
        )

        self.decrypt_and_validate_auth_response(
            packet,
            session_keys.auth_response_key,
            self.handshake_response_packet.id_nonce,
        )
        payload = self.decrypt_and_validate_message(
            packet,
            session_keys.decryption_key,
        )
        message = Message(
            payload=payload,
            node=self.remote_node,
        )
        await self._inbound_message_send_channel.send(message)
        return session_keys
Пример #6
0
 def local_node_id(self) -> NodeID:
     return public_key_to_node_id(self.private_key.public_key)