Пример #1
0
    async def _send_handshake_response(self, packet: Packet[MessagePacket],
                                       sender_endpoint: Endpoint) -> None:
        self.logger.debug("%s: sending handshake response", self)
        try:
            remote_enr = self._enr_db.get_enr(packet.auth_data.source_node_id)
        except KeyError:
            enr_sequence_number = 0
        else:
            enr_sequence_number = remote_enr.sequence_number

        auth_data = WhoAreYouPacket(
            id_nonce=cast(IDNonce, secrets.token_bytes(16)),
            enr_sequence_number=enr_sequence_number,
        )

        self.handshake_response_packet = Packet.prepare(
            aes_gcm_nonce=packet.header.aes_gcm_nonce,
            initiator_key=cast(AES128Key, secrets.token_bytes(16)),
            message=EmptyMessage(),
            auth_data=auth_data,
            dest_node_id=packet.auth_data.source_node_id,
        )
        envelope = OutboundEnvelope(
            packet=self.handshake_response_packet,
            receiver_endpoint=sender_endpoint,
        )
        await self._events.packet_sent.trigger((self, envelope))
        await self._outbound_envelope_send_channel.send(envelope)
Пример #2
0
def extract_challenge_data(challenge_data):
    stream = io.BytesIO(challenge_data)

    masking_iv = stream.read(16)
    static_header = Header.from_wire_bytes(stream.read(HEADER_PACKET_SIZE))
    who_are_you = WhoAreYouPacket.from_wire_bytes(
        stream.read(WHO_ARE_YOU_PACKET_SIZE))

    assert stream.read() == b""

    return masking_iv, static_header, who_are_you
Пример #3
0
def do_who_are_you_packet_fixture_decoding_test(fixture):
    dest_node_id = decode_hex(fixture["dest-node-id"])
    expected_auth_data = WhoAreYouPacket(
        id_nonce=decode_hex(fixture["packet"]["id-nonce"]),
        enr_sequence_number=to_int(hexstr=fixture["packet"]["enr-seq"]),
    )
    encoded_packet = decode_hex(fixture["encoded"])
    aes_gcm_nonce = decode_hex(fixture["packet"]["request-nonce"])

    packet = decode_packet(encoded_packet, dest_node_id)

    assert packet.auth_data == expected_auth_data
    assert packet.header.aes_gcm_nonce == aes_gcm_nonce
Пример #4
0
def test_who_are_you_packet_encoding():
    initiator_key = b"\x01" * 16
    aes_gcm_nonce = b"\x02" * 12
    dest_node_id = b"\x04" * 32
    message = PingMessage(b"\x01", 0)
    auth_data = WhoAreYouPacket(id_nonce=b"\x06" * 16,
                                enr_sequence_number=0x07)

    packet = Packet.prepare(
        aes_gcm_nonce=aes_gcm_nonce,
        initiator_key=initiator_key,
        message=message,
        auth_data=auth_data,
        dest_node_id=dest_node_id,
    )
    packet_wire_bytes = packet.to_wire_bytes()
    result = decode_packet(packet_wire_bytes, dest_node_id)

    assert result == packet
Пример #5
0
def test_who_are_you_packet_encoding():
    initiator_key = b"\x01" * 16
    nonce = b"\x02" * 12
    source_node_id = b"\x03" * 32
    dest_node_id = b"\x04" * 32
    message = PingMessage(1, 0)
    auth_data = WhoAreYouPacket(request_nonce=b"\x05" * 12,
                                id_nonce=b"\x06" * 32,
                                enr_sequence_number=0x07)

    packet = Packet.prepare(
        nonce=nonce,
        initiator_key=initiator_key,
        message=message,
        auth_data=auth_data,
        source_node_id=source_node_id,
        dest_node_id=dest_node_id,
    )
    packet_wire_bytes = packet.to_wire_bytes()
    result = decode_packet(packet_wire_bytes, dest_node_id)

    assert result == packet
Пример #6
0
def do_handshake_packet_fixture_decoding_test(fixture):
    source_node_id = decode_hex(fixture["src-node-id"])
    dest_node_id = decode_hex(fixture["dest-node-id"])
    encoded_packet = decode_hex(fixture["encoded"])
    ping_enr_seq = to_int(hexstr=fixture["packet"]["message"]["enr-seq"])
    who_are_you_enr_seq = to_int(
        hexstr=fixture["handshake-inputs"]["whoareyou"]["enr-seq"])

    if who_are_you_enr_seq == ping_enr_seq and who_are_you_enr_seq != 0:
        should_have_record = False
    else:
        should_have_record = True

    # ephemeral_private_key = decode_hex(fixture['handshake-inputs']['ephemeral-key'])
    ephemeral_public_key = decode_hex(
        fixture["handshake-inputs"]["ephemeral-pubkey"])
    # ephemeral_private_key = decode_hex(fixture["handshake-inputs"]["ephemeral-key"])

    # request_nonce = decode_hex(fixture['handshake-inputs']['whoareyou']['request-nonce'])
    challenge_data = decode_hex(
        fixture["handshake-inputs"]["whoareyou"]["challenge-data"])
    masking_iv, static_header, who_are_you = extract_challenge_data(
        challenge_data)

    id_nonce = decode_hex(fixture["handshake-inputs"]["whoareyou"]["id-nonce"])
    assert who_are_you.id_nonce == id_nonce

    aes_gcm_nonce = decode_hex(fixture["nonce"])
    # TODO: why doesn't this match
    # assert static_header.aes_gcm_nonce == aes_gcm_nonce

    signature_inputs = V4HandshakeScheme.signature_inputs_cls(
        iv=masking_iv,
        header=static_header,
        who_are_you=WhoAreYouPacket(id_nonce, who_are_you_enr_seq),
        ephemeral_public_key=ephemeral_public_key,
        recipient_node_id=dest_node_id,
    )

    id_nonce_signature = V4HandshakeScheme.create_id_nonce_signature(
        signature_inputs=signature_inputs,
        private_key=NODE_KEY_A,
    )

    packet = decode_packet(encoded_packet, dest_node_id)
    expected_auth_data = HandshakePacket(
        auth_data_head=HandshakeHeader(source_node_id, 64, 33),
        id_signature=id_nonce_signature,
        ephemeral_public_key=ephemeral_public_key,
        record=packet.auth_data.record,
    )

    assert expected_auth_data == packet.auth_data
    assert packet.header.aes_gcm_nonce == aes_gcm_nonce

    if should_have_record:
        assert packet.auth_data.record is not None
        assert packet.auth_data.record.node_id == source_node_id
    else:
        assert packet.auth_data.record is None

    expected_message = PingMessage(
        request_id=decode_hex(fixture["packet"]["message"]["req-id"]),
        enr_seq=to_int(hexstr=fixture["packet"]["message"]["enr-seq"]),
    )
    actual_message = decode_message(
        decryption_key=decode_hex(fixture["read-key"]),
        aes_gcm_nonce=aes_gcm_nonce,
        message_cipher_text=packet.message_cipher_text,
        authenticated_data=packet.challenge_data,
    )
    assert expected_message == actual_message
Пример #7
0
from ddht.tools.factories.v5_1 import HeaderFactory, WhoAreYouPacketFactory
from ddht.tools.v5_strategies import iv_st, node_id_st, private_key_st
from ddht.v5_1.constants import ID_NONCE_SIGNATURE_PREFIX, WHO_ARE_YOU_PACKET_SIZE
from ddht.v5_1.handshake_schemes import SignatureInputs, V4HandshakeScheme
from ddht.v5_1.packets import WhoAreYouPacket

header_st = st.binary(min_size=12,
                      max_size=12).map(lambda aes_gcm_nonce: HeaderFactory(
                          flag=WhoAreYouPacket.flag,
                          aes_gcm_nonce=aes_gcm_nonce,
                          auth_data_size=WHO_ARE_YOU_PACKET_SIZE,
                      ))
who_are_you_st = st.tuples(
    st.binary(min_size=16, max_size=16),
    st.integers(min_value=0, max_value=65536),
).map(lambda id_nonce_and_seq_num: WhoAreYouPacket(*id_nonce_and_seq_num))


def test_handshake_key_generation():
    private_key, public_key = V4HandshakeScheme.create_handshake_key_pair()
    V4HandshakeScheme.validate_uncompressed_public_key(public_key)
    V4HandshakeScheme.validate_handshake_public_key(public_key)
    assert PrivateKey(private_key).public_key.to_bytes() == public_key


@pytest.mark.parametrize("public_key", (b"\x01" * 64, b"\x02" * 64))
def test_handshake_public_key_validation_valid(public_key):
    V4HandshakeScheme.validate_handshake_public_key(public_key)


@pytest.mark.parametrize(