nquic_tls_server (nquic v1.0.0)

View Source

Server-side TLS 1.3 handshake flow for QUIC per RFC 9001.

Processes ClientHello, builds the server handshake flight (EncryptedExtensions, Certificate, CertificateVerify, Finished) for full handshakes and the abbreviated EE+Finished flight for PSK resumption, and verifies the client Finished. Codec helpers shared with the client live in nquic_tls; PSK / NewSessionTicket helpers remain there too because they straddle both roles.

Summary

Functions

Build the server handshake flight (EncryptedExtensions, Certificate, CertificateVerify, Finished).

Build the server handshake flight for PSK resumption (no Certificate/CertificateVerify). EncryptedExtensions + Finished only. Optionally includes early_data extension to signal 0-RTT acceptance.

Process a ClientHello, generate a ServerHello, and derive handshake secrets.

Process a ClientHello with options. Opts may include psk_selected => Index to include pre_shared_key in ServerHello.

Validate a PSK offer from a ClientHello against the server's ticket. Decrypts the first matching identity, verifies the binder, and returns the PSK and whether 0-RTT should be accepted. StaticKey is the server's ticket encryption key. ClientHelloBin is the raw ClientHello (needed for binder verification).

Verify the client Finished message using the client handshake traffic secret.

Verify the client Finished message with an explicit cipher suite.

Functions

encode_extensions(Exts)

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

find_alpn(ExtMap)

-spec find_alpn(map()) -> [binary()] | undefined.

find_cipher_match/2

-spec find_cipher_match([atom()], [atom()]) -> atom() | undefined.

find_match/2

-spec find_match([binary()], [binary()]) -> binary() | undefined.

make_certificate_message(LeafDER, ChainDERs)

-spec make_certificate_message(binary(), [binary()]) -> binary().

make_server_handshake_flight(HandshakeSecret, Keys, State, CertDER, CertChain, PrivKey)

-spec make_server_handshake_flight(binary(),
                                   map(),
                                   map(),
                                   binary(),
                                   [binary()],
                                   public_key:private_key()) ->
                                      {ok, binary(), map(), map()} | {error, nquic_error:any_reason()}.

Build the server handshake flight (EncryptedExtensions, Certificate, CertificateVerify, Finished).

make_server_handshake_flight_psk(HandshakeSecret, Keys, State, AcceptEarlyData)

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

Build the server handshake flight for PSK resumption (no Certificate/CertificateVerify). EncryptedExtensions + Finished only. Optionally includes early_data extension to signal 0-RTT acceptance.

parse_alpn_items/1

-spec parse_alpn_items(binary()) -> [binary()].

parse_cipher_suites/1

-spec parse_cipher_suites(binary()) -> [aes_128_gcm | aes_256_gcm | chacha20_poly1305].

process_client_hello(ClientHelloBin, TransportParams, SupportedALPNs)

-spec process_client_hello(binary(), nquic_transport:params(), [binary()] | undefined) ->
                              {ok, binary(), map(), map()} | {error, term()}.

Process a ClientHello, generate a ServerHello, and derive handshake secrets.

process_client_hello(ClientHelloBin, TransportParams, SupportedALPNs, Opts)

-spec process_client_hello(binary(), nquic_transport:params(), [binary()] | undefined, map()) ->
                              {ok, binary(), map(), map()} | {error, term()}.

Process a ClientHello with options. Opts may include psk_selected => Index to include pre_shared_key in ServerHello.

select_alpn/2

-spec select_alpn([binary()] | undefined, [binary()] | undefined) ->
                     {ok, binary() | undefined} | {error, nquic_error:any_reason()}.

select_cipher(ClientCiphers)

-spec select_cipher([aes_128_gcm | aes_256_gcm | chacha20_poly1305]) ->
                       {ok, aes_128_gcm | aes_256_gcm | chacha20_poly1305} |
                       {error, nquic_error:any_reason()}.

select_cipher/2

-spec select_cipher([aes_128_gcm | aes_256_gcm | chacha20_poly1305],
                    [aes_128_gcm | aes_256_gcm | chacha20_poly1305] | undefined) ->
                       {ok, aes_128_gcm | aes_256_gcm | chacha20_poly1305} |
                       {error, nquic_error:any_reason()}.

validate_psk_offer(PSKInfo, ClientHelloBin, StaticKey, NegCipher)

-spec validate_psk_offer(map(), binary(), binary(), atom()) ->
                            {ok, binary(), atom(), boolean(), binary()} | {error, term()}.

Validate a PSK offer from a ClientHello against the server's ticket. Decrypts the first matching identity, verifies the binder, and returns the PSK and whether 0-RTT should be accepted. StaticKey is the server's ticket encryption key. ClientHelloBin is the raw ClientHello (needed for binder verification).

verify_client_finished(Data, ClientSecret, TranscriptCtx)

-spec verify_client_finished(binary(), binary(), crypto:hash_state()) ->
                                ok | {error, nquic_error:any_reason()}.

Verify the client Finished message using the client handshake traffic secret.

verify_client_finished(Data, ClientSecret, TranscriptCtx, Cipher)

-spec verify_client_finished(binary(),
                             binary(),
                             crypto:hash_state(),
                             aes_128_gcm | aes_256_gcm | chacha20_poly1305) ->
                                ok | {error, term()}.

Verify the client Finished message with an explicit cipher suite.