@@ -240,22 +240,32 @@ type ClientSessionState struct {
240
240
sessionTicket []uint8 // Encrypted ticket used for session resumption with server
241
241
vers uint16 // SSL/TLS version negotiated for the session
242
242
cipherSuite uint16 // Ciphersuite negotiated for the session
243
- masterSecret []byte // MasterSecret generated by client on a full handshake
243
+ masterSecret []byte // Full handshake MasterSecret, or TLS 1.3 resumption_master_secret
244
244
serverCertificates []* x509.Certificate // Certificate chain presented by the server
245
245
verifiedChains [][]* x509.Certificate // Certificate chains we built for verification
246
+ receivedAt time.Time // When the session ticket was received from the server
247
+
248
+ // TLS 1.3 fields.
249
+ nonce []byte // Ticket nonce sent by the server, to derive PSK
250
+ useBy time.Time // Expiration of the ticket lifetime as set by the server
251
+ ageAdd uint32 // Random obfuscation factor for sending the ticket age
246
252
}
247
253
248
254
// ClientSessionCache is a cache of ClientSessionState objects that can be used
249
255
// by a client to resume a TLS session with a given server. ClientSessionCache
250
256
// implementations should expect to be called concurrently from different
251
- // goroutines. Only ticket-based resumption is supported, not SessionID-based
252
- // resumption.
257
+ // goroutines. Up to TLS 1.2, only ticket-based resumption is supported, not
258
+ // SessionID-based resumption. In TLS 1.3 they were merged into PSK modes, which
259
+ // are supported via this interface.
253
260
type ClientSessionCache interface {
254
261
// Get searches for a ClientSessionState associated with the given key.
255
262
// On return, ok is true if one was found.
256
263
Get (sessionKey string ) (session * ClientSessionState , ok bool )
257
264
258
- // Put adds the ClientSessionState to the cache with the given key.
265
+ // Put adds the ClientSessionState to the cache with the given key. It might
266
+ // get called multiple times in a connection if a TLS 1.3 server provides
267
+ // more than one session ticket. If called with a nil *ClientSessionState,
268
+ // it should remove the cache entry.
259
269
Put (sessionKey string , cs * ClientSessionState )
260
270
}
261
271
@@ -502,19 +512,19 @@ type Config struct {
502
512
// the order of elements in CipherSuites, is used.
503
513
PreferServerCipherSuites bool
504
514
505
- // SessionTicketsDisabled may be set to true to disable session ticket
506
- // (resumption) support. Note that on clients, session ticket support is
515
+ // SessionTicketsDisabled may be set to true to disable session ticket and
516
+ // PSK (resumption) support. Note that on clients, session ticket support is
507
517
// also disabled if ClientSessionCache is nil.
508
518
SessionTicketsDisabled bool
509
519
510
- // SessionTicketKey is used by TLS servers to provide session
511
- // resumption. See RFC 5077. If zero, it will be filled with
512
- // random data before the first server handshake.
520
+ // SessionTicketKey is used by TLS servers to provide session resumption.
521
+ // See RFC 5077 and the PSK mode of RFC 8446 . If zero, it will be filled
522
+ // with random data before the first server handshake.
513
523
//
514
524
// If multiple servers are terminating connections for the same host
515
525
// they should all have the same SessionTicketKey. If the
516
526
// SessionTicketKey leaks, previously recorded and future TLS
517
- // connections using that key are compromised.
527
+ // connections using that key might be compromised.
518
528
SessionTicketKey [32 ]byte
519
529
520
530
// ClientSessionCache is a cache of ClientSessionState entries for TLS
@@ -937,15 +947,21 @@ func NewLRUClientSessionCache(capacity int) ClientSessionCache {
937
947
}
938
948
}
939
949
940
- // Put adds the provided (sessionKey, cs) pair to the cache.
950
+ // Put adds the provided (sessionKey, cs) pair to the cache. If cs is nil, the entry
951
+ // corresponding to sessionKey is removed from the cache instead.
941
952
func (c * lruSessionCache ) Put (sessionKey string , cs * ClientSessionState ) {
942
953
c .Lock ()
943
954
defer c .Unlock ()
944
955
945
956
if elem , ok := c .m [sessionKey ]; ok {
946
- entry := elem .Value .(* lruSessionCacheEntry )
947
- entry .state = cs
948
- c .q .MoveToFront (elem )
957
+ if cs == nil {
958
+ c .q .Remove (elem )
959
+ delete (c .m , sessionKey )
960
+ } else {
961
+ entry := elem .Value .(* lruSessionCacheEntry )
962
+ entry .state = cs
963
+ c .q .MoveToFront (elem )
964
+ }
949
965
return
950
966
}
951
967
0 commit comments