Skip to content

Commit 9624e67

Browse files
committed
crypto/tls: add SessionState and use it on the server side
This change by itself is useless, because the application has no way to access or provide SessionStates to crypto/tls, but they will be provided in following CLs. For #60105 Change-Id: I8d5de79b1eda0a778420134cf6f346246a1bb296 Reviewed-on: https://go-review.googlesource.com/c/go/+/496818 Reviewed-by: Marten Seemann <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Damien Neil <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]> Run-TryBot: Filippo Valsorda <[email protected]>
1 parent 6b020be commit 9624e67

34 files changed

+2254
-2303
lines changed

api/next/60105.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pkg crypto/tls, func ParseSessionState([]uint8) (*SessionState, error) #60105
2+
pkg crypto/tls, method (*SessionState) Bytes() ([]uint8, error) #60105
3+
pkg crypto/tls, type SessionState struct #60105

src/crypto/tls/handshake_messages_test.go

+24-29
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import (
1515
"time"
1616
)
1717

18-
var tests = []any{
18+
var tests = []handshakeMessage{
1919
&clientHelloMsg{},
2020
&serverHelloMsg{},
2121
&finishedMsg{},
@@ -28,14 +28,13 @@ var tests = []any{
2828
&certificateStatusMsg{},
2929
&clientKeyExchangeMsg{},
3030
&newSessionTicketMsg{},
31-
&sessionState{},
32-
&sessionStateTLS13{},
3331
&encryptedExtensionsMsg{},
3432
&endOfEarlyDataMsg{},
3533
&keyUpdateMsg{},
3634
&newSessionTicketMsgTLS13{},
3735
&certificateRequestMsgTLS13{},
3836
&certificateMsgTLS13{},
37+
&SessionState{},
3938
}
4039

4140
func mustMarshal(t *testing.T, msg handshakeMessage) []byte {
@@ -50,8 +49,8 @@ func mustMarshal(t *testing.T, msg handshakeMessage) []byte {
5049
func TestMarshalUnmarshal(t *testing.T) {
5150
rand := rand.New(rand.NewSource(time.Now().UnixNano()))
5251

53-
for i, iface := range tests {
54-
ty := reflect.ValueOf(iface).Type()
52+
for i, m := range tests {
53+
ty := reflect.ValueOf(m).Type()
5554

5655
n := 100
5756
if testing.Short() {
@@ -66,15 +65,14 @@ func TestMarshalUnmarshal(t *testing.T) {
6665

6766
m1 := v.Interface().(handshakeMessage)
6867
marshaled := mustMarshal(t, m1)
69-
m2 := iface.(handshakeMessage)
70-
if !m2.unmarshal(marshaled) {
68+
if !m.unmarshal(marshaled) {
7169
t.Errorf("#%d failed to unmarshal %#v %x", i, m1, marshaled)
7270
break
7371
}
74-
m2.marshal() // to fill any marshal cache in the message
72+
m.marshal() // to fill any marshal cache in the message
7573

76-
if !reflect.DeepEqual(m1, m2) {
77-
t.Errorf("#%d got:%#v want:%#v %x", i, m2, m1, marshaled)
74+
if !reflect.DeepEqual(m1, m) {
75+
t.Errorf("#%d got:%#v want:%#v %x", i, m, m1, marshaled)
7876
break
7977
}
8078

@@ -85,7 +83,7 @@ func TestMarshalUnmarshal(t *testing.T) {
8583
// data is optional and the length of the
8684
// Finished varies across versions.
8785
for j := 0; j < len(marshaled); j++ {
88-
if m2.unmarshal(marshaled[0:j]) {
86+
if m.unmarshal(marshaled[0:j]) {
8987
t.Errorf("#%d unmarshaled a prefix of length %d of %#v", i, j, m1)
9088
break
9189
}
@@ -97,9 +95,7 @@ func TestMarshalUnmarshal(t *testing.T) {
9795

9896
func TestFuzz(t *testing.T) {
9997
rand := rand.New(rand.NewSource(0))
100-
for _, iface := range tests {
101-
m := iface.(handshakeMessage)
102-
98+
for _, m := range tests {
10399
for j := 0; j < 1000; j++ {
104100
len := rand.Intn(100)
105101
bytes := randomBytes(len, rand)
@@ -317,22 +313,11 @@ func (*newSessionTicketMsg) Generate(rand *rand.Rand, size int) reflect.Value {
317313
return reflect.ValueOf(m)
318314
}
319315

320-
func (*sessionState) Generate(rand *rand.Rand, size int) reflect.Value {
321-
s := &sessionState{}
322-
s.vers = uint16(rand.Intn(10000))
316+
func (*SessionState) Generate(rand *rand.Rand, size int) reflect.Value {
317+
s := &SessionState{}
318+
s.version = uint16(rand.Intn(10000))
323319
s.cipherSuite = uint16(rand.Intn(10000))
324-
s.masterSecret = randomBytes(rand.Intn(100)+1, rand)
325-
s.createdAt = uint64(rand.Int63())
326-
for i := 0; i < rand.Intn(20); i++ {
327-
s.certificates = append(s.certificates, randomBytes(rand.Intn(500)+1, rand))
328-
}
329-
return reflect.ValueOf(s)
330-
}
331-
332-
func (*sessionStateTLS13) Generate(rand *rand.Rand, size int) reflect.Value {
333-
s := &sessionStateTLS13{}
334-
s.cipherSuite = uint16(rand.Intn(10000))
335-
s.resumptionSecret = randomBytes(rand.Intn(100)+1, rand)
320+
s.secret = randomBytes(rand.Intn(100)+1, rand)
336321
s.createdAt = uint64(rand.Int63())
337322
for i := 0; i < rand.Intn(2)+1; i++ {
338323
s.certificate.Certificate = append(
@@ -350,6 +335,16 @@ func (*sessionStateTLS13) Generate(rand *rand.Rand, size int) reflect.Value {
350335
return reflect.ValueOf(s)
351336
}
352337

338+
func (s *SessionState) marshal() ([]byte, error) { return s.Bytes() }
339+
func (s *SessionState) unmarshal(b []byte) bool {
340+
ss, err := ParseSessionState(b)
341+
if err != nil {
342+
return false
343+
}
344+
*s = *ss
345+
return true
346+
}
347+
353348
func (*endOfEarlyDataMsg) Generate(rand *rand.Rand, size int) reflect.Value {
354349
m := &endOfEarlyDataMsg{}
355350
return reflect.ValueOf(m)

src/crypto/tls/handshake_server.go

+20-18
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ type serverHandshakeState struct {
3131
ecSignOk bool
3232
rsaDecryptOk bool
3333
rsaSignOk bool
34-
sessionState *sessionState
34+
sessionState *SessionState
3535
finishedHash finishedHash
3636
masterSecret []byte
3737
cert *Certificate
@@ -410,11 +410,11 @@ func (hs *serverHandshakeState) checkForResumption() bool {
410410
if plaintext == nil {
411411
return false
412412
}
413-
hs.sessionState = &sessionState{}
414-
ok := hs.sessionState.unmarshal(plaintext)
415-
if !ok {
413+
ss, err := ParseSessionState(plaintext)
414+
if err != nil {
416415
return false
417416
}
417+
hs.sessionState = ss
418418

419419
// TLS 1.2 tickets don't natively have a lifetime, but we want to avoid
420420
// re-wrapping the same master secret in different tickets over and over for
@@ -425,7 +425,7 @@ func (hs *serverHandshakeState) checkForResumption() bool {
425425
}
426426

427427
// Never resume a session for a different TLS version.
428-
if c.vers != hs.sessionState.vers {
428+
if c.vers != hs.sessionState.version {
429429
return false
430430
}
431431

@@ -448,7 +448,7 @@ func (hs *serverHandshakeState) checkForResumption() bool {
448448
return false
449449
}
450450

451-
sessionHasClientCerts := len(hs.sessionState.certificates) != 0
451+
sessionHasClientCerts := len(hs.sessionState.certificate.Certificate) != 0
452452
needClientCerts := requiresClientCert(c.config.ClientAuth)
453453
if needClientCerts && !sessionHasClientCerts {
454454
return false
@@ -481,9 +481,7 @@ func (hs *serverHandshakeState) doResumeHandshake() error {
481481
return err
482482
}
483483

484-
if err := c.processCertsFromClient(Certificate{
485-
Certificate: hs.sessionState.certificates,
486-
}); err != nil {
484+
if err := c.processCertsFromClient(hs.sessionState.certificate); err != nil {
487485
return err
488486
}
489487

@@ -494,7 +492,7 @@ func (hs *serverHandshakeState) doResumeHandshake() error {
494492
}
495493
}
496494

497-
hs.masterSecret = hs.sessionState.masterSecret
495+
hs.masterSecret = hs.sessionState.secret
498496

499497
return nil
500498
}
@@ -772,14 +770,18 @@ func (hs *serverHandshakeState) sendSessionTicket() error {
772770
for _, cert := range c.peerCertificates {
773771
certsFromClient = append(certsFromClient, cert.Raw)
774772
}
775-
state := sessionState{
776-
vers: c.vers,
777-
cipherSuite: hs.suite.id,
778-
createdAt: createdAt,
779-
masterSecret: hs.masterSecret,
780-
certificates: certsFromClient,
781-
}
782-
stateBytes, err := state.marshal()
773+
state := SessionState{
774+
version: c.vers,
775+
cipherSuite: hs.suite.id,
776+
createdAt: createdAt,
777+
secret: hs.masterSecret,
778+
certificate: Certificate{
779+
Certificate: certsFromClient,
780+
OCSPStaple: c.ocspResponse,
781+
SignedCertificateTimestamps: c.scts,
782+
},
783+
}
784+
stateBytes, err := state.Bytes()
783785
if err != nil {
784786
return err
785787
}

src/crypto/tls/handshake_server_tls13.go

+13-13
Original file line numberDiff line numberDiff line change
@@ -279,8 +279,8 @@ func (hs *serverHandshakeStateTLS13) checkForResumption() error {
279279
if plaintext == nil {
280280
continue
281281
}
282-
sessionState := new(sessionStateTLS13)
283-
if ok := sessionState.unmarshal(plaintext); !ok {
282+
sessionState, err := ParseSessionState(plaintext)
283+
if err != nil || sessionState.version != VersionTLS13 {
284284
continue
285285
}
286286

@@ -310,9 +310,7 @@ func (hs *serverHandshakeStateTLS13) checkForResumption() error {
310310
continue
311311
}
312312

313-
psk := hs.suite.expandLabel(sessionState.resumptionSecret, "resumption",
314-
nil, hs.suite.hash.Size())
315-
hs.earlySecret = hs.suite.extract(psk, nil)
313+
hs.earlySecret = hs.suite.extract(sessionState.secret, nil)
316314
binderKey := hs.suite.deriveSecret(hs.earlySecret, resumptionBinderLabel, nil)
317315
// Clone the transcript in case a HelloRetryRequest was recorded.
318316
transcript := cloneHash(hs.transcript, hs.suite.hash)
@@ -771,24 +769,29 @@ func (hs *serverHandshakeStateTLS13) sendSessionTickets() error {
771769

772770
resumptionSecret := hs.suite.deriveSecret(hs.masterSecret,
773771
resumptionLabel, hs.transcript)
772+
// ticket_nonce, which must be unique per connection, is always left at
773+
// zero because we only ever send one ticket per connection.
774+
psk := hs.suite.expandLabel(resumptionSecret, "resumption",
775+
nil, hs.suite.hash.Size())
774776

775777
m := new(newSessionTicketMsgTLS13)
776778

777779
var certsFromClient [][]byte
778780
for _, cert := range c.peerCertificates {
779781
certsFromClient = append(certsFromClient, cert.Raw)
780782
}
781-
state := sessionStateTLS13{
782-
cipherSuite: hs.suite.id,
783-
createdAt: uint64(c.config.time().Unix()),
784-
resumptionSecret: resumptionSecret,
783+
state := &SessionState{
784+
version: c.vers,
785+
cipherSuite: hs.suite.id,
786+
createdAt: uint64(c.config.time().Unix()),
787+
secret: psk,
785788
certificate: Certificate{
786789
Certificate: certsFromClient,
787790
OCSPStaple: c.ocspResponse,
788791
SignedCertificateTimestamps: c.scts,
789792
},
790793
}
791-
stateBytes, err := state.marshal()
794+
stateBytes, err := state.Bytes()
792795
if err != nil {
793796
c.sendAlert(alertInternalError)
794797
return err
@@ -809,9 +812,6 @@ func (hs *serverHandshakeStateTLS13) sendSessionTickets() error {
809812
}
810813
m.ageAdd = binary.LittleEndian.Uint32(ageAdd)
811814

812-
// ticket_nonce, which must be unique per connection, is always left at
813-
// zero because we only ever send one ticket per connection.
814-
815815
if _, err := c.writeHandshakeRecord(m, nil); err != nil {
816816
return err
817817
}

src/crypto/tls/testdata/Server-TLSv10-ExportKeyingMaterial

+37-37
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
>>> Flow 1 (client to server)
2-
00000000 16 03 01 00 55 01 00 00 51 03 01 f5 f3 42 9e 4a |....U...Q....B.J|
3-
00000010 f4 5f cc c5 18 d0 77 f2 9f 1a 37 d7 44 6b f5 09 |._....w...7.Dk..|
4-
00000020 69 ab 8b ee d7 1c 63 8d 95 59 bc 00 00 04 c0 14 |i.....c..Y......|
2+
00000000 16 03 01 00 55 01 00 00 51 03 01 58 36 60 2e c2 |....U...Q..X6`..|
3+
00000010 61 c3 fb 34 e3 b1 09 ca 00 58 fb 2b 72 d6 de 35 |a..4.....X.+r..5|
4+
00000020 a1 ed 5b ec 40 64 e2 cc ff 3c c6 00 00 04 c0 14 |..[.@d...<......|
55
00000030 00 ff 01 00 00 24 00 0b 00 04 03 00 01 02 00 0a |.....$..........|
66
00000040 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 23 |...............#|
77
00000050 00 00 00 16 00 00 00 17 00 00 |..........|
@@ -50,42 +50,42 @@
5050
00000290 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 |...=.`.\!.;.....|
5151
000002a0 01 00 aa 0c 00 00 a6 03 00 1d 20 2f e5 7d a3 47 |.......... /.}.G|
5252
000002b0 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af |.bC.(.._.).0....|
53-
000002c0 c4 cf c2 ed 90 99 5f 58 cb 3b 74 00 80 3f 8b 3e |......_X.;t..?.>|
54-
000002d0 b0 29 ea c2 25 87 26 bb 69 0d b8 52 18 d4 82 19 |.)..%.&.i..R....|
55-
000002e0 90 3b e9 dc 77 94 61 fe 69 95 9f 50 85 34 c5 dd |.;..w.a.i..P.4..|
56-
000002f0 c0 a1 d5 d6 83 e4 e3 ba 8c f7 6e 39 e0 14 94 30 |..........n9...0|
57-
00000300 34 16 f0 5b c0 32 92 a3 21 8e 21 c8 57 05 16 a3 |4..[.2..!.!.W...|
58-
00000310 ea 66 0a 29 20 14 32 e2 f6 b2 7f 17 04 dc 8f 1b |.f.) .2.........|
59-
00000320 2c 56 50 75 bf 84 c7 11 84 18 a3 05 08 1a 3a e4 |,VPu..........:.|
60-
00000330 16 ec f2 b5 1f 29 9b 56 8f 5c 9c f2 91 3e 09 5e |.....).V.\...>.^|
61-
00000340 c7 59 45 12 37 39 06 c5 11 3c fc ee 49 16 03 01 |.YE.79...<..I...|
53+
000002c0 c4 cf c2 ed 90 99 5f 58 cb 3b 74 00 80 cc 63 02 |......_X.;t...c.|
54+
000002d0 c4 91 d5 33 71 50 31 1f 7c d0 9c 3d f4 86 33 e6 |...3qP1.|..=..3.|
55+
000002e0 28 32 81 af d9 33 c2 c9 38 89 38 3f 1b 01 07 c2 |(2...3..8.8?....|
56+
000002f0 99 46 68 ea db 0e a3 b0 a7 e6 de b3 8f 9a 3d f1 |.Fh...........=.|
57+
00000300 76 72 a8 e4 4a 63 97 fd d2 77 23 79 13 cb ac d5 |vr..Jc...w#y....|
58+
00000310 db fa 89 ae 45 98 6f 1d 38 2c 20 d2 ba 94 eb 01 |....E.o.8, .....|
59+
00000320 91 5e 57 b6 a0 95 dc 70 ad 06 f7 c4 02 b9 06 c3 |.^W....p........|
60+
00000330 84 04 de b8 2c 71 31 4f 94 47 78 73 b1 72 e4 00 |....,q1O.Gxs.r..|
61+
00000340 4a 58 bb 88 fd 6f 55 6a 49 17 ef b9 6b 16 03 01 |JX...oUjI...k...|
6262
00000350 00 04 0e 00 00 00 |......|
6363
>>> Flow 3 (client to server)
64-
00000000 16 03 01 00 25 10 00 00 21 20 a1 f8 df c3 de d5 |....%...! ......|
65-
00000010 70 2f 18 10 4e 4e 86 18 ae 89 a5 4a 34 81 40 f8 |p/..NN.....J4.@.|
66-
00000020 9d a6 f4 cf b0 5b b5 43 54 08 14 03 01 00 01 01 |.....[.CT.......|
67-
00000030 16 03 01 00 30 86 24 e7 70 5c ea 25 e3 65 63 b5 |....0.$.p\.%.ec.|
68-
00000040 91 de 82 c3 23 ce b1 68 0c b4 a0 f3 ae 5d 46 cd |....#..h.....]F.|
69-
00000050 90 ce 4f 4c b0 c7 14 13 60 17 32 b4 fc 2a 0b 49 |..OL....`.2..*.I|
70-
00000060 8d 0e 3d e8 2a |..=.*|
64+
00000000 16 03 01 00 25 10 00 00 21 20 06 ca bc 6d bc 25 |....%...! ...m.%|
65+
00000010 25 0c 1a 06 b5 36 e6 de 20 57 fe bc 24 e9 87 e4 |%....6.. W..$...|
66+
00000020 cd 57 a0 91 7e 7e f2 79 5b 0b 14 03 01 00 01 01 |.W..~~.y[.......|
67+
00000030 16 03 01 00 30 85 12 fa 73 ea 8f 6f a5 d4 15 3b |....0...s..o...;|
68+
00000040 70 ac 6b 95 bc 3e 75 b3 ee c7 f1 1a 9e b2 b4 f0 |p.k..>u.........|
69+
00000050 0d f3 30 da 63 dc f7 c4 cd d6 ab ed db e5 c6 f9 |..0.c...........|
70+
00000060 6b 4f 52 3d 04 |kOR=.|
7171
>>> Flow 4 (server to client)
7272
00000000 16 03 01 00 7b 04 00 00 77 00 00 00 00 00 71 00 |....{...w.....q.|
7373
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 |................|
74-
00000020 6d ec a4 83 51 ed 14 ef 68 ca 42 c5 4c fe ae 28 |m...Q...h.B.L..(|
75-
00000030 76 e9 99 d7 d3 45 dd ff bd 64 54 a3 a8 bf 69 17 |v....E...dT...i.|
76-
00000040 28 b5 cb bb 13 1c e8 a8 9c f8 a7 43 81 9d 1d bc |(..........C....|
77-
00000050 00 96 83 1d cc da 66 d7 20 e1 52 44 b4 49 38 16 |......f. .RD.I8.|
78-
00000060 56 c5 9e be 43 6c 3c 82 7a 50 fd d6 e6 00 99 27 |V...Cl<.zP.....'|
79-
00000070 49 a1 65 7b cb 82 3f 9a 74 17 08 2b fd 7b de db |I.e{..?.t..+.{..|
80-
00000080 14 03 01 00 01 01 16 03 01 00 30 eb 9f f3 b2 32 |..........0....2|
81-
00000090 44 c2 58 ab 22 7f 41 a0 30 84 71 18 7a df 48 6b |D.X.".A.0.q.z.Hk|
82-
000000a0 c7 2d 8b 8e 8f 8c 7f 5d 58 7c 2c 61 5d 0d bc ce |.-.....]X|,a]...|
83-
000000b0 60 f0 47 b3 e2 86 5a 82 30 26 95 17 03 01 00 20 |`.G...Z.0&..... |
84-
000000c0 12 3e 23 0a f5 97 2a 6b bf be f4 82 7b 31 92 9e |.>#...*k....{1..|
85-
000000d0 32 c9 1f 4f 8e cc 74 5e 41 da ff 45 68 3c 82 07 |2..O..t^A..Eh<..|
86-
000000e0 17 03 01 00 30 31 73 bb fd 8e ba 4d c3 74 14 9b |....01s....M.t..|
87-
000000f0 81 c0 69 38 e6 32 86 35 b2 fb 2a af 2c 69 c1 ca |..i8.2.5..*.,i..|
88-
00000100 0c 94 35 9a fa 7b ab b4 04 1e 56 6f 59 f9 40 38 |..5..{....VoY.@8|
89-
00000110 e6 a9 20 96 15 15 03 01 00 20 09 20 d5 0e cd 68 |.. ...... . ...h|
90-
00000120 79 de ea 6b 0e 84 98 e5 75 64 c4 e8 b1 9f c4 cc |y..k....ud......|
91-
00000130 d6 4c b6 be cf 42 78 c6 6a 2e |.L...Bx.j.|
74+
00000020 6d 2d 70 97 51 ed 14 ef 68 ca 42 c5 4c 12 19 5b |m-p.Q...h.B.L..[|
75+
00000030 90 88 76 b1 48 c1 f4 61 1a 16 81 2e f7 5f 87 79 |..v.H..a....._.y|
76+
00000040 5c b7 dd b1 be 7f f4 b8 6a fb af 51 a3 35 5e 20 |\.......j..Q.5^ |
77+
00000050 b4 a2 b9 69 8b 93 45 4f 1b af 8c 69 c9 49 38 16 |...i..EO...i.I8.|
78+
00000060 79 6d a8 7f 7e 49 b0 b9 5a 88 19 1d 82 c2 68 f7 |ym..~I..Z.....h.|
79+
00000070 8a b4 45 8c f9 86 a7 fe f7 74 27 70 6f 52 6d 11 |..E......t'poRm.|
80+
00000080 14 03 01 00 01 01 16 03 01 00 30 3b 4f 4d 0a 0d |..........0;OM..|
81+
00000090 d8 28 9f 41 e6 be a5 9f f9 f1 a5 a9 f7 9f 24 90 |.(.A..........$.|
82+
000000a0 11 52 8a 0f 59 9c 55 79 68 7c 55 71 43 69 15 d9 |.R..Y.Uyh|UqCi..|
83+
000000b0 b1 5e cc 80 6d ba 38 e5 a7 72 8c 17 03 01 00 20 |.^..m.8..r..... |
84+
000000c0 cb bc e9 a2 a7 d1 3e 2c 6c 1e 37 2e c1 a9 56 25 |......>,l.7...V%|
85+
000000d0 d9 47 8e 3c 82 dc 6c 13 8b 0c 59 dc c2 06 28 ee |.G.<..l...Y...(.|
86+
000000e0 17 03 01 00 30 8d 88 6f ba 26 3f a0 e6 7d 9e cf |....0..o.&?..}..|
87+
000000f0 6f f1 60 af ba 2e db b1 56 7c 95 00 51 fd 36 a0 |o.`.....V|..Q.6.|
88+
00000100 94 64 e9 40 ea 25 8c 99 a2 6b 11 43 34 08 29 79 |.d.@.%...k.C4.)y|
89+
00000110 e9 7e 50 d8 c0 15 03 01 00 20 7d aa 05 d0 ce d6 |.~P...... }.....|
90+
00000120 77 52 d8 f7 65 d9 3b fe c3 51 f3 b6 67 90 f1 39 |wR..e.;..Q..g..9|
91+
00000130 62 a5 97 48 01 b0 4e 8b 16 48 |b..H..N..H|

0 commit comments

Comments
 (0)