]> Cypherpunks.ru repositories - gostls13.git/commitdiff
crypto/tls: make SessionState.Extra a slice of byte slices
authorFilippo Valsorda <filippo@golang.org>
Wed, 7 Jun 2023 19:36:19 +0000 (21:36 +0200)
committerGopher Robot <gobot@golang.org>
Fri, 9 Jun 2023 15:26:32 +0000 (15:26 +0000)
Fixes #60539
Updates #60105

Change-Id: I7b567cc1d0901891ed97d29591db935cd487cc71
Reviewed-on: https://go-review.googlesource.com/c/go/+/501675
Auto-Submit: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Damien Neil <dneil@google.com>
api/go1.21.txt
src/crypto/tls/handshake_messages_test.go
src/crypto/tls/ticket.go

index ec11adf4b741ac67518165d8e6eda55343c64014..964392e0ec1f759a31f9cc4478be93f15bb82652 100644 (file)
@@ -80,7 +80,7 @@ pkg crypto/tls, type QUICEvent struct, Level QUICEncryptionLevel #44886
 pkg crypto/tls, type QUICEvent struct, Suite uint16 #44886
 pkg crypto/tls, type SessionState struct #60105
 pkg crypto/tls, type SessionState struct, EarlyData bool #60107
-pkg crypto/tls, type SessionState struct, Extra []uint8 #60105
+pkg crypto/tls, type SessionState struct, Extra [][]uint8 #60539
 pkg crypto/x509, type RevocationListEntry struct #53573
 pkg crypto/x509, type RevocationListEntry struct, Extensions []pkix.Extension #53573
 pkg crypto/x509, type RevocationListEntry struct, ExtraExtensions []pkix.Extension #53573
index 224e17296f6ff0c76dfffecd5e5ab2205504d24e..72e8bd8c25690463b3083b7d450300000a31ffa8 100644 (file)
@@ -355,7 +355,9 @@ func (*SessionState) Generate(rand *rand.Rand, size int) reflect.Value {
        s.cipherSuite = uint16(rand.Intn(math.MaxUint16))
        s.createdAt = uint64(rand.Int63())
        s.secret = randomBytes(rand.Intn(100)+1, rand)
-       s.Extra = randomBytes(rand.Intn(100), rand)
+       for n, i := rand.Intn(3), 0; i < n; i++ {
+               s.Extra = append(s.Extra, randomBytes(rand.Intn(100), rand))
+       }
        if rand.Intn(10) > 5 {
                s.EarlyData = true
        }
index 1a3d0c7cfdef254c10597a59e7a5e5beb2fc6e09..b43101ff6658c19476233e1b305f50729a480261 100644 (file)
@@ -27,13 +27,15 @@ type SessionState struct {
        //
        //   Certificate CertificateChain<0..2^24-1>;
        //
+       //   opaque Extra<0..2^24-1>;
+       //
        //   struct {
        //       uint16 version;
        //       SessionStateType type;
        //       uint16 cipher_suite;
        //       uint64 created_at;
        //       opaque secret<1..2^8-1>;
-       //       opaque extra<0..2^24-1>;
+       //       Extra extra<0..2^24-1>;
        //       uint8 ext_master_secret = { 0, 1 };
        //       uint8 early_data = { 0, 1 };
        //       CertificateEntry certificate_list<0..2^24-1>;
@@ -62,12 +64,13 @@ type SessionState struct {
        //
        // This allows [Config.UnwrapSession]/[Config.WrapSession] and
        // [ClientSessionCache] implementations to store and retrieve additional
-       // data.
+       // data alongside this session.
        //
-       // If Extra is already set, the implementation must preserve the previous
-       // value across a round-trip, for example by appending and stripping a
-       // fixed-length suffix.
-       Extra []byte
+       // To allow different layers in a protocol stack to share this field,
+       // applications must only append to it, not replace it, and must use entries
+       // that can be recognized even if out of order (for example, by starting
+       // with a id and version prefix).
+       Extra [][]byte
 
        // EarlyData indicates whether the ticket can be used for 0-RTT in a QUIC
        // connection. The application may set this to false if it is true to
@@ -115,7 +118,11 @@ func (s *SessionState) Bytes() ([]byte, error) {
                b.AddBytes(s.secret)
        })
        b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
-               b.AddBytes(s.Extra)
+               for _, extra := range s.Extra {
+                       b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+                               b.AddBytes(extra)
+                       })
+               }
        })
        if s.extMasterSecret {
                b.AddUint8(1)
@@ -176,19 +183,27 @@ func ParseSessionState(data []byte) (*SessionState, error) {
        s := cryptobyte.String(data)
        var typ, extMasterSecret, earlyData uint8
        var cert Certificate
+       var extra cryptobyte.String
        if !s.ReadUint16(&ss.version) ||
                !s.ReadUint8(&typ) ||
                (typ != 1 && typ != 2) ||
                !s.ReadUint16(&ss.cipherSuite) ||
                !readUint64(&s, &ss.createdAt) ||
                !readUint8LengthPrefixed(&s, &ss.secret) ||
-               !readUint24LengthPrefixed(&s, &ss.Extra) ||
+               !s.ReadUint24LengthPrefixed(&extra) ||
                !s.ReadUint8(&extMasterSecret) ||
                !s.ReadUint8(&earlyData) ||
                len(ss.secret) == 0 ||
                !unmarshalCertificate(&s, &cert) {
                return nil, errors.New("tls: invalid session encoding")
        }
+       for !extra.Empty() {
+               var e []byte
+               if !readUint24LengthPrefixed(&extra, &e) {
+                       return nil, errors.New("tls: invalid session encoding")
+               }
+               ss.Extra = append(ss.Extra, e)
+       }
        switch extMasterSecret {
        case 0:
                ss.extMasterSecret = false