Commit 6435d0cf authored by Filippo Valsorda's avatar Filippo Valsorda

crypto/tls: implement TLS 1.3 PSK authentication (server side)

Added some assertions to testHandshake, but avoided checking the error
of one of the Close() because the one that would lose the race would
write the closeNotify to a connection closed on the other side which is
broken on js/wasm (#28650). Moved that Close() after the chan sync to
ensure it happens second.

Accepting a ticket with client certificates when NoClientCert is
configured is probably not a problem, and we could hide them to avoid
confusing the application, but the current behavior is to skip the
ticket, and I'd rather keep behavior changes to a minimum.

Updates #9671

Change-Id: I93b56e44ddfe3d48c2bef52c83285ba2f46f297a
Reviewed-on: https://go-review.googlesource.com/c/147445Reviewed-by: default avatarAdam Langley <agl@golang.org>
parent d669cc47
......@@ -234,6 +234,17 @@ const (
RequireAndVerifyClientCert
)
// requiresClientCert returns whether the ClientAuthType requires a client
// certificate to be provided.
func requiresClientCert(c ClientAuthType) bool {
switch c {
case RequireAnyClientCert, RequireAndVerifyClientCert:
return true
default:
return false
}
}
// ClientSessionState contains the state needed by clients to resume TLS
// sessions.
type ClientSessionState struct {
......@@ -599,6 +610,10 @@ func ticketKeyFromBytes(b [32]byte) (key ticketKey) {
return key
}
// maxSessionTicketLifetime is the maximum allowed lifetime of a TLS 1.3 session
// ticket, and the lifetime we set for tickets we send.
const maxSessionTicketLifetime = 7 * 24 * time.Hour
// Clone returns a shallow clone of c. It is safe to clone a Config that is
// being used concurrently by a TLS client or server.
func (c *Config) Clone() *Config {
......
......@@ -869,11 +869,14 @@ func TestClientKeyUpdate(t *testing.T) {
runClientTestTLS13(t, test)
}
func TestClientResumption(t *testing.T) {
// TODO(filippo): update to test both TLS 1.3 and 1.2 once PSK are
// supported server-side.
func TestResumption(t *testing.T) {
t.Run("TLSv12", func(t *testing.T) { testResumption(t, VersionTLS12) })
t.Run("TLSv13", func(t *testing.T) { testResumption(t, VersionTLS13) })
}
func testResumption(t *testing.T, version uint16) {
serverConfig := &Config{
MaxVersion: version,
CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA},
Certificates: testConfig.Certificates,
}
......@@ -887,6 +890,7 @@ func TestClientResumption(t *testing.T) {
rootCAs.AddCert(issuer)
clientConfig := &Config{
MaxVersion: version,
CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
ClientSessionCache: NewLRUClientSessionCache(32),
RootCAs: rootCAs,
......@@ -924,9 +928,12 @@ func TestClientResumption(t *testing.T) {
testResumeState("Handshake", false)
ticket := getTicket()
testResumeState("Resume", true)
if !bytes.Equal(ticket, getTicket()) {
if !bytes.Equal(ticket, getTicket()) && version != VersionTLS13 {
t.Fatal("first ticket doesn't match ticket after resumption")
}
if bytes.Equal(ticket, getTicket()) && version == VersionTLS13 {
t.Fatal("ticket didn't change after resumption")
}
key1 := randomKey()
serverConfig.SetSessionTicketKeys([][32]byte{key1})
......@@ -946,6 +953,7 @@ func TestClientResumption(t *testing.T) {
// Reset serverConfig to ensure that calling SetSessionTicketKeys
// before the serverConfig is used works.
serverConfig = &Config{
MaxVersion: version,
CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA},
Certificates: testConfig.Certificates,
}
......@@ -953,9 +961,13 @@ func TestClientResumption(t *testing.T) {
testResumeState("FreshConfig", true)
// In TLS 1.3, cross-cipher suite resumption is allowed as long as the KDF
// hash matches. Also, Config.CipherSuites does not apply to TLS 1.3.
if version != VersionTLS13 {
clientConfig.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_RC4_128_SHA}
testResumeState("DifferentCipherSuite", false)
testResumeState("DifferentCipherSuiteRecovers", true)
}
deleteTicket()
testResumeState("WithoutSessionTicket", false)
......@@ -966,6 +978,8 @@ func TestClientResumption(t *testing.T) {
serverConfig.ClientAuth = RequireAndVerifyClientCert
clientConfig.Certificates = serverConfig.Certificates
testResumeState("InitialHandshake", false)
if version != VersionTLS13 {
// TODO(filippo): reenable when client authentication is implemented
testResumeState("WithClientCertificates", true)
// Tickets should be removed from the session cache on TLS handshake failure
......@@ -978,6 +992,7 @@ func TestClientResumption(t *testing.T) {
serverConfig.Time = nil
testResumeState("AfterHandshakeFailure", false)
serverConfig.ClientAuth = NoClientCert
}
clientConfig.ClientSessionCache = nil
testResumeState("WithoutSessionCache", false)
......
......@@ -565,7 +565,7 @@ func (c *Conn) handleNewSessionTicket(msg *newSessionTicketMsgTLS13) error {
return nil
}
lifetime := time.Duration(msg.lifetime) * time.Second
if lifetime > 7*24*time.Hour {
if lifetime > maxSessionTicketLifetime {
c.sendAlert(alertIllegalParameter)
return errors.New("tls: received a session ticket with invalid lifetime")
}
......
......@@ -30,6 +30,23 @@ func addBytesWithLength(b *cryptobyte.Builder, v []byte, n int) {
}))
}
// addUint64 appends a big-endian, 64-bit value to the cryptobyte.Builder.
func addUint64(b *cryptobyte.Builder, v uint64) {
b.AddUint32(uint32(v >> 32))
b.AddUint32(uint32(v))
}
// readUint64 decodes a big-endian, 64-bit value into out and advances over it.
// It reports whether the read was successful.
func readUint64(s *cryptobyte.String, out *uint64) bool {
var hi, lo uint32
if !s.ReadUint32(&hi) || !s.ReadUint32(&lo) {
return false
}
*out = uint64(hi)<<32 | uint64(lo)
return true
}
// readUint8LengthPrefixed acts like s.ReadUint8LengthPrefixed, but targets a
// []byte instead of a cryptobyte.String.
func readUint8LengthPrefixed(s *cryptobyte.String, out *[]byte) bool {
......@@ -1266,8 +1283,24 @@ func (m *certificateMsgTLS13) marshal() []byte {
b.AddUint8(typeCertificate)
b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint8(0) // certificate_request_context
certificate := m.certificate
if !m.ocspStapling {
certificate.OCSPStaple = nil
}
if !m.scts {
certificate.SignedCertificateTimestamps = nil
}
marshalCertificate(b, certificate)
})
m.raw = b.BytesOrPanic()
return m.raw
}
func marshalCertificate(b *cryptobyte.Builder, certificate Certificate) {
b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
for i, cert := range m.certificate.Certificate {
for i, cert := range certificate.Certificate {
b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddBytes(cert)
})
......@@ -1276,20 +1309,20 @@ func (m *certificateMsgTLS13) marshal() []byte {
// This library only supports OCSP and SCT for leaf certificates.
return
}
if m.ocspStapling {
if certificate.OCSPStaple != nil {
b.AddUint16(extensionStatusRequest)
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint8(statusTypeOCSP)
b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddBytes(m.certificate.OCSPStaple)
b.AddBytes(certificate.OCSPStaple)
})
})
}
if m.scts {
if certificate.SignedCertificateTimestamps != nil {
b.AddUint16(extensionSCT)
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
for _, sct := range m.certificate.SignedCertificateTimestamps {
for _, sct := range certificate.SignedCertificateTimestamps {
b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddBytes(sct)
})
......@@ -1300,24 +1333,31 @@ func (m *certificateMsgTLS13) marshal() []byte {
})
}
})
})
m.raw = b.BytesOrPanic()
return m.raw
}
func (m *certificateMsgTLS13) unmarshal(data []byte) bool {
*m = certificateMsgTLS13{raw: data}
s := cryptobyte.String(data)
var context, certList cryptobyte.String
var context cryptobyte.String
if !s.Skip(4) || // message type and uint24 length field
!s.ReadUint8LengthPrefixed(&context) || !context.Empty() ||
!s.ReadUint24LengthPrefixed(&certList) ||
!unmarshalCertificate(&s, &m.certificate) ||
!s.Empty() {
return false
}
m.scts = m.certificate.SignedCertificateTimestamps != nil
m.ocspStapling = m.certificate.OCSPStaple != nil
return true
}
func unmarshalCertificate(s *cryptobyte.String, certificate *Certificate) bool {
var certList cryptobyte.String
if !s.ReadUint24LengthPrefixed(&certList) {
return false
}
for !certList.Empty() {
var cert []byte
var extensions cryptobyte.String
......@@ -1325,7 +1365,7 @@ func (m *certificateMsgTLS13) unmarshal(data []byte) bool {
!certList.ReadUint16LengthPrefixed(&extensions) {
return false
}
m.certificate.Certificate = append(m.certificate.Certificate, cert)
certificate.Certificate = append(certificate.Certificate, cert)
for !extensions.Empty() {
var extension uint16
var extData cryptobyte.String
......@@ -1333,22 +1373,20 @@ func (m *certificateMsgTLS13) unmarshal(data []byte) bool {
!extensions.ReadUint16LengthPrefixed(&extData) {
return false
}
if len(m.certificate.Certificate) > 1 {
if len(certificate.Certificate) > 1 {
// This library only supports OCSP and SCT for leaf certificates.
continue
}
switch extension {
case extensionStatusRequest:
m.ocspStapling = true
var statusType uint8
if !extData.ReadUint8(&statusType) || statusType != statusTypeOCSP ||
!readUint24LengthPrefixed(&extData, &m.certificate.OCSPStaple) ||
len(m.certificate.OCSPStaple) == 0 {
!readUint24LengthPrefixed(&extData, &certificate.OCSPStaple) ||
len(certificate.OCSPStaple) == 0 {
return false
}
case extensionSCT:
m.scts = true
var sctList cryptobyte.String
if !extData.ReadUint16LengthPrefixed(&sctList) || sctList.Empty() {
return false
......@@ -1359,8 +1397,8 @@ func (m *certificateMsgTLS13) unmarshal(data []byte) bool {
len(sct) == 0 {
return false
}
m.certificate.SignedCertificateTimestamps = append(
m.certificate.SignedCertificateTimestamps, sct)
certificate.SignedCertificateTimestamps = append(
certificate.SignedCertificateTimestamps, sct)
}
default:
// Ignore unknown extensions.
......
......@@ -29,6 +29,7 @@ var tests = []interface{}{
&nextProtoMsg{},
&newSessionTicketMsg{},
&sessionState{},
&sessionStateTLS13{},
&encryptedExtensionsMsg{},
&endOfEarlyDataMsg{},
&keyUpdateMsg{},
......@@ -332,6 +333,27 @@ func (*sessionState) Generate(rand *rand.Rand, size int) reflect.Value {
return reflect.ValueOf(s)
}
func (*sessionStateTLS13) Generate(rand *rand.Rand, size int) reflect.Value {
s := &sessionStateTLS13{}
s.cipherSuite = uint16(rand.Intn(10000))
s.resumptionSecret = randomBytes(rand.Intn(100)+1, rand)
s.createdAt = uint64(rand.Int63())
for i := 0; i < rand.Intn(2)+1; i++ {
s.certificate.Certificate = append(
s.certificate.Certificate, randomBytes(rand.Intn(500)+1, rand))
}
if rand.Intn(10) > 5 {
s.certificate.OCSPStaple = randomBytes(rand.Intn(100)+1, rand)
}
if rand.Intn(10) > 5 {
for i := 0; i < rand.Intn(2)+1; i++ {
s.certificate.SignedCertificateTimestamps = append(
s.certificate.SignedCertificateTimestamps, randomBytes(rand.Intn(500)+1, rand))
}
}
return reflect.ValueOf(s)
}
func (*endOfEarlyDataMsg) Generate(rand *rand.Rand, size int) reflect.Value {
m := &endOfEarlyDataMsg{}
return reflect.ValueOf(m)
......
......@@ -323,9 +323,13 @@ func (hs *serverHandshakeState) checkForResumption() bool {
return false
}
var ok bool
var sessionTicket = append([]uint8{}, hs.clientHello.sessionTicket...)
if hs.sessionState, ok = c.decryptTicket(sessionTicket); !ok {
plaintext, usedOldKey := c.decryptTicket(hs.clientHello.sessionTicket)
if plaintext == nil {
return false
}
hs.sessionState = &sessionState{usedOldKey: usedOldKey}
ok := hs.sessionState.unmarshal(plaintext)
if !ok {
return false
}
......@@ -352,7 +356,7 @@ func (hs *serverHandshakeState) checkForResumption() bool {
}
sessionHasClientCerts := len(hs.sessionState.certificates) != 0
needClientCerts := c.config.ClientAuth == RequireAnyClientCert || c.config.ClientAuth == RequireAndVerifyClientCert
needClientCerts := requiresClientCert(c.config.ClientAuth)
if needClientCerts && !sessionHasClientCerts {
return false
}
......@@ -657,7 +661,7 @@ func (hs *serverHandshakeState) sendSessionTicket() error {
masterSecret: hs.masterSecret,
certificates: hs.certsFromClient,
}
m.ticket, err = c.encryptTicket(&state)
m.ticket, err = c.encryptTicket(state.marshal())
if err != nil {
return err
}
......
......@@ -16,6 +16,7 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"math/big"
"net"
"os"
......@@ -348,21 +349,41 @@ func TestClose(t *testing.T) {
func testHandshake(t *testing.T, clientConfig, serverConfig *Config) (serverState, clientState ConnectionState, err error) {
c, s := localPipe(t)
done := make(chan bool)
errChan := make(chan error)
go func() {
cli := Client(c, clientConfig)
cli.Handshake()
clientState = cli.ConnectionState()
err := cli.Handshake()
if err != nil {
errChan <- fmt.Errorf("client: %v", err)
c.Close()
done <- true
return
}
defer cli.Close()
clientState = cli.ConnectionState()
buf, err := ioutil.ReadAll(cli)
if err != nil {
t.Errorf("failed to call cli.Read: %v", err)
}
if got := string(buf); got != opensslSentinel {
t.Errorf("read %q from TLS connection, but expected %q", got, opensslSentinel)
}
errChan <- nil
}()
server := Server(s, serverConfig)
err = server.Handshake()
if err == nil {
serverState = server.ConnectionState()
if _, err := io.WriteString(server, opensslSentinel); err != nil {
t.Errorf("failed to call server.Write: %v", err)
}
if err := server.Close(); err != nil {
t.Errorf("failed to call server.Close: %v", err)
}
err = <-errChan
} else {
s.Close()
<-done
<-errChan
}
return
}
......@@ -1053,49 +1074,83 @@ func TestCipherSuiteCertPreferenceECDSA(t *testing.T) {
runServerTestTLS12(t, test)
}
func TestResumption(t *testing.T) {
func TestServerResumption(t *testing.T) {
sessionFilePath := tempFile("")
defer os.Remove(sessionFilePath)
test := &serverTest{
testIssue := &serverTest{
name: "IssueTicket",
command: []string{"openssl", "s_client", "-cipher", "AES128-SHA", "-sess_out", sessionFilePath},
wait: true,
}
runServerTestTLS12(t, test)
test = &serverTest{
testResume := &serverTest{
name: "Resume",
command: []string{"openssl", "s_client", "-cipher", "AES128-SHA", "-sess_in", sessionFilePath},
validate: func(state ConnectionState) error {
if !state.DidResume {
return errors.New("did not resume")
}
runServerTestTLS12(t, test)
return nil
},
}
runServerTestTLS12(t, testIssue)
runServerTestTLS12(t, testResume)
runServerTestTLS13(t, testIssue)
runServerTestTLS13(t, testResume)
config := testConfig.Clone()
config.CurvePreferences = []CurveID{CurveP256}
testResumeHRR := &serverTest{
name: "Resume-HelloRetryRequest",
command: []string{"openssl", "s_client", "-curves", "X25519:P-256", "-sess_in", sessionFilePath},
config: config,
validate: func(state ConnectionState) error {
if !state.DidResume {
return errors.New("did not resume")
}
return nil
},
}
runServerTestTLS13(t, testResumeHRR)
}
func TestResumptionDisabled(t *testing.T) {
func TestServerResumptionDisabled(t *testing.T) {
sessionFilePath := tempFile("")
defer os.Remove(sessionFilePath)
config := testConfig.Clone()
test := &serverTest{
testIssue := &serverTest{
name: "IssueTicketPreDisable",
command: []string{"openssl", "s_client", "-cipher", "AES128-SHA", "-sess_out", sessionFilePath},
config: config,
wait: true,
}
runServerTestTLS12(t, test)
config.SessionTicketsDisabled = true
test = &serverTest{
testResume := &serverTest{
name: "ResumeDisabled",
command: []string{"openssl", "s_client", "-cipher", "AES128-SHA", "-sess_in", sessionFilePath},
config: config,
validate: func(state ConnectionState) error {
if state.DidResume {
return errors.New("resumed with SessionTicketsDisabled")
}
return nil
},
}
runServerTestTLS12(t, test)
// One needs to manually confirm that the handshake in the golden data
// file for ResumeDisabled does not include a resumption handshake.
config.SessionTicketsDisabled = false
runServerTestTLS12(t, testIssue)
config.SessionTicketsDisabled = true
runServerTestTLS12(t, testResume)
config.SessionTicketsDisabled = false
runServerTestTLS13(t, testIssue)
config.SessionTicketsDisabled = true
runServerTestTLS13(t, testResume)
}
func TestFallbackSCSV(t *testing.T) {
......@@ -1593,3 +1648,14 @@ func TestCloseServerConnectionOnIdleClient(t *testing.T) {
t.Errorf("Error expected, but no error returned")
}
}
func TestCloneHash(t *testing.T) {
h1 := crypto.SHA256.New()
h1.Write([]byte("test"))
s1 := h1.Sum(nil)
h2 := cloneHash(h1, crypto.SHA256)
s2 := h2.Sum(nil)
if !bytes.Equal(s1, s2) {
t.Error("cloned hash generated a different sum")
}
}
......@@ -14,8 +14,14 @@ import (
"hash"
"io"
"sync/atomic"
"time"
)
// maxClientPSKIdentities is the number of client PSK identities the server will
// attempt to validate. It will ignore the rest not to let cheap ClientHello
// messages cause too much work in session ticket decryption attempts.
const maxClientPSKIdentities = 5
type serverHandshakeStateTLS13 struct {
c *Conn
clientHello *clientHelloMsg
......@@ -24,9 +30,12 @@ type serverHandshakeStateTLS13 struct {
suite *cipherSuiteTLS13
cert *Certificate
sigAlg SignatureScheme
earlySecret []byte
sharedKey []byte
handshakeSecret []byte
trafficSecret []byte // client_application_traffic_secret_0
transcript hash.Hash
clientFinished []byte
}
func (hs *serverHandshakeStateTLS13) handshake() error {
......@@ -36,16 +45,33 @@ func (hs *serverHandshakeStateTLS13) handshake() error {
if err := hs.processClientHello(); err != nil {
return err
}
usePSK, err := hs.checkForResumption()
if err != nil {
return err
}
if !usePSK {
if err := hs.pickCertificate(); err != nil {
return err
}
}
c.buffering = true
if err := hs.sendServerParameters(); err != nil {
return err
}
if !usePSK {
if err := hs.sendServerCertificate(); err != nil {
return err
}
}
if err := hs.sendServerFinished(); err != nil {
return err
}
// Note that at this point we could start sending application data without
// waiting for the client's second flight, but the application might not
// expect the lack of replay protection of the ClientHello parameters.
if err := hs.sendSessionTickets(); err != nil {
return err
}
if _, err := c.flush(); err != nil {
return err
}
......@@ -163,14 +189,138 @@ GroupSelection:
return err
}
hs.hello.serverShare = keyShare{group: selectedGroup, data: params.PublicKey()}
sharedKey := params.SharedKey(clientKeyShare.data)
if sharedKey == nil {
hs.sharedKey = params.SharedKey(clientKeyShare.data)
if hs.sharedKey == nil {
c.sendAlert(alertIllegalParameter)
return errors.New("tls: invalid client key share")
}
earlySecret := hs.suite.extract(nil, nil)
hs.handshakeSecret = hs.suite.extract(sharedKey,
hs.suite.deriveSecret(earlySecret, "derived", nil))
return nil
}
func (hs *serverHandshakeStateTLS13) checkForResumption() (usePSK bool, err error) {
c := hs.c
if c.config.SessionTicketsDisabled {
return false, nil
}
modeOK := false
for _, mode := range hs.clientHello.pskModes {
if mode == pskModeDHE {
modeOK = true
break
}
}
if !modeOK {
return false, nil
}
if len(hs.clientHello.pskIdentities) != len(hs.clientHello.pskBinders) {
c.sendAlert(alertIllegalParameter)
return false, errors.New("tls: invalid or missing PSK binders")
}
if len(hs.clientHello.pskIdentities) == 0 {
return false, nil
}
for i, identity := range hs.clientHello.pskIdentities {
if i >= maxClientPSKIdentities {
break
}
plaintext, _ := c.decryptTicket(identity.label)
if plaintext == nil {
continue
}
sessionState := new(sessionStateTLS13)
if ok := sessionState.unmarshal(plaintext); !ok {
continue
}
createdAt := time.Unix(int64(sessionState.createdAt), 0)
if c.config.time().Sub(createdAt) > maxSessionTicketLifetime {
continue
}
// We don't check the obfuscated ticket age because it's affected by
// clock skew and it's only a freshness signal useful for shrinking the
// window for replay attacks, which don't affect us as we don't do 0-RTT.
pskSuite := cipherSuiteTLS13ByID(sessionState.cipherSuite)
if pskSuite == nil || pskSuite.hash != hs.suite.hash {
continue
}
// PSK connections don't re-establish client certificates, but carry
// them over in the session ticket. Ensure the presence of client certs
// in the ticket is consistent with the configured requirements.
sessionHasClientCerts := len(sessionState.certificate.Certificate) != 0
needClientCerts := requiresClientCert(c.config.ClientAuth)
if needClientCerts && !sessionHasClientCerts {
continue
}
if sessionHasClientCerts && c.config.ClientAuth == NoClientCert {
continue
}
psk := hs.suite.expandLabel(sessionState.resumptionSecret, "resumption",
nil, hs.suite.hash.Size())
hs.earlySecret = hs.suite.extract(psk, nil)
binderKey := hs.suite.deriveSecret(hs.earlySecret, resumptionBinderLabel, nil)
// Clone the transcript in case a HelloRetryRequest was recorded.
transcript := cloneHash(hs.transcript, hs.suite.hash)
if transcript == nil {
c.sendAlert(alertInternalError)
return false, errors.New("tls: internal error: failed to clone hash")
}
transcript.Write(hs.clientHello.marshalWithoutBinders())
pskBinder := hs.suite.finishedHash(binderKey, transcript)
if !hmac.Equal(hs.clientHello.pskBinders[i], pskBinder) {
c.sendAlert(alertDecryptError)
return false, errors.New("tls: invalid PSK binder")
}
hs.hello.selectedIdentityPresent = true
hs.hello.selectedIdentity = uint16(i)
c.didResume = true
// TODO(filippo): surface sessionState.certificate.
return true, nil
}
return false, nil
}
// cloneHash uses the encoding.BinaryMarshaler and encoding.BinaryUnmarshaler
// interfaces implemented by standard library hashes to clone the state of in
// to a new instance of h. It returns nil if the operation fails.
func cloneHash(in hash.Hash, h crypto.Hash) hash.Hash {
// Recreate the interface to avoid importing encoding.
type binaryMarshaler interface {
MarshalBinary() (data []byte, err error)
UnmarshalBinary(data []byte) error
}
marshaler, ok := in.(binaryMarshaler)
if !ok {
return nil
}
state, err := marshaler.MarshalBinary()
if err != nil {
return nil
}
out := h.New()
unmarshaler, ok := out.(binaryMarshaler)
if !ok {
return nil
}
if err := unmarshaler.UnmarshalBinary(state); err != nil {
return nil
}
return out
}
func (hs *serverHandshakeStateTLS13) pickCertificate() error {
c := hs.c
// This implements a very simplistic certificate selection strategy for now:
// getCertificate delegates to the application Config.GetCertificate, or
......@@ -350,6 +500,13 @@ func (hs *serverHandshakeStateTLS13) sendServerParameters() error {
return err
}
earlySecret := hs.earlySecret
if earlySecret == nil {
earlySecret = hs.suite.extract(nil, nil)
}
hs.handshakeSecret = hs.suite.extract(hs.sharedKey,
hs.suite.deriveSecret(earlySecret, "derived", nil))
clientSecret := hs.suite.deriveSecret(hs.handshakeSecret,
clientHandshakeTrafficLabel, hs.transcript)
c.in.setTrafficSecret(hs.suite, clientSecret)
......@@ -467,6 +624,60 @@ func (hs *serverHandshakeStateTLS13) sendServerFinished() error {
c.ekm = hs.suite.exportKeyingMaterial(masterSecret, hs.transcript)
// Precompute the expected client flight for the transcript.
hs.clientFinished = hs.suite.finishedHash(c.in.trafficSecret, hs.transcript)
finishedMsg := &finishedMsg{
verifyData: hs.clientFinished,
}
hs.transcript.Write(finishedMsg.marshal())
if hs.shouldSendSessionTickets() {
c.resumptionSecret = hs.suite.deriveSecret(masterSecret,
resumptionLabel, hs.transcript)
}
return nil
}
func (hs *serverHandshakeStateTLS13) shouldSendSessionTickets() bool {
if hs.c.config.SessionTicketsDisabled {
return false
}
// Don't send tickets the client wouldn't use. See RFC 8446, Section 4.2.9.
for _, pskMode := range hs.clientHello.pskModes {
if pskMode == pskModeDHE {
return true
}
}
return false
}
func (hs *serverHandshakeStateTLS13) sendSessionTickets() error {
c := hs.c
if !hs.shouldSendSessionTickets() {
return nil
}
m := new(newSessionTicketMsgTLS13)
var err error
state := sessionStateTLS13{
cipherSuite: hs.suite.id,
createdAt: uint64(c.config.time().Unix()),
resumptionSecret: c.resumptionSecret,
}
m.label, err = c.encryptTicket(state.marshal())
if err != nil {
return err
}
m.lifetime = uint32(maxSessionTicketLifetime / time.Second)
if _, err := c.writeRecord(recordTypeHandshake, m.marshal()); err != nil {
return err
}
return nil
}
......@@ -484,14 +695,11 @@ func (hs *serverHandshakeStateTLS13) readClientFinished() error {
return unexpectedMessageError(finished, msg)
}
expectedMAC := hs.suite.finishedHash(c.in.trafficSecret, hs.transcript)
if !hmac.Equal(expectedMAC, finished.verifyData) {
if !hmac.Equal(hs.clientFinished, finished.verifyData) {
c.sendAlert(alertDecryptError)
return errors.New("tls: invalid client finished hash")
}
hs.transcript.Write(finished.marshal())
c.in.setTrafficSecret(hs.suite, hs.trafficSecret)
return nil
......
This diff is collapsed.
>>> Flow 1 (client to server)
00000000 16 03 01 00 e4 01 00 00 e0 03 03 26 46 4d 2d 7d |...........&FM-}|
00000010 5c dc ef fb 2b 8b f7 15 4b ba 8b 1a 26 da f6 9b |\...+...K...&...|
00000020 e6 3c c6 8c a0 f9 6c 60 f6 11 81 20 53 f8 00 fb |.<....l`... S...|
00000030 8b be ff 98 74 c9 d9 3d aa 40 4d 0e 05 96 f9 30 |....t..=.@M....0|
00000040 d6 f5 7b f1 bc 31 18 30 5f 24 03 a8 00 08 13 02 |..{..1.0_$......|
00000050 13 03 13 01 00 ff 01 00 00 8f 00 00 00 0e 00 0c |................|
00000060 00 00 09 31 32 37 2e 30 2e 30 2e 31 00 0b 00 04 |...127.0.0.1....|
00000070 03 00 01 02 00 0a 00 0c 00 0a 00 1d 00 17 00 1e |................|
00000080 00 19 00 18 00 23 00 00 00 16 00 00 00 17 00 00 |.....#..........|
00000090 00 0d 00 1e 00 1c 04 03 05 03 06 03 08 07 08 08 |................|
000000a0 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 |................|
000000b0 06 01 00 2b 00 03 02 03 04 00 2d 00 02 01 01 00 |...+......-.....|
000000c0 33 00 26 00 24 00 1d 00 20 b6 ad 52 4d 37 b1 eb |3.&.$... ..RM7..|
000000d0 1e 57 2b a8 5d e7 43 b9 a0 98 47 8b ff 40 a9 14 |.W+.].C...G..@..|
000000e0 9e 23 26 c7 47 a7 cb f6 47 |.#&.G...G|
>>> Flow 2 (server to client)
00000000 16 03 03 00 7a 02 00 00 76 03 03 00 00 00 00 00 |....z...v.......|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020 00 00 00 00 00 00 00 00 00 00 00 20 53 f8 00 fb |........... S...|
00000030 8b be ff 98 74 c9 d9 3d aa 40 4d 0e 05 96 f9 30 |....t..=.@M....0|
00000040 d6 f5 7b f1 bc 31 18 30 5f 24 03 a8 13 02 00 00 |..{..1.0_$......|
00000050 2e 00 2b 00 02 03 04 00 33 00 24 00 1d 00 20 2f |..+.....3.$... /|
00000060 e5 7d a3 47 cd 62 43 15 28 da ac 5f bb 29 07 30 |.}.G.bC.(.._.).0|
00000070 ff f6 84 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 14 |.........._X.;t.|
00000080 03 03 00 01 01 17 03 03 00 17 b9 4a b7 2a b5 48 |...........J.*.H|
00000090 bc ba 18 3e 1a 99 bd fa 0d fc 2a 5d 52 93 b5 97 |...>......*]R...|
000000a0 5c 17 03 03 02 6d 30 8f 19 00 1c fa 90 a7 6c 08 |\....m0.......l.|
000000b0 6f 5a e8 d8 e0 3e 81 30 f1 11 85 7e 35 47 b3 d0 |oZ...>.0...~5G..|
000000c0 48 95 ce af e6 2f fc 22 0a 5f 56 bd 1c 7d 8c 48 |H..../."._V..}.H|
000000d0 f3 ad b7 5b 2e 4b d8 d1 16 46 7a ba c3 71 02 3c |...[.K...Fz..q.<|
000000e0 54 75 b8 92 02 b1 b9 cc 15 c4 fa d1 2d ba 0d 9f |Tu..........-...|
000000f0 65 a1 78 0d 8f d6 1c be fa 42 1f d7 48 1a 8e 11 |e.x......B..H...|
00000100 64 4c 12 ef bd 65 9d b4 31 18 4f 2a 77 c4 1f 1b |dL...e..1.O*w...|
00000110 90 90 37 ea 59 aa 05 bf 45 04 fb e8 a9 3f f9 11 |..7.Y...E....?..|
00000120 f9 25 95 fc d4 8e 5c 84 19 f3 4c e4 05 c3 db 8c |.%....\...L.....|
00000130 07 f9 b3 b0 6d ce d3 14 aa 78 17 f9 2f 14 1b bc |....m....x../...|
00000140 4b 23 29 f1 2e 7c 3b 71 9b cf 0b d5 02 48 5e ce |K#)..|;q.....H^.|
00000150 9c 43 dd 29 17 42 0b 9d 0e a7 a7 93 e1 37 cc 97 |.C.).B.......7..|
00000160 df 0f 2d d3 f7 01 08 34 5f bd ad 12 12 6f 87 56 |..-....4_....o.V|
00000170 4e 99 16 f6 6e 61 5c f0 0e 30 0b d5 38 37 70 97 |N...na\..0..87p.|
00000180 ed e1 79 74 00 cc 55 be a9 32 7d 72 50 27 42 c9 |..yt..U..2}rP'B.|
00000190 99 64 ea bd 3e c8 4f b0 cc 31 ef 10 57 9f c1 02 |.d..>.O..1..W...|
000001a0 ca db f6 d6 53 94 d2 83 57 71 e9 06 7a dd 46 3b |....S...Wq..z.F;|
000001b0 b1 2c f8 87 1c 8b 8a 04 05 2f d0 32 54 9a 80 33 |.,......./.2T..3|
000001c0 b2 95 e5 62 71 e9 1a 3b ea 64 ee 81 29 c4 ea 53 |...bq..;.d..)..S|
000001d0 de 6b 27 b1 04 48 27 ba 7f 28 aa 9e 15 82 49 a9 |.k'..H'..(....I.|
000001e0 43 3d d3 33 82 50 a9 4e 38 ed 8d f8 e8 0e 11 ab |C=.3.P.N8.......|
000001f0 8b 6e 63 e9 c1 cf ee 45 4f a0 62 e7 2e 00 b8 61 |.nc....EO.b....a|
00000200 2a 29 5e 04 e2 81 11 b3 64 f3 b5 b0 ec ae 63 6c |*)^.....d.....cl|
00000210 27 56 ac f2 09 d3 a4 c8 18 4a 55 c8 ff fd 8b 42 |'V.......JU....B|
00000220 63 00 3a c9 25 40 b7 8d 17 f3 95 76 7b 01 cf bc |c.:.%@.....v{...|
00000230 9b a7 4c 03 4a 7d 3c 54 16 8f 84 ca 2f 1a f5 12 |..L.J}<T..../...|
00000240 cd 89 93 62 1f ff 8f 03 5d 06 e8 d7 9f 39 65 4e |...b....]....9eN|
00000250 09 b9 a8 e5 16 e8 6f 0d 0f ad d3 e2 95 cc fe 4b |......o........K|
00000260 fb e6 61 9a 25 00 3d b3 81 11 ea 4f e8 a9 f0 ee |..a.%.=....O....|
00000270 81 6c 79 d9 f8 76 d3 e8 76 a9 e2 85 bc 74 0c 7a |.ly..v..v....t.z|
00000280 c3 e2 eb cc f5 78 6e b6 2d 50 d3 65 ae f5 41 8e |.....xn.-P.e..A.|
00000290 86 9a 26 ba 36 44 15 16 a6 4b d7 b0 63 91 90 f8 |..&.6D...K..c...|
000002a0 ee 0a 83 83 cc d2 8b d3 a7 2c 8e 03 10 ac 76 cf |.........,....v.|
000002b0 16 27 1e 43 d3 fc d8 50 e7 73 63 36 ef 78 f7 a6 |.'.C...P.sc6.x..|
000002c0 27 14 39 1f 98 e3 f6 0b d6 93 79 8e 31 a9 6e 41 |'.9.......y.1.nA|
000002d0 2f 03 ab 11 9e 96 1e 16 be bf 0b 73 5c c9 32 57 |/..........s\.2W|
000002e0 e7 e3 24 66 07 9d 3d 29 e4 aa 22 e1 ce c6 fa c0 |..$f..=)..".....|
000002f0 84 cc 0d a7 f7 c2 d1 d2 19 5c 5b 37 31 a3 fe fd |.........\[71...|
00000300 95 81 c2 8f 2f c6 11 f8 7e 94 d6 41 60 ba e8 6b |..../...~..A`..k|
00000310 ea 2c 2a 17 03 03 00 99 f7 51 bf 4c da 85 85 a6 |.,*......Q.L....|
00000320 8f d7 35 25 32 87 01 22 44 7c 61 22 06 72 3e 18 |..5%2.."D|a".r>.|
00000330 f1 1e 11 c7 72 f5 65 b4 03 38 f2 48 16 a9 20 31 |....r.e..8.H.. 1|
00000340 c2 52 4c 33 92 70 45 91 19 f4 5c 08 77 49 af 25 |.RL3.pE...\.wI.%|
00000350 8e b5 bd 3f e3 93 dc e6 26 b0 8a 30 69 f1 86 17 |...?....&..0i...|
00000360 72 31 66 87 2f d4 42 70 4c e0 58 61 6e b2 38 0b |r1f./.BpL.Xan.8.|
00000370 13 ad 32 83 14 81 d4 af dd 9f 17 09 af 3b 64 78 |..2..........;dx|
00000380 c8 63 da 05 70 47 54 f9 c6 f5 f8 e6 97 e1 d0 87 |.c..pGT.........|
00000390 aa 5a e7 5b d3 a3 b3 ce be 56 30 e7 4d ad 43 bd |.Z.[.....V0.M.C.|
000003a0 5e 88 9a ef 34 78 06 eb 6f 8f 04 39 47 6a c2 3d |^...4x..o..9Gj.=|
000003b0 ba 17 03 03 00 45 89 37 db 55 b2 9e 6e 31 a0 9b |.....E.7.U..n1..|
000003c0 97 51 27 13 b0 7e 2e 85 4a 9b 72 b0 fe c5 e4 12 |.Q'..~..J.r.....|
000003d0 fd ea 29 d5 bb ae a2 24 e2 0d b4 cd 28 92 5c 88 |..)....$....(.\.|
000003e0 98 b4 e4 8e a8 46 c6 a0 0e c0 73 ba f7 62 3a 43 |.....F....s..b:C|
000003f0 1a c7 d3 4b 5b 47 7b 44 8b bb 7b 17 03 03 00 a3 |...K[G{D..{.....|
00000400 f1 5f 26 2b 1c 99 6d 1d 55 bc a7 2f ae c8 3a ed |._&+..m.U../..:.|
00000410 5a 16 3c 83 e8 d4 18 7e 84 fa ba 21 0f 30 b0 05 |Z.<....~...!.0..|
00000420 ec 45 92 53 80 7a 78 d4 9e e0 02 e9 11 74 a6 e2 |.E.S.zx......t..|
00000430 87 7e 43 26 c0 18 46 6b 28 e5 f4 92 89 5c 0d b5 |.~C&..Fk(....\..|
00000440 8d 90 55 4f 3b 0a f4 ba 1b fb 60 54 46 23 03 28 |..UO;.....`TF#.(|
00000450 6e c3 3b 4d 69 62 65 d5 4e 95 46 c9 f2 8d ae f9 |n.;Mibe.N.F.....|
00000460 53 a6 65 da ca 1e b7 f7 80 a8 97 97 ca 38 14 a5 |S.e..........8..|
00000470 34 81 e2 68 12 fb 45 90 c2 f9 c9 70 fe 28 b8 b5 |4..h..E....p.(..|
00000480 6c 1d 2c d4 07 69 1d eb 1f 4b df ba ca 5e e0 65 |l.,..i...K...^.e|
00000490 ad ee be 41 02 78 23 19 b9 ea 1d 65 20 43 0e 3d |...A.x#....e C.=|
000004a0 11 03 b3 |...|
>>> Flow 3 (client to server)
00000000 14 03 03 00 01 01 17 03 03 00 45 88 0d 45 f0 61 |..........E..E.a|
00000010 a3 d0 7b 33 9e 17 c5 c3 6f 8f f6 67 b8 03 65 5f |..{3....o..g..e_|
00000020 bf 94 e9 1d 58 eb 4d 12 68 8a 96 42 6f 08 08 b8 |....X.M.h..Bo...|
00000030 be ce 2c f0 c4 00 d4 22 e6 94 09 05 f2 a7 77 0f |..,...."......w.|
00000040 48 e9 5c 6c e9 b2 9a d6 ff 48 2b 08 9a ea 23 1a |H.\l.....H+...#.|
>>> Flow 4 (server to client)
00000000 17 03 03 00 1e 2a f5 09 7f 7b 5f 8a ff d3 cc 16 |.....*...{_.....|
00000010 d1 d3 38 76 5c f7 e3 ee f3 72 b5 92 8e f9 bf 37 |..8v\....r.....7|
00000020 7e dc 61 17 03 03 00 13 66 ba 9e ff 3a 9f 25 74 |~.a.....f...:.%t|
00000030 44 35 70 f4 cf ae dc b0 3c 28 44 |D5p.....<(D|
>>> Flow 1 (client to server)
00000000 16 03 01 00 e4 01 00 00 e0 03 03 4a ec fd a5 c5 |...........J....|
00000010 ef 77 88 18 25 40 50 c8 24 60 45 85 e6 3e 55 86 |.w..%@P.$`E..>U.|
00000020 d1 ea 0e 5f 0b d1 66 7a 1c 90 ad 20 a3 63 23 52 |..._..fz... .c#R|
00000030 d8 c8 f6 79 20 04 8d 07 eb 2f 78 a3 1a 0d 58 af |...y ..../x...X.|
00000040 70 3c ef 4b 90 43 42 67 57 39 bf fa 00 08 13 02 |p<.K.CBgW9......|
00000050 13 03 13 01 00 ff 01 00 00 8f 00 00 00 0e 00 0c |................|
00000060 00 00 09 31 32 37 2e 30 2e 30 2e 31 00 0b 00 04 |...127.0.0.1....|
00000070 03 00 01 02 00 0a 00 0c 00 0a 00 1d 00 17 00 1e |................|
00000080 00 19 00 18 00 23 00 00 00 16 00 00 00 17 00 00 |.....#..........|
00000090 00 0d 00 1e 00 1c 04 03 05 03 06 03 08 07 08 08 |................|
000000a0 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 |................|
000000b0 06 01 00 2b 00 03 02 03 04 00 2d 00 02 01 01 00 |...+......-.....|
000000c0 33 00 26 00 24 00 1d 00 20 23 61 a3 8f f6 41 bc |3.&.$... #a...A.|
000000d0 08 52 ef 97 01 0e ba 95 f4 33 b6 8d 15 d0 ff ed |.R.......3......|
000000e0 a4 d1 84 23 3b f3 ef 3a 2d |...#;..:-|
>>> Flow 2 (server to client)
00000000 16 03 03 00 7a 02 00 00 76 03 03 00 00 00 00 00 |....z...v.......|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020 00 00 00 00 00 00 00 00 00 00 00 20 a3 63 23 52 |........... .c#R|
00000030 d8 c8 f6 79 20 04 8d 07 eb 2f 78 a3 1a 0d 58 af |...y ..../x...X.|
00000040 70 3c ef 4b 90 43 42 67 57 39 bf fa 13 02 00 00 |p<.K.CBgW9......|
00000050 2e 00 2b 00 02 03 04 00 33 00 24 00 1d 00 20 2f |..+.....3.$... /|
00000060 e5 7d a3 47 cd 62 43 15 28 da ac 5f bb 29 07 30 |.}.G.bC.(.._.).0|
00000070 ff f6 84 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 14 |.........._X.;t.|
00000080 03 03 00 01 01 17 03 03 00 17 80 72 6f c7 2d 22 |...........ro.-"|
00000090 40 51 35 22 9b 97 51 33 60 fa c1 2c d3 0f 25 6a |@Q5"..Q3`..,..%j|
000000a0 4d 17 03 03 02 6d f3 3a 89 a6 9a 1f 2b f4 1a 48 |M....m.:....+..H|
000000b0 e9 bd ef da 9d 7b f0 6c 61 ca 21 82 1b 30 6f 60 |.....{.la.!..0o`|
000000c0 01 72 24 4f ea 66 ef 3b 35 b7 ae d9 45 c9 2a 00 |.r$O.f.;5...E.*.|
000000d0 99 da 50 ae ac 8f 77 a4 e7 b4 de f6 c8 dd b8 f3 |..P...w.........|
000000e0 bc cb 7c c8 cf 2f 63 61 66 16 7f 7f 61 2c 52 c9 |..|../caf...a,R.|
000000f0 8f af 0d e2 55 d7 a4 ed 7e 12 b0 0d ec e9 a4 47 |....U...~......G|
00000100 03 e6 fa d1 6b 2f e3 22 a8 f5 c5 e6 e6 78 63 a1 |....k/.".....xc.|
00000110 b7 00 98 04 e8 fd ff 67 62 dc 89 f4 0d 97 93 4e |.......gb......N|
00000120 85 ec e0 68 f0 04 94 02 49 95 f9 08 99 30 37 d8 |...h....I....07.|
00000130 ad 31 52 1d 1d 23 09 9e 7a 97 45 d3 95 2f 03 2d |.1R..#..z.E../.-|
00000140 64 f7 5b cb 53 f5 89 ef 45 90 72 38 33 aa 62 1e |d.[.S...E.r83.b.|
00000150 b8 3e 00 b2 7f 89 0b 3a e6 17 93 ac 19 7d 09 bd |.>.....:.....}..|
00000160 ca ca 83 87 33 f9 f0 63 f3 4e 7b 47 56 0d cb b5 |....3..c.N{GV...|
00000170 90 81 88 cd 02 78 bf 96 64 c0 ba 58 b5 06 18 04 |.....x..d..X....|
00000180 d9 14 8b 92 74 81 76 b3 23 d9 ad 4c 8b 73 61 36 |....t.v.#..L.sa6|
00000190 64 d9 b6 2e 98 7e 7f d4 14 6e 4c a4 b4 71 35 5b |d....~...nL..q5[|
000001a0 4d e7 10 a8 b3 bb 40 5d 9f de 67 bb ae 0c 97 8b |M.....@]..g.....|
000001b0 25 cf cb aa 13 44 9f cb ff 2e 1c 54 ca de cb 13 |%....D.....T....|
000001c0 f9 c7 0e 49 9d d0 b3 d5 0e 29 3c 50 b9 2b 56 1f |...I.....)<P.+V.|
000001d0 5a 40 c9 73 84 34 34 28 25 8d aa cb 65 42 26 0c |Z@.s.44(%...eB&.|
000001e0 26 09 58 9c ae 9f b8 f9 10 b1 01 aa 36 c1 57 16 |&.X.........6.W.|
000001f0 0f c6 d2 8b bc 71 0e 38 f5 60 d3 24 a5 f1 2e 8c |.....q.8.`.$....|
00000200 2f 59 e7 5a 24 1b 8a 13 89 0c da dc cf bd 8a 6b |/Y.Z$..........k|
00000210 b6 75 a8 18 35 bb 2d ee c4 b8 92 09 28 a9 3d cf |.u..5.-.....(.=.|
00000220 ab 98 c1 d2 f2 94 4d 16 e6 39 73 8d 33 50 77 f6 |......M..9s.3Pw.|
00000230 10 4c 6d 94 f3 7d 0f bf c5 8b b9 d4 20 2c de 95 |.Lm..}...... ,..|
00000240 b2 2a 22 38 f2 d2 57 72 72 6d 30 7d 9b e3 dc c5 |.*"8..Wrrm0}....|
00000250 51 e9 b1 e7 7a b5 ab df fc b2 18 02 e1 57 b9 36 |Q...z........W.6|
00000260 d1 27 c0 eb 5f 64 dd fb f7 66 1d 51 72 f3 ef 12 |.'.._d...f.Qr...|
00000270 ef 36 bf e3 1b d1 e0 b5 53 65 5b 7d fd bd f4 67 |.6......Se[}...g|
00000280 53 b1 7f 72 66 84 6c 73 b7 05 60 b1 21 5b 4b fb |S..rf.ls..`.![K.|
00000290 54 cc e0 63 d4 c5 9b 7f 2a d8 09 26 3f 53 3c 97 |T..c....*..&?S<.|
000002a0 f6 9d 5f 6e a3 41 39 cf 16 52 31 b1 37 ec 9f 4e |.._n.A9..R1.7..N|
000002b0 67 55 d8 3b 0d 14 ab db 07 7d 3f e8 69 19 6b 7c |gU.;.....}?.i.k||
000002c0 4e f5 14 af 54 82 8a 4c 7a b6 d2 51 0b 73 3d 88 |N...T..Lz..Q.s=.|
000002d0 0d aa 06 ea bc ca ca c6 b8 59 ea 93 71 26 8a d8 |.........Y..q&..|
000002e0 7e 7b f6 b0 8f fc 2f e8 98 e7 b9 31 78 52 94 cf |~{..../....1xR..|
000002f0 75 02 b1 bb b5 59 e8 8b 8a e7 9b c9 4a cb 76 b7 |u....Y......J.v.|
00000300 0e e6 d0 f1 d5 8a 0e 4e f9 19 7a d4 64 a5 f7 ae |.......N..z.d...|
00000310 57 e9 e1 17 03 03 00 99 c8 6c 18 24 6c 22 19 e7 |W........l.$l"..|
00000320 89 fc 32 fa cb 52 34 43 d8 d3 ff a1 6d f8 69 63 |..2..R4C....m.ic|
00000330 fa 06 17 6c 9b 35 d9 6b 3a be 87 7e e4 da 6c e5 |...l.5.k:..~..l.|
00000340 2a c5 0c 9e e8 c6 06 d4 3f c2 7a bc 38 56 8c 31 |*.......?.z.8V.1|
00000350 17 63 e0 71 3b 1b 0c bb a1 4d 45 fe df ca 15 45 |.c.q;....ME....E|
00000360 cd 21 0d 1d f1 f7 82 e0 94 54 be 5e e4 ee 59 13 |.!.......T.^..Y.|
00000370 21 de 65 7e 47 84 26 b7 35 59 20 da 44 a9 67 e7 |!.e~G.&.5Y .D.g.|
00000380 a7 88 d2 60 e7 ba f0 eb 49 1f 52 a7 28 40 65 51 |...`....I.R.(@eQ|
00000390 7e eb 07 8c 2d a6 b2 e9 b5 2a d3 9b 7b dd bd 62 |~...-....*..{..b|
000003a0 28 a2 17 d1 cf 00 cc 32 c1 88 d7 b1 49 73 1c 32 |(......2....Is.2|
000003b0 ef 17 03 03 00 45 86 f5 39 0f af bd 4c 1e c8 43 |.....E..9...L..C|
000003c0 6e a0 55 92 a8 de 0a 5f 69 9c 9e 23 13 14 34 fb |n.U...._i..#..4.|
000003d0 93 d9 4e 8b 84 c6 a3 94 78 59 98 b7 fb 11 f4 1f |..N.....xY......|
000003e0 96 aa 2e c4 e4 94 66 4a 75 50 88 17 b7 3f cb 5c |......fJuP...?.\|
000003f0 cd c4 e1 2f 09 37 c5 d8 e0 ea c5 17 03 03 00 a3 |.../.7..........|
00000400 54 5f 79 a8 6a 07 d6 b8 35 ac cc 31 7c d8 33 5e |T_y.j...5..1|.3^|
00000410 00 11 14 b2 1f 0e 04 31 6e 89 a8 95 d8 9a f4 43 |.......1n......C|
00000420 6c 64 60 b9 3e e2 31 7b 95 cd a4 89 f6 eb a9 10 |ld`.>.1{........|
00000430 06 d6 19 09 44 c2 8f 7c ef bd ea 06 a6 8f 38 42 |....D..|......8B|
00000440 1b a1 be 12 1f 72 38 49 96 e4 74 2f 42 19 2c 55 |.....r8I..t/B.,U|
00000450 16 45 a9 e0 a8 76 6d 36 68 84 fd 0e 40 44 df 93 |.E...vm6h...@D..|
00000460 ae 12 79 78 4c ec 72 16 fe 54 c0 14 ac 47 ed 88 |..yxL.r..T...G..|
00000470 78 98 c8 cb ca 49 de fd 12 e1 96 d0 c7 89 ee 89 |x....I..........|
00000480 df d5 71 98 8a 42 7e 3e 24 5a 64 44 19 96 cc e4 |..q..B~>$ZdD....|
00000490 9c f2 8e 52 8b 1d 39 15 af c7 cd 54 d9 84 01 ef |...R..9....T....|
000004a0 fc ac 54 |..T|
>>> Flow 3 (client to server)
00000000 14 03 03 00 01 01 17 03 03 00 45 a6 fe 34 ee 91 |..........E..4..|
00000010 b0 c5 35 55 cf 70 3f d4 5d 06 76 28 c3 b5 a9 26 |..5U.p?.].v(...&|
00000020 38 18 ed bb bb bb be e7 4b 6d 61 3e 8f 65 e9 e3 |8.......Kma>.e..|
00000030 b6 4f 5d 50 46 2c 81 a8 fd 47 aa c8 c4 e8 f9 a4 |.O]PF,...G......|
00000040 e7 c7 f0 c5 fa e3 9c b7 be 09 c9 37 c1 7f 1c ff |...........7....|
>>> Flow 4 (server to client)
00000000 17 03 03 00 1e 1b 5e f2 20 7a 1c 27 36 12 e7 9a |......^. z.'6...|
00000010 05 9f fb 12 38 df 1d a0 3e 90 9a 42 4d ca 3a 54 |....8...>..BM.:T|
00000020 db 2c f0 17 03 03 00 13 b1 e4 a6 eb ad 47 ba 4c |.,...........G.L|
00000030 38 2c ee ee f9 a5 8a 41 2f ce 3d |8,.....A/.=|
This diff is collapsed.
>>> Flow 1 (client to server)
00000000 16 03 01 01 a4 01 00 01 a0 03 03 92 e8 fa 14 82 |................|
00000010 03 7c cd fe 01 82 55 99 8b fd 04 ff 88 82 98 c9 |.|....U.........|
00000020 72 18 3b 2e 0a de fc a4 44 9f 1d 20 c0 df df c9 |r.;.....D.. ....|
00000030 1d ed 19 9e 2d ce 57 f6 95 54 67 76 77 64 c7 f4 |....-.W..Tgvwd..|
00000040 ad 18 7d d8 58 6f 08 30 a5 a4 50 cd 00 08 13 02 |..}.Xo.0..P.....|
00000050 13 03 13 01 00 ff 01 00 01 4f 00 00 00 0e 00 0c |.........O......|
00000060 00 00 09 31 32 37 2e 30 2e 30 2e 31 00 0b 00 04 |...127.0.0.1....|
00000070 03 00 01 02 00 0a 00 0c 00 0a 00 1d 00 17 00 1e |................|
00000080 00 19 00 18 00 23 00 00 00 16 00 00 00 17 00 00 |.....#..........|
00000090 00 0d 00 1e 00 1c 04 03 05 03 06 03 08 07 08 08 |................|
000000a0 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 |................|
000000b0 06 01 00 2b 00 03 02 03 04 00 2d 00 02 01 01 00 |...+......-.....|
000000c0 33 00 26 00 24 00 1d 00 20 94 44 cd ce 27 a8 43 |3.&.$... .D..'.C|
000000d0 8a ef cd ef d4 74 d4 e4 62 82 00 e6 46 96 e5 aa |.....t..b...F...|
000000e0 d1 44 8a 55 6b d7 25 06 6f 00 29 00 bc 00 87 00 |.D.Uk.%.o.).....|
000000f0 81 50 46 ad c1 db a8 38 86 7b 2b bb fd d0 c3 42 |.PF....8.{+....B|
00000100 3e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |>...............|
00000110 00 94 68 2c a3 81 51 ed 14 ef 68 ca 42 c5 4c 1f |..h,..Q...h.B.L.|
00000120 90 bf 3c 07 2b e5 52 22 a0 c0 46 db cb f6 b9 a0 |..<.+.R"..F.....|
00000130 b5 56 b0 d6 7f 03 b7 2d 9f a5 2a 25 8e 65 d2 b9 |.V.....-..*%.e..|
00000140 6a f3 e4 7e 79 d7 3d cc b2 3d b6 24 a9 31 82 49 |j..~y.=..=.$.1.I|
00000150 38 16 92 f0 49 97 e2 07 e2 cd 1c 77 d3 e0 00 de |8...I......w....|
00000160 56 11 17 40 00 63 13 00 48 39 8e fd 09 96 08 f3 |V..@.c..H9......|
00000170 81 7c 00 00 00 00 00 31 30 a4 22 35 6e 4a 09 af |.|.....10."5nJ..|
00000180 08 22 97 92 e0 8a eb c0 e0 28 32 f4 8f ed 1e 02 |.".......(2.....|
00000190 a9 b3 43 de f3 04 cb 7b db 01 51 88 46 02 c1 4b |..C....{..Q.F..K|
000001a0 ec fa a8 05 42 a4 00 ae ed |....B....|
>>> Flow 2 (server to client)
00000000 16 03 03 00 80 02 00 00 7c 03 03 00 00 00 00 00 |........|.......|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020 00 00 00 00 00 00 00 00 00 00 00 20 c0 df df c9 |........... ....|
00000030 1d ed 19 9e 2d ce 57 f6 95 54 67 76 77 64 c7 f4 |....-.W..Tgvwd..|
00000040 ad 18 7d d8 58 6f 08 30 a5 a4 50 cd 13 02 00 00 |..}.Xo.0..P.....|
00000050 34 00 2b 00 02 03 04 00 33 00 24 00 1d 00 20 2f |4.+.....3.$... /|
00000060 e5 7d a3 47 cd 62 43 15 28 da ac 5f bb 29 07 30 |.}.G.bC.(.._.).0|
00000070 ff f6 84 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 00 |.........._X.;t.|
00000080 29 00 02 00 00 14 03 03 00 01 01 17 03 03 00 17 |)...............|
00000090 cc 35 3b 89 bc fe dc df 02 d3 00 f8 ef 56 74 6a |.5;..........Vtj|
000000a0 ee af 35 9e d6 91 e1 17 03 03 00 45 07 24 33 da |..5........E.$3.|
000000b0 63 9a eb 15 28 dc e8 60 dc 36 97 12 5e 54 a5 48 |c...(..`.6..^T.H|
000000c0 aa e3 07 35 e7 f0 7c 60 93 d4 4c 24 d7 0d 01 66 |...5..|`..L$...f|
000000d0 d9 b6 e3 c5 ab 9d cf 47 49 f6 4f 87 7a c4 ab 34 |.......GI.O.z..4|
000000e0 df 37 19 a6 f9 36 c8 ea 04 af 9a d7 21 dd 89 e2 |.7...6......!...|
000000f0 79 17 03 03 00 a3 60 8e 39 7e 5d 21 e2 e4 8a 0e |y.....`.9~]!....|
00000100 73 4a 96 09 49 fb 55 b4 68 60 88 0d 01 73 5b d0 |sJ..I.U.h`...s[.|
00000110 42 4d 9a af 22 ae 33 83 16 60 3e 25 e2 fd 76 10 |BM..".3..`>%..v.|
00000120 6e 92 0d 6b 88 c7 54 46 51 bf 86 a4 f4 11 d3 e8 |n..k..TFQ.......|
00000130 29 54 16 31 b2 44 4b 45 5d 3f 97 d9 33 10 ef 92 |)T.1.DKE]?..3...|
00000140 e5 aa 3b 2d 3d 36 ef 85 04 2d 17 66 2a 00 ea 87 |..;-=6...-.f*...|
00000150 9a 95 5e 54 1b 01 f8 5d 34 96 83 cf 28 d4 24 ed |..^T...]4...(.$.|
00000160 c6 9b da 7a 1c d4 a3 5a 53 bb 2f cf 56 f3 ef 99 |...z...ZS./.V...|
00000170 40 e2 34 31 ca 55 c9 7a 02 47 14 8b 7e 04 5a ff |@.41.U.z.G..~.Z.|
00000180 17 f7 95 f0 46 e0 ce cf 8f b0 9f 6b 51 96 d5 f7 |....F......kQ...|
00000190 0b 33 e2 0a 62 4e 05 28 66 |.3..bN.(f|
>>> Flow 3 (client to server)
00000000 14 03 03 00 01 01 17 03 03 00 45 66 00 e2 3f 07 |..........Ef..?.|
00000010 02 a4 1d 71 27 2a fe c7 00 1e 2d bc 50 b6 bc 35 |...q'*....-.P..5|
00000020 22 c4 a4 d8 a1 5f fa 10 d7 48 c8 20 94 50 b1 ae |"...._...H. .P..|
00000030 47 8c 62 26 15 79 33 6b 06 0d 19 67 7e 22 7c a5 |G.b&.y3k...g~"|.|
00000040 ca 05 c9 ae c8 66 6b ca 8e f7 7c 35 de 5e c3 25 |.....fk...|5.^.%|
>>> Flow 4 (server to client)
00000000 17 03 03 00 1e 6a 89 ce e3 1d 13 60 f3 8b 26 97 |.....j.....`..&.|
00000010 3e 5d 9f a8 47 c9 74 f5 66 ad 75 87 57 ec ef b1 |>]..G.t.f.u.W...|
00000020 66 da f0 17 03 03 00 13 95 bd 2d ef d5 30 c1 1b |f.........-..0..|
00000030 bd 54 3d f6 16 02 28 78 a4 4a 24 |.T=...(x.J$|
>>> Flow 1 (client to server)
00000000 16 03 01 01 9e 01 00 01 9a 03 03 75 28 78 ec 6f |...........u(x.o|
00000010 3d d0 60 09 8e 23 dd 91 67 4b e4 2f b0 b7 93 60 |=.`..#..gK./...`|
00000020 3a 4f 92 38 6b 5e 67 ab 49 f4 b8 20 46 e8 0a c4 |:O.8k^g.I.. F...|
00000030 bd 13 ce 09 13 27 a4 5d a4 3b e2 9b 9d ff 17 30 |.....'.].;.....0|
00000040 96 e3 06 1a d6 c6 04 9c f3 9a 15 76 00 08 13 02 |...........v....|
00000050 13 03 13 01 00 ff 01 00 01 49 00 00 00 0e 00 0c |.........I......|
00000060 00 00 09 31 32 37 2e 30 2e 30 2e 31 00 0b 00 04 |...127.0.0.1....|
00000070 03 00 01 02 00 0a 00 06 00 04 00 1d 00 17 00 23 |...............#|
00000080 00 00 00 16 00 00 00 17 00 00 00 0d 00 1e 00 1c |................|
00000090 04 03 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b |................|
000000a0 08 04 08 05 08 06 04 01 05 01 06 01 00 2b 00 03 |.............+..|
000000b0 02 03 04 00 2d 00 02 01 01 00 33 00 26 00 24 00 |....-.....3.&.$.|
000000c0 1d 00 20 a0 26 2f f2 a2 ca d0 ff 0d 5d 9e cc 84 |.. .&/......]...|
000000d0 52 51 07 86 4c 28 44 4e 65 7e 0c a1 9d 50 9c 77 |RQ..L(DNe~...P.w|
000000e0 8a 54 48 00 29 00 bc 00 87 00 81 50 46 ad c1 db |.TH.)......PF...|
000000f0 a8 38 86 7b 2b bb fd d0 c3 42 3e 00 00 00 00 00 |.8.{+....B>.....|
00000100 00 00 00 00 00 00 00 00 00 00 00 94 68 2c a3 81 |............h,..|
00000110 51 ed 14 ef 68 ca 42 c5 4c 1f 90 bf 3c 07 2b e5 |Q...h.B.L...<.+.|
00000120 52 22 a0 c0 46 db cb f6 b9 a0 b5 56 b0 d6 7f 03 |R"..F......V....|
00000130 b7 2d 9f a5 2a 25 8e 65 d2 b9 6a f3 e4 7e 79 d7 |.-..*%.e..j..~y.|
00000140 3d cc b2 3d b6 24 a9 31 82 49 38 16 92 f0 49 97 |=..=.$.1.I8...I.|
00000150 e2 07 e2 cd 1c 77 d3 e0 00 de 56 11 17 40 00 63 |.....w....V..@.c|
00000160 13 00 48 39 8e fd 09 96 08 f3 81 7c 00 00 00 00 |..H9.......|....|
00000170 00 31 30 da 3c 92 3d 0f 55 c9 9e bb 99 c6 e0 ac |.10.<.=.U.......|
00000180 fe 5a 3a 94 7e d6 2a 0a 81 c0 be 8a 4e 1d da 5e |.Z:.~.*.....N..^|
00000190 31 80 97 2d 2a 6a fc 96 03 d2 aa 07 45 f1 78 33 |1..-*j......E.x3|
000001a0 c4 1d 1c |...|
>>> Flow 2 (server to client)
00000000 16 03 03 00 58 02 00 00 54 03 03 cf 21 ad 74 e5 |....X...T...!.t.|
00000010 9a 61 11 be 1d 8c 02 1e 65 b8 91 c2 a2 11 16 7a |.a......e......z|
00000020 bb 8c 5e 07 9e 09 e2 c8 a8 33 9c 20 46 e8 0a c4 |..^......3. F...|
00000030 bd 13 ce 09 13 27 a4 5d a4 3b e2 9b 9d ff 17 30 |.....'.].;.....0|
00000040 96 e3 06 1a d6 c6 04 9c f3 9a 15 76 13 02 00 00 |...........v....|
00000050 0c 00 2b 00 02 03 04 00 33 00 02 00 17 14 03 03 |..+.....3.......|
00000060 00 01 01 |...|
>>> Flow 3 (client to server)
00000000 14 03 03 00 01 01 16 03 03 01 bf 01 00 01 bb 03 |................|
00000010 03 75 28 78 ec 6f 3d d0 60 09 8e 23 dd 91 67 4b |.u(x.o=.`..#..gK|
00000020 e4 2f b0 b7 93 60 3a 4f 92 38 6b 5e 67 ab 49 f4 |./...`:O.8k^g.I.|
00000030 b8 20 46 e8 0a c4 bd 13 ce 09 13 27 a4 5d a4 3b |. F........'.].;|
00000040 e2 9b 9d ff 17 30 96 e3 06 1a d6 c6 04 9c f3 9a |.....0..........|
00000050 15 76 00 08 13 02 13 03 13 01 00 ff 01 00 01 6a |.v.............j|
00000060 00 00 00 0e 00 0c 00 00 09 31 32 37 2e 30 2e 30 |.........127.0.0|
00000070 2e 31 00 0b 00 04 03 00 01 02 00 0a 00 06 00 04 |.1..............|
00000080 00 1d 00 17 00 23 00 00 00 16 00 00 00 17 00 00 |.....#..........|
00000090 00 0d 00 1e 00 1c 04 03 05 03 06 03 08 07 08 08 |................|
000000a0 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 |................|
000000b0 06 01 00 2b 00 03 02 03 04 00 2d 00 02 01 01 00 |...+......-.....|
000000c0 33 00 47 00 45 00 17 00 41 04 79 db 79 c8 0b 77 |3.G.E...A.y.y..w|
000000d0 8b 37 30 65 85 ce 72 49 ab a1 cb 6a 06 00 a6 65 |.70e..rI...j...e|
000000e0 22 51 63 63 16 45 7b 85 ee c3 2e 09 25 d9 a3 49 |"Qcc.E{.....%..I|
000000f0 91 07 35 c4 b6 61 23 9c 91 c1 03 07 ad a2 77 02 |..5..a#.......w.|
00000100 61 93 05 cf 74 36 7a 66 ad 24 00 29 00 bc 00 87 |a...t6zf.$.)....|
00000110 00 81 50 46 ad c1 db a8 38 86 7b 2b bb fd d0 c3 |..PF....8.{+....|
00000120 42 3e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |B>..............|
00000130 00 00 94 68 2c a3 81 51 ed 14 ef 68 ca 42 c5 4c |...h,..Q...h.B.L|
00000140 1f 90 bf 3c 07 2b e5 52 22 a0 c0 46 db cb f6 b9 |...<.+.R"..F....|
00000150 a0 b5 56 b0 d6 7f 03 b7 2d 9f a5 2a 25 8e 65 d2 |..V.....-..*%.e.|
00000160 b9 6a f3 e4 7e 79 d7 3d cc b2 3d b6 24 a9 31 82 |.j..~y.=..=.$.1.|
00000170 49 38 16 92 f0 49 97 e2 07 e2 cd 1c 77 d3 e0 00 |I8...I......w...|
00000180 de 56 11 17 40 00 63 13 00 48 39 8e fd 09 96 08 |.V..@.c..H9.....|
00000190 f3 81 7c 00 00 00 00 00 31 30 e0 ac 7a 74 d9 50 |..|.....10..zt.P|
000001a0 c1 3b 1b 67 7b 5a 74 b0 39 db dd 92 6f 75 38 31 |.;.g{Zt.9...ou81|
000001b0 10 f4 98 dc ad af eb ac ef 11 0d 96 48 01 f8 10 |............H...|
000001c0 d6 e1 68 bf 88 a3 33 b9 9a b9 |..h...3...|
>>> Flow 4 (server to client)
00000000 16 03 03 00 a1 02 00 00 9d 03 03 00 00 00 00 00 |................|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020 00 00 00 00 00 00 00 00 00 00 00 20 46 e8 0a c4 |........... F...|
00000030 bd 13 ce 09 13 27 a4 5d a4 3b e2 9b 9d ff 17 30 |.....'.].;.....0|
00000040 96 e3 06 1a d6 c6 04 9c f3 9a 15 76 13 02 00 00 |...........v....|
00000050 55 00 2b 00 02 03 04 00 33 00 45 00 17 00 41 04 |U.+.....3.E...A.|
00000060 1e 18 37 ef 0d 19 51 88 35 75 71 b5 e5 54 5b 12 |..7...Q.5uq..T[.|
00000070 2e 8f 09 67 fd a7 24 20 3e b2 56 1c ce 97 28 5e |...g..$ >.V...(^|
00000080 f8 2b 2d 4f 9e f1 07 9f 6c 4b 5b 83 56 e2 32 42 |.+-O....lK[.V.2B|
00000090 e9 58 b6 d7 49 a6 b5 68 1a 41 03 56 6b dc 5a 89 |.X..I..h.A.Vk.Z.|
000000a0 00 29 00 02 00 00 17 03 03 00 17 48 f2 b1 a7 11 |.).........H....|
000000b0 68 36 e4 67 b8 e8 d0 6d b8 76 fa 4b 7e bc d0 63 |h6.g...m.v.K~..c|
000000c0 6a 8c 17 03 03 00 45 49 37 80 89 e3 4d b5 60 4a |j.....EI7...M.`J|
000000d0 7c 52 a0 f5 e9 32 85 ad 8a 59 0b 27 66 c7 2f ec ||R...2...Y.'f./.|
000000e0 55 7f 2c 9b 1e ef 0a 11 e1 72 1f 72 b2 10 9f 3f |U.,......r.r...?|
000000f0 bb 51 8f d0 fe e8 62 fd 93 e4 0d e1 57 7f 3a 3c |.Q....b.....W.:<|
00000100 22 b4 ca 20 04 cd 65 94 44 df 1a 1c 17 03 03 00 |".. ..e.D.......|
00000110 a3 38 02 96 5e c2 6d ad 2d 17 79 63 15 bd 06 af |.8..^.m.-.yc....|
00000120 e3 ae 5a 94 66 b5 2d 12 d1 bc 9c 16 56 ac 71 fe |..Z.f.-.....V.q.|
00000130 d7 af 1f 27 9a 22 1a d2 de da 90 ca d5 7f 79 d1 |...'."........y.|
00000140 8a 6e c6 76 e7 76 b4 cc 9b d5 b5 ed b5 b2 9d 4e |.n.v.v.........N|
00000150 f8 88 a0 b1 14 91 8b 6b d9 b8 5d 34 61 8a a3 b3 |.......k..]4a...|
00000160 c8 db e9 c9 8d a7 53 d8 46 f0 bd 4b 30 bf 49 3d |......S.F..K0.I=|
00000170 cc 42 d3 fb b7 f3 ad 78 5b 01 38 5d c3 22 d0 51 |.B.....x[.8].".Q|
00000180 cb a3 d9 fe 61 f9 4a ee 7d 89 8b 88 22 2b 9b fe |....a.J.}..."+..|
00000190 19 cd 17 b7 9e 81 57 f6 cb 14 29 cb 3b 87 0e 83 |......W...).;...|
000001a0 5a 84 7c 13 2d c8 d4 a7 6a db 1d 10 c6 04 ed 0d |Z.|.-...j.......|
000001b0 1d d7 06 bb |....|
>>> Flow 5 (client to server)
00000000 17 03 03 00 45 44 0b 11 40 bf 4b b4 2b 12 76 b3 |....ED..@.K.+.v.|
00000010 e4 59 b3 91 bb 45 21 b3 78 aa dc 76 66 dd d6 3c |.Y...E!.x..vf..<|
00000020 21 cf 32 5c 37 85 ef fb c7 53 cb 55 9c a5 40 0a |!.2\7....S.U..@.|
00000030 9d f8 aa b4 e3 e4 51 bf d8 cb 15 44 f0 02 19 52 |......Q....D...R|
00000040 62 73 82 f2 c2 ae d2 03 0e dc |bs........|
>>> Flow 6 (server to client)
00000000 17 03 03 00 1e fe e8 25 be 32 b9 ce db 3d 36 54 |.......%.2...=6T|
00000010 78 7c 70 50 0e 8e f4 04 ec a9 2e 88 7b e5 23 23 |x|pP........{.##|
00000020 72 f4 04 17 03 03 00 13 cc 7c 8e 1b 85 30 16 57 |r........|...0.W|
00000030 b0 39 6a 3a b3 ee 57 82 17 03 c9 |.9j:..W....|
>>> Flow 1 (client to server)
00000000 16 03 01 01 a4 01 00 01 a0 03 03 96 06 be 39 9a |..............9.|
00000010 6b 71 35 ab f4 2a d2 66 4d 8f 2c 86 c9 b6 7b e1 |kq5..*.fM.,...{.|
00000020 85 55 81 f5 90 49 20 c9 d7 5d ea 20 a2 da 4f 31 |.U...I ..]. ..O1|
00000030 a6 7a bd 07 5d 24 2e 88 1c 88 0e 19 1e 33 51 51 |.z..]$.......3QQ|
00000040 a1 14 df d7 70 b5 62 6d 28 a8 5f 0e 00 08 13 02 |....p.bm(._.....|
00000050 13 03 13 01 00 ff 01 00 01 4f 00 00 00 0e 00 0c |.........O......|
00000060 00 00 09 31 32 37 2e 30 2e 30 2e 31 00 0b 00 04 |...127.0.0.1....|
00000070 03 00 01 02 00 0a 00 0c 00 0a 00 1d 00 17 00 1e |................|
00000080 00 19 00 18 00 23 00 00 00 16 00 00 00 17 00 00 |.....#..........|
00000090 00 0d 00 1e 00 1c 04 03 05 03 06 03 08 07 08 08 |................|
000000a0 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 |................|
000000b0 06 01 00 2b 00 03 02 03 04 00 2d 00 02 01 01 00 |...+......-.....|
000000c0 33 00 26 00 24 00 1d 00 20 6d b7 14 7e 1b 7e c5 |3.&.$... m..~.~.|
000000d0 2b 54 1e 88 bd 64 23 49 84 31 73 f0 b8 55 6c 23 |+T...d#I.1s..Ul#|
000000e0 9e 77 b9 c5 53 a5 7f 1d 15 00 29 00 bc 00 87 00 |.w..S.....).....|
000000f0 81 50 46 ad c1 db a8 38 86 7b 2b bb fd d0 c3 42 |.PF....8.{+....B|
00000100 3e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |>...............|
00000110 00 94 68 2c a3 81 51 ed 14 ef 68 ca 42 c5 4c e2 |..h,..Q...h.B.L.|
00000120 e9 ab 5a 10 63 08 88 5d 47 1a 77 c1 7c 72 14 12 |..Z.c..]G.w.|r..|
00000130 24 5f 79 c4 ce 1a 7c 08 bf 81 6d 0e 55 e6 2d 0d |$_y...|...m.U.-.|
00000140 00 68 79 bc 2d ea f4 19 fd 43 ef 51 3f b5 5f 49 |.hy.-....C.Q?._I|
00000150 38 16 e0 74 43 a4 e9 95 f6 6d eb bf 6d e2 57 79 |8..tC....m..m.Wy|
00000160 7a 6e 53 12 bd a2 e0 32 98 1d 4e cb ae 72 1f 4c |znS....2..N..r.L|
00000170 38 4c 00 00 00 00 00 31 30 b6 c5 6e 26 02 64 56 |8L.....10..n&.dV|
00000180 65 ab 95 9c 16 62 d0 c5 57 41 c7 4c 78 72 44 c7 |e....b..WA.LxrD.|
00000190 4f a4 dc e1 d3 ef 49 af 7d a1 e5 ce 6f 22 f9 ec |O.....I.}...o"..|
000001a0 f4 b3 e4 32 e3 99 b0 85 39 |...2....9|
>>> Flow 2 (server to client)
00000000 16 03 03 00 7a 02 00 00 76 03 03 00 00 00 00 00 |....z...v.......|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020 00 00 00 00 00 00 00 00 00 00 00 20 a2 da 4f 31 |........... ..O1|
00000030 a6 7a bd 07 5d 24 2e 88 1c 88 0e 19 1e 33 51 51 |.z..]$.......3QQ|
00000040 a1 14 df d7 70 b5 62 6d 28 a8 5f 0e 13 02 00 00 |....p.bm(._.....|
00000050 2e 00 2b 00 02 03 04 00 33 00 24 00 1d 00 20 2f |..+.....3.$... /|
00000060 e5 7d a3 47 cd 62 43 15 28 da ac 5f bb 29 07 30 |.}.G.bC.(.._.).0|
00000070 ff f6 84 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 14 |.........._X.;t.|
00000080 03 03 00 01 01 17 03 03 00 17 5a 35 3d 19 9b a7 |..........Z5=...|
00000090 a4 45 2c c3 09 ae 85 be 08 fe 1d e2 9a 5d 7a 4b |.E,..........]zK|
000000a0 8e 17 03 03 02 6d 87 db fb 18 21 96 c7 2b fb ff |.....m....!..+..|
000000b0 89 b9 25 f6 0d 89 0f b4 17 bb 17 e1 ba 95 b7 cd |..%.............|
000000c0 c2 75 b5 8b d8 64 ff 7c dc e2 97 32 0c 2f e0 9f |.u...d.|...2./..|
000000d0 db b9 ef 14 9d cc e4 68 44 f7 0a 55 d2 b1 a0 f7 |.......hD..U....|
000000e0 fc de a5 99 f0 5d 0c 60 7b c3 25 85 f6 79 8f e6 |.....].`{.%..y..|
000000f0 cd 43 1c 43 d9 cd 28 ea ce 10 1c 16 68 b8 d7 3d |.C.C..(.....h..=|
00000100 b4 d4 db b4 bf 76 f8 45 23 d8 9f d1 be d1 bd db |.....v.E#.......|
00000110 9c 45 dd 28 3b 68 22 57 6c b7 65 fc 5e 66 f6 cb |.E.(;h"Wl.e.^f..|
00000120 a2 88 bd 96 e4 00 b5 85 ae 00 95 b9 da 42 16 c9 |.............B..|
00000130 c9 63 c2 67 ec 22 65 6e 66 0e cf de 68 ad e7 87 |.c.g."enf...h...|
00000140 ae 63 b4 e9 1c c0 2f 1e 79 7e a3 3f 6d 2b 68 c1 |.c..../.y~.?m+h.|
00000150 e8 60 cd 26 e0 05 de fa 7b 77 45 71 d8 f9 03 d7 |.`.&....{wEq....|
00000160 d3 50 51 15 cf fc 39 fa 07 19 28 5e e8 2d 31 00 |.PQ...9...(^.-1.|
00000170 2a e1 a4 21 31 83 4e 7d 51 e7 53 eb 33 22 51 fe |*..!1.N}Q.S.3"Q.|
00000180 15 04 e9 3d 73 89 3b 56 3f c6 ec 6e 0a 71 68 a6 |...=s.;V?..n.qh.|
00000190 76 f3 f1 aa 4e d0 9f 85 45 3f 7b aa ae ad 42 b9 |v...N...E?{...B.|
000001a0 07 64 ab ad 03 b1 33 78 93 f0 49 95 65 fb 81 8c |.d....3x..I.e...|
000001b0 04 ee e7 f3 2c 0a 99 51 e5 ef 05 14 d3 93 37 2b |....,..Q......7+|
000001c0 73 96 81 6f f5 9b a3 9a 20 95 5c 13 fc 97 3e c0 |s..o.... .\...>.|
000001d0 87 e4 ec 00 84 0b f2 09 29 63 dd 54 03 ce e0 43 |........)c.T...C|
000001e0 e9 16 a0 98 32 3e fa 58 1d 81 1e 56 ef 64 ff f7 |....2>.X...V.d..|
000001f0 b0 aa fc 5f 8c 89 48 76 ef d2 f1 d0 9c 16 f9 57 |..._..Hv.......W|
00000200 ac a6 4a a4 a8 75 ae fc 4b 9f ef 3c 28 a5 0c c1 |..J..u..K..<(...|
00000210 c8 72 82 bf e9 93 f2 42 00 0a 49 5d be c7 09 91 |.r.....B..I]....|
00000220 29 40 5e a6 ad ae 9c 69 6f d8 33 53 0a 50 5b 48 |)@^....io.3S.P[H|
00000230 7d d7 7e 1e 3b d3 ec e6 cf fe 1e 6a 27 a2 83 35 |}.~.;......j'..5|
00000240 28 13 2f 00 e5 29 c3 10 46 53 a1 17 15 59 5d 74 |(./..)..FS...Y]t|
00000250 f5 7c fa a5 71 34 32 75 48 e6 2c 1d 90 e8 c1 87 |.|..q42uH.,.....|
00000260 50 ac 17 27 b8 f7 a9 8e 59 58 d6 b8 d9 ef b6 57 |P..'....YX.....W|
00000270 b8 13 41 d0 eb 80 1c 48 66 1d 41 a5 b5 0d 12 17 |..A....Hf.A.....|
00000280 52 96 62 29 0e 4a 09 b4 50 b8 37 c3 8f 85 67 27 |R.b).J..P.7...g'|
00000290 d9 6f 33 11 95 ca 0a 36 75 ef 15 45 81 d3 ad 7d |.o3....6u..E...}|
000002a0 1a ff a7 0c 47 21 37 24 27 ce 42 68 5f 5d 7c fe |....G!7$'.Bh_]|.|
000002b0 0c f2 0b 81 ea f9 25 c9 99 c2 56 72 54 bd 2f 4c |......%...VrT./L|
000002c0 40 17 f0 54 a0 6e 1d 14 80 9c 3c d3 f9 81 0d 9d |@..T.n....<.....|
000002d0 e1 47 55 24 e4 62 0e 14 0d 46 3f 52 1b ef ab 45 |.GU$.b...F?R...E|
000002e0 d8 86 c7 ef aa e2 ea e6 5e 2e d8 89 33 46 a0 d0 |........^...3F..|
000002f0 39 e2 cc 13 1d 62 11 ae c0 73 71 b8 ef 4b 43 71 |9....b...sq..KCq|
00000300 dd 14 42 09 c9 10 4e bc b9 93 78 d6 83 02 40 c0 |..B...N...x...@.|
00000310 62 56 40 17 03 03 00 99 6e 03 4b 38 20 98 d7 3e |bV@.....n.K8 ..>|
00000320 52 33 e0 be 26 9b 38 4c 7f 2b c1 cc 84 22 7e 86 |R3..&.8L.+..."~.|
00000330 1d 39 f6 0a c0 ff e9 d9 4d 81 24 26 8d e1 c5 c0 |.9......M.$&....|
00000340 78 18 59 e0 6a ac 35 ad a0 6d 32 09 63 75 88 10 |x.Y.j.5..m2.cu..|
00000350 2b 6b d1 36 ea f9 03 41 a9 a7 26 82 38 37 aa 81 |+k.6...A..&.87..|
00000360 a1 7a 81 5c 0b db 63 32 06 e7 cb a8 1c 0a ff be |.z.\..c2........|
00000370 a2 e5 00 42 59 61 78 40 2e e2 85 0a ad 6b ea ae |...BYax@.....k..|
00000380 17 5a 92 f6 d3 8e 97 a2 18 a5 28 8a 41 1d 70 26 |.Z........(.A.p&|
00000390 bc d8 e7 38 ba c5 68 b9 ae f9 c6 27 bc 5b 3b 9f |...8..h....'.[;.|
000003a0 db ae 38 84 6f 18 3c e6 1d 30 cb 57 b1 95 63 1d |..8.o.<..0.W..c.|
000003b0 ef 17 03 03 00 45 40 43 00 0c 81 0a ed cf 35 9d |.....E@C......5.|
000003c0 45 0f 2b 66 ad b6 bd f9 72 9f 77 aa 87 9a 4f 9a |E.+f....r.w...O.|
000003d0 f4 1b 08 bd 33 aa f7 dc f1 78 58 d7 53 aa 82 12 |....3....xX.S...|
000003e0 b1 f7 c2 dd 8b 0d 90 81 e9 a9 7b 7c 17 52 fe ab |..........{|.R..|
000003f0 e4 94 06 d4 44 b4 7d 81 61 97 6b |....D.}.a.k|
>>> Flow 3 (client to server)
00000000 14 03 03 00 01 01 17 03 03 00 45 0e e9 bb 83 d4 |..........E.....|
00000010 41 da c6 75 69 c2 5c 74 0c 86 c7 b9 08 2f 35 da |A..ui.\t...../5.|
00000020 19 6f cf 43 a4 23 2f fe 59 5d 0f 1f 1e 0f ca e4 |.o.C.#/.Y]......|
00000030 7f 4e 7d bc ce 77 76 f2 ce 1c c4 e8 4e a9 80 a8 |.N}..wv.....N...|
00000040 72 16 5b 3c 97 8f 55 cb 76 cf fa 02 29 41 af 6d |r.[<..U.v...)A.m|
>>> Flow 4 (server to client)
00000000 17 03 03 00 1e f2 5e b6 bd bc c3 c2 58 fe 90 e9 |......^.....X...|
00000010 07 07 a2 ab 66 41 f7 c4 1f 48 48 01 c9 38 d2 c7 |....fA...HH..8..|
00000020 c0 ab b5 17 03 03 00 13 db 6e 0e f9 4a 94 12 a3 |.........n..J...|
00000030 2a 86 3f d1 a7 ac c3 58 20 0d 09 |*.?....X ..|
......@@ -12,6 +12,7 @@ import (
"crypto/sha256"
"crypto/subtle"
"errors"
"golang_org/x/crypto/cryptobyte"
"io"
)
......@@ -104,9 +105,50 @@ func (s *sessionState) unmarshal(data []byte) bool {
return len(data) == 0
}
func (c *Conn) encryptTicket(state *sessionState) ([]byte, error) {
serialized := state.marshal()
encrypted := make([]byte, ticketKeyNameLen+aes.BlockSize+len(serialized)+sha256.Size)
// sessionStateTLS13 is the content of a TLS 1.3 session ticket. Its first
// version (revision = 0) doesn't carry any of the information needed for 0-RTT
// validation and the nonce is always empty.
type sessionStateTLS13 struct {
// uint8 version = 0x0304;
// uint8 revision = 0;
cipherSuite uint16
createdAt uint64
resumptionSecret []byte // opaque resumption_master_secret<1..2^8-1>;
certificate Certificate // CertificateEntry certificate_list<0..2^24-1>;
}
func (m *sessionStateTLS13) marshal() []byte {
var b cryptobyte.Builder
b.AddUint16(VersionTLS13)
b.AddUint8(0) // revision
b.AddUint16(m.cipherSuite)
addUint64(&b, m.createdAt)
b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
b.AddBytes(m.resumptionSecret)
})
marshalCertificate(&b, m.certificate)
return b.BytesOrPanic()
}
func (m *sessionStateTLS13) unmarshal(data []byte) bool {
*m = sessionStateTLS13{}
s := cryptobyte.String(data)
var version uint16
var revision uint8
return s.ReadUint16(&version) &&
version == VersionTLS13 &&
s.ReadUint8(&revision) &&
revision == 0 &&
s.ReadUint16(&m.cipherSuite) &&
readUint64(&s, &m.createdAt) &&
readUint8LengthPrefixed(&s, &m.resumptionSecret) &&
len(m.resumptionSecret) != 0 &&
unmarshalCertificate(&s, &m.certificate) &&
s.Empty()
}
func (c *Conn) encryptTicket(state []byte) ([]byte, error) {
encrypted := make([]byte, ticketKeyNameLen+aes.BlockSize+len(state)+sha256.Size)
keyName := encrypted[:ticketKeyNameLen]
iv := encrypted[ticketKeyNameLen : ticketKeyNameLen+aes.BlockSize]
macBytes := encrypted[len(encrypted)-sha256.Size:]
......@@ -120,7 +162,7 @@ func (c *Conn) encryptTicket(state *sessionState) ([]byte, error) {
if err != nil {
return nil, errors.New("tls: failed to create cipher while encrypting ticket: " + err.Error())
}
cipher.NewCTR(block, iv).XORKeyStream(encrypted[ticketKeyNameLen+aes.BlockSize:], serialized)
cipher.NewCTR(block, iv).XORKeyStream(encrypted[ticketKeyNameLen+aes.BlockSize:], state)
mac := hmac.New(sha256.New, key.hmacKey[:])
mac.Write(encrypted[:len(encrypted)-sha256.Size])
......@@ -129,15 +171,15 @@ func (c *Conn) encryptTicket(state *sessionState) ([]byte, error) {
return encrypted, nil
}
func (c *Conn) decryptTicket(encrypted []byte) (*sessionState, bool) {
if c.config.SessionTicketsDisabled ||
len(encrypted) < ticketKeyNameLen+aes.BlockSize+sha256.Size {
func (c *Conn) decryptTicket(encrypted []byte) (plaintext []byte, usedOldKey bool) {
if len(encrypted) < ticketKeyNameLen+aes.BlockSize+sha256.Size {
return nil, false
}
keyName := encrypted[:ticketKeyNameLen]
iv := encrypted[ticketKeyNameLen : ticketKeyNameLen+aes.BlockSize]
macBytes := encrypted[len(encrypted)-sha256.Size:]
ciphertext := encrypted[ticketKeyNameLen+aes.BlockSize : len(encrypted)-sha256.Size]
keys := c.config.ticketKeys()
keyIndex := -1
......@@ -165,11 +207,8 @@ func (c *Conn) decryptTicket(encrypted []byte) (*sessionState, bool) {
if err != nil {
return nil, false
}
ciphertext := encrypted[ticketKeyNameLen+aes.BlockSize : len(encrypted)-sha256.Size]
plaintext := ciphertext
plaintext = make([]byte, len(ciphertext))
cipher.NewCTR(block, iv).XORKeyStream(plaintext, ciphertext)
state := &sessionState{usedOldKey: keyIndex > 0}
ok := state.unmarshal(plaintext)
return state, ok
return plaintext, keyIndex > 0
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment