nquic_tls (nquic v1.0.0)

View Source

Shared TLS 1.3 codec for QUIC per RFC 9001.

Holds the wire-format parse/encode helpers used by both nquic_tls_client and nquic_tls_server, plus the PSK and NewSessionTicket helpers that straddle the two roles. Role-specific flows (ClientHello / ServerHello construction, handshake-flight generation, Finished verification, certificate-chain validation) live in the role modules.

Summary

Functions

Decode a NewSessionTicket TLS message.

Decrypt a ticket value using the server's static key. Returns {ok, PSK, Cipher} on success, {error, Reason} on failure.

Derive the resumption_master_secret after client Finished is verified.

Encode a NewSessionTicket message (RFC 8446 S4.6.1). Ticket map keys: lifetime, age_add, nonce, ticket, max_early_data (optional).

Extract the partial ClientHello for binder verification. The partial CH is the full ClientHello minus the binders list at the end. BindersLen is the length of the binders field (including the 2-byte length prefix).

Check if the psk_key_exchange_modes extension includes psk_dhe_ke (mode 1). Returns true if present, false otherwise.

Parse a pre_shared_key extension from a ClientHello extension map. Returns {ok, Identities, Binders} or undefined if not present. Identities: [{Identity, ObfuscatedAge}], Binders: [binary()].

Verify a PSK binder against the partial ClientHello transcript. The partial CH is everything in the ClientHello up to (but not including) the binders list in the pre_shared_key extension.

Functions

compute_psk_binder(PSK, PartialCH, Hash, HashLen)

-spec compute_psk_binder(binary(), binary(), sha256 | sha384, pos_integer()) -> binary().

decode_cipher_suite/1

-spec decode_cipher_suite(binary()) ->
                             {ok, aes_128_gcm | aes_256_gcm | chacha20_poly1305} |
                             {error, {unsupported_cipher_suite, binary()}}.

decode_new_session_ticket/1

-spec decode_new_session_ticket(binary()) -> {ok, map()} | {error, term()}.

Decode a NewSessionTicket TLS message.

decrypt_ticket(TicketValue, StaticKey)

-spec decrypt_ticket(binary(), binary()) -> {ok, binary(), atom()} | {error, term()}.

Decrypt a ticket value using the server's static key. Returns {ok, PSK, Cipher} on success, {error, Reason} on failure.

derive_resumption_secret(HandshakeSecret, TranscriptCtx, ClientFinishedBin, Cipher)

-spec derive_resumption_secret(binary(),
                               crypto:hash_state(),
                               binary(),
                               aes_128_gcm | aes_256_gcm | chacha20_poly1305) ->
                                  binary().

Derive the resumption_master_secret after client Finished is verified.

encode_cipher_suite/1

-spec encode_cipher_suite(aes_128_gcm | aes_256_gcm | chacha20_poly1305) -> binary().

encode_new_session_ticket/1

-spec encode_new_session_ticket(map()) -> binary().

Encode a NewSessionTicket message (RFC 8446 S4.6.1). Ticket map keys: lifetime, age_add, nonce, ticket, max_early_data (optional).

extract_partial_client_hello(CHBin, BindersLen)

-spec extract_partial_client_hello(binary(), non_neg_integer()) -> binary().

Extract the partial ClientHello for binder verification. The partial CH is the full ClientHello minus the binders list at the end. BindersLen is the length of the binders field (including the 2-byte length prefix).

find_quic_params(ExtMap, SenderRole)

-spec find_quic_params(#{non_neg_integer() => binary()}, client | server) ->
                          {ok, nquic_transport:params()} | {error, term()}.

has_psk_dhe_ke_mode(ExtMap)

-spec has_psk_dhe_ke_mode(map()) -> boolean().

Check if the psk_key_exchange_modes extension includes psk_dhe_ke (mode 1). Returns true if present, false otherwise.

hash_length/1

-spec hash_length(sha256 | sha384) -> pos_integer().

parse_extensions_recursive/1

-spec parse_extensions_recursive(binary()) -> #{non_neg_integer() => binary()}.

parse_psk_extension(ExtMap)

-spec parse_psk_extension(map()) -> {ok, [{binary(), non_neg_integer()}], [binary()]} | undefined.

Parse a pre_shared_key extension from a ClientHello extension map. Returns {ok, Identities, Binders} or undefined if not present. Identities: [{Identity, ObfuscatedAge}], Binders: [binary()].

parse_vec8/1

-spec parse_vec8(binary()) -> {binary(), binary()}.

parse_vec16/1

-spec parse_vec16(binary()) -> {binary(), binary()}.

verify_psk_binder(PSK, PartialCH, Binder, Hash, HashLen)

-spec verify_psk_binder(binary(), binary(), binary(), sha256 | sha384, pos_integer()) ->
                           ok | {error, term()}.

Verify a PSK binder against the partial ClientHello transcript. The partial CH is everything in the ClientHello up to (but not including) the binders list in the pre_shared_key extension.