Esempio n. 1
0
def _decode_auth(encoded_packet: bytes) -> Tuple[Union[AuthHeader, Nonce], int]:
    try:
        decoded_auth, _, message_start_index = rlp.codec.consume_item(encoded_packet, TAG_SIZE)
    except DecodingError as error:
        raise ValidationError("Packet authentication section is not proper RLP") from error

    if is_bytes(decoded_auth):
        validate_nonce(decoded_auth)
        return Nonce(decoded_auth), message_start_index
    elif is_list_like(decoded_auth):
        validate_length(decoded_auth, 5, "auth header")
        for index, element in enumerate(decoded_auth):
            if not is_bytes(element):
                raise ValidationError(f"Element {index} in auth header is not bytes: {element}")
        auth_header = AuthHeader(
            auth_tag=decoded_auth[0],
            id_nonce=decoded_auth[1],
            auth_scheme_name=decoded_auth[2],
            ephemeral_public_key=decoded_auth[3],
            encrypted_auth_response=decoded_auth[4],
        )
        validate_auth_header(auth_header)
        return auth_header, message_start_index
    else:
        raise Exception("unreachable: RLP can only encode bytes and lists")
Esempio n. 2
0
def _decode_who_are_you_payload(encoded_packet: bytes) -> Tuple[Nonce, IDNonce, int]:
    payload_rlp = encoded_packet[MAGIC_SIZE:]

    try:
        payload = rlp.decode(payload_rlp)
    except DecodingError as error:
        raise ValidationError(
            f"WHOAREYOU payload section is not proper RLP: {encode_hex(payload_rlp)}"
        ) from error

    if not is_list_like(payload):
        raise ValidationError(
            f"WHOAREYOU payload section is not an RLP encoded list: {payload}"
        )
    if len(payload) != 3:
        raise ValidationError(
            f"WHOAREYOU payload consists of {len(payload)} instead of 3 elements: {payload}"
        )

    token, id_nonce, enr_seq_bytes = payload
    enr_seq = big_endian_int.deserialize(enr_seq_bytes)
    validate_nonce(token)
    return Nonce(token), id_nonce, enr_seq
Esempio n. 3
0
def get_random_auth_tag() -> Nonce:
    return Nonce(secrets.token_bytes(NONCE_SIZE))
Esempio n. 4
0
from p2p.discv5.typing import (
    Nonce,
)


AES128_KEY_SIZE = 16  # size of an AES218 key
NONCE_SIZE = 12  # size of an AESGCM nonce
TAG_SIZE = 32  # size of the tag packet prefix
MAGIC_SIZE = 32  # size of the magic hash in the who are you packet
ID_NONCE_SIZE = 32  # size of the id nonce in who are you and auth tag packets
RANDOM_ENCRYPTED_DATA_SIZE = 12  # size of random data we send to initiate a handshake

MAX_PACKET_SIZE = 1280  # maximum allowed size of a packet

ZERO_NONCE = Nonce(b"\x00" * NONCE_SIZE)  # nonce used for the auth header packet
AUTH_RESPONSE_VERSION = 5  # version number used in auth response
AUTH_SCHEME_NAME = b"gcm"  # the name of the only supported authentication scheme

TOPIC_HASH_SIZE = 32  # size of a topic hash
IP_V4_SIZE = 4  # size of an IPv4 address
IP_V6_SIZE = 16  # size of an IPv6 address

ENR_REPR_PREFIX = "enr:"  # prefix used when printing an ENR
MAX_ENR_SIZE = 300  # maximum allowed size of an ENR
IP_V4_ADDRESS_ENR_KEY = b"ip"
UDP_PORT_ENR_KEY = b"udp"

WHO_ARE_YOU_MAGIC_SUFFIX = b"WHOAREYOU"
HKDF_INFO = b"discovery v5 key agreement"

# buffer size used for incoming UDP datagrams (should be larger than MAX_PACKET_SIZE)