aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFilippo Valsorda <filippo@golang.org>2023-06-07 21:36:19 +0200
committerGopher Robot <gobot@golang.org>2023-06-09 15:26:32 +0000
commit6801c27837b44b40aef0878a8a611413ef46e3eb (patch)
tree8d4580877204f6e892617dcf9599b90482beb3aa /src
parent1f11ea6c41e6ef323e9201649ad4863808342669 (diff)
downloadgo-6801c27837b44b40aef0878a8a611413ef46e3eb.tar.xz
crypto/tls: make SessionState.Extra a slice of byte slices
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>
Diffstat (limited to 'src')
-rw-r--r--src/crypto/tls/handshake_messages_test.go4
-rw-r--r--src/crypto/tls/ticket.go31
2 files changed, 26 insertions, 9 deletions
diff --git a/src/crypto/tls/handshake_messages_test.go b/src/crypto/tls/handshake_messages_test.go
index 224e17296f..72e8bd8c25 100644
--- a/src/crypto/tls/handshake_messages_test.go
+++ b/src/crypto/tls/handshake_messages_test.go
@@ -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
}
diff --git a/src/crypto/tls/ticket.go b/src/crypto/tls/ticket.go
index 1a3d0c7cfd..b43101ff66 100644
--- a/src/crypto/tls/ticket.go
+++ b/src/crypto/tls/ticket.go
@@ -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