quic_ticket (quic v1.3.0)
View SourceSession ticket storage and PSK derivation for 0-RTT.
This module handles: - Storing and retrieving NewSessionTicket messages - Deriving PSK from resumption_master_secret - Managing ticket lifetimes and early data limits
Summary
Functions
Build a NewSessionTicket message.
Remove all expired tickets from the store.
Remove a ticket for a server.
Create a session ticket from connection state. This is used by the server to issue tickets to clients.
Derive PSK from resumption_master_secret and ticket nonce. RFC 8446 Section 4.6.1: PSK = HKDF-Expand-Label(resumption_master_secret, "resumption", ticket_nonce, Hash.length)
Derive the resumption_master_secret from the master secret. RFC 8446 Section 7.1: resumption_master_secret = Derive-Secret(Master Secret, "res master", ClientHello..client Finished)
Look up a ticket for a server. Returns {ok, Ticket} if found and not expired, error otherwise.
Create a new empty ticket store.
Parse a NewSessionTicket message from the server. RFC 8446 Section 4.6.1: struct { uint32 ticket_lifetime; uint32 ticket_age_add; opaque ticket_nonce<0..255>; opaque ticket<1..2^16-1>; Extension extensions<0..2^16-2>; } NewSessionTicket;
Store a session ticket for a server. The ticket is indexed by server name.
Types
-type session_ticket() :: #session_ticket{server_name :: binary(), ticket :: binary(), lifetime :: non_neg_integer(), age_add :: non_neg_integer(), nonce :: binary(), resumption_secret :: binary(), max_early_data :: non_neg_integer(), received_at :: non_neg_integer(), cipher :: atom(), alpn :: binary() | undefined}.
-type ticket_store() :: #{binary() => #session_ticket{server_name :: binary(), ticket :: binary(), lifetime :: non_neg_integer(), age_add :: non_neg_integer(), nonce :: binary(), resumption_secret :: binary(), max_early_data :: non_neg_integer(), received_at :: non_neg_integer(), cipher :: atom(), alpn :: binary() | undefined}}.
Functions
-spec build_new_session_ticket(#session_ticket{server_name :: binary(), ticket :: binary(), lifetime :: non_neg_integer(), age_add :: non_neg_integer(), nonce :: binary(), resumption_secret :: binary(), max_early_data :: non_neg_integer(), received_at :: non_neg_integer(), cipher :: atom(), alpn :: binary() | undefined}) -> binary().
Build a NewSessionTicket message.
-spec clear_expired(ticket_store()) -> ticket_store().
Remove all expired tickets from the store.
-spec clear_ticket(binary(), ticket_store()) -> ticket_store().
Remove a ticket for a server.
-spec create_ticket(binary(), binary(), non_neg_integer(), atom(), binary() | undefined) -> #session_ticket{server_name :: binary(), ticket :: binary(), lifetime :: non_neg_integer(), age_add :: non_neg_integer(), nonce :: binary(), resumption_secret :: binary(), max_early_data :: non_neg_integer(), received_at :: non_neg_integer(), cipher :: atom(), alpn :: binary() | undefined}.
Create a session ticket from connection state. This is used by the server to issue tickets to clients.
-spec derive_psk(binary(), #session_ticket{server_name :: binary(), ticket :: binary(), lifetime :: non_neg_integer(), age_add :: non_neg_integer(), nonce :: binary(), resumption_secret :: binary(), max_early_data :: non_neg_integer(), received_at :: non_neg_integer(), cipher :: atom(), alpn :: binary() | undefined}) -> binary().
Derive PSK from resumption_master_secret and ticket nonce. RFC 8446 Section 4.6.1: PSK = HKDF-Expand-Label(resumption_master_secret, "resumption", ticket_nonce, Hash.length)
Derive the resumption_master_secret from the master secret. RFC 8446 Section 7.1: resumption_master_secret = Derive-Secret(Master Secret, "res master", ClientHello..client Finished)
-spec lookup_ticket(binary(), ticket_store()) -> {ok, session_ticket()} | error.
Look up a ticket for a server. Returns {ok, Ticket} if found and not expired, error otherwise.
-spec new_store() -> ticket_store().
Create a new empty ticket store.
-spec parse_new_session_ticket(binary()) -> {ok, #{lifetime := non_neg_integer(), age_add := non_neg_integer(), nonce := binary(), ticket := binary(), max_early_data := non_neg_integer()}} | {error, term()}.
Parse a NewSessionTicket message from the server. RFC 8446 Section 4.6.1: struct { uint32 ticket_lifetime; uint32 ticket_age_add; opaque ticket_nonce<0..255>; opaque ticket<1..2^16-1>; Extension extensions<0..2^16-2>; } NewSessionTicket;
-spec store_ticket(binary(), session_ticket(), ticket_store()) -> ticket_store().
Store a session ticket for a server. The ticket is indexed by server name.