Can you help me understand the differences, both algorithmic and practical, between RFC 5246 SessionID re-use and RFC 5077 Session Resumption?

Both appear to be ways to nail up a second TLS session without a Server certificate exchange, leveraging the full certificate exchange and validation of a previous, separate TLS session.

Having read RFC 5246 § and RFC 5077 § 3, it seems that RFC 5077 hands a token to the client which has session setup information encrypted with the server's key, such that the client can hand the token back to the server and shortcut the negotiation and agreement of session setup parameters. RFC 5246, on the other hand, simply provides a reference to an existing connection that both parties share, and allows them to re-use those session parameters, based on both parties still having them in memory for the original session.

Is that a proper theoretical grasp?

Insofar as that's "close enough for government work", I'm interested in the real-world usage of the two separate types of connections:

  1. Is RFC 5246 SessionID good
    • Only as long as the original session is still active?
    • As long as there's a consecutive chain of sessions using the same SessionID?
    • For a loosely defined amount of time after all such sessions have closed but before the SessionID is dropped from active memory?
  2. Is RFC 5077 Session Resumption
    • Commonly used instead of RFC 5246 SessionID?
    • Commonly used for more widely separated connections that RFC 5246?
    • Commonly used at all?
  3. Do the two differ as described here:
    • RFC 5077 token creation (server send to client) is wholly contained within encrypted packets, e.g., after the handshake?
    • RFC 5246 session exchange is wholly unencrypted, e.g., within the early (ClientHello, ServerHello) parts of the handshake?

Any insight you can share is appreciated!


UPDATE: the below was valid through TLS 1.2. TLS1.3 in 2018 changes this radically; both the old resumption and old optional ticket mechanisms are gone. Instead there is an option for both ends to store (like old resumption) a secret plus some attributes, but instead of the prior session's master secret this stored secret is now a 'pre-shared key' (PSK) one-way derived from the prior session, so that a compromise of the stored PSK does not compromise the prior session. The server uses the 'New Ticket' message type defined for 5077, but now it contains only an identifier not an actual ticket. The new session can use this PSK either directly as the 'input' secret, or to authenticate a new keyexchange using DHE or ECDHE, in the same way it can (and 1.2 and lower already could) for a manually configured PSK -- except that manual PSK always was and I expect still will be extremely rare. In addition renegotiation is now gone -- although specific operations to do client-auth and to renew the working (symmetric) keys are added -- so session and connection now are basically the same.

Yes, you have the basic idea. Session-id info is stored (cached) at both ends; ticket is stored only at client, encrypted by server. Both re-use the "key exchange" which in SSL/TLS is actually key exchange combined with authentication; although authentication can be both directions (server and client) and thus an "exchange" of certs, it is usually server-only.

To be clear on the details, you need to distinguish session and connection. A SSL/TLS session is basically the results of a full handshake: the negotiated version, ciphersuite, and (most importantly) master secret, and perhaps some other bits. This plus nonces is the data needed to correctly do encryption and HMAC, or in TLSv1.2 optionally the "authenticated encryption" modes GCM or CCM instead. A connection is coterminous with a TCP connection, and starts with an initial handshake to either create and use a new session, or resume an existing session. Resumption can be used on connections at different times within some window, or multiple connections at the same time -- most if not all browsers will open maybe 4 to 10 parallel connections to download the 10s or 100s of resources used on most(?) webpages now. It is also possible but rarer to have multiple sessions on one connection using renegotiation, usually to authenticate differently or to rekey a long-lived connection. (Well, possible unless the server disables renegotiation as a clumsy defense against the MitM-prefix attack for which the proper fix is rfc 5746.)

Session-id has been in the base protocols since SSLv3 in 1996; ticket is an optional extension since 2006. Although session-id is in the protocol you don't have to fully implement it -- a server can always return an empty session-id, and a client can always "forget" any session-id it receives. Ticket is mostly useful for servers with large numbers of clients -- like the many millions for google, yahoo, twitter, facebook -- which would need to save huge numbers of sessions and distribute/synchronize them across numerous machines in a server "farm" (solvable problems, but if you don't need to it's easier).

So to your specifics:

  1. session-id is good as long as both endpoints choose to save it and have room. Usually this is minutes to maybe an hour at most, but it can be more if both endpoints support that. On implementations I've looked at, it's configurable per application. It fails gracefully -- if client discards the session for a server and sends ClientHello with empty, server just creates a new session and discards the old one if still saved; if client has (and requests) a session server has discarded, server forces a new one and client discards its old one.

  2. When I've looked I've seen ticket provided (if client offers support) only on a few high-volume sites (and my OpenSSL testbench) but I don't claim to have made anything like a thorough survey and I haven't seen any published. As 5077 describes, if you do use ticket you effectively ignore session-id for that session. It could certainly make sense for server to allow ticket to be valid longer than it would have kept session-id in its (possibly limited and crowded) cache, but I don't have data.

  3. Initial handshake is always unencrypted up to ChangeCipherSpec and Finished, except for specific elements. In particular for RSA keyexchange, client public-key encrypts the premaster secret to server. (For DH* and ECDH*, public-keys don't need to be encrypted and aren't but still produce a secret agreement.) And ticket if used is encrypted by server to itself. If you do use renegotiation, that entire handshake is (super)encrypted, even though it usually doesn't need to be, giving a (clumsy) way to get that functionality.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.