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 <katie@golang.org>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Katie Hockman 2020-05-18 15:50:03 -04:00
parent 2ad14d1adf
commit 5d964e8740
2 changed files with 35 additions and 9 deletions

View file

@ -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.

View file

@ -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,
}