java.lang.Object
net.i2p.router.transport.udp.SSU2Util

final class SSU2Utilextends Object
SSU2 Utils and constants.
  • Field Details

    • PROTOCOL_VERSION

      public static final int PROTOCOL_VERSION
      SSU2 protocol version number.
      See Also:
    • MIN_SUPPORTED_VERSION

      public static final int MIN_SUPPORTED_VERSION
      The oldest SSU2 version accepted when establishing. Reject earlier versions as unsupported.
      See Also:
    • MAX_SUPPORTED_VERSION

      public static final int MAX_SUPPORTED_VERSION
      The newest SSU2 version accepted when establishing.
      See Also:
    • KEY_LEN

      public static final int KEY_LEN
      32 bytes, X25519 public key length.
    • MAC_LEN

      public static final int MAC_LEN
      16 bytes, MAC tag length.
      See Also:
    • CHACHA_IV_LEN

      public static final int CHACHA_IV_LEN
      12 bytes, ChaCha20 nonce length.
      See Also:
    • INTRO_KEY_LEN

      public static final int INTRO_KEY_LEN
      32 bytes, introductory key length.
      See Also:
    • SHORT_HEADER_SIZE

      public static final int SHORT_HEADER_SIZE
      16 bytes, short (data) header size.
      See Also:
    • LONG_HEADER_SIZE

      public static final int LONG_HEADER_SIZE
      32 bytes, long (handshake) header size.
      See Also:
    • SESSION_HEADER_SIZE

      public static final int SESSION_HEADER_SIZE
      64 bytes, combined long header and key.
    • DEST_CONN_ID_OFFSET

      public static final int DEST_CONN_ID_OFFSET
      Offset of destination connection ID in header.
      See Also:
    • PKT_NUM_OFFSET

      public static final int PKT_NUM_OFFSET
      Offset of packet number in header.
      See Also:
    • PKT_NUM_LEN

      public static final int PKT_NUM_LEN
      Length of packet number field in bytes.
      See Also:
    • TYPE_OFFSET

      public static final int TYPE_OFFSET
      Offset of message type in header.
      See Also:
    • VERSION_OFFSET

      public static final int VERSION_OFFSET
      Offset of protocol version in header.
      See Also:
    • SHORT_HEADER_FLAGS_OFFSET

      public static final int SHORT_HEADER_FLAGS_OFFSET
      Offset of short header flags.
      See Also:
    • SHORT_HEADER_FLAGS_LEN

      public static final int SHORT_HEADER_FLAGS_LEN
      Length of short header flags in bytes.
      See Also:
    • NETID_OFFSET

      public static final int NETID_OFFSET
      Offset of network ID in header.
      See Also:
    • LONG_HEADER_FLAGS_OFFSET

      public static final int LONG_HEADER_FLAGS_OFFSET
      Offset of long header flags.
      See Also:
    • SRC_CONN_ID_OFFSET

      public static final int SRC_CONN_ID_OFFSET
      Offset of source connection ID in long header.
      See Also:
    • TOKEN_OFFSET

      public static final int TOKEN_OFFSET
      Offset of token in long header.
      See Also:
    • HEADER_PROT_SAMPLE_LEN

      public static final int HEADER_PROT_SAMPLE_LEN
      Length of header protection sample in bytes.
      See Also:
    • TOTAL_PROT_SAMPLE_LEN

      public static final int TOTAL_PROT_SAMPLE_LEN
      Total header protection sample length for both samples.
      See Also:
    • HEADER_PROT_SAMPLE_1_OFFSET

      public static final int HEADER_PROT_SAMPLE_1_OFFSET
      Offset of first header protection sample.
      See Also:
    • HEADER_PROT_SAMPLE_2_OFFSET

      public static final int HEADER_PROT_SAMPLE_2_OFFSET
      Offset of second header protection sample.
      See Also:
    • HEADER_PROT_DATA_LEN

      public static final int HEADER_PROT_DATA_LEN
      Length of header protection data in bytes.
      See Also:
    • HEADER_PROT_1_OFFSET

      public static final int HEADER_PROT_1_OFFSET
      Offset of first header protection region (dest conn ID).
      See Also:
    • HEADER_PROT_2_OFFSET

      public static final int HEADER_PROT_2_OFFSET
      Offset of second header protection region (packet number).
      See Also:
    • PADDING_MAX

      public static final int PADDING_MAX
      Maximum padding for data packets.
      See Also:
    • PADDING_MAX_SESSION_REQUEST

      public static final int PADDING_MAX_SESSION_REQUEST
      Maximum padding for session request.
      See Also:
    • PADDING_MAX_SESSION_CREATED

      public static final int PADDING_MAX_SESSION_CREATED
      Maximum padding for session created.
      See Also:
    • MIN_DATA_LEN

      public static final int MIN_DATA_LEN
      Minimum short-header data message size, 40 bytes. No minimum here includes the IP or UDP headers.
      See Also:
    • MIN_LONG_DATA_LEN

      public static final int MIN_LONG_DATA_LEN
      Long message type minimum length in bytes (56).
      See Also:
    • MIN_HANDSHAKE_DATA_LEN

      public static final int MIN_HANDSHAKE_DATA_LEN
      Handshake message type minimum length in bytes (88).
    • MIN_TOKEN_REQUEST_LEN

      public static final int MIN_TOKEN_REQUEST_LEN
      Token request minimum length in bytes (56).
      See Also:
    • MIN_RETRY_LEN

      public static final int MIN_RETRY_LEN
      Retry message minimum length in bytes (56).
      See Also:
    • MIN_SESSION_REQUEST_LEN

      public static final int MIN_SESSION_REQUEST_LEN
      Session request minimum length in bytes (88).
    • MIN_SESSION_CREATED_LEN

      public static final int MIN_SESSION_CREATED_LEN
      Session created minimum length in bytes (88).
    • FIRST_FRAGMENT_HEADER_SIZE

      public static final int FIRST_FRAGMENT_HEADER_SIZE
      3 byte block header.
      See Also:
    • DATA_FOLLOWON_EXTRA_SIZE

      public static final int DATA_FOLLOWON_EXTRA_SIZE
      5 for flag and msg number in followon block.
      See Also:
    • FOLLOWON_FRAGMENT_HEADER_SIZE

      public static final int FOLLOWON_FRAGMENT_HEADER_SIZE
      3 byte block header + 4 byte msg ID + 1 byte fragment info = 8.
      See Also:
    • DATA_HEADER_SIZE

      public static final int DATA_HEADER_SIZE
      16 byte short header.
      See Also:
    • SESSION_REQUEST_FLAG_BYTE

      public static final byte SESSION_REQUEST_FLAG_BYTE
      The message types, 0-11, as bytes. Message type flag for session request.
      See Also:
    • SESSION_CREATED_FLAG_BYTE

      public static final byte SESSION_CREATED_FLAG_BYTE
      Message type flag for session created.
      See Also:
    • SESSION_CONFIRMED_FLAG_BYTE

      public static final byte SESSION_CONFIRMED_FLAG_BYTE
      Message type flag for session confirmed.
      See Also:
    • DATA_FLAG_BYTE

      public static final byte DATA_FLAG_BYTE
      Message type flag for data.
      See Also:
    • PEER_TEST_FLAG_BYTE

      public static final byte PEER_TEST_FLAG_BYTE
      Message type flag for peer test.
      See Also:
    • RETRY_FLAG_BYTE

      public static final byte RETRY_FLAG_BYTE
      Message type flag for retry.
      See Also:
    • TOKEN_REQUEST_FLAG_BYTE

      public static final byte TOKEN_REQUEST_FLAG_BYTE
      Message type flag for token request.
      See Also:
    • HOLE_PUNCH_FLAG_BYTE

      public static final byte HOLE_PUNCH_FLAG_BYTE
      Message type flag for hole punch.
      See Also:
    • INFO_CREATED

      public static final String INFO_CREATED
      HKDF info string for session created header key derivation.
      See Also:
    • INFO_CONFIRMED

      public static final String INFO_CONFIRMED
      HKDF info string for session confirmed key derivation.
      See Also:
    • INFO_DATA

      public static final String INFO_DATA
      HKDF info string for data packet key derivation.
      See Also:
    • ZEROLEN

      public static final byte[] ZEROLEN
      Empty byte array, used as HKDF salt.
    • ZEROKEY

      public static final byte[] ZEROKEY
      All-zero key of KEY_LEN bytes.
    • RELAY_REQUEST_PROLOGUE

      public static final byte[] RELAY_REQUEST_PROLOGUE
      Prologue for relay request signatures.
    • RELAY_RESPONSE_PROLOGUE

      public static final byte[] RELAY_RESPONSE_PROLOGUE
      Prologue for relay response signatures.
    • PEER_TEST_PROLOGUE

      public static final byte[] PEER_TEST_PROLOGUE
      Prologue for peer test signatures.
    • TEST_ACCEPT

      public static final int TEST_ACCEPT
      Peer test accepted.
      See Also:
    • TEST_REJECT_BOB_UNSPEC

      public static final int TEST_REJECT_BOB_UNSPEC
      Rejected by Bob: unspecified reason.
      See Also:
    • TEST_REJECT_BOB_NO_CHARLIE

      public static final int TEST_REJECT_BOB_NO_CHARLIE
      Rejected by Bob: no Charlie.
      See Also:
    • TEST_REJECT_BOB_LIMIT

      public static final int TEST_REJECT_BOB_LIMIT
      Rejected by Bob: limit reached.
      See Also:
    • TEST_REJECT_BOB_SIGFAIL

      public static final int TEST_REJECT_BOB_SIGFAIL
      Rejected by Bob: signature failure.
      See Also:
    • TEST_REJECT_BOB_ADDRESS

      public static final int TEST_REJECT_BOB_ADDRESS
      Rejected by Bob: address mismatch.
      See Also:
    • TEST_REJECT_CHARLIE_UNSPEC

      public static final int TEST_REJECT_CHARLIE_UNSPEC
      Rejected by Charlie: unspecified reason.
      See Also:
    • TEST_REJECT_CHARLIE_ADDRESS

      public static final int TEST_REJECT_CHARLIE_ADDRESS
      Rejected by Charlie: address mismatch.
      See Also:
    • TEST_REJECT_CHARLIE_LIMIT

      public static final int TEST_REJECT_CHARLIE_LIMIT
      Rejected by Charlie: limit reached.
      See Also:
    • TEST_REJECT_CHARLIE_SIGFAIL

      public static final int TEST_REJECT_CHARLIE_SIGFAIL
      Rejected by Charlie: signature failure.
      See Also:
    • TEST_REJECT_CHARLIE_CONNECTED

      public static final int TEST_REJECT_CHARLIE_CONNECTED
      Rejected by Charlie: already connected.
      See Also:
    • TEST_REJECT_CHARLIE_BANNED

      public static final int TEST_REJECT_CHARLIE_BANNED
      Rejected by Charlie: banned.
      See Also:
    • TEST_REJECT_CHARLIE_UNKNOWN_ALICE

      public static final int TEST_REJECT_CHARLIE_UNKNOWN_ALICE
      Rejected by Charlie: unknown Alice.
      See Also:
    • RELAY_ACCEPT

      public static final int RELAY_ACCEPT
      Relay accepted.
      See Also:
    • RELAY_REJECT_BOB_UNSPEC

      public static final int RELAY_REJECT_BOB_UNSPEC
      Rejected by Bob: unspecified reason.
      See Also:
    • RELAY_REJECT_BOB_BANNED_CHARLIE

      public static final int RELAY_REJECT_BOB_BANNED_CHARLIE
      Rejected by Bob: Charlie is banned.
      See Also:
    • RELAY_REJECT_BOB_LIMIT

      public static final int RELAY_REJECT_BOB_LIMIT
      Rejected by Bob: limit reached.
      See Also:
    • RELAY_REJECT_BOB_SIGFAIL

      public static final int RELAY_REJECT_BOB_SIGFAIL
      Rejected by Bob: signature failure.
      See Also:
    • RELAY_REJECT_BOB_NO_TAG

      public static final int RELAY_REJECT_BOB_NO_TAG
      Rejected by Bob: no tag found.
      See Also:
    • RELAY_REJECT_BOB_UNKNOWN_ALICE

      public static final int RELAY_REJECT_BOB_UNKNOWN_ALICE
      Rejected by Bob: unknown Alice.
      See Also:
    • RELAY_REJECT_CHARLIE_UNSPEC

      public static final int RELAY_REJECT_CHARLIE_UNSPEC
      Rejected by Charlie: unspecified reason.
      See Also:
    • RELAY_REJECT_CHARLIE_ADDRESS

      public static final int RELAY_REJECT_CHARLIE_ADDRESS
      Rejected by Charlie: address mismatch.
      See Also:
    • RELAY_REJECT_CHARLIE_LIMIT

      public static final int RELAY_REJECT_CHARLIE_LIMIT
      Rejected by Charlie: limit reached.
      See Also:
    • RELAY_REJECT_CHARLIE_SIGFAIL

      public static final int RELAY_REJECT_CHARLIE_SIGFAIL
      Rejected by Charlie: signature failure.
      See Also:
    • RELAY_REJECT_CHARLIE_CONNECTED

      public static final int RELAY_REJECT_CHARLIE_CONNECTED
      Rejected by Charlie: already connected.
      See Also:
    • RELAY_REJECT_CHARLIE_BANNED

      public static final int RELAY_REJECT_CHARLIE_BANNED
      Rejected by Charlie: banned.
      See Also:
    • RELAY_REJECT_CHARLIE_UNKNOWN_ALICE

      public static final int RELAY_REJECT_CHARLIE_UNKNOWN_ALICE
      Rejected by Charlie: unknown Alice.
      See Also:
    • REASON_UNSPEC

      public static final int REASON_UNSPEC
      Unspecified reason.
      See Also:
    • REASON_TERMINATION

      public static final int REASON_TERMINATION
      Termination requested by remote.
      See Also:
    • REASON_TIMEOUT

      public static final int REASON_TIMEOUT
      Connection timeout.
      See Also:
    • REASON_SHUTDOWN

      public static final int REASON_SHUTDOWN
      Router shutting down.
      See Also:
    • REASON_AEAD

      public static final int REASON_AEAD
      AEAD verification failure.
      See Also:
    • REASON_OPTIONS

      public static final int REASON_OPTIONS
      Options parameter mismatch.
      See Also:
    • REASON_SIGTYPE

      public static final int REASON_SIGTYPE
      Signature type error or mismatch.
      See Also:
    • REASON_SKEW

      public static final int REASON_SKEW
      Clock skew exceeds tolerance.
      See Also:
    • REASON_PADDING

      public static final int REASON_PADDING
      Invalid padding.
      See Also:
    • REASON_FRAMING

      public static final int REASON_FRAMING
      Framing protocol error.
      See Also:
    • REASON_PAYLOAD

      public static final int REASON_PAYLOAD
      Payload data error.
      See Also:
    • REASON_MSG1

      public static final int REASON_MSG1
      Error in session request message.
      See Also:
    • REASON_MSG2

      public static final int REASON_MSG2
      Error in session created message.
      See Also:
    • REASON_MSG3

      public static final int REASON_MSG3
      Error in session confirmed message.
      See Also:
    • REASON_FRAME_TIMEOUT

      public static final int REASON_FRAME_TIMEOUT
      Frame acknowledgment timeout.
      See Also:
    • REASON_SIGFAIL

      public static final int REASON_SIGFAIL
      Signature verification failed.
      See Also:
    • REASON_S_MISMATCH

      public static final int REASON_S_MISMATCH
      Session key mismatch.
      See Also:
    • REASON_BANNED

      public static final int REASON_BANNED
      Peer is banned.
      See Also:
    • REASON_TOKEN

      public static final int REASON_TOKEN
      Token validation error.
      See Also:
    • REASON_LIMITS

      public static final int REASON_LIMITS
      Resource limits exceeded.
      See Also:
    • REASON_VERSION

      public static final int REASON_VERSION
      Protocol version mismatch.
      See Also:
    • REASON_NETID

      public static final int REASON_NETID
      Network ID mismatch.
      See Also:
    • REASON_REPLACED

      public static final int REASON_REPLACED
      Session was replaced by a new connection.
      See Also:
    • RELAY_RESPONSE_TOKEN_LEN

      public static final int RELAY_RESPONSE_TOKEN_LEN
      The trailing 8-byte token in a signed relay response with a zero code. When present it is appended after the signature.
      See Also:
    • IPV4_LEN

      public static final int IPV4_LEN
      IPv4 address length in bytes.
      See Also:
    • IPV6_LEN

      public static final int IPV6_LEN
      IPv6 address length in bytes.
      See Also:
    • RELAY_DATA_PORT_LEN

      public static final int RELAY_DATA_PORT_LEN
      Length of the port field in the relay/peer-test address block.
      See Also:
    • RELAY_DATA_VERSION_OFFSET

      public static final int RELAY_DATA_VERSION_OFFSET
      Offset of the version byte in relay response / peer test data.
      See Also:
    • RELAY_DATA_ADDR_LEN_OFFSET

      public static final int RELAY_DATA_ADDR_LEN_OFFSET
      Offset of the address length byte in relay response / peer test data. The byte encodes the IP address length plus the port field length.
      See Also:
    • RELAY_DATA_PORT_OFFSET

      public static final int RELAY_DATA_PORT_OFFSET
      Offset of the 2-byte port in relay response / peer test data.
      See Also:
    • RELAY_DATA_IP_OFFSET

      public static final int RELAY_DATA_IP_OFFSET
      Offset of the IP address bytes in relay response / peer test data.
      See Also:
    • RELAY_DATA_ADDR_LEN_IPV4

      public static final int RELAY_DATA_ADDR_LEN_IPV4
      The encoded address length value in relay response / peer test data for an IPv4 address.
      See Also:
    • RELAY_DATA_ADDR_LEN_IPV6

      public static final int RELAY_DATA_ADDR_LEN_IPV6
      The encoded address length value in relay response / peer test data for an IPv6 address.
      See Also:
  • Constructor Details

    • SSU2Util

      private SSU2Util()
      Utility class, not intended for instantiation.
  • Method Details

    • isSupportedVersion

      public static boolean isSupportedVersion(int version)
      True if the given version is accepted when establishing. The only supported versions are in MIN_SUPPORTED_VERSION to MAX_SUPPORTED_VERSION inclusive.
      Parameters:
      version - the peer's SSU2 version
      Returns:
      true if the version is supported
    • pqRequestExtra

      static int pqRequestExtra(int version)
      Bytes the Noise F token adds to the session request (message 1) for the post-quantum versions: the ML-KEM encapsulation key plus its MAC. Zero for version 2, which has no PQ frame. Noise writes this frame between the ephemeral key and the encrypted payload, so the payload staging offset, the packet length, and the padding budget all have to account for it. An unsupported version is an error rather than a zero-length frame, which would silently omit the frame and fail the tag check.
      Parameters:
      version - the negotiated SSU2 version
      Returns:
      the PQ frame length in bytes, 0 for version 2
      Throws:
      IllegalArgumentException - if the version is not 2, 3 or 4
    • pqCreatedExtra

      static int pqCreatedExtra(int version)
      Bytes the Noise F token adds to the session created (message 2) for the post-quantum versions: the ML-KEM ciphertext plus its MAC. Zero for version 2, which has no PQ frame. Same position rules as pqRequestExtra(int), but the ciphertext is smaller than the encapsulation key for MLKEM-768, which is why a session created fits a smaller MTU than a session request.
      Parameters:
      version - the negotiated SSU2 version
      Returns:
      the PQ frame length in bytes, 0 for version 2
      Throws:
      IllegalArgumentException - if the version is not 2, 3 or 4
    • terminationCodeToString

      public static String terminationCodeToString(int code)
      Convert a termination reason code to a human-readable string.
      Parameters:
      code - one of the REASON_* constants
      Returns:
      a short phrase naming the termination reason, or a string naming the unknown code when it is not one of the REASON_* constants
    • hkdf

      public static byte[] hkdf(I2PAppContext ctx, byte[] key, String info)
      32 byte output, ZEROLEN data.
      Parameters:
      ctx - the application context, providing the HMAC generator
      key - the input keying material
      info - the ASCII info string identifying this derivation, "" if none
      Returns:
      a newly allocated 32-byte output array
    • createPeerTestData

      public static byte[] createPeerTestData(I2PAppContext ctx, Hash h, Hash h2, PeerTestState.Role role, long nonce, byte[] ip, int port, SigningPrivateKey spk)
      Make the data for the peer test block.
      Parameters:
      ctx - the application context, for the clock and DSA service
      h - to be included in sig, not included in data
      h2 - may be null, to be included in sig, not included in data
      role - accepted but never read; any value is ignored
      nonce - the peer's nonce, written into the signed data
      ip - may be null
      port - the peer's UDP port number, written into the data only if ip is non-null
      spk - the signing key
      Returns:
      null on failure
    • createRelayRequestData

      public static byte[] createRelayRequestData(I2PAppContext ctx, Hash h, Hash h2, long nonce, long tag, byte[] ip, int port, SigningPrivateKey spk)
      Make the data for the relay request block.
      Parameters:
      ctx - the application context, for the clock and DSA service
      h - Bob hash to be included in sig, not included in data
      h2 - Charlie hash to be included in sig, not included in data
      nonce - the request nonce to echo in the signed data
      tag - the request's per-tunnel tag, written into the signed data
      ip - non-null
      port - the OBEP's UDP port number
      spk - the signing key
      Returns:
      null on failure
    • getRelayDataAddrLen

      public static int getRelayDataAddrLen(byte[] data)
      Parse the encoded address length byte out of relay response / peer test data. The byte encodes the IP address length plus the port field length.
      Parameters:
      data - the data after the signature
      Returns:
      the encoded address length
    • isValidRelayDataAddrLen

      public static boolean isValidRelayDataAddrLen(int addrLen)
      Is the given encoded address length valid (IPv4 or IPv6)?
      Parameters:
      addrLen - the encoded address length
      Returns:
      true if valid
    • getRelayDataPort

      public static int getRelayDataPort(byte[] data)
      Parse the 2-byte port out of relay response / peer test data.
      Parameters:
      data - the data after the signature
      Returns:
      the 16-bit UDP port number decoded from the 2-byte field
    • getRelayDataIP

      public static byte[] getRelayDataIP(byte[] data, int addrLen)
      Parse the IP address out of relay response / peer test data.
      Parameters:
      data - the data after the signature
      addrLen - the encoded address length
      Returns:
      the IP address bytes
    • getRelayResponseToken

      public static long getRelayResponseToken(byte[] data)
      Parse the trailing token out of the relay response signed data.
      Parameters:
      data - the signed data
      Returns:
      the 8-byte relay token value carried in the trailer
      Throws:
      ArrayIndexOutOfBoundsException - if the token is not present
    • trimRelayResponseToken

      public static byte[] trimRelayResponseToken(byte[] data)
      Trim the trailing token off the relay response signed data, returning the portion that was signed.
      Parameters:
      data - the signed data
      Returns:
      the data without the trailing token
    • createRelayResponseData

      public static byte[] createRelayResponseData(I2PAppContext ctx, Hash h, int code, long nonce, byte[] ip, int port, SigningPrivateKey spk, long token)
      Make the data for the relay response block.
      Parameters:
      ctx - the application context, for the clock and DSA service
      h - Bob hash to be included in sig, not included in data
      code - the termination code, written into the first payload byte
      nonce - the request nonce to echo in the signed data
      ip - may be null
      port - the UDP port number if ip is null
      spk - the signing key
      token - if nonzero, append it
      Returns:
      null on failure
    • sign

      public static Signature sign(I2PAppContext ctx, byte[] prologue, Hash h, Hash h2, byte[] data, int datalen, SigningPrivateKey spk)
      Sign the relay or peer test data, using the prologue and hash as the initial data, and then the provided data.
      Parameters:
      ctx - the application context, providing the DSA service
      prologue - the protocol-specific prologue prepended to the signed buffer
      h - to be included in sig, not included in data
      h2 - may be null, to be included in sig, not included in data
      data - if desired, leave room at end for sig
      datalen - the length of the data to be signed
      spk - the signing key
      Returns:
      null on failure
    • validateSig

      public static boolean validateSig(I2PAppContext ctx, byte[] prologue, Hash h, Hash h2, byte[] data, SigningPublicKey spk)
      Validate the signed relay or peer test data, using the prologue and hash as the initial data, and then the provided data which ends with a signature of the specified type.
      Parameters:
      ctx - the application context, providing the DSA service
      prologue - the protocol-specific prologue prepended to the verified buffer
      h - Bob hash prepended to the verified buffer; a null value fails validation
      h2 - may be null
      data - not including relay response token
      spk - the key the appended signature was made with
      Returns:
      true if the trailing signature of data verifies against the key