aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFilippo Valsorda <filippo@golang.org>2023-05-21 21:27:48 +0200
committerFilippo Valsorda <filippo@golang.org>2023-05-24 23:56:48 +0000
commit371ebe731bf6ebae3d6914835674e276d98254f5 (patch)
treed9c90f7b61645dbcc5395a3b4ff70f8fcf9dc236 /src
parent6d05bc7816feee6e96cabaf5755f52cb212b99e8 (diff)
downloadgo-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.go41
-rw-r--r--src/crypto/tls/ticket.go37
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
+}