Transport Layer Security (TLS) Session Resumption without Server-Side State
obsoleted by
- rfc-5077 — Transport Layer Security (TLS) Session Resumption without Server-Side State
Extracted elements (28)
A server planning to issue a ticket SHOULD include an empty Session ID in the ServerHello to signal stateless resumption intent, whereas a non-empty Session ID signals intent to use stateful session resumption.
The stateless session resumption mechanism was designed to benefit servers handling large transaction volumes, servers needing long session caches, load-balanced server farms, and embedded servers with little memory — all cases where per-client server-side state is costly.
The ticket is opaque to the client, so its internal structure is not subject to interoperability concerns and implementations may diverge from the recommended format. Clients MUST NOT parse or rely on ticket contents following this specification.
This mechanism applies to both TLS 1.0 (RFC 2246) and TLS 1.1 (RFC 4346) and may be used with any TLS ciphersuite. Implementations are expected to support both issuing and consuming tickets.
A client SHOULD delete a ticket and its associated state when the ticket_lifetime_hint expires; it MAY delete the ticket earlier based on local policy.
A client that is NOT prepared to receive a ticket MUST NOT include a SessionTicket extension unless it is sending a non-empty ticket obtained through other means.
A client that is prepared to receive a ticket via NewSessionTicket MUST include a zero-length ticket in the SessionTicket extension of the ClientHello.
If the ticket is accepted by the server but the handshake fails, the client SHOULD delete the ticket.
The client MUST NOT treat the ticket as valid until it has verified the server's Finished message.
The NewSessionTicket message MUST be sent if the server included a SessionTicket extension in the ServerHello, and MUST NOT be sent otherwise. In a full handshake, the server MUST verify the client's Finished before sending the ticket.
The server MUST send a zero-length SessionTicket extension in the ServerHello if it wishes to issue a new ticket via NewSessionTicket; it MUST NOT send this extension if it did not receive one in the ClientHello.
When a ticket is presented, the server MUST NOT use the Session ID from the ClientHello for stateful session resumption, and MUST NOT rely on the Session ID having any particular value when validating the ticket.
Issuing a ticket via a TLS renegotiation handshake within an already-established secure tunnel may help address identity privacy and unlinkability concerns in some environments.
Ticket content confidentiality is mandated to prevent leakage of user-relevant information. However, an on-path adversary observing multiple handshakes using the same ticket can link them to the same endpoints, so unlinkability is not guaranteed.
ClientIdentity encodes the client authentication type as an enum (anonymous=0, certificate_based=1, psk=2) and carries the corresponding credential: nothing for anonymous, an ASN.1 certificate list for certificate_based, or a PSK identity for psk.
Session ticket / Session ID interaction: when presenting a ticket, the client MAY include a non-empty Session ID. If the server accepts the ticket and the Session ID is non-empty, it MUST echo the same Session ID, enabling the client to distinguish resumption from full handshake fallback.
The NewSessionTicket handshake message (type 4) is sent by the server before ChangeCipherSpec. It contains a `uint32 ticket_lifetime_hint` (lifetime in seconds, 0 means unspecified) and `opaque ticket<0..2^16-1>`.
The SessionTicket TLS extension (assigned number 35) carries an opaque ticket in the ClientHello and ServerHello. The client includes any existing ticket or a zero-length ticket; the server includes a zero-length extension to signal intent to issue a new ticket via NewSessionTicket.
IANA assigned TLS extension type 35 to the SessionTicket extension from the TLS ExtensionType registry defined in RFC 4366.
IANA assigned TLS HandshakeType value 4 to NewSessionTicket from the TLS HandshakeType registry defined in RFC 4346.
If an alternate ticket distribution scheme transfers confidential information to the client, it MUST use secure communication to prevent interception; the ticket MUST have integrity and confidentiality protection with strong cryptography.
Ticket protection keys should be at least 128 bits, generated securely, used only for ticket generation/verification, changed regularly, and changed if the ticket format or algorithms change.
Tickets MUST be authenticated and encrypted to prevent modification or eavesdropping. A TLS server MUST use strong encryption and integrity protection (e.g., keyed HMAC-SHA1 and AES-128) to prevent brute-force recovery or forgery of ticket contents.
To mitigate denial-of-service risk from large volumes of forged tickets, ticket verification should be lightweight (using efficient symmetric-key algorithms). The key_name field helps servers quickly reject tickets they did not issue.
Recommended ticket structure: `opaque key_name[16]` (identifies key set), `opaque iv[16]` (AES-CBC IV), `opaque encrypted_state<0..2^16-1>` (AES-128-CBC encrypted session state), `opaque mac[20]` (HMAC-SHA1 over key_name || iv || length || encrypted_state).
The NewSessionTicket message wire format: `uint32 ticket_lifetime_hint` (4 octets, network byte order) followed by `opaque ticket<0..2^16-1>`. A zero-length ticket indicates the server chose not to issue one.
The plaintext session state (StatePlaintext) contains: ProtocolVersion, CipherSuite, CompressionMethod, `opaque master_secret[48]`, ClientIdentity (with authentication type and credentials), and `uint32 timestamp` for expiry.
The SessionTicket extension body is a single opaque field: `opaque ticket<0..2^16-1>`. A zero-length value signals willingness to receive a ticket without presenting one.