Created a TLS client and a server, and tested TLS session resumption behavior.
What did you expect to see?
If a server accepts a ticket sent by the client but the handshake fails, the client SHOULD delete the ticket from its cache, according to Section 3.2 of RFC 5077. https://tools.ietf.org/html/rfc5077. The next connection to the server should fallback to a full TLS handshake.
What did you see instead?
If a client and server attempt to resume a TLS session past the expiry of the client certificate embedded in the ticket, the client gets wedged. The server accepts the ticket, but handshake fails because of the expired certs. The ticket is not deleted from the cache however, so subsequent attempts by the client to connect to the server fail in the same way.
The text was updated successfully, but these errors were encountered:
changed the title
TLS clients don't delete tickets that fail handshakes from ClientSessionCacheApr 18, 2018
The correct fix is to add a Delete method to the ClientSessionCache interface and have the client call it if the handshake fails when trying to resume a session. This is backwards incompatible though, anyone implementing ClientSessionCache will have to change their code.
A hack that could work is to replace the value stored in the cache with nil on failure. In the LRU implementation in crypto/tls, we can special case a nilPut by deleting the entry altogether. This will only break anyone manually stuffing a nil into a cache they got from NewLRUClientSessionCache but this was always dangerous anyway, because clientHandshakeaccesses attributes of candidateSession without checking for nil.
When a server accepts a session ticket presented by a client, but
the TLS handshake fails, RFC 5077 recommends that the client delete
the ticket. Because adding a full Delete method to the interface for
ClientSessionCache would break existing implementations, we have the
handshake implementation put a nil value instead.