@@ -70,9 +70,11 @@ func (hs *serverHandshakeState) handshake() error {
70
70
71
71
// For an overview of TLS handshaking, see RFC 5246, Section 7.3.
72
72
c .buffering = true
73
- if hs .checkForResumption () {
73
+ if err := hs .checkForResumption (); err != nil {
74
+ return err
75
+ }
76
+ if hs .sessionState != nil {
74
77
// The client has included a session ticket and so we do an abbreviated handshake.
75
- c .didResume = true
76
78
if err := hs .doResumeHandshake (); err != nil {
77
79
return err
78
80
}
@@ -399,65 +401,80 @@ func (hs *serverHandshakeState) cipherSuiteOk(c *cipherSuite) bool {
399
401
}
400
402
401
403
// checkForResumption reports whether we should perform resumption on this connection.
402
- func (hs * serverHandshakeState ) checkForResumption () bool {
404
+ func (hs * serverHandshakeState ) checkForResumption () error {
403
405
c := hs .c
404
406
405
407
if c .config .SessionTicketsDisabled {
406
- return false
408
+ return nil
407
409
}
408
410
409
- plaintext := c .decryptTicket (hs .clientHello .sessionTicket )
410
- if plaintext == nil {
411
- return false
412
- }
413
- ss , err := ParseSessionState (plaintext )
414
- if err != nil {
415
- return false
411
+ var sessionState * SessionState
412
+ if c .config .UnwrapSession != nil {
413
+ ss , err := c .config .UnwrapSession (hs .clientHello .sessionTicket , c .connectionStateLocked ())
414
+ if err != nil {
415
+ return err
416
+ }
417
+ if ss == nil {
418
+ return nil
419
+ }
420
+ sessionState = ss
421
+ } else {
422
+ plaintext := c .config .decryptTicket (hs .clientHello .sessionTicket , c .ticketKeys )
423
+ if plaintext == nil {
424
+ return nil
425
+ }
426
+ ss , err := ParseSessionState (plaintext )
427
+ if err != nil {
428
+ return nil
429
+ }
430
+ sessionState = ss
416
431
}
417
- hs .sessionState = ss
418
432
419
433
// TLS 1.2 tickets don't natively have a lifetime, but we want to avoid
420
434
// re-wrapping the same master secret in different tickets over and over for
421
435
// too long, weakening forward secrecy.
422
- createdAt := time .Unix (int64 (hs . sessionState .createdAt ), 0 )
436
+ createdAt := time .Unix (int64 (sessionState .createdAt ), 0 )
423
437
if c .config .time ().Sub (createdAt ) > maxSessionTicketLifetime {
424
- return false
438
+ return nil
425
439
}
426
440
427
441
// Never resume a session for a different TLS version.
428
- if c .vers != hs . sessionState .version {
429
- return false
442
+ if c .vers != sessionState .version {
443
+ return nil
430
444
}
431
445
432
446
cipherSuiteOk := false
433
447
// Check that the client is still offering the ciphersuite in the session.
434
448
for _ , id := range hs .clientHello .cipherSuites {
435
- if id == hs . sessionState .cipherSuite {
449
+ if id == sessionState .cipherSuite {
436
450
cipherSuiteOk = true
437
451
break
438
452
}
439
453
}
440
454
if ! cipherSuiteOk {
441
- return false
455
+ return nil
442
456
}
443
457
444
458
// Check that we also support the ciphersuite from the session.
445
- hs . suite = selectCipherSuite ([]uint16 {hs . sessionState .cipherSuite },
459
+ suite : = selectCipherSuite ([]uint16 {sessionState .cipherSuite },
446
460
c .config .cipherSuites (), hs .cipherSuiteOk )
447
- if hs . suite == nil {
448
- return false
461
+ if suite == nil {
462
+ return nil
449
463
}
450
464
451
- sessionHasClientCerts := len (hs . sessionState .peerCertificates ) != 0
465
+ sessionHasClientCerts := len (sessionState .peerCertificates ) != 0
452
466
needClientCerts := requiresClientCert (c .config .ClientAuth )
453
467
if needClientCerts && ! sessionHasClientCerts {
454
- return false
468
+ return nil
455
469
}
456
470
if sessionHasClientCerts && c .config .ClientAuth == NoClientCert {
457
- return false
471
+ return nil
458
472
}
459
473
460
- return true
474
+ hs .sessionState = sessionState
475
+ hs .suite = suite
476
+ c .didResume = true
477
+ return nil
461
478
}
462
479
463
480
func (hs * serverHandshakeState ) doResumeHandshake () error {
@@ -769,13 +786,20 @@ func (hs *serverHandshakeState) sendSessionTicket() error {
769
786
// the original time it was created.
770
787
state .createdAt = hs .sessionState .createdAt
771
788
}
772
- stateBytes , err := state .Bytes ()
773
- if err != nil {
774
- return err
775
- }
776
- m .ticket , err = c .encryptTicket (stateBytes )
777
- if err != nil {
778
- return err
789
+ if c .config .WrapSession != nil {
790
+ m .ticket , err = c .config .WrapSession (c .connectionStateLocked (), state )
791
+ if err != nil {
792
+ return err
793
+ }
794
+ } else {
795
+ stateBytes , err := state .Bytes ()
796
+ if err != nil {
797
+ return err
798
+ }
799
+ m .ticket , err = c .config .encryptTicket (stateBytes , c .ticketKeys )
800
+ if err != nil {
801
+ return err
802
+ }
779
803
}
780
804
781
805
if _ , err := hs .c .writeHandshakeRecord (m , & hs .finishedHash ); err != nil {
0 commit comments