]> Cypherpunks.ru repositories - gostls13.git/commitdiff
crypto/tls: add ClientSessionState.ResumptionState and NewResumptionState
authorFilippo Valsorda <filippo@golang.org>
Sun, 21 May 2023 19:27:48 +0000 (21:27 +0200)
committerFilippo Valsorda <filippo@golang.org>
Wed, 24 May 2023 23:56:48 +0000 (23:56 +0000)
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>
api/next/60105.txt
src/crypto/tls/handshake_client_test.go
src/crypto/tls/ticket.go

index 75adbcc8aafde0384adbc155dbeb4e2d400e41c9..251f574c8fbb5c38eb64cc42db2c657b3ab70063 100644 (file)
@@ -1,3 +1,5 @@
 pkg crypto/tls, func ParseSessionState([]uint8) (*SessionState, error) #60105
 pkg crypto/tls, method (*SessionState) Bytes() ([]uint8, error) #60105
 pkg crypto/tls, type SessionState struct #60105
+pkg crypto/tls, func NewResumptionState([]uint8, *SessionState) (*ClientSessionState, error) #60105
+pkg crypto/tls, method (*ClientSessionState) ResumptionState() ([]uint8, *SessionState, error) #60105
index cf7c09b08faed9d63f2ed049ee78c787b2e5e6c8..f5695df44f10d0551d3edd84a6ea93865f2f3075 100644 (file)
@@ -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) {
index 44bedd66de5a7d8f5c8577dc0470b5e32b1e1eec..4eacd4305576298ad86b7e6ef9587cf8e43a8a14 100644 (file)
@@ -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
+}