From 3b0882e8387d63aeffab3929e2590655c61c1a8e Mon Sep 17 00:00:00 2001 From: Katie Hockman Date: Mon, 18 May 2020 15:50:03 -0400 Subject: [PATCH] crypto/tls: persist the createdAt time when re-wrapping session tickets Change-Id: I33fcde2d544943fb04c2599810cf7fb773aeba1f Reviewed-on: https://go-review.googlesource.com/c/go/+/234483 Run-TryBot: Katie Hockman Reviewed-by: Filippo Valsorda TryBot-Result: Gobot Gobot --- src/crypto/tls/handshake_client_test.go | 23 ++++++++++++++++++++++- src/crypto/tls/handshake_server.go | 21 +++++++++++++-------- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/crypto/tls/handshake_client_test.go b/src/crypto/tls/handshake_client_test.go index 313872ca76..de93e1b63f 100644 --- a/src/crypto/tls/handshake_client_test.go +++ b/src/crypto/tls/handshake_client_test.go @@ -980,7 +980,28 @@ func testResumption(t *testing.T, version uint16) { if bytes.Equal(ticket, getTicket()) { t.Fatal("new ticket wasn't provided after old ticket expired") } - testResumeState("FreshSessionTicket", true) + + // Age the session ticket a bit at a time, but don't expire it. + d := 0 * time.Hour + for i := 0; i < 13; i++ { + d += 12 * time.Hour + serverConfig.Time = func() time.Time { return time.Now().Add(d) } + testResumeState("OldSessionTicket", true) + } + // Expire it (now a little more than 7 days) and make sure a full + // handshake occurs for TLS 1.2. Resumption should still occur for + // TLS 1.3 since the client should be using a fresh ticket sent over + // by the server. + d += 12 * time.Hour + serverConfig.Time = func() time.Time { return time.Now().Add(d) } + if version == VersionTLS13 { + testResumeState("ExpiredSessionTicket", true) + } else { + testResumeState("ExpiredSessionTicket", false) + } + if bytes.Equal(ticket, getTicket()) { + t.Fatal("new ticket wasn't provided after old ticket expired") + } // Reset serverConfig to ensure that calling SetSessionTicketKeys // before the serverConfig is used works. diff --git a/src/crypto/tls/handshake_server.go b/src/crypto/tls/handshake_server.go index 6aacfa1ff6..57fba108a7 100644 --- a/src/crypto/tls/handshake_server.go +++ b/src/crypto/tls/handshake_server.go @@ -75,13 +75,8 @@ func (hs *serverHandshakeState) handshake() error { if err := hs.establishKeys(); err != nil { return err } - // ticketSupported is set in a resumption handshake if the - // ticket from the client was encrypted with an old session - // ticket key and thus a refreshed ticket should be sent. - if hs.hello.ticketSupported { - if err := hs.sendSessionTicket(); err != nil { - return err - } + if err := hs.sendSessionTicket(); err != nil { + return err } if err := hs.sendFinished(c.serverFinished[:]); err != nil { return err @@ -688,6 +683,9 @@ func (hs *serverHandshakeState) readFinished(out []byte) error { } func (hs *serverHandshakeState) sendSessionTicket() error { + // ticketSupported is set in a resumption handshake if the + // ticket from the client was encrypted with an old session + // ticket key and thus a refreshed ticket should be sent. if !hs.hello.ticketSupported { return nil } @@ -695,6 +693,13 @@ func (hs *serverHandshakeState) sendSessionTicket() error { c := hs.c m := new(newSessionTicketMsg) + createdAt := uint64(c.config.time().Unix()) + if hs.sessionState != nil { + // If this is re-wrapping an old key, then keep + // the original time it was created. + createdAt = hs.sessionState.createdAt + } + var certsFromClient [][]byte for _, cert := range c.peerCertificates { certsFromClient = append(certsFromClient, cert.Raw) @@ -702,7 +707,7 @@ func (hs *serverHandshakeState) sendSessionTicket() error { state := sessionState{ vers: c.vers, cipherSuite: hs.suite.id, - createdAt: uint64(c.config.time().Unix()), + createdAt: createdAt, masterSecret: hs.masterSecret, certificates: certsFromClient, } -- 2.50.0