diff options
| author | Filippo Valsorda <filippo@golang.org> | 2023-05-21 21:27:48 +0200 |
|---|---|---|
| committer | Filippo Valsorda <filippo@golang.org> | 2023-05-24 23:56:48 +0000 |
| commit | 371ebe731bf6ebae3d6914835674e276d98254f5 (patch) | |
| tree | d9c90f7b61645dbcc5395a3b4ff70f8fcf9dc236 /src | |
| parent | 6d05bc7816feee6e96cabaf5755f52cb212b99e8 (diff) | |
| download | go-371ebe731bf6ebae3d6914835674e276d98254f5.tar.xz | |
crypto/tls: add ClientSessionState.ResumptionState and NewResumptionState
For #60105
Fixes #25351
Change-Id: Iffd658f2663cfc47b48157824226ed6c0260a59e
Reviewed-on: https://go-review.googlesource.com/c/go/+/496820
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Marten Seemann <martenseemann@gmail.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/crypto/tls/handshake_client_test.go | 41 | ||||
| -rw-r--r-- | src/crypto/tls/ticket.go | 37 |
2 files changed, 70 insertions, 8 deletions
diff --git a/src/crypto/tls/handshake_client_test.go b/src/crypto/tls/handshake_client_test.go index cf7c09b08f..f5695df44f 100644 --- a/src/crypto/tls/handshake_client_test.go +++ b/src/crypto/tls/handshake_client_test.go @@ -1069,6 +1069,47 @@ func testResumption(t *testing.T, version uint16) { clientConfig.ClientSessionCache = nil testResumeState("WithoutSessionCache", false) + + clientConfig.ClientSessionCache = &serializingClientCache{t: t} + testResumeState("BeforeSerializingCache", false) + testResumeState("WithSerializingCache", true) +} + +type serializingClientCache struct { + t *testing.T + + ticket, state []byte +} + +func (c *serializingClientCache) Get(sessionKey string) (session *ClientSessionState, ok bool) { + if c.ticket == nil { + return nil, false + } + state, err := ParseSessionState(c.state) + if err != nil { + c.t.Error(err) + return nil, false + } + cs, err := NewResumptionState(c.ticket, state) + if err != nil { + c.t.Error(err) + return nil, false + } + return cs, true +} + +func (c *serializingClientCache) Put(sessionKey string, cs *ClientSessionState) { + ticket, state, err := cs.ResumptionState() + if err != nil { + c.t.Error(err) + return + } + stateBytes, err := state.Bytes() + if err != nil { + c.t.Error(err) + return + } + c.ticket, c.state = ticket, stateBytes } func TestLRUClientSessionCache(t *testing.T) { diff --git a/src/crypto/tls/ticket.go b/src/crypto/tls/ticket.go index 44bedd66de..4eacd43055 100644 --- a/src/crypto/tls/ticket.go +++ b/src/crypto/tls/ticket.go @@ -71,15 +71,9 @@ type SessionState struct { ageAdd uint32 } -// ClientSessionState contains the state needed by clients to resume TLS -// sessions. -type ClientSessionState struct { - ticket []byte - session *SessionState -} - // Bytes encodes the session, including any private fields, so that it can be -// parsed by [ParseSessionState]. The encoding contains secret values. +// parsed by [ParseSessionState]. The encoding contains secret values critical +// to the security of future and possibly past sessions. // // The specific encoding should be considered opaque and may change incompatibly // between Go versions. @@ -293,3 +287,30 @@ func (c *Conn) decryptTicket(encrypted []byte) []byte { return nil } + +// ClientSessionState contains the state needed by a client to +// resume a previous TLS session. +type ClientSessionState struct { + ticket []byte + session *SessionState +} + +// ResumptionState returns the session ticket sent by the server (also known as +// the session's identity) and the state necessary to resume this session. +// +// It can be called by [ClientSessionCache.Put] to serialize (with +// [SessionState.Bytes]) and store the session. +func (cs *ClientSessionState) ResumptionState() (ticket []byte, state *SessionState, err error) { + return cs.ticket, cs.session, nil +} + +// NewResumptionState returns a state value that can be returned by +// [ClientSessionCache.Get] to resume a previous session. +// +// state needs to be returned by [ParseSessionState], and the ticket and session +// state must have been returned by [ClientSessionState.ResumptionState]. +func NewResumptionState(ticket []byte, state *SessionState) (*ClientSessionState, error) { + return &ClientSessionState{ + ticket: ticket, session: state, + }, nil +} |
