summaryrefslogtreecommitdiffstats
path: root/src/crypto/tls
diff options
context:
space:
mode:
Diffstat (limited to 'src/crypto/tls')
-rw-r--r--src/crypto/tls/alert.go109
-rw-r--r--src/crypto/tls/auth.go293
-rw-r--r--src/crypto/tls/auth_test.go168
-rw-r--r--src/crypto/tls/boring.go98
-rw-r--r--src/crypto/tls/boring_test.go617
-rw-r--r--src/crypto/tls/cache.go95
-rw-r--r--src/crypto/tls/cache_test.go117
-rw-r--r--src/crypto/tls/cipher_suites.go694
-rw-r--r--src/crypto/tls/common.go1547
-rw-r--r--src/crypto/tls/common_string.go116
-rw-r--r--src/crypto/tls/conn.go1655
-rw-r--r--src/crypto/tls/conn_test.go319
-rw-r--r--src/crypto/tls/example_test.go232
-rw-r--r--src/crypto/tls/fipsonly/fipsonly.go29
-rw-r--r--src/crypto/tls/fipsonly/fipsonly_test.go18
-rw-r--r--src/crypto/tls/generate_cert.go171
-rw-r--r--src/crypto/tls/handshake_client.go1140
-rw-r--r--src/crypto/tls/handshake_client_test.go2826
-rw-r--r--src/crypto/tls/handshake_client_tls13.go772
-rw-r--r--src/crypto/tls/handshake_messages.go1903
-rw-r--r--src/crypto/tls/handshake_messages_test.go558
-rw-r--r--src/crypto/tls/handshake_server.go954
-rw-r--r--src/crypto/tls/handshake_server_test.go2047
-rw-r--r--src/crypto/tls/handshake_server_tls13.go991
-rw-r--r--src/crypto/tls/handshake_test.go530
-rw-r--r--src/crypto/tls/handshake_unix_test.go18
-rw-r--r--src/crypto/tls/key_agreement.go366
-rw-r--r--src/crypto/tls/key_schedule.go159
-rw-r--r--src/crypto/tls/key_schedule_test.go175
-rw-r--r--src/crypto/tls/link_test.go107
-rw-r--r--src/crypto/tls/notboring.go20
-rw-r--r--src/crypto/tls/prf.go292
-rw-r--r--src/crypto/tls/prf_test.go140
-rw-r--r--src/crypto/tls/quic.go421
-rw-r--r--src/crypto/tls/quic_test.go489
-rw-r--r--src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-ECDSA135
-rw-r--r--src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-RSA139
-rw-r--r--src/crypto/tls/testdata/Client-TLSv10-ClientCert-Ed25519110
-rw-r--r--src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-ECDSA134
-rw-r--r--src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-RSA138
-rw-r--r--src/crypto/tls/testdata/Client-TLSv10-ECDHE-ECDSA-AES92
-rw-r--r--src/crypto/tls/testdata/Client-TLSv10-ECDHE-RSA-AES96
-rw-r--r--src/crypto/tls/testdata/Client-TLSv10-Ed255190
-rw-r--r--src/crypto/tls/testdata/Client-TLSv10-ExportKeyingMaterial96
-rw-r--r--src/crypto/tls/testdata/Client-TLSv10-RSA-RC486
-rw-r--r--src/crypto/tls/testdata/Client-TLSv11-ECDHE-ECDSA-AES94
-rw-r--r--src/crypto/tls/testdata/Client-TLSv11-ECDHE-RSA-AES98
-rw-r--r--src/crypto/tls/testdata/Client-TLSv11-Ed255190
-rw-r--r--src/crypto/tls/testdata/Client-TLSv11-RSA-RC486
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-AES128-GCM-SHA25688
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-AES128-SHA25697
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-AES256-GCM-SHA38488
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ALPN93
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ALPN-NoMatch91
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-ECDSA140
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-RSA140
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ClientCert-Ed25519120
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-AES256-GCM-SHA384138
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-ECDSA139
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSA138
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSAPKCS1v15135
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSAPSS143
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES94
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES-GCM89
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES128-SHA25698
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES256-GCM-SHA38489
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-CHACHA20-POLY130584
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES98
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES128-SHA256102
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-CHACHA20-POLY130588
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-Ed2551969
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ExportKeyingMaterial91
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-P256-ECDHE98
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-RSA-RC486
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-RenegotiateOnce246
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwice346
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwiceRejected249
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-RenegotiationRejected96
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-SCT114
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-X25519-ECDHE92
-rw-r--r--src/crypto/tls/testdata/Client-TLSv13-AES128-SHA25691
-rw-r--r--src/crypto/tls/testdata/Client-TLSv13-AES256-SHA38493
-rw-r--r--src/crypto/tls/testdata/Client-TLSv13-ALPN93
-rw-r--r--src/crypto/tls/testdata/Client-TLSv13-CHACHA20-SHA25691
-rw-r--r--src/crypto/tls/testdata/Client-TLSv13-ClientCert-ECDSA-RSA140
-rw-r--r--src/crypto/tls/testdata/Client-TLSv13-ClientCert-Ed25519123
-rw-r--r--src/crypto/tls/testdata/Client-TLSv13-ClientCert-RSA-ECDSA135
-rw-r--r--src/crypto/tls/testdata/Client-TLSv13-ClientCert-RSA-RSAPSS144
-rw-r--r--src/crypto/tls/testdata/Client-TLSv13-ECDSA87
-rw-r--r--src/crypto/tls/testdata/Client-TLSv13-Ed2551969
-rw-r--r--src/crypto/tls/testdata/Client-TLSv13-ExportKeyingMaterial91
-rw-r--r--src/crypto/tls/testdata/Client-TLSv13-HelloRetryRequest119
-rw-r--r--src/crypto/tls/testdata/Client-TLSv13-KeyUpdate103
-rw-r--r--src/crypto/tls/testdata/Client-TLSv13-P256-ECDHE94
-rw-r--r--src/crypto/tls/testdata/Client-TLSv13-X25519-ECDHE90
-rw-r--r--src/crypto/tls/testdata/Server-TLSv10-ECDHE-ECDSA-AES79
-rw-r--r--src/crypto/tls/testdata/Server-TLSv10-ExportKeyingMaterial92
-rw-r--r--src/crypto/tls/testdata/Server-TLSv10-RSA-3DES73
-rw-r--r--src/crypto/tls/testdata/Server-TLSv10-RSA-AES76
-rw-r--r--src/crypto/tls/testdata/Server-TLSv10-RSA-RC470
-rw-r--r--src/crypto/tls/testdata/Server-TLSv11-FallbackSCSV11
-rw-r--r--src/crypto/tls/testdata/Server-TLSv11-RSA-RC470
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-ALPN91
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-ALPN-Fallback90
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch14
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-ALPN-NotConfigured90
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndECDSAGiven126
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndEd25519Given109
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndGiven125
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndPKCS1v15Given125
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedNotGiven85
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-ECDHE-ECDSA-AES84
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-Ed2551958
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-ExportKeyingMaterial96
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-IssueTicket90
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-IssueTicketPreDisable90
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-P25684
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-RSA-3DES78
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-RSA-AES82
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-RSA-AES-GCM81
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-RSA-AES256-GCM-SHA38481
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-RSA-RC474
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-RSA-RSAPKCS1v1577
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-RSA-RSAPSS77
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-Resume54
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-ResumeDisabled91
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-SNI83
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-SNI-GetCertificate83
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-SNI-GetCertificateNotFound83
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-X2551980
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-AES128-SHA25697
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-AES256-SHA384100
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-ALPN100
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-ALPN-Fallback99
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-ALPN-NoMatch18
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-ALPN-NotConfigured99
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-CHACHA20-SHA25697
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndECDSAGiven180
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndEd25519Given149
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndGiven177
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedNotGiven103
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-ECDHE-ECDSA-AES93
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-Ed2551975
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-ExportKeyingMaterial98
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-HelloRetryRequest123
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-IssueTicket98
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-IssueTicketPreDisable98
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-P256101
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-RSA-RSAPSS96
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-RSA-RSAPSS-TooSmall15
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-Resume59
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-Resume-HelloRetryRequest94
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-ResumeDisabled99
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-X2551997
-rw-r--r--src/crypto/tls/testdata/example-cert.pem11
-rw-r--r--src/crypto/tls/testdata/example-key.pem5
-rw-r--r--src/crypto/tls/ticket.go421
-rw-r--r--src/crypto/tls/ticket_test.go8
-rw-r--r--src/crypto/tls/tls.go356
-rw-r--r--src/crypto/tls/tls_test.go1804
160 files changed, 34654 insertions, 0 deletions
diff --git a/src/crypto/tls/alert.go b/src/crypto/tls/alert.go
new file mode 100644
index 0000000..33022cd
--- /dev/null
+++ b/src/crypto/tls/alert.go
@@ -0,0 +1,109 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import "strconv"
+
+// An AlertError is a TLS alert.
+//
+// When using a QUIC transport, QUICConn methods will return an error
+// which wraps AlertError rather than sending a TLS alert.
+type AlertError uint8
+
+func (e AlertError) Error() string {
+ return alert(e).String()
+}
+
+type alert uint8
+
+const (
+ // alert level
+ alertLevelWarning = 1
+ alertLevelError = 2
+)
+
+const (
+ alertCloseNotify alert = 0
+ alertUnexpectedMessage alert = 10
+ alertBadRecordMAC alert = 20
+ alertDecryptionFailed alert = 21
+ alertRecordOverflow alert = 22
+ alertDecompressionFailure alert = 30
+ alertHandshakeFailure alert = 40
+ alertBadCertificate alert = 42
+ alertUnsupportedCertificate alert = 43
+ alertCertificateRevoked alert = 44
+ alertCertificateExpired alert = 45
+ alertCertificateUnknown alert = 46
+ alertIllegalParameter alert = 47
+ alertUnknownCA alert = 48
+ alertAccessDenied alert = 49
+ alertDecodeError alert = 50
+ alertDecryptError alert = 51
+ alertExportRestriction alert = 60
+ alertProtocolVersion alert = 70
+ alertInsufficientSecurity alert = 71
+ alertInternalError alert = 80
+ alertInappropriateFallback alert = 86
+ alertUserCanceled alert = 90
+ alertNoRenegotiation alert = 100
+ alertMissingExtension alert = 109
+ alertUnsupportedExtension alert = 110
+ alertCertificateUnobtainable alert = 111
+ alertUnrecognizedName alert = 112
+ alertBadCertificateStatusResponse alert = 113
+ alertBadCertificateHashValue alert = 114
+ alertUnknownPSKIdentity alert = 115
+ alertCertificateRequired alert = 116
+ alertNoApplicationProtocol alert = 120
+)
+
+var alertText = map[alert]string{
+ alertCloseNotify: "close notify",
+ alertUnexpectedMessage: "unexpected message",
+ alertBadRecordMAC: "bad record MAC",
+ alertDecryptionFailed: "decryption failed",
+ alertRecordOverflow: "record overflow",
+ alertDecompressionFailure: "decompression failure",
+ alertHandshakeFailure: "handshake failure",
+ alertBadCertificate: "bad certificate",
+ alertUnsupportedCertificate: "unsupported certificate",
+ alertCertificateRevoked: "revoked certificate",
+ alertCertificateExpired: "expired certificate",
+ alertCertificateUnknown: "unknown certificate",
+ alertIllegalParameter: "illegal parameter",
+ alertUnknownCA: "unknown certificate authority",
+ alertAccessDenied: "access denied",
+ alertDecodeError: "error decoding message",
+ alertDecryptError: "error decrypting message",
+ alertExportRestriction: "export restriction",
+ alertProtocolVersion: "protocol version not supported",
+ alertInsufficientSecurity: "insufficient security level",
+ alertInternalError: "internal error",
+ alertInappropriateFallback: "inappropriate fallback",
+ alertUserCanceled: "user canceled",
+ alertNoRenegotiation: "no renegotiation",
+ alertMissingExtension: "missing extension",
+ alertUnsupportedExtension: "unsupported extension",
+ alertCertificateUnobtainable: "certificate unobtainable",
+ alertUnrecognizedName: "unrecognized name",
+ alertBadCertificateStatusResponse: "bad certificate status response",
+ alertBadCertificateHashValue: "bad certificate hash value",
+ alertUnknownPSKIdentity: "unknown PSK identity",
+ alertCertificateRequired: "certificate required",
+ alertNoApplicationProtocol: "no application protocol",
+}
+
+func (e alert) String() string {
+ s, ok := alertText[e]
+ if ok {
+ return "tls: " + s
+ }
+ return "tls: alert(" + strconv.Itoa(int(e)) + ")"
+}
+
+func (e alert) Error() string {
+ return e.String()
+}
diff --git a/src/crypto/tls/auth.go b/src/crypto/tls/auth.go
new file mode 100644
index 0000000..7c5675c
--- /dev/null
+++ b/src/crypto/tls/auth.go
@@ -0,0 +1,293 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+ "bytes"
+ "crypto"
+ "crypto/ecdsa"
+ "crypto/ed25519"
+ "crypto/elliptic"
+ "crypto/rsa"
+ "errors"
+ "fmt"
+ "hash"
+ "io"
+)
+
+// verifyHandshakeSignature verifies a signature against pre-hashed
+// (if required) handshake contents.
+func verifyHandshakeSignature(sigType uint8, pubkey crypto.PublicKey, hashFunc crypto.Hash, signed, sig []byte) error {
+ switch sigType {
+ case signatureECDSA:
+ pubKey, ok := pubkey.(*ecdsa.PublicKey)
+ if !ok {
+ return fmt.Errorf("expected an ECDSA public key, got %T", pubkey)
+ }
+ if !ecdsa.VerifyASN1(pubKey, signed, sig) {
+ return errors.New("ECDSA verification failure")
+ }
+ case signatureEd25519:
+ pubKey, ok := pubkey.(ed25519.PublicKey)
+ if !ok {
+ return fmt.Errorf("expected an Ed25519 public key, got %T", pubkey)
+ }
+ if !ed25519.Verify(pubKey, signed, sig) {
+ return errors.New("Ed25519 verification failure")
+ }
+ case signaturePKCS1v15:
+ pubKey, ok := pubkey.(*rsa.PublicKey)
+ if !ok {
+ return fmt.Errorf("expected an RSA public key, got %T", pubkey)
+ }
+ if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, signed, sig); err != nil {
+ return err
+ }
+ case signatureRSAPSS:
+ pubKey, ok := pubkey.(*rsa.PublicKey)
+ if !ok {
+ return fmt.Errorf("expected an RSA public key, got %T", pubkey)
+ }
+ signOpts := &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash}
+ if err := rsa.VerifyPSS(pubKey, hashFunc, signed, sig, signOpts); err != nil {
+ return err
+ }
+ default:
+ return errors.New("internal error: unknown signature type")
+ }
+ return nil
+}
+
+const (
+ serverSignatureContext = "TLS 1.3, server CertificateVerify\x00"
+ clientSignatureContext = "TLS 1.3, client CertificateVerify\x00"
+)
+
+var signaturePadding = []byte{
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+}
+
+// signedMessage returns the pre-hashed (if necessary) message to be signed by
+// certificate keys in TLS 1.3. See RFC 8446, Section 4.4.3.
+func signedMessage(sigHash crypto.Hash, context string, transcript hash.Hash) []byte {
+ if sigHash == directSigning {
+ b := &bytes.Buffer{}
+ b.Write(signaturePadding)
+ io.WriteString(b, context)
+ b.Write(transcript.Sum(nil))
+ return b.Bytes()
+ }
+ h := sigHash.New()
+ h.Write(signaturePadding)
+ io.WriteString(h, context)
+ h.Write(transcript.Sum(nil))
+ return h.Sum(nil)
+}
+
+// typeAndHashFromSignatureScheme returns the corresponding signature type and
+// crypto.Hash for a given TLS SignatureScheme.
+func typeAndHashFromSignatureScheme(signatureAlgorithm SignatureScheme) (sigType uint8, hash crypto.Hash, err error) {
+ switch signatureAlgorithm {
+ case PKCS1WithSHA1, PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512:
+ sigType = signaturePKCS1v15
+ case PSSWithSHA256, PSSWithSHA384, PSSWithSHA512:
+ sigType = signatureRSAPSS
+ case ECDSAWithSHA1, ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512:
+ sigType = signatureECDSA
+ case Ed25519:
+ sigType = signatureEd25519
+ default:
+ return 0, 0, fmt.Errorf("unsupported signature algorithm: %v", signatureAlgorithm)
+ }
+ switch signatureAlgorithm {
+ case PKCS1WithSHA1, ECDSAWithSHA1:
+ hash = crypto.SHA1
+ case PKCS1WithSHA256, PSSWithSHA256, ECDSAWithP256AndSHA256:
+ hash = crypto.SHA256
+ case PKCS1WithSHA384, PSSWithSHA384, ECDSAWithP384AndSHA384:
+ hash = crypto.SHA384
+ case PKCS1WithSHA512, PSSWithSHA512, ECDSAWithP521AndSHA512:
+ hash = crypto.SHA512
+ case Ed25519:
+ hash = directSigning
+ default:
+ return 0, 0, fmt.Errorf("unsupported signature algorithm: %v", signatureAlgorithm)
+ }
+ return sigType, hash, nil
+}
+
+// legacyTypeAndHashFromPublicKey returns the fixed signature type and crypto.Hash for
+// a given public key used with TLS 1.0 and 1.1, before the introduction of
+// signature algorithm negotiation.
+func legacyTypeAndHashFromPublicKey(pub crypto.PublicKey) (sigType uint8, hash crypto.Hash, err error) {
+ switch pub.(type) {
+ case *rsa.PublicKey:
+ return signaturePKCS1v15, crypto.MD5SHA1, nil
+ case *ecdsa.PublicKey:
+ return signatureECDSA, crypto.SHA1, nil
+ case ed25519.PublicKey:
+ // RFC 8422 specifies support for Ed25519 in TLS 1.0 and 1.1,
+ // but it requires holding on to a handshake transcript to do a
+ // full signature, and not even OpenSSL bothers with the
+ // complexity, so we can't even test it properly.
+ return 0, 0, fmt.Errorf("tls: Ed25519 public keys are not supported before TLS 1.2")
+ default:
+ return 0, 0, fmt.Errorf("tls: unsupported public key: %T", pub)
+ }
+}
+
+var rsaSignatureSchemes = []struct {
+ scheme SignatureScheme
+ minModulusBytes int
+ maxVersion uint16
+}{
+ // RSA-PSS is used with PSSSaltLengthEqualsHash, and requires
+ // emLen >= hLen + sLen + 2
+ {PSSWithSHA256, crypto.SHA256.Size()*2 + 2, VersionTLS13},
+ {PSSWithSHA384, crypto.SHA384.Size()*2 + 2, VersionTLS13},
+ {PSSWithSHA512, crypto.SHA512.Size()*2 + 2, VersionTLS13},
+ // PKCS #1 v1.5 uses prefixes from hashPrefixes in crypto/rsa, and requires
+ // emLen >= len(prefix) + hLen + 11
+ // TLS 1.3 dropped support for PKCS #1 v1.5 in favor of RSA-PSS.
+ {PKCS1WithSHA256, 19 + crypto.SHA256.Size() + 11, VersionTLS12},
+ {PKCS1WithSHA384, 19 + crypto.SHA384.Size() + 11, VersionTLS12},
+ {PKCS1WithSHA512, 19 + crypto.SHA512.Size() + 11, VersionTLS12},
+ {PKCS1WithSHA1, 15 + crypto.SHA1.Size() + 11, VersionTLS12},
+}
+
+// signatureSchemesForCertificate returns the list of supported SignatureSchemes
+// for a given certificate, based on the public key and the protocol version,
+// and optionally filtered by its explicit SupportedSignatureAlgorithms.
+//
+// This function must be kept in sync with supportedSignatureAlgorithms.
+// FIPS filtering is applied in the caller, selectSignatureScheme.
+func signatureSchemesForCertificate(version uint16, cert *Certificate) []SignatureScheme {
+ priv, ok := cert.PrivateKey.(crypto.Signer)
+ if !ok {
+ return nil
+ }
+
+ var sigAlgs []SignatureScheme
+ switch pub := priv.Public().(type) {
+ case *ecdsa.PublicKey:
+ if version != VersionTLS13 {
+ // In TLS 1.2 and earlier, ECDSA algorithms are not
+ // constrained to a single curve.
+ sigAlgs = []SignatureScheme{
+ ECDSAWithP256AndSHA256,
+ ECDSAWithP384AndSHA384,
+ ECDSAWithP521AndSHA512,
+ ECDSAWithSHA1,
+ }
+ break
+ }
+ switch pub.Curve {
+ case elliptic.P256():
+ sigAlgs = []SignatureScheme{ECDSAWithP256AndSHA256}
+ case elliptic.P384():
+ sigAlgs = []SignatureScheme{ECDSAWithP384AndSHA384}
+ case elliptic.P521():
+ sigAlgs = []SignatureScheme{ECDSAWithP521AndSHA512}
+ default:
+ return nil
+ }
+ case *rsa.PublicKey:
+ size := pub.Size()
+ sigAlgs = make([]SignatureScheme, 0, len(rsaSignatureSchemes))
+ for _, candidate := range rsaSignatureSchemes {
+ if size >= candidate.minModulusBytes && version <= candidate.maxVersion {
+ sigAlgs = append(sigAlgs, candidate.scheme)
+ }
+ }
+ case ed25519.PublicKey:
+ sigAlgs = []SignatureScheme{Ed25519}
+ default:
+ return nil
+ }
+
+ if cert.SupportedSignatureAlgorithms != nil {
+ var filteredSigAlgs []SignatureScheme
+ for _, sigAlg := range sigAlgs {
+ if isSupportedSignatureAlgorithm(sigAlg, cert.SupportedSignatureAlgorithms) {
+ filteredSigAlgs = append(filteredSigAlgs, sigAlg)
+ }
+ }
+ return filteredSigAlgs
+ }
+ return sigAlgs
+}
+
+// selectSignatureScheme picks a SignatureScheme from the peer's preference list
+// that works with the selected certificate. It's only called for protocol
+// versions that support signature algorithms, so TLS 1.2 and 1.3.
+func selectSignatureScheme(vers uint16, c *Certificate, peerAlgs []SignatureScheme) (SignatureScheme, error) {
+ supportedAlgs := signatureSchemesForCertificate(vers, c)
+ if len(supportedAlgs) == 0 {
+ return 0, unsupportedCertificateError(c)
+ }
+ if len(peerAlgs) == 0 && vers == VersionTLS12 {
+ // For TLS 1.2, if the client didn't send signature_algorithms then we
+ // can assume that it supports SHA1. See RFC 5246, Section 7.4.1.4.1.
+ peerAlgs = []SignatureScheme{PKCS1WithSHA1, ECDSAWithSHA1}
+ }
+ // Pick signature scheme in the peer's preference order, as our
+ // preference order is not configurable.
+ for _, preferredAlg := range peerAlgs {
+ if needFIPS() && !isSupportedSignatureAlgorithm(preferredAlg, fipsSupportedSignatureAlgorithms) {
+ continue
+ }
+ if isSupportedSignatureAlgorithm(preferredAlg, supportedAlgs) {
+ return preferredAlg, nil
+ }
+ }
+ return 0, errors.New("tls: peer doesn't support any of the certificate's signature algorithms")
+}
+
+// unsupportedCertificateError returns a helpful error for certificates with
+// an unsupported private key.
+func unsupportedCertificateError(cert *Certificate) error {
+ switch cert.PrivateKey.(type) {
+ case rsa.PrivateKey, ecdsa.PrivateKey:
+ return fmt.Errorf("tls: unsupported certificate: private key is %T, expected *%T",
+ cert.PrivateKey, cert.PrivateKey)
+ case *ed25519.PrivateKey:
+ return fmt.Errorf("tls: unsupported certificate: private key is *ed25519.PrivateKey, expected ed25519.PrivateKey")
+ }
+
+ signer, ok := cert.PrivateKey.(crypto.Signer)
+ if !ok {
+ return fmt.Errorf("tls: certificate private key (%T) does not implement crypto.Signer",
+ cert.PrivateKey)
+ }
+
+ switch pub := signer.Public().(type) {
+ case *ecdsa.PublicKey:
+ switch pub.Curve {
+ case elliptic.P256():
+ case elliptic.P384():
+ case elliptic.P521():
+ default:
+ return fmt.Errorf("tls: unsupported certificate curve (%s)", pub.Curve.Params().Name)
+ }
+ case *rsa.PublicKey:
+ return fmt.Errorf("tls: certificate RSA key size too small for supported signature algorithms")
+ case ed25519.PublicKey:
+ default:
+ return fmt.Errorf("tls: unsupported certificate key (%T)", pub)
+ }
+
+ if cert.SupportedSignatureAlgorithms != nil {
+ return fmt.Errorf("tls: peer doesn't support the certificate custom signature algorithms")
+ }
+
+ return fmt.Errorf("tls: internal error: unsupported key (%T)", cert.PrivateKey)
+}
diff --git a/src/crypto/tls/auth_test.go b/src/crypto/tls/auth_test.go
new file mode 100644
index 0000000..c23d93f
--- /dev/null
+++ b/src/crypto/tls/auth_test.go
@@ -0,0 +1,168 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+ "crypto"
+ "testing"
+)
+
+func TestSignatureSelection(t *testing.T) {
+ rsaCert := &Certificate{
+ Certificate: [][]byte{testRSACertificate},
+ PrivateKey: testRSAPrivateKey,
+ }
+ pkcs1Cert := &Certificate{
+ Certificate: [][]byte{testRSACertificate},
+ PrivateKey: testRSAPrivateKey,
+ SupportedSignatureAlgorithms: []SignatureScheme{PKCS1WithSHA1, PKCS1WithSHA256},
+ }
+ ecdsaCert := &Certificate{
+ Certificate: [][]byte{testP256Certificate},
+ PrivateKey: testP256PrivateKey,
+ }
+ ed25519Cert := &Certificate{
+ Certificate: [][]byte{testEd25519Certificate},
+ PrivateKey: testEd25519PrivateKey,
+ }
+
+ tests := []struct {
+ cert *Certificate
+ peerSigAlgs []SignatureScheme
+ tlsVersion uint16
+
+ expectedSigAlg SignatureScheme
+ expectedSigType uint8
+ expectedHash crypto.Hash
+ }{
+ {rsaCert, []SignatureScheme{PKCS1WithSHA1, PKCS1WithSHA256}, VersionTLS12, PKCS1WithSHA1, signaturePKCS1v15, crypto.SHA1},
+ {rsaCert, []SignatureScheme{PKCS1WithSHA512, PKCS1WithSHA1}, VersionTLS12, PKCS1WithSHA512, signaturePKCS1v15, crypto.SHA512},
+ {rsaCert, []SignatureScheme{PSSWithSHA256, PKCS1WithSHA256}, VersionTLS12, PSSWithSHA256, signatureRSAPSS, crypto.SHA256},
+ {pkcs1Cert, []SignatureScheme{PSSWithSHA256, PKCS1WithSHA256}, VersionTLS12, PKCS1WithSHA256, signaturePKCS1v15, crypto.SHA256},
+ {rsaCert, []SignatureScheme{PSSWithSHA384, PKCS1WithSHA1}, VersionTLS13, PSSWithSHA384, signatureRSAPSS, crypto.SHA384},
+ {ecdsaCert, []SignatureScheme{ECDSAWithSHA1}, VersionTLS12, ECDSAWithSHA1, signatureECDSA, crypto.SHA1},
+ {ecdsaCert, []SignatureScheme{ECDSAWithP256AndSHA256}, VersionTLS12, ECDSAWithP256AndSHA256, signatureECDSA, crypto.SHA256},
+ {ecdsaCert, []SignatureScheme{ECDSAWithP256AndSHA256}, VersionTLS13, ECDSAWithP256AndSHA256, signatureECDSA, crypto.SHA256},
+ {ed25519Cert, []SignatureScheme{Ed25519}, VersionTLS12, Ed25519, signatureEd25519, directSigning},
+ {ed25519Cert, []SignatureScheme{Ed25519}, VersionTLS13, Ed25519, signatureEd25519, directSigning},
+
+ // TLS 1.2 without signature_algorithms extension
+ {rsaCert, nil, VersionTLS12, PKCS1WithSHA1, signaturePKCS1v15, crypto.SHA1},
+ {ecdsaCert, nil, VersionTLS12, ECDSAWithSHA1, signatureECDSA, crypto.SHA1},
+
+ // TLS 1.2 does not restrict the ECDSA curve (our ecdsaCert is P-256)
+ {ecdsaCert, []SignatureScheme{ECDSAWithP384AndSHA384}, VersionTLS12, ECDSAWithP384AndSHA384, signatureECDSA, crypto.SHA384},
+ }
+
+ for testNo, test := range tests {
+ sigAlg, err := selectSignatureScheme(test.tlsVersion, test.cert, test.peerSigAlgs)
+ if err != nil {
+ t.Errorf("test[%d]: unexpected selectSignatureScheme error: %v", testNo, err)
+ }
+ if test.expectedSigAlg != sigAlg {
+ t.Errorf("test[%d]: expected signature scheme %v, got %v", testNo, test.expectedSigAlg, sigAlg)
+ }
+ sigType, hashFunc, err := typeAndHashFromSignatureScheme(sigAlg)
+ if err != nil {
+ t.Errorf("test[%d]: unexpected typeAndHashFromSignatureScheme error: %v", testNo, err)
+ }
+ if test.expectedSigType != sigType {
+ t.Errorf("test[%d]: expected signature algorithm %#x, got %#x", testNo, test.expectedSigType, sigType)
+ }
+ if test.expectedHash != hashFunc {
+ t.Errorf("test[%d]: expected hash function %#x, got %#x", testNo, test.expectedHash, hashFunc)
+ }
+ }
+
+ brokenCert := &Certificate{
+ Certificate: [][]byte{testRSACertificate},
+ PrivateKey: testRSAPrivateKey,
+ SupportedSignatureAlgorithms: []SignatureScheme{Ed25519},
+ }
+
+ badTests := []struct {
+ cert *Certificate
+ peerSigAlgs []SignatureScheme
+ tlsVersion uint16
+ }{
+ {rsaCert, []SignatureScheme{ECDSAWithP256AndSHA256, ECDSAWithSHA1}, VersionTLS12},
+ {ecdsaCert, []SignatureScheme{PKCS1WithSHA256, PKCS1WithSHA1}, VersionTLS12},
+ {rsaCert, []SignatureScheme{0}, VersionTLS12},
+ {ed25519Cert, []SignatureScheme{ECDSAWithP256AndSHA256, ECDSAWithSHA1}, VersionTLS12},
+ {ecdsaCert, []SignatureScheme{Ed25519}, VersionTLS12},
+ {brokenCert, []SignatureScheme{Ed25519}, VersionTLS12},
+ {brokenCert, []SignatureScheme{PKCS1WithSHA256}, VersionTLS12},
+ // RFC 5246, Section 7.4.1.4.1, says to only consider {sha1,ecdsa} as
+ // default when the extension is missing, and RFC 8422 does not update
+ // it. Anyway, if a stack supports Ed25519 it better support sigalgs.
+ {ed25519Cert, nil, VersionTLS12},
+ // TLS 1.3 has no default signature_algorithms.
+ {rsaCert, nil, VersionTLS13},
+ {ecdsaCert, nil, VersionTLS13},
+ {ed25519Cert, nil, VersionTLS13},
+ // Wrong curve, which TLS 1.3 checks
+ {ecdsaCert, []SignatureScheme{ECDSAWithP384AndSHA384}, VersionTLS13},
+ // TLS 1.3 does not support PKCS1v1.5 or SHA-1.
+ {rsaCert, []SignatureScheme{PKCS1WithSHA256}, VersionTLS13},
+ {pkcs1Cert, []SignatureScheme{PSSWithSHA256, PKCS1WithSHA256}, VersionTLS13},
+ {ecdsaCert, []SignatureScheme{ECDSAWithSHA1}, VersionTLS13},
+ // The key can be too small for the hash.
+ {rsaCert, []SignatureScheme{PSSWithSHA512}, VersionTLS12},
+ }
+
+ for testNo, test := range badTests {
+ sigAlg, err := selectSignatureScheme(test.tlsVersion, test.cert, test.peerSigAlgs)
+ if err == nil {
+ t.Errorf("test[%d]: unexpected success, got %v", testNo, sigAlg)
+ }
+ }
+}
+
+func TestLegacyTypeAndHash(t *testing.T) {
+ sigType, hashFunc, err := legacyTypeAndHashFromPublicKey(testRSAPrivateKey.Public())
+ if err != nil {
+ t.Errorf("RSA: unexpected error: %v", err)
+ }
+ if expectedSigType := signaturePKCS1v15; expectedSigType != sigType {
+ t.Errorf("RSA: expected signature type %#x, got %#x", expectedSigType, sigType)
+ }
+ if expectedHashFunc := crypto.MD5SHA1; expectedHashFunc != hashFunc {
+ t.Errorf("RSA: expected hash %#x, got %#x", expectedHashFunc, hashFunc)
+ }
+
+ sigType, hashFunc, err = legacyTypeAndHashFromPublicKey(testECDSAPrivateKey.Public())
+ if err != nil {
+ t.Errorf("ECDSA: unexpected error: %v", err)
+ }
+ if expectedSigType := signatureECDSA; expectedSigType != sigType {
+ t.Errorf("ECDSA: expected signature type %#x, got %#x", expectedSigType, sigType)
+ }
+ if expectedHashFunc := crypto.SHA1; expectedHashFunc != hashFunc {
+ t.Errorf("ECDSA: expected hash %#x, got %#x", expectedHashFunc, hashFunc)
+ }
+
+ // Ed25519 is not supported by TLS 1.0 and 1.1.
+ _, _, err = legacyTypeAndHashFromPublicKey(testEd25519PrivateKey.Public())
+ if err == nil {
+ t.Errorf("Ed25519: unexpected success")
+ }
+}
+
+// TestSupportedSignatureAlgorithms checks that all supportedSignatureAlgorithms
+// have valid type and hash information.
+func TestSupportedSignatureAlgorithms(t *testing.T) {
+ for _, sigAlg := range supportedSignatureAlgorithms() {
+ sigType, hash, err := typeAndHashFromSignatureScheme(sigAlg)
+ if err != nil {
+ t.Errorf("%v: unexpected error: %v", sigAlg, err)
+ }
+ if sigType == 0 {
+ t.Errorf("%v: missing signature type", sigAlg)
+ }
+ if hash == 0 && sigAlg != Ed25519 {
+ t.Errorf("%v: missing hash", sigAlg)
+ }
+ }
+}
diff --git a/src/crypto/tls/boring.go b/src/crypto/tls/boring.go
new file mode 100644
index 0000000..1827f76
--- /dev/null
+++ b/src/crypto/tls/boring.go
@@ -0,0 +1,98 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build boringcrypto
+
+package tls
+
+import (
+ "crypto/internal/boring/fipstls"
+)
+
+// needFIPS returns fipstls.Required(); it avoids a new import in common.go.
+func needFIPS() bool {
+ return fipstls.Required()
+}
+
+// fipsMinVersion replaces c.minVersion in FIPS-only mode.
+func fipsMinVersion(c *Config) uint16 {
+ // FIPS requires TLS 1.2.
+ return VersionTLS12
+}
+
+// fipsMaxVersion replaces c.maxVersion in FIPS-only mode.
+func fipsMaxVersion(c *Config) uint16 {
+ // FIPS requires TLS 1.2.
+ return VersionTLS12
+}
+
+// default defaultFIPSCurvePreferences is the FIPS-allowed curves,
+// in preference order (most preferable first).
+var defaultFIPSCurvePreferences = []CurveID{CurveP256, CurveP384, CurveP521}
+
+// fipsCurvePreferences replaces c.curvePreferences in FIPS-only mode.
+func fipsCurvePreferences(c *Config) []CurveID {
+ if c == nil || len(c.CurvePreferences) == 0 {
+ return defaultFIPSCurvePreferences
+ }
+ var list []CurveID
+ for _, id := range c.CurvePreferences {
+ for _, allowed := range defaultFIPSCurvePreferences {
+ if id == allowed {
+ list = append(list, id)
+ break
+ }
+ }
+ }
+ return list
+}
+
+// defaultCipherSuitesFIPS are the FIPS-allowed cipher suites.
+var defaultCipherSuitesFIPS = []uint16{
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+ TLS_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_RSA_WITH_AES_256_GCM_SHA384,
+}
+
+// fipsCipherSuites replaces c.cipherSuites in FIPS-only mode.
+func fipsCipherSuites(c *Config) []uint16 {
+ if c == nil || c.CipherSuites == nil {
+ return defaultCipherSuitesFIPS
+ }
+ list := make([]uint16, 0, len(defaultCipherSuitesFIPS))
+ for _, id := range c.CipherSuites {
+ for _, allowed := range defaultCipherSuitesFIPS {
+ if id == allowed {
+ list = append(list, id)
+ break
+ }
+ }
+ }
+ return list
+}
+
+// fipsSupportedSignatureAlgorithms currently are a subset of
+// defaultSupportedSignatureAlgorithms without Ed25519 and SHA-1.
+var fipsSupportedSignatureAlgorithms = []SignatureScheme{
+ PSSWithSHA256,
+ PSSWithSHA384,
+ PSSWithSHA512,
+ PKCS1WithSHA256,
+ ECDSAWithP256AndSHA256,
+ PKCS1WithSHA384,
+ ECDSAWithP384AndSHA384,
+ PKCS1WithSHA512,
+ ECDSAWithP521AndSHA512,
+}
+
+// supportedSignatureAlgorithms returns the supported signature algorithms.
+func supportedSignatureAlgorithms() []SignatureScheme {
+ if !needFIPS() {
+ return defaultSupportedSignatureAlgorithms
+ }
+ return fipsSupportedSignatureAlgorithms
+}
diff --git a/src/crypto/tls/boring_test.go b/src/crypto/tls/boring_test.go
new file mode 100644
index 0000000..ba68f35
--- /dev/null
+++ b/src/crypto/tls/boring_test.go
@@ -0,0 +1,617 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build boringcrypto
+
+package tls
+
+import (
+ "crypto/ecdsa"
+ "crypto/elliptic"
+ "crypto/internal/boring/fipstls"
+ "crypto/rand"
+ "crypto/rsa"
+ "crypto/x509"
+ "crypto/x509/pkix"
+ "encoding/pem"
+ "fmt"
+ "internal/obscuretestdata"
+ "math/big"
+ "net"
+ "runtime"
+ "strings"
+ "testing"
+ "time"
+)
+
+func TestBoringServerProtocolVersion(t *testing.T) {
+ test := func(name string, v uint16, msg string) {
+ t.Run(name, func(t *testing.T) {
+ serverConfig := testConfig.Clone()
+ serverConfig.MinVersion = VersionSSL30
+ clientHello := &clientHelloMsg{
+ vers: v,
+ random: make([]byte, 32),
+ cipherSuites: allCipherSuites(),
+ compressionMethods: []uint8{compressionNone},
+ supportedVersions: []uint16{v},
+ }
+ testClientHelloFailure(t, serverConfig, clientHello, msg)
+ })
+ }
+
+ test("VersionTLS10", VersionTLS10, "")
+ test("VersionTLS11", VersionTLS11, "")
+ test("VersionTLS12", VersionTLS12, "")
+ test("VersionTLS13", VersionTLS13, "")
+
+ fipstls.Force()
+ defer fipstls.Abandon()
+ test("VersionSSL30", VersionSSL30, "client offered only unsupported versions")
+ test("VersionTLS10", VersionTLS10, "client offered only unsupported versions")
+ test("VersionTLS11", VersionTLS11, "client offered only unsupported versions")
+ test("VersionTLS12", VersionTLS12, "")
+ test("VersionTLS13", VersionTLS13, "client offered only unsupported versions")
+}
+
+func isBoringVersion(v uint16) bool {
+ return v == VersionTLS12
+}
+
+func isBoringCipherSuite(id uint16) bool {
+ switch id {
+ case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
+ TLS_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_RSA_WITH_AES_256_GCM_SHA384:
+ return true
+ }
+ return false
+}
+
+func isBoringCurve(id CurveID) bool {
+ switch id {
+ case CurveP256, CurveP384, CurveP521:
+ return true
+ }
+ return false
+}
+
+func isECDSA(id uint16) bool {
+ for _, suite := range cipherSuites {
+ if suite.id == id {
+ return suite.flags&suiteECSign == suiteECSign
+ }
+ }
+ panic(fmt.Sprintf("unknown cipher suite %#x", id))
+}
+
+func isBoringSignatureScheme(alg SignatureScheme) bool {
+ switch alg {
+ default:
+ return false
+ case PKCS1WithSHA256,
+ ECDSAWithP256AndSHA256,
+ PKCS1WithSHA384,
+ ECDSAWithP384AndSHA384,
+ PKCS1WithSHA512,
+ ECDSAWithP521AndSHA512,
+ PSSWithSHA256,
+ PSSWithSHA384,
+ PSSWithSHA512:
+ // ok
+ }
+ return true
+}
+
+func TestBoringServerCipherSuites(t *testing.T) {
+ serverConfig := testConfig.Clone()
+ serverConfig.CipherSuites = allCipherSuites()
+ serverConfig.Certificates = make([]Certificate, 1)
+
+ for _, id := range allCipherSuites() {
+ if isECDSA(id) {
+ serverConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate}
+ serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey
+ } else {
+ serverConfig.Certificates[0].Certificate = [][]byte{testRSACertificate}
+ serverConfig.Certificates[0].PrivateKey = testRSAPrivateKey
+ }
+ serverConfig.BuildNameToCertificate()
+ t.Run(fmt.Sprintf("suite=%#x", id), func(t *testing.T) {
+ clientHello := &clientHelloMsg{
+ vers: VersionTLS12,
+ random: make([]byte, 32),
+ cipherSuites: []uint16{id},
+ compressionMethods: []uint8{compressionNone},
+ supportedCurves: defaultCurvePreferences,
+ supportedPoints: []uint8{pointFormatUncompressed},
+ }
+
+ testClientHello(t, serverConfig, clientHello)
+ t.Run("fipstls", func(t *testing.T) {
+ fipstls.Force()
+ defer fipstls.Abandon()
+ msg := ""
+ if !isBoringCipherSuite(id) {
+ msg = "no cipher suite supported by both client and server"
+ }
+ testClientHelloFailure(t, serverConfig, clientHello, msg)
+ })
+ })
+ }
+}
+
+func TestBoringServerCurves(t *testing.T) {
+ serverConfig := testConfig.Clone()
+ serverConfig.Certificates = make([]Certificate, 1)
+ serverConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate}
+ serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey
+ serverConfig.BuildNameToCertificate()
+
+ for _, curveid := range defaultCurvePreferences {
+ t.Run(fmt.Sprintf("curve=%d", curveid), func(t *testing.T) {
+ clientHello := &clientHelloMsg{
+ vers: VersionTLS12,
+ random: make([]byte, 32),
+ cipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
+ compressionMethods: []uint8{compressionNone},
+ supportedCurves: []CurveID{curveid},
+ supportedPoints: []uint8{pointFormatUncompressed},
+ }
+
+ testClientHello(t, serverConfig, clientHello)
+
+ // With fipstls forced, bad curves should be rejected.
+ t.Run("fipstls", func(t *testing.T) {
+ fipstls.Force()
+ defer fipstls.Abandon()
+ msg := ""
+ if !isBoringCurve(curveid) {
+ msg = "no cipher suite supported by both client and server"
+ }
+ testClientHelloFailure(t, serverConfig, clientHello, msg)
+ })
+ })
+ }
+}
+
+func boringHandshake(t *testing.T, clientConfig, serverConfig *Config) (clientErr, serverErr error) {
+ c, s := localPipe(t)
+ client := Client(c, clientConfig)
+ server := Server(s, serverConfig)
+ done := make(chan error, 1)
+ go func() {
+ done <- client.Handshake()
+ c.Close()
+ }()
+ serverErr = server.Handshake()
+ s.Close()
+ clientErr = <-done
+ return
+}
+
+func TestBoringServerSignatureAndHash(t *testing.T) {
+ defer func() {
+ testingOnlyForceClientHelloSignatureAlgorithms = nil
+ }()
+
+ for _, sigHash := range defaultSupportedSignatureAlgorithms {
+ t.Run(fmt.Sprintf("%#x", sigHash), func(t *testing.T) {
+ serverConfig := testConfig.Clone()
+ serverConfig.Certificates = make([]Certificate, 1)
+
+ testingOnlyForceClientHelloSignatureAlgorithms = []SignatureScheme{sigHash}
+
+ sigType, _, _ := typeAndHashFromSignatureScheme(sigHash)
+ switch sigType {
+ case signaturePKCS1v15, signatureRSAPSS:
+ serverConfig.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}
+ serverConfig.Certificates[0].Certificate = [][]byte{testRSA2048Certificate}
+ serverConfig.Certificates[0].PrivateKey = testRSA2048PrivateKey
+ case signatureEd25519:
+ serverConfig.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}
+ serverConfig.Certificates[0].Certificate = [][]byte{testEd25519Certificate}
+ serverConfig.Certificates[0].PrivateKey = testEd25519PrivateKey
+ case signatureECDSA:
+ serverConfig.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}
+ serverConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate}
+ serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey
+ }
+ serverConfig.BuildNameToCertificate()
+ // PKCS#1 v1.5 signature algorithms can't be used standalone in TLS
+ // 1.3, and the ECDSA ones bind to the curve used.
+ serverConfig.MaxVersion = VersionTLS12
+
+ clientErr, serverErr := boringHandshake(t, testConfig, serverConfig)
+ if clientErr != nil {
+ t.Fatalf("expected handshake with %#x to succeed; client error: %v; server error: %v", sigHash, clientErr, serverErr)
+ }
+
+ // With fipstls forced, bad curves should be rejected.
+ t.Run("fipstls", func(t *testing.T) {
+ fipstls.Force()
+ defer fipstls.Abandon()
+ clientErr, _ := boringHandshake(t, testConfig, serverConfig)
+ if isBoringSignatureScheme(sigHash) {
+ if clientErr != nil {
+ t.Fatalf("expected handshake with %#x to succeed; err=%v", sigHash, clientErr)
+ }
+ } else {
+ if clientErr == nil {
+ t.Fatalf("expected handshake with %#x to fail, but it succeeded", sigHash)
+ }
+ }
+ })
+ })
+ }
+}
+
+func TestBoringClientHello(t *testing.T) {
+ // Test that no matter what we put in the client config,
+ // the client does not offer non-FIPS configurations.
+ fipstls.Force()
+ defer fipstls.Abandon()
+
+ c, s := net.Pipe()
+ defer c.Close()
+ defer s.Close()
+
+ clientConfig := testConfig.Clone()
+ // All sorts of traps for the client to avoid.
+ clientConfig.MinVersion = VersionSSL30
+ clientConfig.MaxVersion = VersionTLS13
+ clientConfig.CipherSuites = allCipherSuites()
+ clientConfig.CurvePreferences = defaultCurvePreferences
+
+ go Client(c, clientConfig).Handshake()
+ srv := Server(s, testConfig)
+ msg, err := srv.readHandshake(nil)
+ if err != nil {
+ t.Fatal(err)
+ }
+ hello, ok := msg.(*clientHelloMsg)
+ if !ok {
+ t.Fatalf("unexpected message type %T", msg)
+ }
+
+ if !isBoringVersion(hello.vers) {
+ t.Errorf("client vers=%#x, want %#x (TLS 1.2)", hello.vers, VersionTLS12)
+ }
+ for _, v := range hello.supportedVersions {
+ if !isBoringVersion(v) {
+ t.Errorf("client offered disallowed version %#x", v)
+ }
+ }
+ for _, id := range hello.cipherSuites {
+ if !isBoringCipherSuite(id) {
+ t.Errorf("client offered disallowed suite %#x", id)
+ }
+ }
+ for _, id := range hello.supportedCurves {
+ if !isBoringCurve(id) {
+ t.Errorf("client offered disallowed curve %d", id)
+ }
+ }
+ for _, sigHash := range hello.supportedSignatureAlgorithms {
+ if !isBoringSignatureScheme(sigHash) {
+ t.Errorf("client offered disallowed signature-and-hash %v", sigHash)
+ }
+ }
+}
+
+func TestBoringCertAlgs(t *testing.T) {
+ // NaCl, arm and wasm time out generating keys. Nothing in this test is architecture-specific, so just don't bother on those.
+ if runtime.GOOS == "nacl" || runtime.GOARCH == "arm" || runtime.GOOS == "js" {
+ t.Skipf("skipping on %s/%s because key generation takes too long", runtime.GOOS, runtime.GOARCH)
+ }
+
+ // Set up some roots, intermediate CAs, and leaf certs with various algorithms.
+ // X_Y is X signed by Y.
+ R1 := boringCert(t, "R1", boringRSAKey(t, 2048), nil, boringCertCA|boringCertFIPSOK)
+ R2 := boringCert(t, "R2", boringRSAKey(t, 512), nil, boringCertCA)
+
+ M1_R1 := boringCert(t, "M1_R1", boringECDSAKey(t, elliptic.P256()), R1, boringCertCA|boringCertFIPSOK)
+ M2_R1 := boringCert(t, "M2_R1", boringECDSAKey(t, elliptic.P224()), R1, boringCertCA)
+
+ I_R1 := boringCert(t, "I_R1", boringRSAKey(t, 3072), R1, boringCertCA|boringCertFIPSOK)
+ I_R2 := boringCert(t, "I_R2", I_R1.key, R2, boringCertCA|boringCertFIPSOK)
+ I_M1 := boringCert(t, "I_M1", I_R1.key, M1_R1, boringCertCA|boringCertFIPSOK)
+ I_M2 := boringCert(t, "I_M2", I_R1.key, M2_R1, boringCertCA|boringCertFIPSOK)
+
+ L1_I := boringCert(t, "L1_I", boringECDSAKey(t, elliptic.P384()), I_R1, boringCertLeaf|boringCertFIPSOK)
+ L2_I := boringCert(t, "L2_I", boringRSAKey(t, 1024), I_R1, boringCertLeaf)
+
+ // client verifying server cert
+ testServerCert := func(t *testing.T, desc string, pool *x509.CertPool, key interface{}, list [][]byte, ok bool) {
+ clientConfig := testConfig.Clone()
+ clientConfig.RootCAs = pool
+ clientConfig.InsecureSkipVerify = false
+ clientConfig.ServerName = "example.com"
+
+ serverConfig := testConfig.Clone()
+ serverConfig.Certificates = []Certificate{{Certificate: list, PrivateKey: key}}
+ serverConfig.BuildNameToCertificate()
+
+ clientErr, _ := boringHandshake(t, clientConfig, serverConfig)
+
+ if (clientErr == nil) == ok {
+ if ok {
+ t.Logf("%s: accept", desc)
+ } else {
+ t.Logf("%s: reject", desc)
+ }
+ } else {
+ if ok {
+ t.Errorf("%s: BAD reject (%v)", desc, clientErr)
+ } else {
+ t.Errorf("%s: BAD accept", desc)
+ }
+ }
+ }
+
+ // server verifying client cert
+ testClientCert := func(t *testing.T, desc string, pool *x509.CertPool, key interface{}, list [][]byte, ok bool) {
+ clientConfig := testConfig.Clone()
+ clientConfig.ServerName = "example.com"
+ clientConfig.Certificates = []Certificate{{Certificate: list, PrivateKey: key}}
+
+ serverConfig := testConfig.Clone()
+ serverConfig.ClientCAs = pool
+ serverConfig.ClientAuth = RequireAndVerifyClientCert
+
+ _, serverErr := boringHandshake(t, clientConfig, serverConfig)
+
+ if (serverErr == nil) == ok {
+ if ok {
+ t.Logf("%s: accept", desc)
+ } else {
+ t.Logf("%s: reject", desc)
+ }
+ } else {
+ if ok {
+ t.Errorf("%s: BAD reject (%v)", desc, serverErr)
+ } else {
+ t.Errorf("%s: BAD accept", desc)
+ }
+ }
+ }
+
+ // Run simple basic test with known answers before proceeding to
+ // exhaustive test with computed answers.
+ r1pool := x509.NewCertPool()
+ r1pool.AddCert(R1.cert)
+ testServerCert(t, "basic", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, true)
+ testClientCert(t, "basic (client cert)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, true)
+ fipstls.Force()
+ testServerCert(t, "basic (fips)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, false)
+ testClientCert(t, "basic (fips, client cert)", r1pool, L2_I.key, [][]byte{L2_I.der, I_R1.der}, false)
+ fipstls.Abandon()
+
+ if t.Failed() {
+ t.Fatal("basic test failed, skipping exhaustive test")
+ }
+
+ if testing.Short() {
+ t.Logf("basic test passed; skipping exhaustive test in -short mode")
+ return
+ }
+
+ for l := 1; l <= 2; l++ {
+ leaf := L1_I
+ if l == 2 {
+ leaf = L2_I
+ }
+ for i := 0; i < 64; i++ {
+ reachable := map[string]bool{leaf.parentOrg: true}
+ reachableFIPS := map[string]bool{leaf.parentOrg: leaf.fipsOK}
+ list := [][]byte{leaf.der}
+ listName := leaf.name
+ addList := func(cond int, c *boringCertificate) {
+ if cond != 0 {
+ list = append(list, c.der)
+ listName += "," + c.name
+ if reachable[c.org] {
+ reachable[c.parentOrg] = true
+ }
+ if reachableFIPS[c.org] && c.fipsOK {
+ reachableFIPS[c.parentOrg] = true
+ }
+ }
+ }
+ addList(i&1, I_R1)
+ addList(i&2, I_R2)
+ addList(i&4, I_M1)
+ addList(i&8, I_M2)
+ addList(i&16, M1_R1)
+ addList(i&32, M2_R1)
+
+ for r := 1; r <= 3; r++ {
+ pool := x509.NewCertPool()
+ rootName := ","
+ shouldVerify := false
+ shouldVerifyFIPS := false
+ addRoot := func(cond int, c *boringCertificate) {
+ if cond != 0 {
+ rootName += "," + c.name
+ pool.AddCert(c.cert)
+ if reachable[c.org] {
+ shouldVerify = true
+ }
+ if reachableFIPS[c.org] && c.fipsOK {
+ shouldVerifyFIPS = true
+ }
+ }
+ }
+ addRoot(r&1, R1)
+ addRoot(r&2, R2)
+ rootName = rootName[1:] // strip leading comma
+ testServerCert(t, listName+"->"+rootName[1:], pool, leaf.key, list, shouldVerify)
+ testClientCert(t, listName+"->"+rootName[1:]+"(client cert)", pool, leaf.key, list, shouldVerify)
+ fipstls.Force()
+ testServerCert(t, listName+"->"+rootName[1:]+" (fips)", pool, leaf.key, list, shouldVerifyFIPS)
+ testClientCert(t, listName+"->"+rootName[1:]+" (fips, client cert)", pool, leaf.key, list, shouldVerifyFIPS)
+ fipstls.Abandon()
+ }
+ }
+ }
+}
+
+const (
+ boringCertCA = iota
+ boringCertLeaf
+ boringCertFIPSOK = 0x80
+)
+
+func boringRSAKey(t *testing.T, size int) *rsa.PrivateKey {
+ k, err := rsa.GenerateKey(rand.Reader, size)
+ if err != nil {
+ t.Fatal(err)
+ }
+ return k
+}
+
+func boringECDSAKey(t *testing.T, curve elliptic.Curve) *ecdsa.PrivateKey {
+ k, err := ecdsa.GenerateKey(curve, rand.Reader)
+ if err != nil {
+ t.Fatal(err)
+ }
+ return k
+}
+
+type boringCertificate struct {
+ name string
+ org string
+ parentOrg string
+ der []byte
+ cert *x509.Certificate
+ key interface{}
+ fipsOK bool
+}
+
+func boringCert(t *testing.T, name string, key interface{}, parent *boringCertificate, mode int) *boringCertificate {
+ org := name
+ parentOrg := ""
+ if i := strings.Index(org, "_"); i >= 0 {
+ org = org[:i]
+ parentOrg = name[i+1:]
+ }
+ tmpl := &x509.Certificate{
+ SerialNumber: big.NewInt(1),
+ Subject: pkix.Name{
+ Organization: []string{org},
+ },
+ NotBefore: time.Unix(0, 0),
+ NotAfter: time.Unix(0, 0),
+
+ KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
+ ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
+ BasicConstraintsValid: true,
+ }
+ if mode&^boringCertFIPSOK == boringCertLeaf {
+ tmpl.DNSNames = []string{"example.com"}
+ } else {
+ tmpl.IsCA = true
+ tmpl.KeyUsage |= x509.KeyUsageCertSign
+ }
+
+ var pcert *x509.Certificate
+ var pkey interface{}
+ if parent != nil {
+ pcert = parent.cert
+ pkey = parent.key
+ } else {
+ pcert = tmpl
+ pkey = key
+ }
+
+ var pub interface{}
+ switch k := key.(type) {
+ case *rsa.PrivateKey:
+ pub = &k.PublicKey
+ case *ecdsa.PrivateKey:
+ pub = &k.PublicKey
+ default:
+ t.Fatalf("invalid key %T", key)
+ }
+
+ der, err := x509.CreateCertificate(rand.Reader, tmpl, pcert, pub, pkey)
+ if err != nil {
+ t.Fatal(err)
+ }
+ cert, err := x509.ParseCertificate(der)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ fipsOK := mode&boringCertFIPSOK != 0
+ return &boringCertificate{name, org, parentOrg, der, cert, key, fipsOK}
+}
+
+// A self-signed test certificate with an RSA key of size 2048, for testing
+// RSA-PSS with SHA512. SAN of example.golang.
+var (
+ testRSA2048Certificate []byte
+ testRSA2048PrivateKey *rsa.PrivateKey
+)
+
+func init() {
+ block, _ := pem.Decode(obscuretestdata.Rot13([]byte(`
+-----ORTVA PREGVSVPNGR-----
+ZVVP/mPPNrrtNjVONtVENYUUK/xu4+4mZH9QnemORpDjQDLWXbMVuipANDRYODNj
+RwRDZN4TN1HRPuZUDJAgMFOQomNrSj0kZGNkZQRkAGN0ZQInSj0lZQRlZwxkAGN0
+ZQInZOVkRQNBOtAIONbGO0SwoJHtD28jttRvZN0TPFdTFVo3QDRONDHNN4VOQjNj
+ttRXNbVONDPs8sx0A6vrPOK4VBIVsXvgg4xTpBDYrvzPsfwddUplfZVITRgSFZ6R
+4Nl141s/7VdqJ0HgVdAo4CKuEBVQ7lQkE284kY6KoPhi/g5uC3HpruLp3uzYvlIq
+ZxMDvMJgsHHWs/1dBgZ+buAt59YEJc4q+6vK0yn1WY3RjPVpxxAwW9uDoS7Co2PF
++RF9Lb55XNnc8XBoycpE8ZOFA38odajwsDqPKiBRBwnz2UHkXmRSK5ZN+sN0zr4P
+vbPpPEYJXy+TbA9S8sNOsbM+G+2rny4QYhB95eKE8FeBVIOu3KSBe/EIuwgKpAIS
+MXpiQg6q68I6wNXNLXz5ayw9TCcq4i+eNtZONNTwHQOBZN4TN1HqQjRO/jDRNjVS
+bQNGOtAIUFHRQQNXOtteOtRSODpQNGNZOtAIUEZONs8RNwNNZOxTN1HqRDDFZOPP
+QzI4LJ1joTHhM29fLJ5aZN0TPFdTFVo3QDROPjHNN4VONDPBbLfIpSPOuobdr3JU
+qP6I7KKKRPzawu01e8u80li0AE379aFQ3pj2Z+UXinKlfJdey5uwTIXj0igjQ81e
+I4WmQh7VsVbt5z8+DAP+7YdQMfm88iQXBefblFIBzHPtzPXSKrj+YN+rB/vDRWGe
+7rafqqBrKWRc27Rq5iJ+xzJJ3Dztyp2Tjl8jSeZQVdaeaBmON4bPaQRtgKWg0mbt
+aEjosRZNJv1nDEl5qG9XN3FC9zb5FrGSFmTTUvR4f4tUHr7wifNSS2dtgQ6+jU6f
+m9o6fukaP7t5VyOXuV7FIO/Hdg2lqW+xU1LowZpVd6ANZ5rAZXtMhWe3+mjfFtju
+TAnR
+-----RAQ PREGVSVPNGR-----`)))
+ testRSA2048Certificate = block.Bytes
+
+ block, _ = pem.Decode(obscuretestdata.Rot13([]byte(`
+-----ORTVA EFN CEVINGR XRL-----
+ZVVRcNVONNXPNDRNa/U5AQrbattI+PQyFUlbeorWOaQxP3bcta7V6du3ZeQPSEuY
+EHwBuBNZgrAK/+lXaIgSYFXwJ+Q14HGvN+8t8HqiBZF+y2jee/7rLG91UUbJUA4M
+v4fyKGWTHVzIeK1SPK/9nweGCdVGLBsF0IdrUshby9WJgFF9kZNvUWWQLlsLHTkr
+m29txiuRiJXBrFtTdsPwz5nKRsQNHwq/T6c8V30UDy7muQb2cgu1ZFfkOI+GNCaj
+AWahNbdNaNxF1vcsudQsEsUjNK6Tsx/gazcrNl7wirn10sRdmvSDLq1kGd/0ILL7
+I3QIEJFaYj7rariSrbjPtTPchM5L/Ew6KrY/djVQNDNONbVONDPAcZMvsq/it42u
+UqPiYhMnLF0E7FhaSycbKRfygTqYSfac0VsbWM/htSDOFNVVsYjZhzH6bKN1m7Hi
+98nVLI61QrCeGPQIQSOfUoAzC8WNb8JgohfRojq5mlbO7YLT2+pyxWxyJR73XdHd
+ezV+HWrlFpy2Tva7MGkOKm1JCOx9IjpajxrnKctNFVOJ23suRPZ9taLRRjnOrm5G
+6Zr8q1gUgLDi7ifXr7eb9j9/UXeEKrwdLXX1YkxusSevlI+z8YMWMa2aKBn6T3tS
+Ao8Dx1Hx5CHORAOzlZSWuG4Z/hhFd4LgZeeB2tv8D+sCuhTmp5FfuLXEOc0J4C5e
+zgIPgRSENbTONZRAOVSYeI2+UfTw0kLSnfXbi/DCr6UFGE1Uu2VMBAc+bX4bfmJR
+wOG4IpaVGzcy6gP1Jl4TpekwAtXVSMNw+1k1YHHYqbeKxhT8le0gNuT9mAlsJfFl
+CeFbiP0HIome8Wkkyn+xDIkRDDdJDkCyRIhY8xKnVQN6Ylg1Uchn2YiCNbTONADM
+p6Yd2G7+OkYkAqv2z8xMmrw5xtmOc/KqIfoSJEyroVK2XeSUfeUmG9CHx3QR1iMX
+Z6cmGg94aDuJFxQtPnj1FbuRyW3USVSjphfS1FWNp3cDrcq8ht6VLqycQZYgOw/C
+/5C6OIHgtb05R4+V/G3vLngztyDkGgyM0ExFI2yyNbTONYBKxXSK7nuCis0JxfQu
+hGshSBGCbbjtDT0RctJ0jEqPkrt/WYvp3yFQ0tfggDI2JfErpelJpknryEt10EzB
+38OobtzunS4kitfFihwBsvMGR8bX1G43Z+6AXfVyZY3LVYocH/9nWkCJl0f2QdQe
+pDWuMeyx+cmwON7Oas/HEqjkNbTNXE/PAj14Q+zeY3LYoovPKvlqdkIjki5cqMqm
+8guv3GApfJP4vTHEqpIdosHvaICqWvKr/Xnp3JTPrEWnSItoXNBkYgv1EO5ZxVut
+Q8rlhcOdx4J1Y1txekdfqw4GSykxjZljwy2R2F4LlD8COg6I04QbIEMfVXmdm+CS
+HvbaCd0PtLOPLKidvbWuCrjxBd/L5jeQOrMJ1SDX5DQ9J5Z8/5mkq4eqiWgwuoWc
+bBegiZqey6hcl9Um4OWQ3SKjISvCSR7wdrAdv0S21ivYkOCZZQ3HBQS6YY5RlYvE
+9I4kIZF8XKkit7ekfhdmZCfpIvnJHY6JAIOufQ2+92qUkFKmm5RWXD==
+-----RAQ EFN CEVINGR XRL-----`)))
+ var err error
+ testRSA2048PrivateKey, err = x509.ParsePKCS1PrivateKey(block.Bytes)
+ if err != nil {
+ panic(err)
+ }
+}
diff --git a/src/crypto/tls/cache.go b/src/crypto/tls/cache.go
new file mode 100644
index 0000000..a767761
--- /dev/null
+++ b/src/crypto/tls/cache.go
@@ -0,0 +1,95 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+ "crypto/x509"
+ "runtime"
+ "sync"
+ "sync/atomic"
+)
+
+type cacheEntry struct {
+ refs atomic.Int64
+ cert *x509.Certificate
+}
+
+// certCache implements an intern table for reference counted x509.Certificates,
+// implemented in a similar fashion to BoringSSL's CRYPTO_BUFFER_POOL. This
+// allows for a single x509.Certificate to be kept in memory and referenced from
+// multiple Conns. Returned references should not be mutated by callers. Certificates
+// are still safe to use after they are removed from the cache.
+//
+// Certificates are returned wrapped in an activeCert struct that should be held by
+// the caller. When references to the activeCert are freed, the number of references
+// to the certificate in the cache is decremented. Once the number of references
+// reaches zero, the entry is evicted from the cache.
+//
+// The main difference between this implementation and CRYPTO_BUFFER_POOL is that
+// CRYPTO_BUFFER_POOL is a more generic structure which supports blobs of data,
+// rather than specific structures. Since we only care about x509.Certificates,
+// certCache is implemented as a specific cache, rather than a generic one.
+//
+// See https://boringssl.googlesource.com/boringssl/+/master/include/openssl/pool.h
+// and https://boringssl.googlesource.com/boringssl/+/master/crypto/pool/pool.c
+// for the BoringSSL reference.
+type certCache struct {
+ sync.Map
+}
+
+var globalCertCache = new(certCache)
+
+// activeCert is a handle to a certificate held in the cache. Once there are
+// no alive activeCerts for a given certificate, the certificate is removed
+// from the cache by a finalizer.
+type activeCert struct {
+ cert *x509.Certificate
+}
+
+// active increments the number of references to the entry, wraps the
+// certificate in the entry in an activeCert, and sets the finalizer.
+//
+// Note that there is a race between active and the finalizer set on the
+// returned activeCert, triggered if active is called after the ref count is
+// decremented such that refs may be > 0 when evict is called. We consider this
+// safe, since the caller holding an activeCert for an entry that is no longer
+// in the cache is fine, with the only side effect being the memory overhead of
+// there being more than one distinct reference to a certificate alive at once.
+func (cc *certCache) active(e *cacheEntry) *activeCert {
+ e.refs.Add(1)
+ a := &activeCert{e.cert}
+ runtime.SetFinalizer(a, func(_ *activeCert) {
+ if e.refs.Add(-1) == 0 {
+ cc.evict(e)
+ }
+ })
+ return a
+}
+
+// evict removes a cacheEntry from the cache.
+func (cc *certCache) evict(e *cacheEntry) {
+ cc.Delete(string(e.cert.Raw))
+}
+
+// newCert returns a x509.Certificate parsed from der. If there is already a copy
+// of the certificate in the cache, a reference to the existing certificate will
+// be returned. Otherwise, a fresh certificate will be added to the cache, and
+// the reference returned. The returned reference should not be mutated.
+func (cc *certCache) newCert(der []byte) (*activeCert, error) {
+ if entry, ok := cc.Load(string(der)); ok {
+ return cc.active(entry.(*cacheEntry)), nil
+ }
+
+ cert, err := x509.ParseCertificate(der)
+ if err != nil {
+ return nil, err
+ }
+
+ entry := &cacheEntry{cert: cert}
+ if entry, loaded := cc.LoadOrStore(string(der), entry); loaded {
+ return cc.active(entry.(*cacheEntry)), nil
+ }
+ return cc.active(entry), nil
+}
diff --git a/src/crypto/tls/cache_test.go b/src/crypto/tls/cache_test.go
new file mode 100644
index 0000000..2846734
--- /dev/null
+++ b/src/crypto/tls/cache_test.go
@@ -0,0 +1,117 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+ "encoding/pem"
+ "fmt"
+ "runtime"
+ "testing"
+ "time"
+)
+
+func TestCertCache(t *testing.T) {
+ cc := certCache{}
+ p, _ := pem.Decode([]byte(rsaCertPEM))
+ if p == nil {
+ t.Fatal("Failed to decode certificate")
+ }
+
+ certA, err := cc.newCert(p.Bytes)
+ if err != nil {
+ t.Fatalf("newCert failed: %s", err)
+ }
+ certB, err := cc.newCert(p.Bytes)
+ if err != nil {
+ t.Fatalf("newCert failed: %s", err)
+ }
+ if certA.cert != certB.cert {
+ t.Fatal("newCert returned a unique reference for a duplicate certificate")
+ }
+
+ if entry, ok := cc.Load(string(p.Bytes)); !ok {
+ t.Fatal("cache does not contain expected entry")
+ } else {
+ if refs := entry.(*cacheEntry).refs.Load(); refs != 2 {
+ t.Fatalf("unexpected number of references: got %d, want 2", refs)
+ }
+ }
+
+ timeoutRefCheck := func(t *testing.T, key string, count int64) {
+ t.Helper()
+ c := time.After(4 * time.Second)
+ for {
+ select {
+ case <-c:
+ t.Fatal("timed out waiting for expected ref count")
+ default:
+ e, ok := cc.Load(key)
+ if !ok && count != 0 {
+ t.Fatal("cache does not contain expected key")
+ } else if count == 0 && !ok {
+ return
+ }
+
+ if e.(*cacheEntry).refs.Load() == count {
+ return
+ }
+ }
+ }
+ }
+
+ // Keep certA alive until at least now, so that we can
+ // purposefully nil it and force the finalizer to be
+ // called.
+ runtime.KeepAlive(certA)
+ certA = nil
+ runtime.GC()
+
+ timeoutRefCheck(t, string(p.Bytes), 1)
+
+ // Keep certB alive until at least now, so that we can
+ // purposefully nil it and force the finalizer to be
+ // called.
+ runtime.KeepAlive(certB)
+ certB = nil
+ runtime.GC()
+
+ timeoutRefCheck(t, string(p.Bytes), 0)
+}
+
+func BenchmarkCertCache(b *testing.B) {
+ p, _ := pem.Decode([]byte(rsaCertPEM))
+ if p == nil {
+ b.Fatal("Failed to decode certificate")
+ }
+
+ cc := certCache{}
+ b.ReportAllocs()
+ b.ResetTimer()
+ // We expect that calling newCert additional times after
+ // the initial call should not cause additional allocations.
+ for extra := 0; extra < 4; extra++ {
+ b.Run(fmt.Sprint(extra), func(b *testing.B) {
+ actives := make([]*activeCert, extra+1)
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ var err error
+ actives[0], err = cc.newCert(p.Bytes)
+ if err != nil {
+ b.Fatal(err)
+ }
+ for j := 0; j < extra; j++ {
+ actives[j+1], err = cc.newCert(p.Bytes)
+ if err != nil {
+ b.Fatal(err)
+ }
+ }
+ for j := 0; j < extra+1; j++ {
+ actives[j] = nil
+ }
+ runtime.GC()
+ }
+ })
+ }
+}
diff --git a/src/crypto/tls/cipher_suites.go b/src/crypto/tls/cipher_suites.go
new file mode 100644
index 0000000..589e8b6
--- /dev/null
+++ b/src/crypto/tls/cipher_suites.go
@@ -0,0 +1,694 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+ "crypto"
+ "crypto/aes"
+ "crypto/cipher"
+ "crypto/des"
+ "crypto/hmac"
+ "crypto/internal/boring"
+ "crypto/rc4"
+ "crypto/sha1"
+ "crypto/sha256"
+ "fmt"
+ "hash"
+ "internal/cpu"
+ "runtime"
+
+ "golang.org/x/crypto/chacha20poly1305"
+)
+
+// CipherSuite is a TLS cipher suite. Note that most functions in this package
+// accept and expose cipher suite IDs instead of this type.
+type CipherSuite struct {
+ ID uint16
+ Name string
+
+ // Supported versions is the list of TLS protocol versions that can
+ // negotiate this cipher suite.
+ SupportedVersions []uint16
+
+ // Insecure is true if the cipher suite has known security issues
+ // due to its primitives, design, or implementation.
+ Insecure bool
+}
+
+var (
+ supportedUpToTLS12 = []uint16{VersionTLS10, VersionTLS11, VersionTLS12}
+ supportedOnlyTLS12 = []uint16{VersionTLS12}
+ supportedOnlyTLS13 = []uint16{VersionTLS13}
+)
+
+// CipherSuites returns a list of cipher suites currently implemented by this
+// package, excluding those with security issues, which are returned by
+// InsecureCipherSuites.
+//
+// The list is sorted by ID. Note that the default cipher suites selected by
+// this package might depend on logic that can't be captured by a static list,
+// and might not match those returned by this function.
+func CipherSuites() []*CipherSuite {
+ return []*CipherSuite{
+ {TLS_RSA_WITH_AES_128_CBC_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, false},
+ {TLS_RSA_WITH_AES_256_CBC_SHA, "TLS_RSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, false},
+ {TLS_RSA_WITH_AES_128_GCM_SHA256, "TLS_RSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, false},
+ {TLS_RSA_WITH_AES_256_GCM_SHA384, "TLS_RSA_WITH_AES_256_GCM_SHA384", supportedOnlyTLS12, false},
+
+ {TLS_AES_128_GCM_SHA256, "TLS_AES_128_GCM_SHA256", supportedOnlyTLS13, false},
+ {TLS_AES_256_GCM_SHA384, "TLS_AES_256_GCM_SHA384", supportedOnlyTLS13, false},
+ {TLS_CHACHA20_POLY1305_SHA256, "TLS_CHACHA20_POLY1305_SHA256", supportedOnlyTLS13, false},
+
+ {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, false},
+ {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, false},
+ {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", supportedUpToTLS12, false},
+ {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", supportedUpToTLS12, false},
+ {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, false},
+ {TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", supportedOnlyTLS12, false},
+ {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", supportedOnlyTLS12, false},
+ {TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", supportedOnlyTLS12, false},
+ {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", supportedOnlyTLS12, false},
+ {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", supportedOnlyTLS12, false},
+ }
+}
+
+// InsecureCipherSuites returns a list of cipher suites currently implemented by
+// this package and which have security issues.
+//
+// Most applications should not use the cipher suites in this list, and should
+// only use those returned by CipherSuites.
+func InsecureCipherSuites() []*CipherSuite {
+ // This list includes RC4, CBC_SHA256, and 3DES cipher suites. See
+ // cipherSuitesPreferenceOrder for details.
+ return []*CipherSuite{
+ {TLS_RSA_WITH_RC4_128_SHA, "TLS_RSA_WITH_RC4_128_SHA", supportedUpToTLS12, true},
+ {TLS_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_RSA_WITH_3DES_EDE_CBC_SHA", supportedUpToTLS12, true},
+ {TLS_RSA_WITH_AES_128_CBC_SHA256, "TLS_RSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true},
+ {TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", supportedUpToTLS12, true},
+ {TLS_ECDHE_RSA_WITH_RC4_128_SHA, "TLS_ECDHE_RSA_WITH_RC4_128_SHA", supportedUpToTLS12, true},
+ {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", supportedUpToTLS12, true},
+ {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true},
+ {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", supportedOnlyTLS12, true},
+ }
+}
+
+// CipherSuiteName returns the standard name for the passed cipher suite ID
+// (e.g. "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"), or a fallback representation
+// of the ID value if the cipher suite is not implemented by this package.
+func CipherSuiteName(id uint16) string {
+ for _, c := range CipherSuites() {
+ if c.ID == id {
+ return c.Name
+ }
+ }
+ for _, c := range InsecureCipherSuites() {
+ if c.ID == id {
+ return c.Name
+ }
+ }
+ return fmt.Sprintf("0x%04X", id)
+}
+
+const (
+ // suiteECDHE indicates that the cipher suite involves elliptic curve
+ // Diffie-Hellman. This means that it should only be selected when the
+ // client indicates that it supports ECC with a curve and point format
+ // that we're happy with.
+ suiteECDHE = 1 << iota
+ // suiteECSign indicates that the cipher suite involves an ECDSA or
+ // EdDSA signature and therefore may only be selected when the server's
+ // certificate is ECDSA or EdDSA. If this is not set then the cipher suite
+ // is RSA based.
+ suiteECSign
+ // suiteTLS12 indicates that the cipher suite should only be advertised
+ // and accepted when using TLS 1.2.
+ suiteTLS12
+ // suiteSHA384 indicates that the cipher suite uses SHA384 as the
+ // handshake hash.
+ suiteSHA384
+)
+
+// A cipherSuite is a TLS 1.0–1.2 cipher suite, and defines the key exchange
+// mechanism, as well as the cipher+MAC pair or the AEAD.
+type cipherSuite struct {
+ id uint16
+ // the lengths, in bytes, of the key material needed for each component.
+ keyLen int
+ macLen int
+ ivLen int
+ ka func(version uint16) keyAgreement
+ // flags is a bitmask of the suite* values, above.
+ flags int
+ cipher func(key, iv []byte, isRead bool) any
+ mac func(key []byte) hash.Hash
+ aead func(key, fixedNonce []byte) aead
+}
+
+var cipherSuites = []*cipherSuite{ // TODO: replace with a map, since the order doesn't matter.
+ {TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, 32, 0, 12, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadChaCha20Poly1305},
+ {TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, 32, 0, 12, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12, nil, nil, aeadChaCha20Poly1305},
+ {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadAESGCM},
+ {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12, nil, nil, aeadAESGCM},
+ {TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
+ {TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
+ {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheRSAKA, suiteECDHE | suiteTLS12, cipherAES, macSHA256, nil},
+ {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
+ {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, ecdheECDSAKA, suiteECDHE | suiteECSign | suiteTLS12, cipherAES, macSHA256, nil},
+ {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECSign, cipherAES, macSHA1, nil},
+ {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
+ {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECSign, cipherAES, macSHA1, nil},
+ {TLS_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, rsaKA, suiteTLS12, nil, nil, aeadAESGCM},
+ {TLS_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, rsaKA, suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
+ {TLS_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, rsaKA, suiteTLS12, cipherAES, macSHA256, nil},
+ {TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
+ {TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil},
+ {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil},
+ {TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, 0, cipher3DES, macSHA1, nil},
+ {TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, 0, cipherRC4, macSHA1, nil},
+ {TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, suiteECDHE, cipherRC4, macSHA1, nil},
+ {TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheECDSAKA, suiteECDHE | suiteECSign, cipherRC4, macSHA1, nil},
+}
+
+// selectCipherSuite returns the first TLS 1.0–1.2 cipher suite from ids which
+// is also in supportedIDs and passes the ok filter.
+func selectCipherSuite(ids, supportedIDs []uint16, ok func(*cipherSuite) bool) *cipherSuite {
+ for _, id := range ids {
+ candidate := cipherSuiteByID(id)
+ if candidate == nil || !ok(candidate) {
+ continue
+ }
+
+ for _, suppID := range supportedIDs {
+ if id == suppID {
+ return candidate
+ }
+ }
+ }
+ return nil
+}
+
+// A cipherSuiteTLS13 defines only the pair of the AEAD algorithm and hash
+// algorithm to be used with HKDF. See RFC 8446, Appendix B.4.
+type cipherSuiteTLS13 struct {
+ id uint16
+ keyLen int
+ aead func(key, fixedNonce []byte) aead
+ hash crypto.Hash
+}
+
+var cipherSuitesTLS13 = []*cipherSuiteTLS13{ // TODO: replace with a map.
+ {TLS_AES_128_GCM_SHA256, 16, aeadAESGCMTLS13, crypto.SHA256},
+ {TLS_CHACHA20_POLY1305_SHA256, 32, aeadChaCha20Poly1305, crypto.SHA256},
+ {TLS_AES_256_GCM_SHA384, 32, aeadAESGCMTLS13, crypto.SHA384},
+}
+
+// cipherSuitesPreferenceOrder is the order in which we'll select (on the
+// server) or advertise (on the client) TLS 1.0–1.2 cipher suites.
+//
+// Cipher suites are filtered but not reordered based on the application and
+// peer's preferences, meaning we'll never select a suite lower in this list if
+// any higher one is available. This makes it more defensible to keep weaker
+// cipher suites enabled, especially on the server side where we get the last
+// word, since there are no known downgrade attacks on cipher suites selection.
+//
+// The list is sorted by applying the following priority rules, stopping at the
+// first (most important) applicable one:
+//
+// - Anything else comes before RC4
+//
+// RC4 has practically exploitable biases. See https://www.rc4nomore.com.
+//
+// - Anything else comes before CBC_SHA256
+//
+// SHA-256 variants of the CBC ciphersuites don't implement any Lucky13
+// countermeasures. See http://www.isg.rhul.ac.uk/tls/Lucky13.html and
+// https://www.imperialviolet.org/2013/02/04/luckythirteen.html.
+//
+// - Anything else comes before 3DES
+//
+// 3DES has 64-bit blocks, which makes it fundamentally susceptible to
+// birthday attacks. See https://sweet32.info.
+//
+// - ECDHE comes before anything else
+//
+// Once we got the broken stuff out of the way, the most important
+// property a cipher suite can have is forward secrecy. We don't
+// implement FFDHE, so that means ECDHE.
+//
+// - AEADs come before CBC ciphers
+//
+// Even with Lucky13 countermeasures, MAC-then-Encrypt CBC cipher suites
+// are fundamentally fragile, and suffered from an endless sequence of
+// padding oracle attacks. See https://eprint.iacr.org/2015/1129,
+// https://www.imperialviolet.org/2014/12/08/poodleagain.html, and
+// https://blog.cloudflare.com/yet-another-padding-oracle-in-openssl-cbc-ciphersuites/.
+//
+// - AES comes before ChaCha20
+//
+// When AES hardware is available, AES-128-GCM and AES-256-GCM are faster
+// than ChaCha20Poly1305.
+//
+// When AES hardware is not available, AES-128-GCM is one or more of: much
+// slower, way more complex, and less safe (because not constant time)
+// than ChaCha20Poly1305.
+//
+// We use this list if we think both peers have AES hardware, and
+// cipherSuitesPreferenceOrderNoAES otherwise.
+//
+// - AES-128 comes before AES-256
+//
+// The only potential advantages of AES-256 are better multi-target
+// margins, and hypothetical post-quantum properties. Neither apply to
+// TLS, and AES-256 is slower due to its four extra rounds (which don't
+// contribute to the advantages above).
+//
+// - ECDSA comes before RSA
+//
+// The relative order of ECDSA and RSA cipher suites doesn't matter,
+// as they depend on the certificate. Pick one to get a stable order.
+var cipherSuitesPreferenceOrder = []uint16{
+ // AEADs w/ ECDHE
+ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+ TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+
+ // CBC w/ ECDHE
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+
+ // AEADs w/o ECDHE
+ TLS_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_RSA_WITH_AES_256_GCM_SHA384,
+
+ // CBC w/o ECDHE
+ TLS_RSA_WITH_AES_128_CBC_SHA,
+ TLS_RSA_WITH_AES_256_CBC_SHA,
+
+ // 3DES
+ TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
+ TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+
+ // CBC_SHA256
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_RSA_WITH_AES_128_CBC_SHA256,
+
+ // RC4
+ TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA,
+ TLS_RSA_WITH_RC4_128_SHA,
+}
+
+var cipherSuitesPreferenceOrderNoAES = []uint16{
+ // ChaCha20Poly1305
+ TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+
+ // AES-GCM w/ ECDHE
+ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+
+ // The rest of cipherSuitesPreferenceOrder.
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+ TLS_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_RSA_WITH_AES_256_GCM_SHA384,
+ TLS_RSA_WITH_AES_128_CBC_SHA,
+ TLS_RSA_WITH_AES_256_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
+ TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA,
+ TLS_RSA_WITH_RC4_128_SHA,
+}
+
+// disabledCipherSuites are not used unless explicitly listed in
+// Config.CipherSuites. They MUST be at the end of cipherSuitesPreferenceOrder.
+var disabledCipherSuites = []uint16{
+ // CBC_SHA256
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_RSA_WITH_AES_128_CBC_SHA256,
+
+ // RC4
+ TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA,
+ TLS_RSA_WITH_RC4_128_SHA,
+}
+
+var (
+ defaultCipherSuitesLen = len(cipherSuitesPreferenceOrder) - len(disabledCipherSuites)
+ defaultCipherSuites = cipherSuitesPreferenceOrder[:defaultCipherSuitesLen]
+)
+
+// defaultCipherSuitesTLS13 is also the preference order, since there are no
+// disabled by default TLS 1.3 cipher suites. The same AES vs ChaCha20 logic as
+// cipherSuitesPreferenceOrder applies.
+var defaultCipherSuitesTLS13 = []uint16{
+ TLS_AES_128_GCM_SHA256,
+ TLS_AES_256_GCM_SHA384,
+ TLS_CHACHA20_POLY1305_SHA256,
+}
+
+var defaultCipherSuitesTLS13NoAES = []uint16{
+ TLS_CHACHA20_POLY1305_SHA256,
+ TLS_AES_128_GCM_SHA256,
+ TLS_AES_256_GCM_SHA384,
+}
+
+var (
+ hasGCMAsmAMD64 = cpu.X86.HasAES && cpu.X86.HasPCLMULQDQ
+ hasGCMAsmARM64 = cpu.ARM64.HasAES && cpu.ARM64.HasPMULL
+ // Keep in sync with crypto/aes/cipher_s390x.go.
+ hasGCMAsmS390X = cpu.S390X.HasAES && cpu.S390X.HasAESCBC && cpu.S390X.HasAESCTR &&
+ (cpu.S390X.HasGHASH || cpu.S390X.HasAESGCM)
+
+ hasAESGCMHardwareSupport = runtime.GOARCH == "amd64" && hasGCMAsmAMD64 ||
+ runtime.GOARCH == "arm64" && hasGCMAsmARM64 ||
+ runtime.GOARCH == "s390x" && hasGCMAsmS390X
+)
+
+var aesgcmCiphers = map[uint16]bool{
+ // TLS 1.2
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: true,
+ TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: true,
+ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: true,
+ TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: true,
+ // TLS 1.3
+ TLS_AES_128_GCM_SHA256: true,
+ TLS_AES_256_GCM_SHA384: true,
+}
+
+// aesgcmPreferred returns whether the first known cipher in the preference list
+// is an AES-GCM cipher, implying the peer has hardware support for it.
+func aesgcmPreferred(ciphers []uint16) bool {
+ for _, cID := range ciphers {
+ if c := cipherSuiteByID(cID); c != nil {
+ return aesgcmCiphers[cID]
+ }
+ if c := cipherSuiteTLS13ByID(cID); c != nil {
+ return aesgcmCiphers[cID]
+ }
+ }
+ return false
+}
+
+func cipherRC4(key, iv []byte, isRead bool) any {
+ cipher, _ := rc4.NewCipher(key)
+ return cipher
+}
+
+func cipher3DES(key, iv []byte, isRead bool) any {
+ block, _ := des.NewTripleDESCipher(key)
+ if isRead {
+ return cipher.NewCBCDecrypter(block, iv)
+ }
+ return cipher.NewCBCEncrypter(block, iv)
+}
+
+func cipherAES(key, iv []byte, isRead bool) any {
+ block, _ := aes.NewCipher(key)
+ if isRead {
+ return cipher.NewCBCDecrypter(block, iv)
+ }
+ return cipher.NewCBCEncrypter(block, iv)
+}
+
+// macSHA1 returns a SHA-1 based constant time MAC.
+func macSHA1(key []byte) hash.Hash {
+ h := sha1.New
+ // The BoringCrypto SHA1 does not have a constant-time
+ // checksum function, so don't try to use it.
+ if !boring.Enabled {
+ h = newConstantTimeHash(h)
+ }
+ return hmac.New(h, key)
+}
+
+// macSHA256 returns a SHA-256 based MAC. This is only supported in TLS 1.2 and
+// is currently only used in disabled-by-default cipher suites.
+func macSHA256(key []byte) hash.Hash {
+ return hmac.New(sha256.New, key)
+}
+
+type aead interface {
+ cipher.AEAD
+
+ // explicitNonceLen returns the number of bytes of explicit nonce
+ // included in each record. This is eight for older AEADs and
+ // zero for modern ones.
+ explicitNonceLen() int
+}
+
+const (
+ aeadNonceLength = 12
+ noncePrefixLength = 4
+)
+
+// prefixNonceAEAD wraps an AEAD and prefixes a fixed portion of the nonce to
+// each call.
+type prefixNonceAEAD struct {
+ // nonce contains the fixed part of the nonce in the first four bytes.
+ nonce [aeadNonceLength]byte
+ aead cipher.AEAD
+}
+
+func (f *prefixNonceAEAD) NonceSize() int { return aeadNonceLength - noncePrefixLength }
+func (f *prefixNonceAEAD) Overhead() int { return f.aead.Overhead() }
+func (f *prefixNonceAEAD) explicitNonceLen() int { return f.NonceSize() }
+
+func (f *prefixNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte {
+ copy(f.nonce[4:], nonce)
+ return f.aead.Seal(out, f.nonce[:], plaintext, additionalData)
+}
+
+func (f *prefixNonceAEAD) Open(out, nonce, ciphertext, additionalData []byte) ([]byte, error) {
+ copy(f.nonce[4:], nonce)
+ return f.aead.Open(out, f.nonce[:], ciphertext, additionalData)
+}
+
+// xorNonceAEAD wraps an AEAD by XORing in a fixed pattern to the nonce
+// before each call.
+type xorNonceAEAD struct {
+ nonceMask [aeadNonceLength]byte
+ aead cipher.AEAD
+}
+
+func (f *xorNonceAEAD) NonceSize() int { return 8 } // 64-bit sequence number
+func (f *xorNonceAEAD) Overhead() int { return f.aead.Overhead() }
+func (f *xorNonceAEAD) explicitNonceLen() int { return 0 }
+
+func (f *xorNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte {
+ for i, b := range nonce {
+ f.nonceMask[4+i] ^= b
+ }
+ result := f.aead.Seal(out, f.nonceMask[:], plaintext, additionalData)
+ for i, b := range nonce {
+ f.nonceMask[4+i] ^= b
+ }
+
+ return result
+}
+
+func (f *xorNonceAEAD) Open(out, nonce, ciphertext, additionalData []byte) ([]byte, error) {
+ for i, b := range nonce {
+ f.nonceMask[4+i] ^= b
+ }
+ result, err := f.aead.Open(out, f.nonceMask[:], ciphertext, additionalData)
+ for i, b := range nonce {
+ f.nonceMask[4+i] ^= b
+ }
+
+ return result, err
+}
+
+func aeadAESGCM(key, noncePrefix []byte) aead {
+ if len(noncePrefix) != noncePrefixLength {
+ panic("tls: internal error: wrong nonce length")
+ }
+ aes, err := aes.NewCipher(key)
+ if err != nil {
+ panic(err)
+ }
+ var aead cipher.AEAD
+ if boring.Enabled {
+ aead, err = boring.NewGCMTLS(aes)
+ } else {
+ boring.Unreachable()
+ aead, err = cipher.NewGCM(aes)
+ }
+ if err != nil {
+ panic(err)
+ }
+
+ ret := &prefixNonceAEAD{aead: aead}
+ copy(ret.nonce[:], noncePrefix)
+ return ret
+}
+
+func aeadAESGCMTLS13(key, nonceMask []byte) aead {
+ if len(nonceMask) != aeadNonceLength {
+ panic("tls: internal error: wrong nonce length")
+ }
+ aes, err := aes.NewCipher(key)
+ if err != nil {
+ panic(err)
+ }
+ aead, err := cipher.NewGCM(aes)
+ if err != nil {
+ panic(err)
+ }
+
+ ret := &xorNonceAEAD{aead: aead}
+ copy(ret.nonceMask[:], nonceMask)
+ return ret
+}
+
+func aeadChaCha20Poly1305(key, nonceMask []byte) aead {
+ if len(nonceMask) != aeadNonceLength {
+ panic("tls: internal error: wrong nonce length")
+ }
+ aead, err := chacha20poly1305.New(key)
+ if err != nil {
+ panic(err)
+ }
+
+ ret := &xorNonceAEAD{aead: aead}
+ copy(ret.nonceMask[:], nonceMask)
+ return ret
+}
+
+type constantTimeHash interface {
+ hash.Hash
+ ConstantTimeSum(b []byte) []byte
+}
+
+// cthWrapper wraps any hash.Hash that implements ConstantTimeSum, and replaces
+// with that all calls to Sum. It's used to obtain a ConstantTimeSum-based HMAC.
+type cthWrapper struct {
+ h constantTimeHash
+}
+
+func (c *cthWrapper) Size() int { return c.h.Size() }
+func (c *cthWrapper) BlockSize() int { return c.h.BlockSize() }
+func (c *cthWrapper) Reset() { c.h.Reset() }
+func (c *cthWrapper) Write(p []byte) (int, error) { return c.h.Write(p) }
+func (c *cthWrapper) Sum(b []byte) []byte { return c.h.ConstantTimeSum(b) }
+
+func newConstantTimeHash(h func() hash.Hash) func() hash.Hash {
+ boring.Unreachable()
+ return func() hash.Hash {
+ return &cthWrapper{h().(constantTimeHash)}
+ }
+}
+
+// tls10MAC implements the TLS 1.0 MAC function. RFC 2246, Section 6.2.3.
+func tls10MAC(h hash.Hash, out, seq, header, data, extra []byte) []byte {
+ h.Reset()
+ h.Write(seq)
+ h.Write(header)
+ h.Write(data)
+ res := h.Sum(out)
+ if extra != nil {
+ h.Write(extra)
+ }
+ return res
+}
+
+func rsaKA(version uint16) keyAgreement {
+ return rsaKeyAgreement{}
+}
+
+func ecdheECDSAKA(version uint16) keyAgreement {
+ return &ecdheKeyAgreement{
+ isRSA: false,
+ version: version,
+ }
+}
+
+func ecdheRSAKA(version uint16) keyAgreement {
+ return &ecdheKeyAgreement{
+ isRSA: true,
+ version: version,
+ }
+}
+
+// mutualCipherSuite returns a cipherSuite given a list of supported
+// ciphersuites and the id requested by the peer.
+func mutualCipherSuite(have []uint16, want uint16) *cipherSuite {
+ for _, id := range have {
+ if id == want {
+ return cipherSuiteByID(id)
+ }
+ }
+ return nil
+}
+
+func cipherSuiteByID(id uint16) *cipherSuite {
+ for _, cipherSuite := range cipherSuites {
+ if cipherSuite.id == id {
+ return cipherSuite
+ }
+ }
+ return nil
+}
+
+func mutualCipherSuiteTLS13(have []uint16, want uint16) *cipherSuiteTLS13 {
+ for _, id := range have {
+ if id == want {
+ return cipherSuiteTLS13ByID(id)
+ }
+ }
+ return nil
+}
+
+func cipherSuiteTLS13ByID(id uint16) *cipherSuiteTLS13 {
+ for _, cipherSuite := range cipherSuitesTLS13 {
+ if cipherSuite.id == id {
+ return cipherSuite
+ }
+ }
+ return nil
+}
+
+// A list of cipher suite IDs that are, or have been, implemented by this
+// package.
+//
+// See https://www.iana.org/assignments/tls-parameters/tls-parameters.xml
+const (
+ // TLS 1.0 - 1.2 cipher suites.
+ TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005
+ TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a
+ TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002f
+ TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035
+ TLS_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0x003c
+ TLS_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0x009c
+ TLS_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0x009d
+ TLS_ECDHE_ECDSA_WITH_RC4_128_SHA uint16 = 0xc007
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xc009
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xc00a
+ TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xc011
+ TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xc012
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xc013
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xc014
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc023
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 uint16 = 0xc027
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02f
+ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b
+ TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc030
+ TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc02c
+ TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcca8
+ TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcca9
+
+ // TLS 1.3 cipher suites.
+ TLS_AES_128_GCM_SHA256 uint16 = 0x1301
+ TLS_AES_256_GCM_SHA384 uint16 = 0x1302
+ TLS_CHACHA20_POLY1305_SHA256 uint16 = 0x1303
+
+ // TLS_FALLBACK_SCSV isn't a standard cipher suite but an indicator
+ // that the client is doing version fallback. See RFC 7507.
+ TLS_FALLBACK_SCSV uint16 = 0x5600
+
+ // Legacy names for the corresponding cipher suites with the correct _SHA256
+ // suffix, retained for backward compatibility.
+ TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305 = TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
+ TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305 = TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
+)
diff --git a/src/crypto/tls/common.go b/src/crypto/tls/common.go
new file mode 100644
index 0000000..e0885a0
--- /dev/null
+++ b/src/crypto/tls/common.go
@@ -0,0 +1,1547 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+ "bytes"
+ "container/list"
+ "context"
+ "crypto"
+ "crypto/ecdsa"
+ "crypto/ed25519"
+ "crypto/elliptic"
+ "crypto/rand"
+ "crypto/rsa"
+ "crypto/sha512"
+ "crypto/x509"
+ "errors"
+ "fmt"
+ "io"
+ "net"
+ "strings"
+ "sync"
+ "time"
+)
+
+const (
+ VersionTLS10 = 0x0301
+ VersionTLS11 = 0x0302
+ VersionTLS12 = 0x0303
+ VersionTLS13 = 0x0304
+
+ // Deprecated: SSLv3 is cryptographically broken, and is no longer
+ // supported by this package. See golang.org/issue/32716.
+ VersionSSL30 = 0x0300
+)
+
+// VersionName returns the name for the provided TLS version number
+// (e.g. "TLS 1.3"), or a fallback representation of the value if the
+// version is not implemented by this package.
+func VersionName(version uint16) string {
+ switch version {
+ case VersionSSL30:
+ return "SSLv3"
+ case VersionTLS10:
+ return "TLS 1.0"
+ case VersionTLS11:
+ return "TLS 1.1"
+ case VersionTLS12:
+ return "TLS 1.2"
+ case VersionTLS13:
+ return "TLS 1.3"
+ default:
+ return fmt.Sprintf("0x%04X", version)
+ }
+}
+
+const (
+ maxPlaintext = 16384 // maximum plaintext payload length
+ maxCiphertext = 16384 + 2048 // maximum ciphertext payload length
+ maxCiphertextTLS13 = 16384 + 256 // maximum ciphertext length in TLS 1.3
+ recordHeaderLen = 5 // record header length
+ maxHandshake = 65536 // maximum handshake we support (protocol max is 16 MB)
+ maxUselessRecords = 16 // maximum number of consecutive non-advancing records
+)
+
+// TLS record types.
+type recordType uint8
+
+const (
+ recordTypeChangeCipherSpec recordType = 20
+ recordTypeAlert recordType = 21
+ recordTypeHandshake recordType = 22
+ recordTypeApplicationData recordType = 23
+)
+
+// TLS handshake message types.
+const (
+ typeHelloRequest uint8 = 0
+ typeClientHello uint8 = 1
+ typeServerHello uint8 = 2
+ typeNewSessionTicket uint8 = 4
+ typeEndOfEarlyData uint8 = 5
+ typeEncryptedExtensions uint8 = 8
+ typeCertificate uint8 = 11
+ typeServerKeyExchange uint8 = 12
+ typeCertificateRequest uint8 = 13
+ typeServerHelloDone uint8 = 14
+ typeCertificateVerify uint8 = 15
+ typeClientKeyExchange uint8 = 16
+ typeFinished uint8 = 20
+ typeCertificateStatus uint8 = 22
+ typeKeyUpdate uint8 = 24
+ typeNextProtocol uint8 = 67 // Not IANA assigned
+ typeMessageHash uint8 = 254 // synthetic message
+)
+
+// TLS compression types.
+const (
+ compressionNone uint8 = 0
+)
+
+// TLS extension numbers
+const (
+ extensionServerName uint16 = 0
+ extensionStatusRequest uint16 = 5
+ extensionSupportedCurves uint16 = 10 // supported_groups in TLS 1.3, see RFC 8446, Section 4.2.7
+ extensionSupportedPoints uint16 = 11
+ extensionSignatureAlgorithms uint16 = 13
+ extensionALPN uint16 = 16
+ extensionSCT uint16 = 18
+ extensionExtendedMasterSecret uint16 = 23
+ extensionSessionTicket uint16 = 35
+ extensionPreSharedKey uint16 = 41
+ extensionEarlyData uint16 = 42
+ extensionSupportedVersions uint16 = 43
+ extensionCookie uint16 = 44
+ extensionPSKModes uint16 = 45
+ extensionCertificateAuthorities uint16 = 47
+ extensionSignatureAlgorithmsCert uint16 = 50
+ extensionKeyShare uint16 = 51
+ extensionQUICTransportParameters uint16 = 57
+ extensionRenegotiationInfo uint16 = 0xff01
+)
+
+// TLS signaling cipher suite values
+const (
+ scsvRenegotiation uint16 = 0x00ff
+)
+
+// CurveID is the type of a TLS identifier for an elliptic curve. See
+// https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8.
+//
+// In TLS 1.3, this type is called NamedGroup, but at this time this library
+// only supports Elliptic Curve based groups. See RFC 8446, Section 4.2.7.
+type CurveID uint16
+
+const (
+ CurveP256 CurveID = 23
+ CurveP384 CurveID = 24
+ CurveP521 CurveID = 25
+ X25519 CurveID = 29
+)
+
+// TLS 1.3 Key Share. See RFC 8446, Section 4.2.8.
+type keyShare struct {
+ group CurveID
+ data []byte
+}
+
+// TLS 1.3 PSK Key Exchange Modes. See RFC 8446, Section 4.2.9.
+const (
+ pskModePlain uint8 = 0
+ pskModeDHE uint8 = 1
+)
+
+// TLS 1.3 PSK Identity. Can be a Session Ticket, or a reference to a saved
+// session. See RFC 8446, Section 4.2.11.
+type pskIdentity struct {
+ label []byte
+ obfuscatedTicketAge uint32
+}
+
+// TLS Elliptic Curve Point Formats
+// https://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-9
+const (
+ pointFormatUncompressed uint8 = 0
+)
+
+// TLS CertificateStatusType (RFC 3546)
+const (
+ statusTypeOCSP uint8 = 1
+)
+
+// Certificate types (for certificateRequestMsg)
+const (
+ certTypeRSASign = 1
+ certTypeECDSASign = 64 // ECDSA or EdDSA keys, see RFC 8422, Section 3.
+)
+
+// Signature algorithms (for internal signaling use). Starting at 225 to avoid overlap with
+// TLS 1.2 codepoints (RFC 5246, Appendix A.4.1), with which these have nothing to do.
+const (
+ signaturePKCS1v15 uint8 = iota + 225
+ signatureRSAPSS
+ signatureECDSA
+ signatureEd25519
+)
+
+// directSigning is a standard Hash value that signals that no pre-hashing
+// should be performed, and that the input should be signed directly. It is the
+// hash function associated with the Ed25519 signature scheme.
+var directSigning crypto.Hash = 0
+
+// defaultSupportedSignatureAlgorithms contains the signature and hash algorithms that
+// the code advertises as supported in a TLS 1.2+ ClientHello and in a TLS 1.2+
+// CertificateRequest. The two fields are merged to match with TLS 1.3.
+// Note that in TLS 1.2, the ECDSA algorithms are not constrained to P-256, etc.
+var defaultSupportedSignatureAlgorithms = []SignatureScheme{
+ PSSWithSHA256,
+ ECDSAWithP256AndSHA256,
+ Ed25519,
+ PSSWithSHA384,
+ PSSWithSHA512,
+ PKCS1WithSHA256,
+ PKCS1WithSHA384,
+ PKCS1WithSHA512,
+ ECDSAWithP384AndSHA384,
+ ECDSAWithP521AndSHA512,
+ PKCS1WithSHA1,
+ ECDSAWithSHA1,
+}
+
+// helloRetryRequestRandom is set as the Random value of a ServerHello
+// to signal that the message is actually a HelloRetryRequest.
+var helloRetryRequestRandom = []byte{ // See RFC 8446, Section 4.1.3.
+ 0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11,
+ 0xBE, 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91,
+ 0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E,
+ 0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C,
+}
+
+const (
+ // downgradeCanaryTLS12 or downgradeCanaryTLS11 is embedded in the server
+ // random as a downgrade protection if the server would be capable of
+ // negotiating a higher version. See RFC 8446, Section 4.1.3.
+ downgradeCanaryTLS12 = "DOWNGRD\x01"
+ downgradeCanaryTLS11 = "DOWNGRD\x00"
+)
+
+// testingOnlyForceDowngradeCanary is set in tests to force the server side to
+// include downgrade canaries even if it's using its highers supported version.
+var testingOnlyForceDowngradeCanary bool
+
+// ConnectionState records basic TLS details about the connection.
+type ConnectionState struct {
+ // Version is the TLS version used by the connection (e.g. VersionTLS12).
+ Version uint16
+
+ // HandshakeComplete is true if the handshake has concluded.
+ HandshakeComplete bool
+
+ // DidResume is true if this connection was successfully resumed from a
+ // previous session with a session ticket or similar mechanism.
+ DidResume bool
+
+ // CipherSuite is the cipher suite negotiated for the connection (e.g.
+ // TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_AES_128_GCM_SHA256).
+ CipherSuite uint16
+
+ // NegotiatedProtocol is the application protocol negotiated with ALPN.
+ NegotiatedProtocol string
+
+ // NegotiatedProtocolIsMutual used to indicate a mutual NPN negotiation.
+ //
+ // Deprecated: this value is always true.
+ NegotiatedProtocolIsMutual bool
+
+ // ServerName is the value of the Server Name Indication extension sent by
+ // the client. It's available both on the server and on the client side.
+ ServerName string
+
+ // PeerCertificates are the parsed certificates sent by the peer, in the
+ // order in which they were sent. The first element is the leaf certificate
+ // that the connection is verified against.
+ //
+ // On the client side, it can't be empty. On the server side, it can be
+ // empty if Config.ClientAuth is not RequireAnyClientCert or
+ // RequireAndVerifyClientCert.
+ //
+ // PeerCertificates and its contents should not be modified.
+ PeerCertificates []*x509.Certificate
+
+ // VerifiedChains is a list of one or more chains where the first element is
+ // PeerCertificates[0] and the last element is from Config.RootCAs (on the
+ // client side) or Config.ClientCAs (on the server side).
+ //
+ // On the client side, it's set if Config.InsecureSkipVerify is false. On
+ // the server side, it's set if Config.ClientAuth is VerifyClientCertIfGiven
+ // (and the peer provided a certificate) or RequireAndVerifyClientCert.
+ //
+ // VerifiedChains and its contents should not be modified.
+ VerifiedChains [][]*x509.Certificate
+
+ // SignedCertificateTimestamps is a list of SCTs provided by the peer
+ // through the TLS handshake for the leaf certificate, if any.
+ SignedCertificateTimestamps [][]byte
+
+ // OCSPResponse is a stapled Online Certificate Status Protocol (OCSP)
+ // response provided by the peer for the leaf certificate, if any.
+ OCSPResponse []byte
+
+ // TLSUnique contains the "tls-unique" channel binding value (see RFC 5929,
+ // Section 3). This value will be nil for TLS 1.3 connections and for
+ // resumed connections that don't support Extended Master Secret (RFC 7627).
+ TLSUnique []byte
+
+ // ekm is a closure exposed via ExportKeyingMaterial.
+ ekm func(label string, context []byte, length int) ([]byte, error)
+}
+
+// ExportKeyingMaterial returns length bytes of exported key material in a new
+// slice as defined in RFC 5705. If context is nil, it is not used as part of
+// the seed. If the connection was set to allow renegotiation via
+// Config.Renegotiation, this function will return an error.
+//
+// There are conditions in which the returned values might not be unique to a
+// connection. See the Security Considerations sections of RFC 5705 and RFC 7627,
+// and https://mitls.org/pages/attacks/3SHAKE#channelbindings.
+func (cs *ConnectionState) ExportKeyingMaterial(label string, context []byte, length int) ([]byte, error) {
+ return cs.ekm(label, context, length)
+}
+
+// ClientAuthType declares the policy the server will follow for
+// TLS Client Authentication.
+type ClientAuthType int
+
+const (
+ // NoClientCert indicates that no client certificate should be requested
+ // during the handshake, and if any certificates are sent they will not
+ // be verified.
+ NoClientCert ClientAuthType = iota
+ // RequestClientCert indicates that a client certificate should be requested
+ // during the handshake, but does not require that the client send any
+ // certificates.
+ RequestClientCert
+ // RequireAnyClientCert indicates that a client certificate should be requested
+ // during the handshake, and that at least one certificate is required to be
+ // sent by the client, but that certificate is not required to be valid.
+ RequireAnyClientCert
+ // VerifyClientCertIfGiven indicates that a client certificate should be requested
+ // during the handshake, but does not require that the client sends a
+ // certificate. If the client does send a certificate it is required to be
+ // valid.
+ VerifyClientCertIfGiven
+ // RequireAndVerifyClientCert indicates that a client certificate should be requested
+ // during the handshake, and that at least one valid certificate is required
+ // to be sent by the client.
+ RequireAndVerifyClientCert
+)
+
+// requiresClientCert reports 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
+ }
+}
+
+// ClientSessionCache is a cache of ClientSessionState objects that can be used
+// by a client to resume a TLS session with a given server. ClientSessionCache
+// implementations should expect to be called concurrently from different
+// goroutines. Up to TLS 1.2, only ticket-based resumption is supported, not
+// SessionID-based resumption. In TLS 1.3 they were merged into PSK modes, which
+// are supported via this interface.
+type ClientSessionCache interface {
+ // Get searches for a ClientSessionState associated with the given key.
+ // On return, ok is true if one was found.
+ Get(sessionKey string) (session *ClientSessionState, ok bool)
+
+ // Put adds the ClientSessionState to the cache with the given key. It might
+ // get called multiple times in a connection if a TLS 1.3 server provides
+ // more than one session ticket. If called with a nil *ClientSessionState,
+ // it should remove the cache entry.
+ Put(sessionKey string, cs *ClientSessionState)
+}
+
+//go:generate stringer -type=SignatureScheme,CurveID,ClientAuthType -output=common_string.go
+
+// SignatureScheme identifies a signature algorithm supported by TLS. See
+// RFC 8446, Section 4.2.3.
+type SignatureScheme uint16
+
+const (
+ // RSASSA-PKCS1-v1_5 algorithms.
+ PKCS1WithSHA256 SignatureScheme = 0x0401
+ PKCS1WithSHA384 SignatureScheme = 0x0501
+ PKCS1WithSHA512 SignatureScheme = 0x0601
+
+ // RSASSA-PSS algorithms with public key OID rsaEncryption.
+ PSSWithSHA256 SignatureScheme = 0x0804
+ PSSWithSHA384 SignatureScheme = 0x0805
+ PSSWithSHA512 SignatureScheme = 0x0806
+
+ // ECDSA algorithms. Only constrained to a specific curve in TLS 1.3.
+ ECDSAWithP256AndSHA256 SignatureScheme = 0x0403
+ ECDSAWithP384AndSHA384 SignatureScheme = 0x0503
+ ECDSAWithP521AndSHA512 SignatureScheme = 0x0603
+
+ // EdDSA algorithms.
+ Ed25519 SignatureScheme = 0x0807
+
+ // Legacy signature and hash algorithms for TLS 1.2.
+ PKCS1WithSHA1 SignatureScheme = 0x0201
+ ECDSAWithSHA1 SignatureScheme = 0x0203
+)
+
+// ClientHelloInfo contains information from a ClientHello message in order to
+// guide application logic in the GetCertificate and GetConfigForClient callbacks.
+type ClientHelloInfo struct {
+ // CipherSuites lists the CipherSuites supported by the client (e.g.
+ // TLS_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256).
+ CipherSuites []uint16
+
+ // ServerName indicates the name of the server requested by the client
+ // in order to support virtual hosting. ServerName is only set if the
+ // client is using SNI (see RFC 4366, Section 3.1).
+ ServerName string
+
+ // SupportedCurves lists the elliptic curves supported by the client.
+ // SupportedCurves is set only if the Supported Elliptic Curves
+ // Extension is being used (see RFC 4492, Section 5.1.1).
+ SupportedCurves []CurveID
+
+ // SupportedPoints lists the point formats supported by the client.
+ // SupportedPoints is set only if the Supported Point Formats Extension
+ // is being used (see RFC 4492, Section 5.1.2).
+ SupportedPoints []uint8
+
+ // SignatureSchemes lists the signature and hash schemes that the client
+ // is willing to verify. SignatureSchemes is set only if the Signature
+ // Algorithms Extension is being used (see RFC 5246, Section 7.4.1.4.1).
+ SignatureSchemes []SignatureScheme
+
+ // SupportedProtos lists the application protocols supported by the client.
+ // SupportedProtos is set only if the Application-Layer Protocol
+ // Negotiation Extension is being used (see RFC 7301, Section 3.1).
+ //
+ // Servers can select a protocol by setting Config.NextProtos in a
+ // GetConfigForClient return value.
+ SupportedProtos []string
+
+ // SupportedVersions lists the TLS versions supported by the client.
+ // For TLS versions less than 1.3, this is extrapolated from the max
+ // version advertised by the client, so values other than the greatest
+ // might be rejected if used.
+ SupportedVersions []uint16
+
+ // Conn is the underlying net.Conn for the connection. Do not read
+ // from, or write to, this connection; that will cause the TLS
+ // connection to fail.
+ Conn net.Conn
+
+ // config is embedded by the GetCertificate or GetConfigForClient caller,
+ // for use with SupportsCertificate.
+ config *Config
+
+ // ctx is the context of the handshake that is in progress.
+ ctx context.Context
+}
+
+// Context returns the context of the handshake that is in progress.
+// This context is a child of the context passed to HandshakeContext,
+// if any, and is canceled when the handshake concludes.
+func (c *ClientHelloInfo) Context() context.Context {
+ return c.ctx
+}
+
+// CertificateRequestInfo contains information from a server's
+// CertificateRequest message, which is used to demand a certificate and proof
+// of control from a client.
+type CertificateRequestInfo struct {
+ // AcceptableCAs contains zero or more, DER-encoded, X.501
+ // Distinguished Names. These are the names of root or intermediate CAs
+ // that the server wishes the returned certificate to be signed by. An
+ // empty slice indicates that the server has no preference.
+ AcceptableCAs [][]byte
+
+ // SignatureSchemes lists the signature schemes that the server is
+ // willing to verify.
+ SignatureSchemes []SignatureScheme
+
+ // Version is the TLS version that was negotiated for this connection.
+ Version uint16
+
+ // ctx is the context of the handshake that is in progress.
+ ctx context.Context
+}
+
+// Context returns the context of the handshake that is in progress.
+// This context is a child of the context passed to HandshakeContext,
+// if any, and is canceled when the handshake concludes.
+func (c *CertificateRequestInfo) Context() context.Context {
+ return c.ctx
+}
+
+// RenegotiationSupport enumerates the different levels of support for TLS
+// renegotiation. TLS renegotiation is the act of performing subsequent
+// handshakes on a connection after the first. This significantly complicates
+// the state machine and has been the source of numerous, subtle security
+// issues. Initiating a renegotiation is not supported, but support for
+// accepting renegotiation requests may be enabled.
+//
+// Even when enabled, the server may not change its identity between handshakes
+// (i.e. the leaf certificate must be the same). Additionally, concurrent
+// handshake and application data flow is not permitted so renegotiation can
+// only be used with protocols that synchronise with the renegotiation, such as
+// HTTPS.
+//
+// Renegotiation is not defined in TLS 1.3.
+type RenegotiationSupport int
+
+const (
+ // RenegotiateNever disables renegotiation.
+ RenegotiateNever RenegotiationSupport = iota
+
+ // RenegotiateOnceAsClient allows a remote server to request
+ // renegotiation once per connection.
+ RenegotiateOnceAsClient
+
+ // RenegotiateFreelyAsClient allows a remote server to repeatedly
+ // request renegotiation.
+ RenegotiateFreelyAsClient
+)
+
+// A Config structure is used to configure a TLS client or server.
+// After one has been passed to a TLS function it must not be
+// modified. A Config may be reused; the tls package will also not
+// modify it.
+type Config struct {
+ // Rand provides the source of entropy for nonces and RSA blinding.
+ // If Rand is nil, TLS uses the cryptographic random reader in package
+ // crypto/rand.
+ // The Reader must be safe for use by multiple goroutines.
+ Rand io.Reader
+
+ // Time returns the current time as the number of seconds since the epoch.
+ // If Time is nil, TLS uses time.Now.
+ Time func() time.Time
+
+ // Certificates contains one or more certificate chains to present to the
+ // other side of the connection. The first certificate compatible with the
+ // peer's requirements is selected automatically.
+ //
+ // Server configurations must set one of Certificates, GetCertificate or
+ // GetConfigForClient. Clients doing client-authentication may set either
+ // Certificates or GetClientCertificate.
+ //
+ // Note: if there are multiple Certificates, and they don't have the
+ // optional field Leaf set, certificate selection will incur a significant
+ // per-handshake performance cost.
+ Certificates []Certificate
+
+ // NameToCertificate maps from a certificate name to an element of
+ // Certificates. Note that a certificate name can be of the form
+ // '*.example.com' and so doesn't have to be a domain name as such.
+ //
+ // Deprecated: NameToCertificate only allows associating a single
+ // certificate with a given name. Leave this field nil to let the library
+ // select the first compatible chain from Certificates.
+ NameToCertificate map[string]*Certificate
+
+ // GetCertificate returns a Certificate based on the given
+ // ClientHelloInfo. It will only be called if the client supplies SNI
+ // information or if Certificates is empty.
+ //
+ // If GetCertificate is nil or returns nil, then the certificate is
+ // retrieved from NameToCertificate. If NameToCertificate is nil, the
+ // best element of Certificates will be used.
+ //
+ // Once a Certificate is returned it should not be modified.
+ GetCertificate func(*ClientHelloInfo) (*Certificate, error)
+
+ // GetClientCertificate, if not nil, is called when a server requests a
+ // certificate from a client. If set, the contents of Certificates will
+ // be ignored.
+ //
+ // If GetClientCertificate returns an error, the handshake will be
+ // aborted and that error will be returned. Otherwise
+ // GetClientCertificate must return a non-nil Certificate. If
+ // Certificate.Certificate is empty then no certificate will be sent to
+ // the server. If this is unacceptable to the server then it may abort
+ // the handshake.
+ //
+ // GetClientCertificate may be called multiple times for the same
+ // connection if renegotiation occurs or if TLS 1.3 is in use.
+ //
+ // Once a Certificate is returned it should not be modified.
+ GetClientCertificate func(*CertificateRequestInfo) (*Certificate, error)
+
+ // GetConfigForClient, if not nil, is called after a ClientHello is
+ // received from a client. It may return a non-nil Config in order to
+ // change the Config that will be used to handle this connection. If
+ // the returned Config is nil, the original Config will be used. The
+ // Config returned by this callback may not be subsequently modified.
+ //
+ // If GetConfigForClient is nil, the Config passed to Server() will be
+ // used for all connections.
+ //
+ // If SessionTicketKey was explicitly set on the returned Config, or if
+ // SetSessionTicketKeys was called on the returned Config, those keys will
+ // be used. Otherwise, the original Config keys will be used (and possibly
+ // rotated if they are automatically managed).
+ GetConfigForClient func(*ClientHelloInfo) (*Config, error)
+
+ // VerifyPeerCertificate, if not nil, is called after normal
+ // certificate verification by either a TLS client or server. It
+ // receives the raw ASN.1 certificates provided by the peer and also
+ // any verified chains that normal processing found. If it returns a
+ // non-nil error, the handshake is aborted and that error results.
+ //
+ // If normal verification fails then the handshake will abort before
+ // considering this callback. If normal verification is disabled (on the
+ // client when InsecureSkipVerify is set, or on a server when ClientAuth is
+ // RequestClientCert or RequireAnyClientCert), then this callback will be
+ // considered but the verifiedChains argument will always be nil. When
+ // ClientAuth is NoClientCert, this callback is not called on the server.
+ // rawCerts may be empty on the server if ClientAuth is RequestClientCert or
+ // VerifyClientCertIfGiven.
+ //
+ // This callback is not invoked on resumed connections, as certificates are
+ // not re-verified on resumption.
+ //
+ // verifiedChains and its contents should not be modified.
+ VerifyPeerCertificate func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error
+
+ // VerifyConnection, if not nil, is called after normal certificate
+ // verification and after VerifyPeerCertificate by either a TLS client
+ // or server. If it returns a non-nil error, the handshake is aborted
+ // and that error results.
+ //
+ // If normal verification fails then the handshake will abort before
+ // considering this callback. This callback will run for all connections,
+ // including resumptions, regardless of InsecureSkipVerify or ClientAuth
+ // settings.
+ VerifyConnection func(ConnectionState) error
+
+ // RootCAs defines the set of root certificate authorities
+ // that clients use when verifying server certificates.
+ // If RootCAs is nil, TLS uses the host's root CA set.
+ RootCAs *x509.CertPool
+
+ // NextProtos is a list of supported application level protocols, in
+ // order of preference. If both peers support ALPN, the selected
+ // protocol will be one from this list, and the connection will fail
+ // if there is no mutually supported protocol. If NextProtos is empty
+ // or the peer doesn't support ALPN, the connection will succeed and
+ // ConnectionState.NegotiatedProtocol will be empty.
+ NextProtos []string
+
+ // ServerName is used to verify the hostname on the returned
+ // certificates unless InsecureSkipVerify is given. It is also included
+ // in the client's handshake to support virtual hosting unless it is
+ // an IP address.
+ ServerName string
+
+ // ClientAuth determines the server's policy for
+ // TLS Client Authentication. The default is NoClientCert.
+ ClientAuth ClientAuthType
+
+ // ClientCAs defines the set of root certificate authorities
+ // that servers use if required to verify a client certificate
+ // by the policy in ClientAuth.
+ ClientCAs *x509.CertPool
+
+ // InsecureSkipVerify controls whether a client verifies the server's
+ // certificate chain and host name. If InsecureSkipVerify is true, crypto/tls
+ // accepts any certificate presented by the server and any host name in that
+ // certificate. In this mode, TLS is susceptible to machine-in-the-middle
+ // attacks unless custom verification is used. This should be used only for
+ // testing or in combination with VerifyConnection or VerifyPeerCertificate.
+ InsecureSkipVerify bool
+
+ // CipherSuites is a list of enabled TLS 1.0–1.2 cipher suites. The order of
+ // the list is ignored. Note that TLS 1.3 ciphersuites are not configurable.
+ //
+ // If CipherSuites is nil, a safe default list is used. The default cipher
+ // suites might change over time.
+ CipherSuites []uint16
+
+ // PreferServerCipherSuites is a legacy field and has no effect.
+ //
+ // It used to control whether the server would follow the client's or the
+ // server's preference. Servers now select the best mutually supported
+ // cipher suite based on logic that takes into account inferred client
+ // hardware, server hardware, and security.
+ //
+ // Deprecated: PreferServerCipherSuites is ignored.
+ PreferServerCipherSuites bool
+
+ // SessionTicketsDisabled may be set to true to disable session ticket and
+ // PSK (resumption) support. Note that on clients, session ticket support is
+ // also disabled if ClientSessionCache is nil.
+ SessionTicketsDisabled bool
+
+ // SessionTicketKey is used by TLS servers to provide session resumption.
+ // See RFC 5077 and the PSK mode of RFC 8446. If zero, it will be filled
+ // with random data before the first server handshake.
+ //
+ // Deprecated: if this field is left at zero, session ticket keys will be
+ // automatically rotated every day and dropped after seven days. For
+ // customizing the rotation schedule or synchronizing servers that are
+ // terminating connections for the same host, use SetSessionTicketKeys.
+ SessionTicketKey [32]byte
+
+ // ClientSessionCache is a cache of ClientSessionState entries for TLS
+ // session resumption. It is only used by clients.
+ ClientSessionCache ClientSessionCache
+
+ // UnwrapSession is called on the server to turn a ticket/identity
+ // previously produced by [WrapSession] into a usable session.
+ //
+ // UnwrapSession will usually either decrypt a session state in the ticket
+ // (for example with [Config.EncryptTicket]), or use the ticket as a handle
+ // to recover a previously stored state. It must use [ParseSessionState] to
+ // deserialize the session state.
+ //
+ // If UnwrapSession returns an error, the connection is terminated. If it
+ // returns (nil, nil), the session is ignored. crypto/tls may still choose
+ // not to resume the returned session.
+ UnwrapSession func(identity []byte, cs ConnectionState) (*SessionState, error)
+
+ // WrapSession is called on the server to produce a session ticket/identity.
+ //
+ // WrapSession must serialize the session state with [SessionState.Bytes].
+ // It may then encrypt the serialized state (for example with
+ // [Config.DecryptTicket]) and use it as the ticket, or store the state and
+ // return a handle for it.
+ //
+ // If WrapSession returns an error, the connection is terminated.
+ //
+ // Warning: the return value will be exposed on the wire and to clients in
+ // plaintext. The application is in charge of encrypting and authenticating
+ // it (and rotating keys) or returning high-entropy identifiers. Failing to
+ // do so correctly can compromise current, previous, and future connections
+ // depending on the protocol version.
+ WrapSession func(ConnectionState, *SessionState) ([]byte, error)
+
+ // MinVersion contains the minimum TLS version that is acceptable.
+ //
+ // By default, TLS 1.2 is currently used as the minimum when acting as a
+ // client, and TLS 1.0 when acting as a server. TLS 1.0 is the minimum
+ // supported by this package, both as a client and as a server.
+ //
+ // The client-side default can temporarily be reverted to TLS 1.0 by
+ // including the value "x509sha1=1" in the GODEBUG environment variable.
+ // Note that this option will be removed in Go 1.19 (but it will still be
+ // possible to set this field to VersionTLS10 explicitly).
+ MinVersion uint16
+
+ // MaxVersion contains the maximum TLS version that is acceptable.
+ //
+ // By default, the maximum version supported by this package is used,
+ // which is currently TLS 1.3.
+ MaxVersion uint16
+
+ // CurvePreferences contains the elliptic curves that will be used in
+ // an ECDHE handshake, in preference order. If empty, the default will
+ // be used. The client will use the first preference as the type for
+ // its key share in TLS 1.3. This may change in the future.
+ CurvePreferences []CurveID
+
+ // DynamicRecordSizingDisabled disables adaptive sizing of TLS records.
+ // When true, the largest possible TLS record size is always used. When
+ // false, the size of TLS records may be adjusted in an attempt to
+ // improve latency.
+ DynamicRecordSizingDisabled bool
+
+ // Renegotiation controls what types of renegotiation are supported.
+ // The default, none, is correct for the vast majority of applications.
+ Renegotiation RenegotiationSupport
+
+ // KeyLogWriter optionally specifies a destination for TLS master secrets
+ // in NSS key log format that can be used to allow external programs
+ // such as Wireshark to decrypt TLS connections.
+ // See https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format.
+ // Use of KeyLogWriter compromises security and should only be
+ // used for debugging.
+ KeyLogWriter io.Writer
+
+ // mutex protects sessionTicketKeys and autoSessionTicketKeys.
+ mutex sync.RWMutex
+ // sessionTicketKeys contains zero or more ticket keys. If set, it means
+ // the keys were set with SessionTicketKey or SetSessionTicketKeys. The
+ // first key is used for new tickets and any subsequent keys can be used to
+ // decrypt old tickets. The slice contents are not protected by the mutex
+ // and are immutable.
+ sessionTicketKeys []ticketKey
+ // autoSessionTicketKeys is like sessionTicketKeys but is owned by the
+ // auto-rotation logic. See Config.ticketKeys.
+ autoSessionTicketKeys []ticketKey
+}
+
+const (
+ // ticketKeyLifetime is how long a ticket key remains valid and can be used to
+ // resume a client connection.
+ ticketKeyLifetime = 7 * 24 * time.Hour // 7 days
+
+ // ticketKeyRotation is how often the server should rotate the session ticket key
+ // that is used for new tickets.
+ ticketKeyRotation = 24 * time.Hour
+)
+
+// ticketKey is the internal representation of a session ticket key.
+type ticketKey struct {
+ aesKey [16]byte
+ hmacKey [16]byte
+ // created is the time at which this ticket key was created. See Config.ticketKeys.
+ created time.Time
+}
+
+// ticketKeyFromBytes converts from the external representation of a session
+// ticket key to a ticketKey. Externally, session ticket keys are 32 random
+// bytes and this function expands that into sufficient name and key material.
+func (c *Config) ticketKeyFromBytes(b [32]byte) (key ticketKey) {
+ hashed := sha512.Sum512(b[:])
+ // The first 16 bytes of the hash used to be exposed on the wire as a ticket
+ // prefix. They MUST NOT be used as a secret. In the future, it would make
+ // sense to use a proper KDF here, like HKDF with a fixed salt.
+ const legacyTicketKeyNameLen = 16
+ copy(key.aesKey[:], hashed[legacyTicketKeyNameLen:])
+ copy(key.hmacKey[:], hashed[legacyTicketKeyNameLen+len(key.aesKey):])
+ key.created = c.time()
+ return key
+}
+
+// maxSessionTicketLifetime is the maximum allowed lifetime of a TLS 1.3 session
+// ticket, and the lifetime we set for all tickets we send.
+const maxSessionTicketLifetime = 7 * 24 * time.Hour
+
+// Clone returns a shallow clone of c or nil if c is nil. It is safe to clone a Config that is
+// being used concurrently by a TLS client or server.
+func (c *Config) Clone() *Config {
+ if c == nil {
+ return nil
+ }
+ c.mutex.RLock()
+ defer c.mutex.RUnlock()
+ return &Config{
+ Rand: c.Rand,
+ Time: c.Time,
+ Certificates: c.Certificates,
+ NameToCertificate: c.NameToCertificate,
+ GetCertificate: c.GetCertificate,
+ GetClientCertificate: c.GetClientCertificate,
+ GetConfigForClient: c.GetConfigForClient,
+ VerifyPeerCertificate: c.VerifyPeerCertificate,
+ VerifyConnection: c.VerifyConnection,
+ RootCAs: c.RootCAs,
+ NextProtos: c.NextProtos,
+ ServerName: c.ServerName,
+ ClientAuth: c.ClientAuth,
+ ClientCAs: c.ClientCAs,
+ InsecureSkipVerify: c.InsecureSkipVerify,
+ CipherSuites: c.CipherSuites,
+ PreferServerCipherSuites: c.PreferServerCipherSuites,
+ SessionTicketsDisabled: c.SessionTicketsDisabled,
+ SessionTicketKey: c.SessionTicketKey,
+ ClientSessionCache: c.ClientSessionCache,
+ UnwrapSession: c.UnwrapSession,
+ WrapSession: c.WrapSession,
+ MinVersion: c.MinVersion,
+ MaxVersion: c.MaxVersion,
+ CurvePreferences: c.CurvePreferences,
+ DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled,
+ Renegotiation: c.Renegotiation,
+ KeyLogWriter: c.KeyLogWriter,
+ sessionTicketKeys: c.sessionTicketKeys,
+ autoSessionTicketKeys: c.autoSessionTicketKeys,
+ }
+}
+
+// deprecatedSessionTicketKey is set as the prefix of SessionTicketKey if it was
+// randomized for backwards compatibility but is not in use.
+var deprecatedSessionTicketKey = []byte("DEPRECATED")
+
+// initLegacySessionTicketKeyRLocked ensures the legacy SessionTicketKey field is
+// randomized if empty, and that sessionTicketKeys is populated from it otherwise.
+func (c *Config) initLegacySessionTicketKeyRLocked() {
+ // Don't write if SessionTicketKey is already defined as our deprecated string,
+ // or if it is defined by the user but sessionTicketKeys is already set.
+ if c.SessionTicketKey != [32]byte{} &&
+ (bytes.HasPrefix(c.SessionTicketKey[:], deprecatedSessionTicketKey) || len(c.sessionTicketKeys) > 0) {
+ return
+ }
+
+ // We need to write some data, so get an exclusive lock and re-check any conditions.
+ c.mutex.RUnlock()
+ defer c.mutex.RLock()
+ c.mutex.Lock()
+ defer c.mutex.Unlock()
+ if c.SessionTicketKey == [32]byte{} {
+ if _, err := io.ReadFull(c.rand(), c.SessionTicketKey[:]); err != nil {
+ panic(fmt.Sprintf("tls: unable to generate random session ticket key: %v", err))
+ }
+ // Write the deprecated prefix at the beginning so we know we created
+ // it. This key with the DEPRECATED prefix isn't used as an actual
+ // session ticket key, and is only randomized in case the application
+ // reuses it for some reason.
+ copy(c.SessionTicketKey[:], deprecatedSessionTicketKey)
+ } else if !bytes.HasPrefix(c.SessionTicketKey[:], deprecatedSessionTicketKey) && len(c.sessionTicketKeys) == 0 {
+ c.sessionTicketKeys = []ticketKey{c.ticketKeyFromBytes(c.SessionTicketKey)}
+ }
+
+}
+
+// ticketKeys returns the ticketKeys for this connection.
+// If configForClient has explicitly set keys, those will
+// be returned. Otherwise, the keys on c will be used and
+// may be rotated if auto-managed.
+// During rotation, any expired session ticket keys are deleted from
+// c.sessionTicketKeys. If the session ticket key that is currently
+// encrypting tickets (ie. the first ticketKey in c.sessionTicketKeys)
+// is not fresh, then a new session ticket key will be
+// created and prepended to c.sessionTicketKeys.
+func (c *Config) ticketKeys(configForClient *Config) []ticketKey {
+ // If the ConfigForClient callback returned a Config with explicitly set
+ // keys, use those, otherwise just use the original Config.
+ if configForClient != nil {
+ configForClient.mutex.RLock()
+ if configForClient.SessionTicketsDisabled {
+ return nil
+ }
+ configForClient.initLegacySessionTicketKeyRLocked()
+ if len(configForClient.sessionTicketKeys) != 0 {
+ ret := configForClient.sessionTicketKeys
+ configForClient.mutex.RUnlock()
+ return ret
+ }
+ configForClient.mutex.RUnlock()
+ }
+
+ c.mutex.RLock()
+ defer c.mutex.RUnlock()
+ if c.SessionTicketsDisabled {
+ return nil
+ }
+ c.initLegacySessionTicketKeyRLocked()
+ if len(c.sessionTicketKeys) != 0 {
+ return c.sessionTicketKeys
+ }
+ // Fast path for the common case where the key is fresh enough.
+ if len(c.autoSessionTicketKeys) > 0 && c.time().Sub(c.autoSessionTicketKeys[0].created) < ticketKeyRotation {
+ return c.autoSessionTicketKeys
+ }
+
+ // autoSessionTicketKeys are managed by auto-rotation.
+ c.mutex.RUnlock()
+ defer c.mutex.RLock()
+ c.mutex.Lock()
+ defer c.mutex.Unlock()
+ // Re-check the condition in case it changed since obtaining the new lock.
+ if len(c.autoSessionTicketKeys) == 0 || c.time().Sub(c.autoSessionTicketKeys[0].created) >= ticketKeyRotation {
+ var newKey [32]byte
+ if _, err := io.ReadFull(c.rand(), newKey[:]); err != nil {
+ panic(fmt.Sprintf("unable to generate random session ticket key: %v", err))
+ }
+ valid := make([]ticketKey, 0, len(c.autoSessionTicketKeys)+1)
+ valid = append(valid, c.ticketKeyFromBytes(newKey))
+ for _, k := range c.autoSessionTicketKeys {
+ // While rotating the current key, also remove any expired ones.
+ if c.time().Sub(k.created) < ticketKeyLifetime {
+ valid = append(valid, k)
+ }
+ }
+ c.autoSessionTicketKeys = valid
+ }
+ return c.autoSessionTicketKeys
+}
+
+// SetSessionTicketKeys updates the session ticket keys for a server.
+//
+// The first key will be used when creating new tickets, while all keys can be
+// used for decrypting tickets. It is safe to call this function while the
+// server is running in order to rotate the session ticket keys. The function
+// will panic if keys is empty.
+//
+// Calling this function will turn off automatic session ticket key rotation.
+//
+// If multiple servers are terminating connections for the same host they should
+// all have the same session ticket keys. If the session ticket keys leaks,
+// previously recorded and future TLS connections using those keys might be
+// compromised.
+func (c *Config) SetSessionTicketKeys(keys [][32]byte) {
+ if len(keys) == 0 {
+ panic("tls: keys must have at least one key")
+ }
+
+ newKeys := make([]ticketKey, len(keys))
+ for i, bytes := range keys {
+ newKeys[i] = c.ticketKeyFromBytes(bytes)
+ }
+
+ c.mutex.Lock()
+ c.sessionTicketKeys = newKeys
+ c.mutex.Unlock()
+}
+
+func (c *Config) rand() io.Reader {
+ r := c.Rand
+ if r == nil {
+ return rand.Reader
+ }
+ return r
+}
+
+func (c *Config) time() time.Time {
+ t := c.Time
+ if t == nil {
+ t = time.Now
+ }
+ return t()
+}
+
+func (c *Config) cipherSuites() []uint16 {
+ if needFIPS() {
+ return fipsCipherSuites(c)
+ }
+ if c.CipherSuites != nil {
+ return c.CipherSuites
+ }
+ return defaultCipherSuites
+}
+
+var supportedVersions = []uint16{
+ VersionTLS13,
+ VersionTLS12,
+ VersionTLS11,
+ VersionTLS10,
+}
+
+// roleClient and roleServer are meant to call supportedVersions and parents
+// with more readability at the callsite.
+const roleClient = true
+const roleServer = false
+
+func (c *Config) supportedVersions(isClient bool) []uint16 {
+ versions := make([]uint16, 0, len(supportedVersions))
+ for _, v := range supportedVersions {
+ if needFIPS() && (v < fipsMinVersion(c) || v > fipsMaxVersion(c)) {
+ continue
+ }
+ if (c == nil || c.MinVersion == 0) &&
+ isClient && v < VersionTLS12 {
+ continue
+ }
+ if c != nil && c.MinVersion != 0 && v < c.MinVersion {
+ continue
+ }
+ if c != nil && c.MaxVersion != 0 && v > c.MaxVersion {
+ continue
+ }
+ versions = append(versions, v)
+ }
+ return versions
+}
+
+func (c *Config) maxSupportedVersion(isClient bool) uint16 {
+ supportedVersions := c.supportedVersions(isClient)
+ if len(supportedVersions) == 0 {
+ return 0
+ }
+ return supportedVersions[0]
+}
+
+// supportedVersionsFromMax returns a list of supported versions derived from a
+// legacy maximum version value. Note that only versions supported by this
+// library are returned. Any newer peer will use supportedVersions anyway.
+func supportedVersionsFromMax(maxVersion uint16) []uint16 {
+ versions := make([]uint16, 0, len(supportedVersions))
+ for _, v := range supportedVersions {
+ if v > maxVersion {
+ continue
+ }
+ versions = append(versions, v)
+ }
+ return versions
+}
+
+var defaultCurvePreferences = []CurveID{X25519, CurveP256, CurveP384, CurveP521}
+
+func (c *Config) curvePreferences() []CurveID {
+ if needFIPS() {
+ return fipsCurvePreferences(c)
+ }
+ if c == nil || len(c.CurvePreferences) == 0 {
+ return defaultCurvePreferences
+ }
+ return c.CurvePreferences
+}
+
+func (c *Config) supportsCurve(curve CurveID) bool {
+ for _, cc := range c.curvePreferences() {
+ if cc == curve {
+ return true
+ }
+ }
+ return false
+}
+
+// mutualVersion returns the protocol version to use given the advertised
+// versions of the peer. Priority is given to the peer preference order.
+func (c *Config) mutualVersion(isClient bool, peerVersions []uint16) (uint16, bool) {
+ supportedVersions := c.supportedVersions(isClient)
+ for _, peerVersion := range peerVersions {
+ for _, v := range supportedVersions {
+ if v == peerVersion {
+ return v, true
+ }
+ }
+ }
+ return 0, false
+}
+
+var errNoCertificates = errors.New("tls: no certificates configured")
+
+// getCertificate returns the best certificate for the given ClientHelloInfo,
+// defaulting to the first element of c.Certificates.
+func (c *Config) getCertificate(clientHello *ClientHelloInfo) (*Certificate, error) {
+ if c.GetCertificate != nil &&
+ (len(c.Certificates) == 0 || len(clientHello.ServerName) > 0) {
+ cert, err := c.GetCertificate(clientHello)
+ if cert != nil || err != nil {
+ return cert, err
+ }
+ }
+
+ if len(c.Certificates) == 0 {
+ return nil, errNoCertificates
+ }
+
+ if len(c.Certificates) == 1 {
+ // There's only one choice, so no point doing any work.
+ return &c.Certificates[0], nil
+ }
+
+ if c.NameToCertificate != nil {
+ name := strings.ToLower(clientHello.ServerName)
+ if cert, ok := c.NameToCertificate[name]; ok {
+ return cert, nil
+ }
+ if len(name) > 0 {
+ labels := strings.Split(name, ".")
+ labels[0] = "*"
+ wildcardName := strings.Join(labels, ".")
+ if cert, ok := c.NameToCertificate[wildcardName]; ok {
+ return cert, nil
+ }
+ }
+ }
+
+ for _, cert := range c.Certificates {
+ if err := clientHello.SupportsCertificate(&cert); err == nil {
+ return &cert, nil
+ }
+ }
+
+ // If nothing matches, return the first certificate.
+ return &c.Certificates[0], nil
+}
+
+// SupportsCertificate returns nil if the provided certificate is supported by
+// the client that sent the ClientHello. Otherwise, it returns an error
+// describing the reason for the incompatibility.
+//
+// If this ClientHelloInfo was passed to a GetConfigForClient or GetCertificate
+// callback, this method will take into account the associated Config. Note that
+// if GetConfigForClient returns a different Config, the change can't be
+// accounted for by this method.
+//
+// This function will call x509.ParseCertificate unless c.Leaf is set, which can
+// incur a significant performance cost.
+func (chi *ClientHelloInfo) SupportsCertificate(c *Certificate) error {
+ // Note we don't currently support certificate_authorities nor
+ // signature_algorithms_cert, and don't check the algorithms of the
+ // signatures on the chain (which anyway are a SHOULD, see RFC 8446,
+ // Section 4.4.2.2).
+
+ config := chi.config
+ if config == nil {
+ config = &Config{}
+ }
+ vers, ok := config.mutualVersion(roleServer, chi.SupportedVersions)
+ if !ok {
+ return errors.New("no mutually supported protocol versions")
+ }
+
+ // If the client specified the name they are trying to connect to, the
+ // certificate needs to be valid for it.
+ if chi.ServerName != "" {
+ x509Cert, err := c.leaf()
+ if err != nil {
+ return fmt.Errorf("failed to parse certificate: %w", err)
+ }
+ if err := x509Cert.VerifyHostname(chi.ServerName); err != nil {
+ return fmt.Errorf("certificate is not valid for requested server name: %w", err)
+ }
+ }
+
+ // supportsRSAFallback returns nil if the certificate and connection support
+ // the static RSA key exchange, and unsupported otherwise. The logic for
+ // supporting static RSA is completely disjoint from the logic for
+ // supporting signed key exchanges, so we just check it as a fallback.
+ supportsRSAFallback := func(unsupported error) error {
+ // TLS 1.3 dropped support for the static RSA key exchange.
+ if vers == VersionTLS13 {
+ return unsupported
+ }
+ // The static RSA key exchange works by decrypting a challenge with the
+ // RSA private key, not by signing, so check the PrivateKey implements
+ // crypto.Decrypter, like *rsa.PrivateKey does.
+ if priv, ok := c.PrivateKey.(crypto.Decrypter); ok {
+ if _, ok := priv.Public().(*rsa.PublicKey); !ok {
+ return unsupported
+ }
+ } else {
+ return unsupported
+ }
+ // Finally, there needs to be a mutual cipher suite that uses the static
+ // RSA key exchange instead of ECDHE.
+ rsaCipherSuite := selectCipherSuite(chi.CipherSuites, config.cipherSuites(), func(c *cipherSuite) bool {
+ if c.flags&suiteECDHE != 0 {
+ return false
+ }
+ if vers < VersionTLS12 && c.flags&suiteTLS12 != 0 {
+ return false
+ }
+ return true
+ })
+ if rsaCipherSuite == nil {
+ return unsupported
+ }
+ return nil
+ }
+
+ // If the client sent the signature_algorithms extension, ensure it supports
+ // schemes we can use with this certificate and TLS version.
+ if len(chi.SignatureSchemes) > 0 {
+ if _, err := selectSignatureScheme(vers, c, chi.SignatureSchemes); err != nil {
+ return supportsRSAFallback(err)
+ }
+ }
+
+ // In TLS 1.3 we are done because supported_groups is only relevant to the
+ // ECDHE computation, point format negotiation is removed, cipher suites are
+ // only relevant to the AEAD choice, and static RSA does not exist.
+ if vers == VersionTLS13 {
+ return nil
+ }
+
+ // The only signed key exchange we support is ECDHE.
+ if !supportsECDHE(config, chi.SupportedCurves, chi.SupportedPoints) {
+ return supportsRSAFallback(errors.New("client doesn't support ECDHE, can only use legacy RSA key exchange"))
+ }
+
+ var ecdsaCipherSuite bool
+ if priv, ok := c.PrivateKey.(crypto.Signer); ok {
+ switch pub := priv.Public().(type) {
+ case *ecdsa.PublicKey:
+ var curve CurveID
+ switch pub.Curve {
+ case elliptic.P256():
+ curve = CurveP256
+ case elliptic.P384():
+ curve = CurveP384
+ case elliptic.P521():
+ curve = CurveP521
+ default:
+ return supportsRSAFallback(unsupportedCertificateError(c))
+ }
+ var curveOk bool
+ for _, c := range chi.SupportedCurves {
+ if c == curve && config.supportsCurve(c) {
+ curveOk = true
+ break
+ }
+ }
+ if !curveOk {
+ return errors.New("client doesn't support certificate curve")
+ }
+ ecdsaCipherSuite = true
+ case ed25519.PublicKey:
+ if vers < VersionTLS12 || len(chi.SignatureSchemes) == 0 {
+ return errors.New("connection doesn't support Ed25519")
+ }
+ ecdsaCipherSuite = true
+ case *rsa.PublicKey:
+ default:
+ return supportsRSAFallback(unsupportedCertificateError(c))
+ }
+ } else {
+ return supportsRSAFallback(unsupportedCertificateError(c))
+ }
+
+ // Make sure that there is a mutually supported cipher suite that works with
+ // this certificate. Cipher suite selection will then apply the logic in
+ // reverse to pick it. See also serverHandshakeState.cipherSuiteOk.
+ cipherSuite := selectCipherSuite(chi.CipherSuites, config.cipherSuites(), func(c *cipherSuite) bool {
+ if c.flags&suiteECDHE == 0 {
+ return false
+ }
+ if c.flags&suiteECSign != 0 {
+ if !ecdsaCipherSuite {
+ return false
+ }
+ } else {
+ if ecdsaCipherSuite {
+ return false
+ }
+ }
+ if vers < VersionTLS12 && c.flags&suiteTLS12 != 0 {
+ return false
+ }
+ return true
+ })
+ if cipherSuite == nil {
+ return supportsRSAFallback(errors.New("client doesn't support any cipher suites compatible with the certificate"))
+ }
+
+ return nil
+}
+
+// SupportsCertificate returns nil if the provided certificate is supported by
+// the server that sent the CertificateRequest. Otherwise, it returns an error
+// describing the reason for the incompatibility.
+func (cri *CertificateRequestInfo) SupportsCertificate(c *Certificate) error {
+ if _, err := selectSignatureScheme(cri.Version, c, cri.SignatureSchemes); err != nil {
+ return err
+ }
+
+ if len(cri.AcceptableCAs) == 0 {
+ return nil
+ }
+
+ for j, cert := range c.Certificate {
+ x509Cert := c.Leaf
+ // Parse the certificate if this isn't the leaf node, or if
+ // chain.Leaf was nil.
+ if j != 0 || x509Cert == nil {
+ var err error
+ if x509Cert, err = x509.ParseCertificate(cert); err != nil {
+ return fmt.Errorf("failed to parse certificate #%d in the chain: %w", j, err)
+ }
+ }
+
+ for _, ca := range cri.AcceptableCAs {
+ if bytes.Equal(x509Cert.RawIssuer, ca) {
+ return nil
+ }
+ }
+ }
+ return errors.New("chain is not signed by an acceptable CA")
+}
+
+// BuildNameToCertificate parses c.Certificates and builds c.NameToCertificate
+// from the CommonName and SubjectAlternateName fields of each of the leaf
+// certificates.
+//
+// Deprecated: NameToCertificate only allows associating a single certificate
+// with a given name. Leave that field nil to let the library select the first
+// compatible chain from Certificates.
+func (c *Config) BuildNameToCertificate() {
+ c.NameToCertificate = make(map[string]*Certificate)
+ for i := range c.Certificates {
+ cert := &c.Certificates[i]
+ x509Cert, err := cert.leaf()
+ if err != nil {
+ continue
+ }
+ // If SANs are *not* present, some clients will consider the certificate
+ // valid for the name in the Common Name.
+ if x509Cert.Subject.CommonName != "" && len(x509Cert.DNSNames) == 0 {
+ c.NameToCertificate[x509Cert.Subject.CommonName] = cert
+ }
+ for _, san := range x509Cert.DNSNames {
+ c.NameToCertificate[san] = cert
+ }
+ }
+}
+
+const (
+ keyLogLabelTLS12 = "CLIENT_RANDOM"
+ keyLogLabelClientHandshake = "CLIENT_HANDSHAKE_TRAFFIC_SECRET"
+ keyLogLabelServerHandshake = "SERVER_HANDSHAKE_TRAFFIC_SECRET"
+ keyLogLabelClientTraffic = "CLIENT_TRAFFIC_SECRET_0"
+ keyLogLabelServerTraffic = "SERVER_TRAFFIC_SECRET_0"
+)
+
+func (c *Config) writeKeyLog(label string, clientRandom, secret []byte) error {
+ if c.KeyLogWriter == nil {
+ return nil
+ }
+
+ logLine := fmt.Appendf(nil, "%s %x %x\n", label, clientRandom, secret)
+
+ writerMutex.Lock()
+ _, err := c.KeyLogWriter.Write(logLine)
+ writerMutex.Unlock()
+
+ return err
+}
+
+// writerMutex protects all KeyLogWriters globally. It is rarely enabled,
+// and is only for debugging, so a global mutex saves space.
+var writerMutex sync.Mutex
+
+// A Certificate is a chain of one or more certificates, leaf first.
+type Certificate struct {
+ Certificate [][]byte
+ // PrivateKey contains the private key corresponding to the public key in
+ // Leaf. This must implement crypto.Signer with an RSA, ECDSA or Ed25519 PublicKey.
+ // For a server up to TLS 1.2, it can also implement crypto.Decrypter with
+ // an RSA PublicKey.
+ PrivateKey crypto.PrivateKey
+ // SupportedSignatureAlgorithms is an optional list restricting what
+ // signature algorithms the PrivateKey can be used for.
+ SupportedSignatureAlgorithms []SignatureScheme
+ // OCSPStaple contains an optional OCSP response which will be served
+ // to clients that request it.
+ OCSPStaple []byte
+ // SignedCertificateTimestamps contains an optional list of Signed
+ // Certificate Timestamps which will be served to clients that request it.
+ SignedCertificateTimestamps [][]byte
+ // Leaf is the parsed form of the leaf certificate, which may be initialized
+ // using x509.ParseCertificate to reduce per-handshake processing. If nil,
+ // the leaf certificate will be parsed as needed.
+ Leaf *x509.Certificate
+}
+
+// leaf returns the parsed leaf certificate, either from c.Leaf or by parsing
+// the corresponding c.Certificate[0].
+func (c *Certificate) leaf() (*x509.Certificate, error) {
+ if c.Leaf != nil {
+ return c.Leaf, nil
+ }
+ return x509.ParseCertificate(c.Certificate[0])
+}
+
+type handshakeMessage interface {
+ marshal() ([]byte, error)
+ unmarshal([]byte) bool
+}
+
+// lruSessionCache is a ClientSessionCache implementation that uses an LRU
+// caching strategy.
+type lruSessionCache struct {
+ sync.Mutex
+
+ m map[string]*list.Element
+ q *list.List
+ capacity int
+}
+
+type lruSessionCacheEntry struct {
+ sessionKey string
+ state *ClientSessionState
+}
+
+// NewLRUClientSessionCache returns a ClientSessionCache with the given
+// capacity that uses an LRU strategy. If capacity is < 1, a default capacity
+// is used instead.
+func NewLRUClientSessionCache(capacity int) ClientSessionCache {
+ const defaultSessionCacheCapacity = 64
+
+ if capacity < 1 {
+ capacity = defaultSessionCacheCapacity
+ }
+ return &lruSessionCache{
+ m: make(map[string]*list.Element),
+ q: list.New(),
+ capacity: capacity,
+ }
+}
+
+// Put adds the provided (sessionKey, cs) pair to the cache. If cs is nil, the entry
+// corresponding to sessionKey is removed from the cache instead.
+func (c *lruSessionCache) Put(sessionKey string, cs *ClientSessionState) {
+ c.Lock()
+ defer c.Unlock()
+
+ if elem, ok := c.m[sessionKey]; ok {
+ if cs == nil {
+ c.q.Remove(elem)
+ delete(c.m, sessionKey)
+ } else {
+ entry := elem.Value.(*lruSessionCacheEntry)
+ entry.state = cs
+ c.q.MoveToFront(elem)
+ }
+ return
+ }
+
+ if c.q.Len() < c.capacity {
+ entry := &lruSessionCacheEntry{sessionKey, cs}
+ c.m[sessionKey] = c.q.PushFront(entry)
+ return
+ }
+
+ elem := c.q.Back()
+ entry := elem.Value.(*lruSessionCacheEntry)
+ delete(c.m, entry.sessionKey)
+ entry.sessionKey = sessionKey
+ entry.state = cs
+ c.q.MoveToFront(elem)
+ c.m[sessionKey] = elem
+}
+
+// Get returns the ClientSessionState value associated with a given key. It
+// returns (nil, false) if no value is found.
+func (c *lruSessionCache) Get(sessionKey string) (*ClientSessionState, bool) {
+ c.Lock()
+ defer c.Unlock()
+
+ if elem, ok := c.m[sessionKey]; ok {
+ c.q.MoveToFront(elem)
+ return elem.Value.(*lruSessionCacheEntry).state, true
+ }
+ return nil, false
+}
+
+var emptyConfig Config
+
+func defaultConfig() *Config {
+ return &emptyConfig
+}
+
+func unexpectedMessageError(wanted, got any) error {
+ return fmt.Errorf("tls: received unexpected handshake message of type %T when waiting for %T", got, wanted)
+}
+
+func isSupportedSignatureAlgorithm(sigAlg SignatureScheme, supportedSignatureAlgorithms []SignatureScheme) bool {
+ for _, s := range supportedSignatureAlgorithms {
+ if s == sigAlg {
+ return true
+ }
+ }
+ return false
+}
+
+// CertificateVerificationError is returned when certificate verification fails during the handshake.
+type CertificateVerificationError struct {
+ // UnverifiedCertificates and its contents should not be modified.
+ UnverifiedCertificates []*x509.Certificate
+ Err error
+}
+
+func (e *CertificateVerificationError) Error() string {
+ return fmt.Sprintf("tls: failed to verify certificate: %s", e.Err)
+}
+
+func (e *CertificateVerificationError) Unwrap() error {
+ return e.Err
+}
diff --git a/src/crypto/tls/common_string.go b/src/crypto/tls/common_string.go
new file mode 100644
index 0000000..2381088
--- /dev/null
+++ b/src/crypto/tls/common_string.go
@@ -0,0 +1,116 @@
+// Code generated by "stringer -type=SignatureScheme,CurveID,ClientAuthType -output=common_string.go"; DO NOT EDIT.
+
+package tls
+
+import "strconv"
+
+func _() {
+ // An "invalid array index" compiler error signifies that the constant values have changed.
+ // Re-run the stringer command to generate them again.
+ var x [1]struct{}
+ _ = x[PKCS1WithSHA256-1025]
+ _ = x[PKCS1WithSHA384-1281]
+ _ = x[PKCS1WithSHA512-1537]
+ _ = x[PSSWithSHA256-2052]
+ _ = x[PSSWithSHA384-2053]
+ _ = x[PSSWithSHA512-2054]
+ _ = x[ECDSAWithP256AndSHA256-1027]
+ _ = x[ECDSAWithP384AndSHA384-1283]
+ _ = x[ECDSAWithP521AndSHA512-1539]
+ _ = x[Ed25519-2055]
+ _ = x[PKCS1WithSHA1-513]
+ _ = x[ECDSAWithSHA1-515]
+}
+
+const (
+ _SignatureScheme_name_0 = "PKCS1WithSHA1"
+ _SignatureScheme_name_1 = "ECDSAWithSHA1"
+ _SignatureScheme_name_2 = "PKCS1WithSHA256"
+ _SignatureScheme_name_3 = "ECDSAWithP256AndSHA256"
+ _SignatureScheme_name_4 = "PKCS1WithSHA384"
+ _SignatureScheme_name_5 = "ECDSAWithP384AndSHA384"
+ _SignatureScheme_name_6 = "PKCS1WithSHA512"
+ _SignatureScheme_name_7 = "ECDSAWithP521AndSHA512"
+ _SignatureScheme_name_8 = "PSSWithSHA256PSSWithSHA384PSSWithSHA512Ed25519"
+)
+
+var (
+ _SignatureScheme_index_8 = [...]uint8{0, 13, 26, 39, 46}
+)
+
+func (i SignatureScheme) String() string {
+ switch {
+ case i == 513:
+ return _SignatureScheme_name_0
+ case i == 515:
+ return _SignatureScheme_name_1
+ case i == 1025:
+ return _SignatureScheme_name_2
+ case i == 1027:
+ return _SignatureScheme_name_3
+ case i == 1281:
+ return _SignatureScheme_name_4
+ case i == 1283:
+ return _SignatureScheme_name_5
+ case i == 1537:
+ return _SignatureScheme_name_6
+ case i == 1539:
+ return _SignatureScheme_name_7
+ case 2052 <= i && i <= 2055:
+ i -= 2052
+ return _SignatureScheme_name_8[_SignatureScheme_index_8[i]:_SignatureScheme_index_8[i+1]]
+ default:
+ return "SignatureScheme(" + strconv.FormatInt(int64(i), 10) + ")"
+ }
+}
+func _() {
+ // An "invalid array index" compiler error signifies that the constant values have changed.
+ // Re-run the stringer command to generate them again.
+ var x [1]struct{}
+ _ = x[CurveP256-23]
+ _ = x[CurveP384-24]
+ _ = x[CurveP521-25]
+ _ = x[X25519-29]
+}
+
+const (
+ _CurveID_name_0 = "CurveP256CurveP384CurveP521"
+ _CurveID_name_1 = "X25519"
+)
+
+var (
+ _CurveID_index_0 = [...]uint8{0, 9, 18, 27}
+)
+
+func (i CurveID) String() string {
+ switch {
+ case 23 <= i && i <= 25:
+ i -= 23
+ return _CurveID_name_0[_CurveID_index_0[i]:_CurveID_index_0[i+1]]
+ case i == 29:
+ return _CurveID_name_1
+ default:
+ return "CurveID(" + strconv.FormatInt(int64(i), 10) + ")"
+ }
+}
+func _() {
+ // An "invalid array index" compiler error signifies that the constant values have changed.
+ // Re-run the stringer command to generate them again.
+ var x [1]struct{}
+ _ = x[NoClientCert-0]
+ _ = x[RequestClientCert-1]
+ _ = x[RequireAnyClientCert-2]
+ _ = x[VerifyClientCertIfGiven-3]
+ _ = x[RequireAndVerifyClientCert-4]
+}
+
+const _ClientAuthType_name = "NoClientCertRequestClientCertRequireAnyClientCertVerifyClientCertIfGivenRequireAndVerifyClientCert"
+
+var _ClientAuthType_index = [...]uint8{0, 12, 29, 49, 72, 98}
+
+func (i ClientAuthType) String() string {
+ if i < 0 || i >= ClientAuthType(len(_ClientAuthType_index)-1) {
+ return "ClientAuthType(" + strconv.FormatInt(int64(i), 10) + ")"
+ }
+ return _ClientAuthType_name[_ClientAuthType_index[i]:_ClientAuthType_index[i+1]]
+}
diff --git a/src/crypto/tls/conn.go b/src/crypto/tls/conn.go
new file mode 100644
index 0000000..c04bd48
--- /dev/null
+++ b/src/crypto/tls/conn.go
@@ -0,0 +1,1655 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// TLS low level connection and record layer
+
+package tls
+
+import (
+ "bytes"
+ "context"
+ "crypto/cipher"
+ "crypto/subtle"
+ "crypto/x509"
+ "errors"
+ "fmt"
+ "hash"
+ "io"
+ "net"
+ "sync"
+ "sync/atomic"
+ "time"
+)
+
+// A Conn represents a secured connection.
+// It implements the net.Conn interface.
+type Conn struct {
+ // constant
+ conn net.Conn
+ isClient bool
+ handshakeFn func(context.Context) error // (*Conn).clientHandshake or serverHandshake
+ quic *quicState // nil for non-QUIC connections
+
+ // isHandshakeComplete is true if the connection is currently transferring
+ // application data (i.e. is not currently processing a handshake).
+ // isHandshakeComplete is true implies handshakeErr == nil.
+ isHandshakeComplete atomic.Bool
+ // constant after handshake; protected by handshakeMutex
+ handshakeMutex sync.Mutex
+ handshakeErr error // error resulting from handshake
+ vers uint16 // TLS version
+ haveVers bool // version has been negotiated
+ config *Config // configuration passed to constructor
+ // handshakes counts the number of handshakes performed on the
+ // connection so far. If renegotiation is disabled then this is either
+ // zero or one.
+ handshakes int
+ extMasterSecret bool
+ didResume bool // whether this connection was a session resumption
+ cipherSuite uint16
+ ocspResponse []byte // stapled OCSP response
+ scts [][]byte // signed certificate timestamps from server
+ peerCertificates []*x509.Certificate
+ // activeCertHandles contains the cache handles to certificates in
+ // peerCertificates that are used to track active references.
+ activeCertHandles []*activeCert
+ // verifiedChains contains the certificate chains that we built, as
+ // opposed to the ones presented by the server.
+ verifiedChains [][]*x509.Certificate
+ // serverName contains the server name indicated by the client, if any.
+ serverName string
+ // secureRenegotiation is true if the server echoed the secure
+ // renegotiation extension. (This is meaningless as a server because
+ // renegotiation is not supported in that case.)
+ secureRenegotiation bool
+ // ekm is a closure for exporting keying material.
+ ekm func(label string, context []byte, length int) ([]byte, error)
+ // resumptionSecret is the resumption_master_secret for handling
+ // or sending NewSessionTicket messages.
+ resumptionSecret []byte
+
+ // ticketKeys is the set of active session ticket keys for this
+ // connection. The first one is used to encrypt new tickets and
+ // all are tried to decrypt tickets.
+ ticketKeys []ticketKey
+
+ // clientFinishedIsFirst is true if the client sent the first Finished
+ // message during the most recent handshake. This is recorded because
+ // the first transmitted Finished message is the tls-unique
+ // channel-binding value.
+ clientFinishedIsFirst bool
+
+ // closeNotifyErr is any error from sending the alertCloseNotify record.
+ closeNotifyErr error
+ // closeNotifySent is true if the Conn attempted to send an
+ // alertCloseNotify record.
+ closeNotifySent bool
+
+ // clientFinished and serverFinished contain the Finished message sent
+ // by the client or server in the most recent handshake. This is
+ // retained to support the renegotiation extension and tls-unique
+ // channel-binding.
+ clientFinished [12]byte
+ serverFinished [12]byte
+
+ // clientProtocol is the negotiated ALPN protocol.
+ clientProtocol string
+
+ // input/output
+ in, out halfConn
+ rawInput bytes.Buffer // raw input, starting with a record header
+ input bytes.Reader // application data waiting to be read, from rawInput.Next
+ hand bytes.Buffer // handshake data waiting to be read
+ buffering bool // whether records are buffered in sendBuf
+ sendBuf []byte // a buffer of records waiting to be sent
+
+ // bytesSent counts the bytes of application data sent.
+ // packetsSent counts packets.
+ bytesSent int64
+ packetsSent int64
+
+ // retryCount counts the number of consecutive non-advancing records
+ // received by Conn.readRecord. That is, records that neither advance the
+ // handshake, nor deliver application data. Protected by in.Mutex.
+ retryCount int
+
+ // activeCall indicates whether Close has been call in the low bit.
+ // the rest of the bits are the number of goroutines in Conn.Write.
+ activeCall atomic.Int32
+
+ tmp [16]byte
+}
+
+// Access to net.Conn methods.
+// Cannot just embed net.Conn because that would
+// export the struct field too.
+
+// LocalAddr returns the local network address.
+func (c *Conn) LocalAddr() net.Addr {
+ return c.conn.LocalAddr()
+}
+
+// RemoteAddr returns the remote network address.
+func (c *Conn) RemoteAddr() net.Addr {
+ return c.conn.RemoteAddr()
+}
+
+// SetDeadline sets the read and write deadlines associated with the connection.
+// A zero value for t means Read and Write will not time out.
+// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.
+func (c *Conn) SetDeadline(t time.Time) error {
+ return c.conn.SetDeadline(t)
+}
+
+// SetReadDeadline sets the read deadline on the underlying connection.
+// A zero value for t means Read will not time out.
+func (c *Conn) SetReadDeadline(t time.Time) error {
+ return c.conn.SetReadDeadline(t)
+}
+
+// SetWriteDeadline sets the write deadline on the underlying connection.
+// A zero value for t means Write will not time out.
+// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error.
+func (c *Conn) SetWriteDeadline(t time.Time) error {
+ return c.conn.SetWriteDeadline(t)
+}
+
+// NetConn returns the underlying connection that is wrapped by c.
+// Note that writing to or reading from this connection directly will corrupt the
+// TLS session.
+func (c *Conn) NetConn() net.Conn {
+ return c.conn
+}
+
+// A halfConn represents one direction of the record layer
+// connection, either sending or receiving.
+type halfConn struct {
+ sync.Mutex
+
+ err error // first permanent error
+ version uint16 // protocol version
+ cipher any // cipher algorithm
+ mac hash.Hash
+ seq [8]byte // 64-bit sequence number
+
+ scratchBuf [13]byte // to avoid allocs; interface method args escape
+
+ nextCipher any // next encryption state
+ nextMac hash.Hash // next MAC algorithm
+
+ level QUICEncryptionLevel // current QUIC encryption level
+ trafficSecret []byte // current TLS 1.3 traffic secret
+}
+
+type permanentError struct {
+ err net.Error
+}
+
+func (e *permanentError) Error() string { return e.err.Error() }
+func (e *permanentError) Unwrap() error { return e.err }
+func (e *permanentError) Timeout() bool { return e.err.Timeout() }
+func (e *permanentError) Temporary() bool { return false }
+
+func (hc *halfConn) setErrorLocked(err error) error {
+ if e, ok := err.(net.Error); ok {
+ hc.err = &permanentError{err: e}
+ } else {
+ hc.err = err
+ }
+ return hc.err
+}
+
+// prepareCipherSpec sets the encryption and MAC states
+// that a subsequent changeCipherSpec will use.
+func (hc *halfConn) prepareCipherSpec(version uint16, cipher any, mac hash.Hash) {
+ hc.version = version
+ hc.nextCipher = cipher
+ hc.nextMac = mac
+}
+
+// changeCipherSpec changes the encryption and MAC states
+// to the ones previously passed to prepareCipherSpec.
+func (hc *halfConn) changeCipherSpec() error {
+ if hc.nextCipher == nil || hc.version == VersionTLS13 {
+ return alertInternalError
+ }
+ hc.cipher = hc.nextCipher
+ hc.mac = hc.nextMac
+ hc.nextCipher = nil
+ hc.nextMac = nil
+ for i := range hc.seq {
+ hc.seq[i] = 0
+ }
+ return nil
+}
+
+func (hc *halfConn) setTrafficSecret(suite *cipherSuiteTLS13, level QUICEncryptionLevel, secret []byte) {
+ hc.trafficSecret = secret
+ hc.level = level
+ key, iv := suite.trafficKey(secret)
+ hc.cipher = suite.aead(key, iv)
+ for i := range hc.seq {
+ hc.seq[i] = 0
+ }
+}
+
+// incSeq increments the sequence number.
+func (hc *halfConn) incSeq() {
+ for i := 7; i >= 0; i-- {
+ hc.seq[i]++
+ if hc.seq[i] != 0 {
+ return
+ }
+ }
+
+ // Not allowed to let sequence number wrap.
+ // Instead, must renegotiate before it does.
+ // Not likely enough to bother.
+ panic("TLS: sequence number wraparound")
+}
+
+// explicitNonceLen returns the number of bytes of explicit nonce or IV included
+// in each record. Explicit nonces are present only in CBC modes after TLS 1.0
+// and in certain AEAD modes in TLS 1.2.
+func (hc *halfConn) explicitNonceLen() int {
+ if hc.cipher == nil {
+ return 0
+ }
+
+ switch c := hc.cipher.(type) {
+ case cipher.Stream:
+ return 0
+ case aead:
+ return c.explicitNonceLen()
+ case cbcMode:
+ // TLS 1.1 introduced a per-record explicit IV to fix the BEAST attack.
+ if hc.version >= VersionTLS11 {
+ return c.BlockSize()
+ }
+ return 0
+ default:
+ panic("unknown cipher type")
+ }
+}
+
+// extractPadding returns, in constant time, the length of the padding to remove
+// from the end of payload. It also returns a byte which is equal to 255 if the
+// padding was valid and 0 otherwise. See RFC 2246, Section 6.2.3.2.
+func extractPadding(payload []byte) (toRemove int, good byte) {
+ if len(payload) < 1 {
+ return 0, 0
+ }
+
+ paddingLen := payload[len(payload)-1]
+ t := uint(len(payload)-1) - uint(paddingLen)
+ // if len(payload) >= (paddingLen - 1) then the MSB of t is zero
+ good = byte(int32(^t) >> 31)
+
+ // The maximum possible padding length plus the actual length field
+ toCheck := 256
+ // The length of the padded data is public, so we can use an if here
+ if toCheck > len(payload) {
+ toCheck = len(payload)
+ }
+
+ for i := 0; i < toCheck; i++ {
+ t := uint(paddingLen) - uint(i)
+ // if i <= paddingLen then the MSB of t is zero
+ mask := byte(int32(^t) >> 31)
+ b := payload[len(payload)-1-i]
+ good &^= mask&paddingLen ^ mask&b
+ }
+
+ // We AND together the bits of good and replicate the result across
+ // all the bits.
+ good &= good << 4
+ good &= good << 2
+ good &= good << 1
+ good = uint8(int8(good) >> 7)
+
+ // Zero the padding length on error. This ensures any unchecked bytes
+ // are included in the MAC. Otherwise, an attacker that could
+ // distinguish MAC failures from padding failures could mount an attack
+ // similar to POODLE in SSL 3.0: given a good ciphertext that uses a
+ // full block's worth of padding, replace the final block with another
+ // block. If the MAC check passed but the padding check failed, the
+ // last byte of that block decrypted to the block size.
+ //
+ // See also macAndPaddingGood logic below.
+ paddingLen &= good
+
+ toRemove = int(paddingLen) + 1
+ return
+}
+
+func roundUp(a, b int) int {
+ return a + (b-a%b)%b
+}
+
+// cbcMode is an interface for block ciphers using cipher block chaining.
+type cbcMode interface {
+ cipher.BlockMode
+ SetIV([]byte)
+}
+
+// decrypt authenticates and decrypts the record if protection is active at
+// this stage. The returned plaintext might overlap with the input.
+func (hc *halfConn) decrypt(record []byte) ([]byte, recordType, error) {
+ var plaintext []byte
+ typ := recordType(record[0])
+ payload := record[recordHeaderLen:]
+
+ // In TLS 1.3, change_cipher_spec messages are to be ignored without being
+ // decrypted. See RFC 8446, Appendix D.4.
+ if hc.version == VersionTLS13 && typ == recordTypeChangeCipherSpec {
+ return payload, typ, nil
+ }
+
+ paddingGood := byte(255)
+ paddingLen := 0
+
+ explicitNonceLen := hc.explicitNonceLen()
+
+ if hc.cipher != nil {
+ switch c := hc.cipher.(type) {
+ case cipher.Stream:
+ c.XORKeyStream(payload, payload)
+ case aead:
+ if len(payload) < explicitNonceLen {
+ return nil, 0, alertBadRecordMAC
+ }
+ nonce := payload[:explicitNonceLen]
+ if len(nonce) == 0 {
+ nonce = hc.seq[:]
+ }
+ payload = payload[explicitNonceLen:]
+
+ var additionalData []byte
+ if hc.version == VersionTLS13 {
+ additionalData = record[:recordHeaderLen]
+ } else {
+ additionalData = append(hc.scratchBuf[:0], hc.seq[:]...)
+ additionalData = append(additionalData, record[:3]...)
+ n := len(payload) - c.Overhead()
+ additionalData = append(additionalData, byte(n>>8), byte(n))
+ }
+
+ var err error
+ plaintext, err = c.Open(payload[:0], nonce, payload, additionalData)
+ if err != nil {
+ return nil, 0, alertBadRecordMAC
+ }
+ case cbcMode:
+ blockSize := c.BlockSize()
+ minPayload := explicitNonceLen + roundUp(hc.mac.Size()+1, blockSize)
+ if len(payload)%blockSize != 0 || len(payload) < minPayload {
+ return nil, 0, alertBadRecordMAC
+ }
+
+ if explicitNonceLen > 0 {
+ c.SetIV(payload[:explicitNonceLen])
+ payload = payload[explicitNonceLen:]
+ }
+ c.CryptBlocks(payload, payload)
+
+ // In a limited attempt to protect against CBC padding oracles like
+ // Lucky13, the data past paddingLen (which is secret) is passed to
+ // the MAC function as extra data, to be fed into the HMAC after
+ // computing the digest. This makes the MAC roughly constant time as
+ // long as the digest computation is constant time and does not
+ // affect the subsequent write, modulo cache effects.
+ paddingLen, paddingGood = extractPadding(payload)
+ default:
+ panic("unknown cipher type")
+ }
+
+ if hc.version == VersionTLS13 {
+ if typ != recordTypeApplicationData {
+ return nil, 0, alertUnexpectedMessage
+ }
+ if len(plaintext) > maxPlaintext+1 {
+ return nil, 0, alertRecordOverflow
+ }
+ // Remove padding and find the ContentType scanning from the end.
+ for i := len(plaintext) - 1; i >= 0; i-- {
+ if plaintext[i] != 0 {
+ typ = recordType(plaintext[i])
+ plaintext = plaintext[:i]
+ break
+ }
+ if i == 0 {
+ return nil, 0, alertUnexpectedMessage
+ }
+ }
+ }
+ } else {
+ plaintext = payload
+ }
+
+ if hc.mac != nil {
+ macSize := hc.mac.Size()
+ if len(payload) < macSize {
+ return nil, 0, alertBadRecordMAC
+ }
+
+ n := len(payload) - macSize - paddingLen
+ n = subtle.ConstantTimeSelect(int(uint32(n)>>31), 0, n) // if n < 0 { n = 0 }
+ record[3] = byte(n >> 8)
+ record[4] = byte(n)
+ remoteMAC := payload[n : n+macSize]
+ localMAC := tls10MAC(hc.mac, hc.scratchBuf[:0], hc.seq[:], record[:recordHeaderLen], payload[:n], payload[n+macSize:])
+
+ // This is equivalent to checking the MACs and paddingGood
+ // separately, but in constant-time to prevent distinguishing
+ // padding failures from MAC failures. Depending on what value
+ // of paddingLen was returned on bad padding, distinguishing
+ // bad MAC from bad padding can lead to an attack.
+ //
+ // See also the logic at the end of extractPadding.
+ macAndPaddingGood := subtle.ConstantTimeCompare(localMAC, remoteMAC) & int(paddingGood)
+ if macAndPaddingGood != 1 {
+ return nil, 0, alertBadRecordMAC
+ }
+
+ plaintext = payload[:n]
+ }
+
+ hc.incSeq()
+ return plaintext, typ, nil
+}
+
+// sliceForAppend extends the input slice by n bytes. head is the full extended
+// slice, while tail is the appended part. If the original slice has sufficient
+// capacity no allocation is performed.
+func sliceForAppend(in []byte, n int) (head, tail []byte) {
+ if total := len(in) + n; cap(in) >= total {
+ head = in[:total]
+ } else {
+ head = make([]byte, total)
+ copy(head, in)
+ }
+ tail = head[len(in):]
+ return
+}
+
+// encrypt encrypts payload, adding the appropriate nonce and/or MAC, and
+// appends it to record, which must already contain the record header.
+func (hc *halfConn) encrypt(record, payload []byte, rand io.Reader) ([]byte, error) {
+ if hc.cipher == nil {
+ return append(record, payload...), nil
+ }
+
+ var explicitNonce []byte
+ if explicitNonceLen := hc.explicitNonceLen(); explicitNonceLen > 0 {
+ record, explicitNonce = sliceForAppend(record, explicitNonceLen)
+ if _, isCBC := hc.cipher.(cbcMode); !isCBC && explicitNonceLen < 16 {
+ // The AES-GCM construction in TLS has an explicit nonce so that the
+ // nonce can be random. However, the nonce is only 8 bytes which is
+ // too small for a secure, random nonce. Therefore we use the
+ // sequence number as the nonce. The 3DES-CBC construction also has
+ // an 8 bytes nonce but its nonces must be unpredictable (see RFC
+ // 5246, Appendix F.3), forcing us to use randomness. That's not
+ // 3DES' biggest problem anyway because the birthday bound on block
+ // collision is reached first due to its similarly small block size
+ // (see the Sweet32 attack).
+ copy(explicitNonce, hc.seq[:])
+ } else {
+ if _, err := io.ReadFull(rand, explicitNonce); err != nil {
+ return nil, err
+ }
+ }
+ }
+
+ var dst []byte
+ switch c := hc.cipher.(type) {
+ case cipher.Stream:
+ mac := tls10MAC(hc.mac, hc.scratchBuf[:0], hc.seq[:], record[:recordHeaderLen], payload, nil)
+ record, dst = sliceForAppend(record, len(payload)+len(mac))
+ c.XORKeyStream(dst[:len(payload)], payload)
+ c.XORKeyStream(dst[len(payload):], mac)
+ case aead:
+ nonce := explicitNonce
+ if len(nonce) == 0 {
+ nonce = hc.seq[:]
+ }
+
+ if hc.version == VersionTLS13 {
+ record = append(record, payload...)
+
+ // Encrypt the actual ContentType and replace the plaintext one.
+ record = append(record, record[0])
+ record[0] = byte(recordTypeApplicationData)
+
+ n := len(payload) + 1 + c.Overhead()
+ record[3] = byte(n >> 8)
+ record[4] = byte(n)
+
+ record = c.Seal(record[:recordHeaderLen],
+ nonce, record[recordHeaderLen:], record[:recordHeaderLen])
+ } else {
+ additionalData := append(hc.scratchBuf[:0], hc.seq[:]...)
+ additionalData = append(additionalData, record[:recordHeaderLen]...)
+ record = c.Seal(record, nonce, payload, additionalData)
+ }
+ case cbcMode:
+ mac := tls10MAC(hc.mac, hc.scratchBuf[:0], hc.seq[:], record[:recordHeaderLen], payload, nil)
+ blockSize := c.BlockSize()
+ plaintextLen := len(payload) + len(mac)
+ paddingLen := blockSize - plaintextLen%blockSize
+ record, dst = sliceForAppend(record, plaintextLen+paddingLen)
+ copy(dst, payload)
+ copy(dst[len(payload):], mac)
+ for i := plaintextLen; i < len(dst); i++ {
+ dst[i] = byte(paddingLen - 1)
+ }
+ if len(explicitNonce) > 0 {
+ c.SetIV(explicitNonce)
+ }
+ c.CryptBlocks(dst, dst)
+ default:
+ panic("unknown cipher type")
+ }
+
+ // Update length to include nonce, MAC and any block padding needed.
+ n := len(record) - recordHeaderLen
+ record[3] = byte(n >> 8)
+ record[4] = byte(n)
+ hc.incSeq()
+
+ return record, nil
+}
+
+// RecordHeaderError is returned when a TLS record header is invalid.
+type RecordHeaderError struct {
+ // Msg contains a human readable string that describes the error.
+ Msg string
+ // RecordHeader contains the five bytes of TLS record header that
+ // triggered the error.
+ RecordHeader [5]byte
+ // Conn provides the underlying net.Conn in the case that a client
+ // sent an initial handshake that didn't look like TLS.
+ // It is nil if there's already been a handshake or a TLS alert has
+ // been written to the connection.
+ Conn net.Conn
+}
+
+func (e RecordHeaderError) Error() string { return "tls: " + e.Msg }
+
+func (c *Conn) newRecordHeaderError(conn net.Conn, msg string) (err RecordHeaderError) {
+ err.Msg = msg
+ err.Conn = conn
+ copy(err.RecordHeader[:], c.rawInput.Bytes())
+ return err
+}
+
+func (c *Conn) readRecord() error {
+ return c.readRecordOrCCS(false)
+}
+
+func (c *Conn) readChangeCipherSpec() error {
+ return c.readRecordOrCCS(true)
+}
+
+// readRecordOrCCS reads one or more TLS records from the connection and
+// updates the record layer state. Some invariants:
+// - c.in must be locked
+// - c.input must be empty
+//
+// During the handshake one and only one of the following will happen:
+// - c.hand grows
+// - c.in.changeCipherSpec is called
+// - an error is returned
+//
+// After the handshake one and only one of the following will happen:
+// - c.hand grows
+// - c.input is set
+// - an error is returned
+func (c *Conn) readRecordOrCCS(expectChangeCipherSpec bool) error {
+ if c.in.err != nil {
+ return c.in.err
+ }
+ handshakeComplete := c.isHandshakeComplete.Load()
+
+ // This function modifies c.rawInput, which owns the c.input memory.
+ if c.input.Len() != 0 {
+ return c.in.setErrorLocked(errors.New("tls: internal error: attempted to read record with pending application data"))
+ }
+ c.input.Reset(nil)
+
+ if c.quic != nil {
+ return c.in.setErrorLocked(errors.New("tls: internal error: attempted to read record with QUIC transport"))
+ }
+
+ // Read header, payload.
+ if err := c.readFromUntil(c.conn, recordHeaderLen); err != nil {
+ // RFC 8446, Section 6.1 suggests that EOF without an alertCloseNotify
+ // is an error, but popular web sites seem to do this, so we accept it
+ // if and only if at the record boundary.
+ if err == io.ErrUnexpectedEOF && c.rawInput.Len() == 0 {
+ err = io.EOF
+ }
+ if e, ok := err.(net.Error); !ok || !e.Temporary() {
+ c.in.setErrorLocked(err)
+ }
+ return err
+ }
+ hdr := c.rawInput.Bytes()[:recordHeaderLen]
+ typ := recordType(hdr[0])
+
+ // No valid TLS record has a type of 0x80, however SSLv2 handshakes
+ // start with a uint16 length where the MSB is set and the first record
+ // is always < 256 bytes long. Therefore typ == 0x80 strongly suggests
+ // an SSLv2 client.
+ if !handshakeComplete && typ == 0x80 {
+ c.sendAlert(alertProtocolVersion)
+ return c.in.setErrorLocked(c.newRecordHeaderError(nil, "unsupported SSLv2 handshake received"))
+ }
+
+ vers := uint16(hdr[1])<<8 | uint16(hdr[2])
+ expectedVers := c.vers
+ if expectedVers == VersionTLS13 {
+ // All TLS 1.3 records are expected to have 0x0303 (1.2) after
+ // the initial hello (RFC 8446 Section 5.1).
+ expectedVers = VersionTLS12
+ }
+ n := int(hdr[3])<<8 | int(hdr[4])
+ if c.haveVers && vers != expectedVers {
+ c.sendAlert(alertProtocolVersion)
+ msg := fmt.Sprintf("received record with version %x when expecting version %x", vers, expectedVers)
+ return c.in.setErrorLocked(c.newRecordHeaderError(nil, msg))
+ }
+ if !c.haveVers {
+ // First message, be extra suspicious: this might not be a TLS
+ // client. Bail out before reading a full 'body', if possible.
+ // The current max version is 3.3 so if the version is >= 16.0,
+ // it's probably not real.
+ if (typ != recordTypeAlert && typ != recordTypeHandshake) || vers >= 0x1000 {
+ return c.in.setErrorLocked(c.newRecordHeaderError(c.conn, "first record does not look like a TLS handshake"))
+ }
+ }
+ if c.vers == VersionTLS13 && n > maxCiphertextTLS13 || n > maxCiphertext {
+ c.sendAlert(alertRecordOverflow)
+ msg := fmt.Sprintf("oversized record received with length %d", n)
+ return c.in.setErrorLocked(c.newRecordHeaderError(nil, msg))
+ }
+ if err := c.readFromUntil(c.conn, recordHeaderLen+n); err != nil {
+ if e, ok := err.(net.Error); !ok || !e.Temporary() {
+ c.in.setErrorLocked(err)
+ }
+ return err
+ }
+
+ // Process message.
+ record := c.rawInput.Next(recordHeaderLen + n)
+ data, typ, err := c.in.decrypt(record)
+ if err != nil {
+ return c.in.setErrorLocked(c.sendAlert(err.(alert)))
+ }
+ if len(data) > maxPlaintext {
+ return c.in.setErrorLocked(c.sendAlert(alertRecordOverflow))
+ }
+
+ // Application Data messages are always protected.
+ if c.in.cipher == nil && typ == recordTypeApplicationData {
+ return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+ }
+
+ if typ != recordTypeAlert && typ != recordTypeChangeCipherSpec && len(data) > 0 {
+ // This is a state-advancing message: reset the retry count.
+ c.retryCount = 0
+ }
+
+ // Handshake messages MUST NOT be interleaved with other record types in TLS 1.3.
+ if c.vers == VersionTLS13 && typ != recordTypeHandshake && c.hand.Len() > 0 {
+ return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+ }
+
+ switch typ {
+ default:
+ return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+
+ case recordTypeAlert:
+ if c.quic != nil {
+ return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+ }
+ if len(data) != 2 {
+ return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+ }
+ if alert(data[1]) == alertCloseNotify {
+ return c.in.setErrorLocked(io.EOF)
+ }
+ if c.vers == VersionTLS13 {
+ return c.in.setErrorLocked(&net.OpError{Op: "remote error", Err: alert(data[1])})
+ }
+ switch data[0] {
+ case alertLevelWarning:
+ // Drop the record on the floor and retry.
+ return c.retryReadRecord(expectChangeCipherSpec)
+ case alertLevelError:
+ return c.in.setErrorLocked(&net.OpError{Op: "remote error", Err: alert(data[1])})
+ default:
+ return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+ }
+
+ case recordTypeChangeCipherSpec:
+ if len(data) != 1 || data[0] != 1 {
+ return c.in.setErrorLocked(c.sendAlert(alertDecodeError))
+ }
+ // Handshake messages are not allowed to fragment across the CCS.
+ if c.hand.Len() > 0 {
+ return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+ }
+ // In TLS 1.3, change_cipher_spec records are ignored until the
+ // Finished. See RFC 8446, Appendix D.4. Note that according to Section
+ // 5, a server can send a ChangeCipherSpec before its ServerHello, when
+ // c.vers is still unset. That's not useful though and suspicious if the
+ // server then selects a lower protocol version, so don't allow that.
+ if c.vers == VersionTLS13 {
+ return c.retryReadRecord(expectChangeCipherSpec)
+ }
+ if !expectChangeCipherSpec {
+ return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+ }
+ if err := c.in.changeCipherSpec(); err != nil {
+ return c.in.setErrorLocked(c.sendAlert(err.(alert)))
+ }
+
+ case recordTypeApplicationData:
+ if !handshakeComplete || expectChangeCipherSpec {
+ return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+ }
+ // Some OpenSSL servers send empty records in order to randomize the
+ // CBC IV. Ignore a limited number of empty records.
+ if len(data) == 0 {
+ return c.retryReadRecord(expectChangeCipherSpec)
+ }
+ // Note that data is owned by c.rawInput, following the Next call above,
+ // to avoid copying the plaintext. This is safe because c.rawInput is
+ // not read from or written to until c.input is drained.
+ c.input.Reset(data)
+
+ case recordTypeHandshake:
+ if len(data) == 0 || expectChangeCipherSpec {
+ return c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+ }
+ c.hand.Write(data)
+ }
+
+ return nil
+}
+
+// retryReadRecord recurs into readRecordOrCCS to drop a non-advancing record, like
+// a warning alert, empty application_data, or a change_cipher_spec in TLS 1.3.
+func (c *Conn) retryReadRecord(expectChangeCipherSpec bool) error {
+ c.retryCount++
+ if c.retryCount > maxUselessRecords {
+ c.sendAlert(alertUnexpectedMessage)
+ return c.in.setErrorLocked(errors.New("tls: too many ignored records"))
+ }
+ return c.readRecordOrCCS(expectChangeCipherSpec)
+}
+
+// atLeastReader reads from R, stopping with EOF once at least N bytes have been
+// read. It is different from an io.LimitedReader in that it doesn't cut short
+// the last Read call, and in that it considers an early EOF an error.
+type atLeastReader struct {
+ R io.Reader
+ N int64
+}
+
+func (r *atLeastReader) Read(p []byte) (int, error) {
+ if r.N <= 0 {
+ return 0, io.EOF
+ }
+ n, err := r.R.Read(p)
+ r.N -= int64(n) // won't underflow unless len(p) >= n > 9223372036854775809
+ if r.N > 0 && err == io.EOF {
+ return n, io.ErrUnexpectedEOF
+ }
+ if r.N <= 0 && err == nil {
+ return n, io.EOF
+ }
+ return n, err
+}
+
+// readFromUntil reads from r into c.rawInput until c.rawInput contains
+// at least n bytes or else returns an error.
+func (c *Conn) readFromUntil(r io.Reader, n int) error {
+ if c.rawInput.Len() >= n {
+ return nil
+ }
+ needs := n - c.rawInput.Len()
+ // There might be extra input waiting on the wire. Make a best effort
+ // attempt to fetch it so that it can be used in (*Conn).Read to
+ // "predict" closeNotify alerts.
+ c.rawInput.Grow(needs + bytes.MinRead)
+ _, err := c.rawInput.ReadFrom(&atLeastReader{r, int64(needs)})
+ return err
+}
+
+// sendAlertLocked sends a TLS alert message.
+func (c *Conn) sendAlertLocked(err alert) error {
+ if c.quic != nil {
+ return c.out.setErrorLocked(&net.OpError{Op: "local error", Err: err})
+ }
+
+ switch err {
+ case alertNoRenegotiation, alertCloseNotify:
+ c.tmp[0] = alertLevelWarning
+ default:
+ c.tmp[0] = alertLevelError
+ }
+ c.tmp[1] = byte(err)
+
+ _, writeErr := c.writeRecordLocked(recordTypeAlert, c.tmp[0:2])
+ if err == alertCloseNotify {
+ // closeNotify is a special case in that it isn't an error.
+ return writeErr
+ }
+
+ return c.out.setErrorLocked(&net.OpError{Op: "local error", Err: err})
+}
+
+// sendAlert sends a TLS alert message.
+func (c *Conn) sendAlert(err alert) error {
+ c.out.Lock()
+ defer c.out.Unlock()
+ return c.sendAlertLocked(err)
+}
+
+const (
+ // tcpMSSEstimate is a conservative estimate of the TCP maximum segment
+ // size (MSS). A constant is used, rather than querying the kernel for
+ // the actual MSS, to avoid complexity. The value here is the IPv6
+ // minimum MTU (1280 bytes) minus the overhead of an IPv6 header (40
+ // bytes) and a TCP header with timestamps (32 bytes).
+ tcpMSSEstimate = 1208
+
+ // recordSizeBoostThreshold is the number of bytes of application data
+ // sent after which the TLS record size will be increased to the
+ // maximum.
+ recordSizeBoostThreshold = 128 * 1024
+)
+
+// maxPayloadSizeForWrite returns the maximum TLS payload size to use for the
+// next application data record. There is the following trade-off:
+//
+// - For latency-sensitive applications, such as web browsing, each TLS
+// record should fit in one TCP segment.
+// - For throughput-sensitive applications, such as large file transfers,
+// larger TLS records better amortize framing and encryption overheads.
+//
+// A simple heuristic that works well in practice is to use small records for
+// the first 1MB of data, then use larger records for subsequent data, and
+// reset back to smaller records after the connection becomes idle. See "High
+// Performance Web Networking", Chapter 4, or:
+// https://www.igvita.com/2013/10/24/optimizing-tls-record-size-and-buffering-latency/
+//
+// In the interests of simplicity and determinism, this code does not attempt
+// to reset the record size once the connection is idle, however.
+func (c *Conn) maxPayloadSizeForWrite(typ recordType) int {
+ if c.config.DynamicRecordSizingDisabled || typ != recordTypeApplicationData {
+ return maxPlaintext
+ }
+
+ if c.bytesSent >= recordSizeBoostThreshold {
+ return maxPlaintext
+ }
+
+ // Subtract TLS overheads to get the maximum payload size.
+ payloadBytes := tcpMSSEstimate - recordHeaderLen - c.out.explicitNonceLen()
+ if c.out.cipher != nil {
+ switch ciph := c.out.cipher.(type) {
+ case cipher.Stream:
+ payloadBytes -= c.out.mac.Size()
+ case cipher.AEAD:
+ payloadBytes -= ciph.Overhead()
+ case cbcMode:
+ blockSize := ciph.BlockSize()
+ // The payload must fit in a multiple of blockSize, with
+ // room for at least one padding byte.
+ payloadBytes = (payloadBytes & ^(blockSize - 1)) - 1
+ // The MAC is appended before padding so affects the
+ // payload size directly.
+ payloadBytes -= c.out.mac.Size()
+ default:
+ panic("unknown cipher type")
+ }
+ }
+ if c.vers == VersionTLS13 {
+ payloadBytes-- // encrypted ContentType
+ }
+
+ // Allow packet growth in arithmetic progression up to max.
+ pkt := c.packetsSent
+ c.packetsSent++
+ if pkt > 1000 {
+ return maxPlaintext // avoid overflow in multiply below
+ }
+
+ n := payloadBytes * int(pkt+1)
+ if n > maxPlaintext {
+ n = maxPlaintext
+ }
+ return n
+}
+
+func (c *Conn) write(data []byte) (int, error) {
+ if c.buffering {
+ c.sendBuf = append(c.sendBuf, data...)
+ return len(data), nil
+ }
+
+ n, err := c.conn.Write(data)
+ c.bytesSent += int64(n)
+ return n, err
+}
+
+func (c *Conn) flush() (int, error) {
+ if len(c.sendBuf) == 0 {
+ return 0, nil
+ }
+
+ n, err := c.conn.Write(c.sendBuf)
+ c.bytesSent += int64(n)
+ c.sendBuf = nil
+ c.buffering = false
+ return n, err
+}
+
+// outBufPool pools the record-sized scratch buffers used by writeRecordLocked.
+var outBufPool = sync.Pool{
+ New: func() any {
+ return new([]byte)
+ },
+}
+
+// writeRecordLocked writes a TLS record with the given type and payload to the
+// connection and updates the record layer state.
+func (c *Conn) writeRecordLocked(typ recordType, data []byte) (int, error) {
+ if c.quic != nil {
+ if typ != recordTypeHandshake {
+ return 0, errors.New("tls: internal error: sending non-handshake message to QUIC transport")
+ }
+ c.quicWriteCryptoData(c.out.level, data)
+ if !c.buffering {
+ if _, err := c.flush(); err != nil {
+ return 0, err
+ }
+ }
+ return len(data), nil
+ }
+
+ outBufPtr := outBufPool.Get().(*[]byte)
+ outBuf := *outBufPtr
+ defer func() {
+ // You might be tempted to simplify this by just passing &outBuf to Put,
+ // but that would make the local copy of the outBuf slice header escape
+ // to the heap, causing an allocation. Instead, we keep around the
+ // pointer to the slice header returned by Get, which is already on the
+ // heap, and overwrite and return that.
+ *outBufPtr = outBuf
+ outBufPool.Put(outBufPtr)
+ }()
+
+ var n int
+ for len(data) > 0 {
+ m := len(data)
+ if maxPayload := c.maxPayloadSizeForWrite(typ); m > maxPayload {
+ m = maxPayload
+ }
+
+ _, outBuf = sliceForAppend(outBuf[:0], recordHeaderLen)
+ outBuf[0] = byte(typ)
+ vers := c.vers
+ if vers == 0 {
+ // Some TLS servers fail if the record version is
+ // greater than TLS 1.0 for the initial ClientHello.
+ vers = VersionTLS10
+ } else if vers == VersionTLS13 {
+ // TLS 1.3 froze the record layer version to 1.2.
+ // See RFC 8446, Section 5.1.
+ vers = VersionTLS12
+ }
+ outBuf[1] = byte(vers >> 8)
+ outBuf[2] = byte(vers)
+ outBuf[3] = byte(m >> 8)
+ outBuf[4] = byte(m)
+
+ var err error
+ outBuf, err = c.out.encrypt(outBuf, data[:m], c.config.rand())
+ if err != nil {
+ return n, err
+ }
+ if _, err := c.write(outBuf); err != nil {
+ return n, err
+ }
+ n += m
+ data = data[m:]
+ }
+
+ if typ == recordTypeChangeCipherSpec && c.vers != VersionTLS13 {
+ if err := c.out.changeCipherSpec(); err != nil {
+ return n, c.sendAlertLocked(err.(alert))
+ }
+ }
+
+ return n, nil
+}
+
+// writeHandshakeRecord writes a handshake message to the connection and updates
+// the record layer state. If transcript is non-nil the marshalled message is
+// written to it.
+func (c *Conn) writeHandshakeRecord(msg handshakeMessage, transcript transcriptHash) (int, error) {
+ c.out.Lock()
+ defer c.out.Unlock()
+
+ data, err := msg.marshal()
+ if err != nil {
+ return 0, err
+ }
+ if transcript != nil {
+ transcript.Write(data)
+ }
+
+ return c.writeRecordLocked(recordTypeHandshake, data)
+}
+
+// writeChangeCipherRecord writes a ChangeCipherSpec message to the connection and
+// updates the record layer state.
+func (c *Conn) writeChangeCipherRecord() error {
+ c.out.Lock()
+ defer c.out.Unlock()
+ _, err := c.writeRecordLocked(recordTypeChangeCipherSpec, []byte{1})
+ return err
+}
+
+// readHandshakeBytes reads handshake data until c.hand contains at least n bytes.
+func (c *Conn) readHandshakeBytes(n int) error {
+ if c.quic != nil {
+ return c.quicReadHandshakeBytes(n)
+ }
+ for c.hand.Len() < n {
+ if err := c.readRecord(); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// readHandshake reads the next handshake message from
+// the record layer. If transcript is non-nil, the message
+// is written to the passed transcriptHash.
+func (c *Conn) readHandshake(transcript transcriptHash) (any, error) {
+ if err := c.readHandshakeBytes(4); err != nil {
+ return nil, err
+ }
+ data := c.hand.Bytes()
+ n := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
+ if n > maxHandshake {
+ c.sendAlertLocked(alertInternalError)
+ return nil, c.in.setErrorLocked(fmt.Errorf("tls: handshake message of length %d bytes exceeds maximum of %d bytes", n, maxHandshake))
+ }
+ if err := c.readHandshakeBytes(4 + n); err != nil {
+ return nil, err
+ }
+ data = c.hand.Next(4 + n)
+ return c.unmarshalHandshakeMessage(data, transcript)
+}
+
+func (c *Conn) unmarshalHandshakeMessage(data []byte, transcript transcriptHash) (handshakeMessage, error) {
+ var m handshakeMessage
+ switch data[0] {
+ case typeHelloRequest:
+ m = new(helloRequestMsg)
+ case typeClientHello:
+ m = new(clientHelloMsg)
+ case typeServerHello:
+ m = new(serverHelloMsg)
+ case typeNewSessionTicket:
+ if c.vers == VersionTLS13 {
+ m = new(newSessionTicketMsgTLS13)
+ } else {
+ m = new(newSessionTicketMsg)
+ }
+ case typeCertificate:
+ if c.vers == VersionTLS13 {
+ m = new(certificateMsgTLS13)
+ } else {
+ m = new(certificateMsg)
+ }
+ case typeCertificateRequest:
+ if c.vers == VersionTLS13 {
+ m = new(certificateRequestMsgTLS13)
+ } else {
+ m = &certificateRequestMsg{
+ hasSignatureAlgorithm: c.vers >= VersionTLS12,
+ }
+ }
+ case typeCertificateStatus:
+ m = new(certificateStatusMsg)
+ case typeServerKeyExchange:
+ m = new(serverKeyExchangeMsg)
+ case typeServerHelloDone:
+ m = new(serverHelloDoneMsg)
+ case typeClientKeyExchange:
+ m = new(clientKeyExchangeMsg)
+ case typeCertificateVerify:
+ m = &certificateVerifyMsg{
+ hasSignatureAlgorithm: c.vers >= VersionTLS12,
+ }
+ case typeFinished:
+ m = new(finishedMsg)
+ case typeEncryptedExtensions:
+ m = new(encryptedExtensionsMsg)
+ case typeEndOfEarlyData:
+ m = new(endOfEarlyDataMsg)
+ case typeKeyUpdate:
+ m = new(keyUpdateMsg)
+ default:
+ return nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+ }
+
+ // The handshake message unmarshalers
+ // expect to be able to keep references to data,
+ // so pass in a fresh copy that won't be overwritten.
+ data = append([]byte(nil), data...)
+
+ if !m.unmarshal(data) {
+ return nil, c.in.setErrorLocked(c.sendAlert(alertUnexpectedMessage))
+ }
+
+ if transcript != nil {
+ transcript.Write(data)
+ }
+
+ return m, nil
+}
+
+var (
+ errShutdown = errors.New("tls: protocol is shutdown")
+)
+
+// Write writes data to the connection.
+//
+// As Write calls Handshake, in order to prevent indefinite blocking a deadline
+// must be set for both Read and Write before Write is called when the handshake
+// has not yet completed. See SetDeadline, SetReadDeadline, and
+// SetWriteDeadline.
+func (c *Conn) Write(b []byte) (int, error) {
+ // interlock with Close below
+ for {
+ x := c.activeCall.Load()
+ if x&1 != 0 {
+ return 0, net.ErrClosed
+ }
+ if c.activeCall.CompareAndSwap(x, x+2) {
+ break
+ }
+ }
+ defer c.activeCall.Add(-2)
+
+ if err := c.Handshake(); err != nil {
+ return 0, err
+ }
+
+ c.out.Lock()
+ defer c.out.Unlock()
+
+ if err := c.out.err; err != nil {
+ return 0, err
+ }
+
+ if !c.isHandshakeComplete.Load() {
+ return 0, alertInternalError
+ }
+
+ if c.closeNotifySent {
+ return 0, errShutdown
+ }
+
+ // TLS 1.0 is susceptible to a chosen-plaintext
+ // attack when using block mode ciphers due to predictable IVs.
+ // This can be prevented by splitting each Application Data
+ // record into two records, effectively randomizing the IV.
+ //
+ // https://www.openssl.org/~bodo/tls-cbc.txt
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=665814
+ // https://www.imperialviolet.org/2012/01/15/beastfollowup.html
+
+ var m int
+ if len(b) > 1 && c.vers == VersionTLS10 {
+ if _, ok := c.out.cipher.(cipher.BlockMode); ok {
+ n, err := c.writeRecordLocked(recordTypeApplicationData, b[:1])
+ if err != nil {
+ return n, c.out.setErrorLocked(err)
+ }
+ m, b = 1, b[1:]
+ }
+ }
+
+ n, err := c.writeRecordLocked(recordTypeApplicationData, b)
+ return n + m, c.out.setErrorLocked(err)
+}
+
+// handleRenegotiation processes a HelloRequest handshake message.
+func (c *Conn) handleRenegotiation() error {
+ if c.vers == VersionTLS13 {
+ return errors.New("tls: internal error: unexpected renegotiation")
+ }
+
+ msg, err := c.readHandshake(nil)
+ if err != nil {
+ return err
+ }
+
+ helloReq, ok := msg.(*helloRequestMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(helloReq, msg)
+ }
+
+ if !c.isClient {
+ return c.sendAlert(alertNoRenegotiation)
+ }
+
+ switch c.config.Renegotiation {
+ case RenegotiateNever:
+ return c.sendAlert(alertNoRenegotiation)
+ case RenegotiateOnceAsClient:
+ if c.handshakes > 1 {
+ return c.sendAlert(alertNoRenegotiation)
+ }
+ case RenegotiateFreelyAsClient:
+ // Ok.
+ default:
+ c.sendAlert(alertInternalError)
+ return errors.New("tls: unknown Renegotiation value")
+ }
+
+ c.handshakeMutex.Lock()
+ defer c.handshakeMutex.Unlock()
+
+ c.isHandshakeComplete.Store(false)
+ if c.handshakeErr = c.clientHandshake(context.Background()); c.handshakeErr == nil {
+ c.handshakes++
+ }
+ return c.handshakeErr
+}
+
+// handlePostHandshakeMessage processes a handshake message arrived after the
+// handshake is complete. Up to TLS 1.2, it indicates the start of a renegotiation.
+func (c *Conn) handlePostHandshakeMessage() error {
+ if c.vers != VersionTLS13 {
+ return c.handleRenegotiation()
+ }
+
+ msg, err := c.readHandshake(nil)
+ if err != nil {
+ return err
+ }
+ c.retryCount++
+ if c.retryCount > maxUselessRecords {
+ c.sendAlert(alertUnexpectedMessage)
+ return c.in.setErrorLocked(errors.New("tls: too many non-advancing records"))
+ }
+
+ switch msg := msg.(type) {
+ case *newSessionTicketMsgTLS13:
+ return c.handleNewSessionTicket(msg)
+ case *keyUpdateMsg:
+ return c.handleKeyUpdate(msg)
+ }
+ // The QUIC layer is supposed to treat an unexpected post-handshake CertificateRequest
+ // as a QUIC-level PROTOCOL_VIOLATION error (RFC 9001, Section 4.4). Returning an
+ // unexpected_message alert here doesn't provide it with enough information to distinguish
+ // this condition from other unexpected messages. This is probably fine.
+ c.sendAlert(alertUnexpectedMessage)
+ return fmt.Errorf("tls: received unexpected handshake message of type %T", msg)
+}
+
+func (c *Conn) handleKeyUpdate(keyUpdate *keyUpdateMsg) error {
+ if c.quic != nil {
+ c.sendAlert(alertUnexpectedMessage)
+ return c.in.setErrorLocked(errors.New("tls: received unexpected key update message"))
+ }
+
+ cipherSuite := cipherSuiteTLS13ByID(c.cipherSuite)
+ if cipherSuite == nil {
+ return c.in.setErrorLocked(c.sendAlert(alertInternalError))
+ }
+
+ newSecret := cipherSuite.nextTrafficSecret(c.in.trafficSecret)
+ c.in.setTrafficSecret(cipherSuite, QUICEncryptionLevelInitial, newSecret)
+
+ if keyUpdate.updateRequested {
+ c.out.Lock()
+ defer c.out.Unlock()
+
+ msg := &keyUpdateMsg{}
+ msgBytes, err := msg.marshal()
+ if err != nil {
+ return err
+ }
+ _, err = c.writeRecordLocked(recordTypeHandshake, msgBytes)
+ if err != nil {
+ // Surface the error at the next write.
+ c.out.setErrorLocked(err)
+ return nil
+ }
+
+ newSecret := cipherSuite.nextTrafficSecret(c.out.trafficSecret)
+ c.out.setTrafficSecret(cipherSuite, QUICEncryptionLevelInitial, newSecret)
+ }
+
+ return nil
+}
+
+// Read reads data from the connection.
+//
+// As Read calls Handshake, in order to prevent indefinite blocking a deadline
+// must be set for both Read and Write before Read is called when the handshake
+// has not yet completed. See SetDeadline, SetReadDeadline, and
+// SetWriteDeadline.
+func (c *Conn) Read(b []byte) (int, error) {
+ if err := c.Handshake(); err != nil {
+ return 0, err
+ }
+ if len(b) == 0 {
+ // Put this after Handshake, in case people were calling
+ // Read(nil) for the side effect of the Handshake.
+ return 0, nil
+ }
+
+ c.in.Lock()
+ defer c.in.Unlock()
+
+ for c.input.Len() == 0 {
+ if err := c.readRecord(); err != nil {
+ return 0, err
+ }
+ for c.hand.Len() > 0 {
+ if err := c.handlePostHandshakeMessage(); err != nil {
+ return 0, err
+ }
+ }
+ }
+
+ n, _ := c.input.Read(b)
+
+ // If a close-notify alert is waiting, read it so that we can return (n,
+ // EOF) instead of (n, nil), to signal to the HTTP response reading
+ // goroutine that the connection is now closed. This eliminates a race
+ // where the HTTP response reading goroutine would otherwise not observe
+ // the EOF until its next read, by which time a client goroutine might
+ // have already tried to reuse the HTTP connection for a new request.
+ // See https://golang.org/cl/76400046 and https://golang.org/issue/3514
+ if n != 0 && c.input.Len() == 0 && c.rawInput.Len() > 0 &&
+ recordType(c.rawInput.Bytes()[0]) == recordTypeAlert {
+ if err := c.readRecord(); err != nil {
+ return n, err // will be io.EOF on closeNotify
+ }
+ }
+
+ return n, nil
+}
+
+// Close closes the connection.
+func (c *Conn) Close() error {
+ // Interlock with Conn.Write above.
+ var x int32
+ for {
+ x = c.activeCall.Load()
+ if x&1 != 0 {
+ return net.ErrClosed
+ }
+ if c.activeCall.CompareAndSwap(x, x|1) {
+ break
+ }
+ }
+ if x != 0 {
+ // io.Writer and io.Closer should not be used concurrently.
+ // If Close is called while a Write is currently in-flight,
+ // interpret that as a sign that this Close is really just
+ // being used to break the Write and/or clean up resources and
+ // avoid sending the alertCloseNotify, which may block
+ // waiting on handshakeMutex or the c.out mutex.
+ return c.conn.Close()
+ }
+
+ var alertErr error
+ if c.isHandshakeComplete.Load() {
+ if err := c.closeNotify(); err != nil {
+ alertErr = fmt.Errorf("tls: failed to send closeNotify alert (but connection was closed anyway): %w", err)
+ }
+ }
+
+ if err := c.conn.Close(); err != nil {
+ return err
+ }
+ return alertErr
+}
+
+var errEarlyCloseWrite = errors.New("tls: CloseWrite called before handshake complete")
+
+// CloseWrite shuts down the writing side of the connection. It should only be
+// called once the handshake has completed and does not call CloseWrite on the
+// underlying connection. Most callers should just use Close.
+func (c *Conn) CloseWrite() error {
+ if !c.isHandshakeComplete.Load() {
+ return errEarlyCloseWrite
+ }
+
+ return c.closeNotify()
+}
+
+func (c *Conn) closeNotify() error {
+ c.out.Lock()
+ defer c.out.Unlock()
+
+ if !c.closeNotifySent {
+ // Set a Write Deadline to prevent possibly blocking forever.
+ c.SetWriteDeadline(time.Now().Add(time.Second * 5))
+ c.closeNotifyErr = c.sendAlertLocked(alertCloseNotify)
+ c.closeNotifySent = true
+ // Any subsequent writes will fail.
+ c.SetWriteDeadline(time.Now())
+ }
+ return c.closeNotifyErr
+}
+
+// Handshake runs the client or server handshake
+// protocol if it has not yet been run.
+//
+// Most uses of this package need not call Handshake explicitly: the
+// first Read or Write will call it automatically.
+//
+// For control over canceling or setting a timeout on a handshake, use
+// HandshakeContext or the Dialer's DialContext method instead.
+//
+// In order to avoid denial of service attacks, the maximum RSA key size allowed
+// in certificates sent by either the TLS server or client is limited to 8192
+// bits. This limit can be overridden by setting tlsmaxrsasize in the GODEBUG
+// environment variable (e.g. GODEBUG=tlsmaxrsasize=4096).
+func (c *Conn) Handshake() error {
+ return c.HandshakeContext(context.Background())
+}
+
+// HandshakeContext runs the client or server handshake
+// protocol if it has not yet been run.
+//
+// The provided Context must be non-nil. If the context is canceled before
+// the handshake is complete, the handshake is interrupted and an error is returned.
+// Once the handshake has completed, cancellation of the context will not affect the
+// connection.
+//
+// Most uses of this package need not call HandshakeContext explicitly: the
+// first Read or Write will call it automatically.
+func (c *Conn) HandshakeContext(ctx context.Context) error {
+ // Delegate to unexported method for named return
+ // without confusing documented signature.
+ return c.handshakeContext(ctx)
+}
+
+func (c *Conn) handshakeContext(ctx context.Context) (ret error) {
+ // Fast sync/atomic-based exit if there is no handshake in flight and the
+ // last one succeeded without an error. Avoids the expensive context setup
+ // and mutex for most Read and Write calls.
+ if c.isHandshakeComplete.Load() {
+ return nil
+ }
+
+ handshakeCtx, cancel := context.WithCancel(ctx)
+ // Note: defer this before starting the "interrupter" goroutine
+ // so that we can tell the difference between the input being canceled and
+ // this cancellation. In the former case, we need to close the connection.
+ defer cancel()
+
+ if c.quic != nil {
+ c.quic.cancelc = handshakeCtx.Done()
+ c.quic.cancel = cancel
+ } else if ctx.Done() != nil {
+ // Start the "interrupter" goroutine, if this context might be canceled.
+ // (The background context cannot).
+ //
+ // The interrupter goroutine waits for the input context to be done and
+ // closes the connection if this happens before the function returns.
+ done := make(chan struct{})
+ interruptRes := make(chan error, 1)
+ defer func() {
+ close(done)
+ if ctxErr := <-interruptRes; ctxErr != nil {
+ // Return context error to user.
+ ret = ctxErr
+ }
+ }()
+ go func() {
+ select {
+ case <-handshakeCtx.Done():
+ // Close the connection, discarding the error
+ _ = c.conn.Close()
+ interruptRes <- handshakeCtx.Err()
+ case <-done:
+ interruptRes <- nil
+ }
+ }()
+ }
+
+ c.handshakeMutex.Lock()
+ defer c.handshakeMutex.Unlock()
+
+ if err := c.handshakeErr; err != nil {
+ return err
+ }
+ if c.isHandshakeComplete.Load() {
+ return nil
+ }
+
+ c.in.Lock()
+ defer c.in.Unlock()
+
+ c.handshakeErr = c.handshakeFn(handshakeCtx)
+ if c.handshakeErr == nil {
+ c.handshakes++
+ } else {
+ // If an error occurred during the handshake try to flush the
+ // alert that might be left in the buffer.
+ c.flush()
+ }
+
+ if c.handshakeErr == nil && !c.isHandshakeComplete.Load() {
+ c.handshakeErr = errors.New("tls: internal error: handshake should have had a result")
+ }
+ if c.handshakeErr != nil && c.isHandshakeComplete.Load() {
+ panic("tls: internal error: handshake returned an error but is marked successful")
+ }
+
+ if c.quic != nil {
+ if c.handshakeErr == nil {
+ c.quicHandshakeComplete()
+ // Provide the 1-RTT read secret now that the handshake is complete.
+ // The QUIC layer MUST NOT decrypt 1-RTT packets prior to completing
+ // the handshake (RFC 9001, Section 5.7).
+ c.quicSetReadSecret(QUICEncryptionLevelApplication, c.cipherSuite, c.in.trafficSecret)
+ } else {
+ var a alert
+ c.out.Lock()
+ if !errors.As(c.out.err, &a) {
+ a = alertInternalError
+ }
+ c.out.Unlock()
+ // Return an error which wraps both the handshake error and
+ // any alert error we may have sent, or alertInternalError
+ // if we didn't send an alert.
+ // Truncate the text of the alert to 0 characters.
+ c.handshakeErr = fmt.Errorf("%w%.0w", c.handshakeErr, AlertError(a))
+ }
+ close(c.quic.blockedc)
+ close(c.quic.signalc)
+ }
+
+ return c.handshakeErr
+}
+
+// ConnectionState returns basic TLS details about the connection.
+func (c *Conn) ConnectionState() ConnectionState {
+ c.handshakeMutex.Lock()
+ defer c.handshakeMutex.Unlock()
+ return c.connectionStateLocked()
+}
+
+func (c *Conn) connectionStateLocked() ConnectionState {
+ var state ConnectionState
+ state.HandshakeComplete = c.isHandshakeComplete.Load()
+ state.Version = c.vers
+ state.NegotiatedProtocol = c.clientProtocol
+ state.DidResume = c.didResume
+ state.NegotiatedProtocolIsMutual = true
+ state.ServerName = c.serverName
+ state.CipherSuite = c.cipherSuite
+ state.PeerCertificates = c.peerCertificates
+ state.VerifiedChains = c.verifiedChains
+ state.SignedCertificateTimestamps = c.scts
+ state.OCSPResponse = c.ocspResponse
+ if (!c.didResume || c.extMasterSecret) && c.vers != VersionTLS13 {
+ if c.clientFinishedIsFirst {
+ state.TLSUnique = c.clientFinished[:]
+ } else {
+ state.TLSUnique = c.serverFinished[:]
+ }
+ }
+ if c.config.Renegotiation != RenegotiateNever {
+ state.ekm = noExportedKeyingMaterial
+ } else {
+ state.ekm = c.ekm
+ }
+ return state
+}
+
+// OCSPResponse returns the stapled OCSP response from the TLS server, if
+// any. (Only valid for client connections.)
+func (c *Conn) OCSPResponse() []byte {
+ c.handshakeMutex.Lock()
+ defer c.handshakeMutex.Unlock()
+
+ return c.ocspResponse
+}
+
+// VerifyHostname checks that the peer certificate chain is valid for
+// connecting to host. If so, it returns nil; if not, it returns an error
+// describing the problem.
+func (c *Conn) VerifyHostname(host string) error {
+ c.handshakeMutex.Lock()
+ defer c.handshakeMutex.Unlock()
+ if !c.isClient {
+ return errors.New("tls: VerifyHostname called on TLS server connection")
+ }
+ if !c.isHandshakeComplete.Load() {
+ return errors.New("tls: handshake has not yet been performed")
+ }
+ if len(c.verifiedChains) == 0 {
+ return errors.New("tls: handshake did not verify certificate chain")
+ }
+ return c.peerCertificates[0].VerifyHostname(host)
+}
diff --git a/src/crypto/tls/conn_test.go b/src/crypto/tls/conn_test.go
new file mode 100644
index 0000000..5e090a0
--- /dev/null
+++ b/src/crypto/tls/conn_test.go
@@ -0,0 +1,319 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+ "bytes"
+ "io"
+ "net"
+ "testing"
+)
+
+func TestRoundUp(t *testing.T) {
+ if roundUp(0, 16) != 0 ||
+ roundUp(1, 16) != 16 ||
+ roundUp(15, 16) != 16 ||
+ roundUp(16, 16) != 16 ||
+ roundUp(17, 16) != 32 {
+ t.Error("roundUp broken")
+ }
+}
+
+// will be initialized with {0, 255, 255, ..., 255}
+var padding255Bad = [256]byte{}
+
+// will be initialized with {255, 255, 255, ..., 255}
+var padding255Good = [256]byte{255}
+
+var paddingTests = []struct {
+ in []byte
+ good bool
+ expectedLen int
+}{
+ {[]byte{1, 2, 3, 4, 0}, true, 4},
+ {[]byte{1, 2, 3, 4, 0, 1}, false, 0},
+ {[]byte{1, 2, 3, 4, 99, 99}, false, 0},
+ {[]byte{1, 2, 3, 4, 1, 1}, true, 4},
+ {[]byte{1, 2, 3, 2, 2, 2}, true, 3},
+ {[]byte{1, 2, 3, 3, 3, 3}, true, 2},
+ {[]byte{1, 2, 3, 4, 3, 3}, false, 0},
+ {[]byte{1, 4, 4, 4, 4, 4}, true, 1},
+ {[]byte{5, 5, 5, 5, 5, 5}, true, 0},
+ {[]byte{6, 6, 6, 6, 6, 6}, false, 0},
+ {padding255Bad[:], false, 0},
+ {padding255Good[:], true, 0},
+}
+
+func TestRemovePadding(t *testing.T) {
+ for i := 1; i < len(padding255Bad); i++ {
+ padding255Bad[i] = 255
+ padding255Good[i] = 255
+ }
+ for i, test := range paddingTests {
+ paddingLen, good := extractPadding(test.in)
+ expectedGood := byte(255)
+ if !test.good {
+ expectedGood = 0
+ }
+ if good != expectedGood {
+ t.Errorf("#%d: wrong validity, want:%d got:%d", i, expectedGood, good)
+ }
+ if good == 255 && len(test.in)-paddingLen != test.expectedLen {
+ t.Errorf("#%d: got %d, want %d", i, len(test.in)-paddingLen, test.expectedLen)
+ }
+ }
+}
+
+var certExampleCom = `308201713082011ba003020102021005a75ddf21014d5f417083b7a010ba2e300d06092a864886f70d01010b050030123110300e060355040a130741636d6520436f301e170d3136303831373231343135335a170d3137303831373231343135335a30123110300e060355040a130741636d6520436f305c300d06092a864886f70d0101010500034b003048024100b37f0fdd67e715bf532046ac34acbd8fdc4dabe2b598588f3f58b1f12e6219a16cbfe54d2b4b665396013589262360b6721efa27d546854f17cc9aeec6751db10203010001a34d304b300e0603551d0f0101ff0404030205a030130603551d25040c300a06082b06010505070301300c0603551d130101ff0402300030160603551d11040f300d820b6578616d706c652e636f6d300d06092a864886f70d01010b050003410059fc487866d3d855503c8e064ca32aac5e9babcece89ec597f8b2b24c17867f4a5d3b4ece06e795bfc5448ccbd2ffca1b3433171ebf3557a4737b020565350a0`
+
+var certWildcardExampleCom = `308201743082011ea003020102021100a7aa6297c9416a4633af8bec2958c607300d06092a864886f70d01010b050030123110300e060355040a130741636d6520436f301e170d3136303831373231343231395a170d3137303831373231343231395a30123110300e060355040a130741636d6520436f305c300d06092a864886f70d0101010500034b003048024100b105afc859a711ee864114e7d2d46c2dcbe392d3506249f6c2285b0eb342cc4bf2d803677c61c0abde443f084745c1a6d62080e5664ef2cc8f50ad8a0ab8870b0203010001a34f304d300e0603551d0f0101ff0404030205a030130603551d25040c300a06082b06010505070301300c0603551d130101ff0402300030180603551d110411300f820d2a2e6578616d706c652e636f6d300d06092a864886f70d01010b0500034100af26088584d266e3f6566360cf862c7fecc441484b098b107439543144a2b93f20781988281e108c6d7656934e56950e1e5f2bcf38796b814ccb729445856c34`
+
+var certFooExampleCom = `308201753082011fa00302010202101bbdb6070b0aeffc49008cde74deef29300d06092a864886f70d01010b050030123110300e060355040a130741636d6520436f301e170d3136303831373231343234345a170d3137303831373231343234345a30123110300e060355040a130741636d6520436f305c300d06092a864886f70d0101010500034b003048024100f00ac69d8ca2829f26216c7b50f1d4bbabad58d447706476cd89a2f3e1859943748aa42c15eedc93ac7c49e40d3b05ed645cb6b81c4efba60d961f44211a54eb0203010001a351304f300e0603551d0f0101ff0404030205a030130603551d25040c300a06082b06010505070301300c0603551d130101ff04023000301a0603551d1104133011820f666f6f2e6578616d706c652e636f6d300d06092a864886f70d01010b0500034100a0957fca6d1e0f1ef4b247348c7a8ca092c29c9c0ecc1898ea6b8065d23af6d922a410dd2335a0ea15edd1394cef9f62c9e876a21e35250a0b4fe1ddceba0f36`
+
+func TestCertificateSelection(t *testing.T) {
+ config := Config{
+ Certificates: []Certificate{
+ {
+ Certificate: [][]byte{fromHex(certExampleCom)},
+ },
+ {
+ Certificate: [][]byte{fromHex(certWildcardExampleCom)},
+ },
+ {
+ Certificate: [][]byte{fromHex(certFooExampleCom)},
+ },
+ },
+ }
+
+ config.BuildNameToCertificate()
+
+ pointerToIndex := func(c *Certificate) int {
+ for i := range config.Certificates {
+ if c == &config.Certificates[i] {
+ return i
+ }
+ }
+ return -1
+ }
+
+ certificateForName := func(name string) *Certificate {
+ clientHello := &ClientHelloInfo{
+ ServerName: name,
+ }
+ if cert, err := config.getCertificate(clientHello); err != nil {
+ t.Errorf("unable to get certificate for name '%s': %s", name, err)
+ return nil
+ } else {
+ return cert
+ }
+ }
+
+ if n := pointerToIndex(certificateForName("example.com")); n != 0 {
+ t.Errorf("example.com returned certificate %d, not 0", n)
+ }
+ if n := pointerToIndex(certificateForName("bar.example.com")); n != 1 {
+ t.Errorf("bar.example.com returned certificate %d, not 1", n)
+ }
+ if n := pointerToIndex(certificateForName("foo.example.com")); n != 2 {
+ t.Errorf("foo.example.com returned certificate %d, not 2", n)
+ }
+ if n := pointerToIndex(certificateForName("foo.bar.example.com")); n != 0 {
+ t.Errorf("foo.bar.example.com returned certificate %d, not 0", n)
+ }
+}
+
+// Run with multiple crypto configs to test the logic for computing TLS record overheads.
+func runDynamicRecordSizingTest(t *testing.T, config *Config) {
+ clientConn, serverConn := localPipe(t)
+
+ serverConfig := config.Clone()
+ serverConfig.DynamicRecordSizingDisabled = false
+ tlsConn := Server(serverConn, serverConfig)
+
+ handshakeDone := make(chan struct{})
+ recordSizesChan := make(chan []int, 1)
+ defer func() { <-recordSizesChan }() // wait for the goroutine to exit
+ go func() {
+ // This goroutine performs a TLS handshake over clientConn and
+ // then reads TLS records until EOF. It writes a slice that
+ // contains all the record sizes to recordSizesChan.
+ defer close(recordSizesChan)
+ defer clientConn.Close()
+
+ tlsConn := Client(clientConn, config)
+ if err := tlsConn.Handshake(); err != nil {
+ t.Errorf("Error from client handshake: %v", err)
+ return
+ }
+ close(handshakeDone)
+
+ var recordHeader [recordHeaderLen]byte
+ var record []byte
+ var recordSizes []int
+
+ for {
+ n, err := io.ReadFull(clientConn, recordHeader[:])
+ if err == io.EOF {
+ break
+ }
+ if err != nil || n != len(recordHeader) {
+ t.Errorf("io.ReadFull = %d, %v", n, err)
+ return
+ }
+
+ length := int(recordHeader[3])<<8 | int(recordHeader[4])
+ if len(record) < length {
+ record = make([]byte, length)
+ }
+
+ n, err = io.ReadFull(clientConn, record[:length])
+ if err != nil || n != length {
+ t.Errorf("io.ReadFull = %d, %v", n, err)
+ return
+ }
+
+ recordSizes = append(recordSizes, recordHeaderLen+length)
+ }
+
+ recordSizesChan <- recordSizes
+ }()
+
+ if err := tlsConn.Handshake(); err != nil {
+ t.Fatalf("Error from server handshake: %s", err)
+ }
+ <-handshakeDone
+
+ // The server writes these plaintexts in order.
+ plaintext := bytes.Join([][]byte{
+ bytes.Repeat([]byte("x"), recordSizeBoostThreshold),
+ bytes.Repeat([]byte("y"), maxPlaintext*2),
+ bytes.Repeat([]byte("z"), maxPlaintext),
+ }, nil)
+
+ if _, err := tlsConn.Write(plaintext); err != nil {
+ t.Fatalf("Error from server write: %s", err)
+ }
+ if err := tlsConn.Close(); err != nil {
+ t.Fatalf("Error from server close: %s", err)
+ }
+
+ recordSizes := <-recordSizesChan
+ if recordSizes == nil {
+ t.Fatalf("Client encountered an error")
+ }
+
+ // Drop the size of the second to last record, which is likely to be
+ // truncated, and the last record, which is a close_notify alert.
+ recordSizes = recordSizes[:len(recordSizes)-2]
+
+ // recordSizes should contain a series of records smaller than
+ // tcpMSSEstimate followed by some larger than maxPlaintext.
+ seenLargeRecord := false
+ for i, size := range recordSizes {
+ if !seenLargeRecord {
+ if size > (i+1)*tcpMSSEstimate {
+ t.Fatalf("Record #%d has size %d, which is too large too soon", i, size)
+ }
+ if size >= maxPlaintext {
+ seenLargeRecord = true
+ }
+ } else if size <= maxPlaintext {
+ t.Fatalf("Record #%d has size %d but should be full sized", i, size)
+ }
+ }
+
+ if !seenLargeRecord {
+ t.Fatalf("No large records observed")
+ }
+}
+
+func TestDynamicRecordSizingWithStreamCipher(t *testing.T) {
+ config := testConfig.Clone()
+ config.MaxVersion = VersionTLS12
+ config.CipherSuites = []uint16{TLS_RSA_WITH_RC4_128_SHA}
+ runDynamicRecordSizingTest(t, config)
+}
+
+func TestDynamicRecordSizingWithCBC(t *testing.T) {
+ config := testConfig.Clone()
+ config.MaxVersion = VersionTLS12
+ config.CipherSuites = []uint16{TLS_RSA_WITH_AES_256_CBC_SHA}
+ runDynamicRecordSizingTest(t, config)
+}
+
+func TestDynamicRecordSizingWithAEAD(t *testing.T) {
+ config := testConfig.Clone()
+ config.MaxVersion = VersionTLS12
+ config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}
+ runDynamicRecordSizingTest(t, config)
+}
+
+func TestDynamicRecordSizingWithTLSv13(t *testing.T) {
+ config := testConfig.Clone()
+ runDynamicRecordSizingTest(t, config)
+}
+
+// hairpinConn is a net.Conn that makes a “hairpin” call when closed, back into
+// the tls.Conn which is calling it.
+type hairpinConn struct {
+ net.Conn
+ tlsConn *Conn
+}
+
+func (conn *hairpinConn) Close() error {
+ conn.tlsConn.ConnectionState()
+ return nil
+}
+
+func TestHairpinInClose(t *testing.T) {
+ // This tests that the underlying net.Conn can call back into the
+ // tls.Conn when being closed without deadlocking.
+ client, server := localPipe(t)
+ defer server.Close()
+ defer client.Close()
+
+ conn := &hairpinConn{client, nil}
+ tlsConn := Server(conn, &Config{
+ GetCertificate: func(*ClientHelloInfo) (*Certificate, error) {
+ panic("unreachable")
+ },
+ })
+ conn.tlsConn = tlsConn
+
+ // This call should not deadlock.
+ tlsConn.Close()
+}
+
+func TestRecordBadVersionTLS13(t *testing.T) {
+ client, server := localPipe(t)
+ defer server.Close()
+ defer client.Close()
+
+ config := testConfig.Clone()
+ config.MinVersion, config.MaxVersion = VersionTLS13, VersionTLS13
+
+ go func() {
+ tlsConn := Client(client, config)
+ if err := tlsConn.Handshake(); err != nil {
+ t.Errorf("Error from client handshake: %v", err)
+ return
+ }
+ tlsConn.vers = 0x1111
+ tlsConn.Write([]byte{1})
+ }()
+
+ tlsConn := Server(server, config)
+ if err := tlsConn.Handshake(); err != nil {
+ t.Errorf("Error from client handshake: %v", err)
+ return
+ }
+
+ expectedErr := "tls: received record with version 1111 when expecting version 303"
+
+ _, err := tlsConn.Read(make([]byte, 10))
+ if err.Error() != expectedErr {
+ t.Fatalf("unexpected error: got %q, want %q", err, expectedErr)
+ }
+}
diff --git a/src/crypto/tls/example_test.go b/src/crypto/tls/example_test.go
new file mode 100644
index 0000000..6389fd7
--- /dev/null
+++ b/src/crypto/tls/example_test.go
@@ -0,0 +1,232 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls_test
+
+import (
+ "crypto/tls"
+ "crypto/x509"
+ "log"
+ "net/http"
+ "net/http/httptest"
+ "os"
+ "time"
+)
+
+// zeroSource is an io.Reader that returns an unlimited number of zero bytes.
+type zeroSource struct{}
+
+func (zeroSource) Read(b []byte) (n int, err error) {
+ for i := range b {
+ b[i] = 0
+ }
+
+ return len(b), nil
+}
+
+func ExampleDial() {
+ // Connecting with a custom root-certificate set.
+
+ const rootPEM = `
+-- GlobalSign Root R2, valid until Dec 15, 2021
+-----BEGIN CERTIFICATE-----
+MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G
+A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp
+Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1
+MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG
+A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
+hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL
+v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8
+eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq
+tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd
+C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa
+zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB
+mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH
+V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n
+bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG
+3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs
+J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO
+291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS
+ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd
+AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
+TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
+-----END CERTIFICATE-----`
+
+ // First, create the set of root certificates. For this example we only
+ // have one. It's also possible to omit this in order to use the
+ // default root set of the current operating system.
+ roots := x509.NewCertPool()
+ ok := roots.AppendCertsFromPEM([]byte(rootPEM))
+ if !ok {
+ panic("failed to parse root certificate")
+ }
+
+ conn, err := tls.Dial("tcp", "mail.google.com:443", &tls.Config{
+ RootCAs: roots,
+ })
+ if err != nil {
+ panic("failed to connect: " + err.Error())
+ }
+ conn.Close()
+}
+
+func ExampleConfig_keyLogWriter() {
+ // Debugging TLS applications by decrypting a network traffic capture.
+
+ // WARNING: Use of KeyLogWriter compromises security and should only be
+ // used for debugging.
+
+ // Dummy test HTTP server for the example with insecure random so output is
+ // reproducible.
+ server := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
+ server.TLS = &tls.Config{
+ Rand: zeroSource{}, // for example only; don't do this.
+ }
+ server.StartTLS()
+ defer server.Close()
+
+ // Typically the log would go to an open file:
+ // w, err := os.OpenFile("tls-secrets.txt", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
+ w := os.Stdout
+
+ client := &http.Client{
+ Transport: &http.Transport{
+ TLSClientConfig: &tls.Config{
+ KeyLogWriter: w,
+
+ Rand: zeroSource{}, // for reproducible output; don't do this.
+ InsecureSkipVerify: true, // test server certificate is not trusted.
+ },
+ },
+ }
+ resp, err := client.Get(server.URL)
+ if err != nil {
+ log.Fatalf("Failed to get URL: %v", err)
+ }
+ resp.Body.Close()
+
+ // The resulting file can be used with Wireshark to decrypt the TLS
+ // connection by setting (Pre)-Master-Secret log filename in SSL Protocol
+ // preferences.
+}
+
+func ExampleLoadX509KeyPair() {
+ cert, err := tls.LoadX509KeyPair("testdata/example-cert.pem", "testdata/example-key.pem")
+ if err != nil {
+ log.Fatal(err)
+ }
+ cfg := &tls.Config{Certificates: []tls.Certificate{cert}}
+ listener, err := tls.Listen("tcp", ":2000", cfg)
+ if err != nil {
+ log.Fatal(err)
+ }
+ _ = listener
+}
+
+func ExampleX509KeyPair() {
+ certPem := []byte(`-----BEGIN CERTIFICATE-----
+MIIBhTCCASugAwIBAgIQIRi6zePL6mKjOipn+dNuaTAKBggqhkjOPQQDAjASMRAw
+DgYDVQQKEwdBY21lIENvMB4XDTE3MTAyMDE5NDMwNloXDTE4MTAyMDE5NDMwNlow
+EjEQMA4GA1UEChMHQWNtZSBDbzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABD0d
+7VNhbWvZLWPuj/RtHFjvtJBEwOkhbN/BnnE8rnZR8+sbwnc/KhCk3FhnpHZnQz7B
+5aETbbIgmuvewdjvSBSjYzBhMA4GA1UdDwEB/wQEAwICpDATBgNVHSUEDDAKBggr
+BgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdEQQiMCCCDmxvY2FsaG9zdDo1
+NDUzgg4xMjcuMC4wLjE6NTQ1MzAKBggqhkjOPQQDAgNIADBFAiEA2zpJEPQyz6/l
+Wf86aX6PepsntZv2GYlA5UpabfT2EZICICpJ5h/iI+i341gBmLiAFQOyTDT+/wQc
+6MF9+Yw1Yy0t
+-----END CERTIFICATE-----`)
+ keyPem := []byte(`-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIIrYSSNQFaA2Hwf1duRSxKtLYX5CB04fSeQ6tF1aY/PuoAoGCCqGSM49
+AwEHoUQDQgAEPR3tU2Fta9ktY+6P9G0cWO+0kETA6SFs38GecTyudlHz6xvCdz8q
+EKTcWGekdmdDPsHloRNtsiCa697B2O9IFA==
+-----END EC PRIVATE KEY-----`)
+ cert, err := tls.X509KeyPair(certPem, keyPem)
+ if err != nil {
+ log.Fatal(err)
+ }
+ cfg := &tls.Config{Certificates: []tls.Certificate{cert}}
+ listener, err := tls.Listen("tcp", ":2000", cfg)
+ if err != nil {
+ log.Fatal(err)
+ }
+ _ = listener
+}
+
+func ExampleX509KeyPair_httpServer() {
+ certPem := []byte(`-----BEGIN CERTIFICATE-----
+MIIBhTCCASugAwIBAgIQIRi6zePL6mKjOipn+dNuaTAKBggqhkjOPQQDAjASMRAw
+DgYDVQQKEwdBY21lIENvMB4XDTE3MTAyMDE5NDMwNloXDTE4MTAyMDE5NDMwNlow
+EjEQMA4GA1UEChMHQWNtZSBDbzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABD0d
+7VNhbWvZLWPuj/RtHFjvtJBEwOkhbN/BnnE8rnZR8+sbwnc/KhCk3FhnpHZnQz7B
+5aETbbIgmuvewdjvSBSjYzBhMA4GA1UdDwEB/wQEAwICpDATBgNVHSUEDDAKBggr
+BgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdEQQiMCCCDmxvY2FsaG9zdDo1
+NDUzgg4xMjcuMC4wLjE6NTQ1MzAKBggqhkjOPQQDAgNIADBFAiEA2zpJEPQyz6/l
+Wf86aX6PepsntZv2GYlA5UpabfT2EZICICpJ5h/iI+i341gBmLiAFQOyTDT+/wQc
+6MF9+Yw1Yy0t
+-----END CERTIFICATE-----`)
+ keyPem := []byte(`-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIIrYSSNQFaA2Hwf1duRSxKtLYX5CB04fSeQ6tF1aY/PuoAoGCCqGSM49
+AwEHoUQDQgAEPR3tU2Fta9ktY+6P9G0cWO+0kETA6SFs38GecTyudlHz6xvCdz8q
+EKTcWGekdmdDPsHloRNtsiCa697B2O9IFA==
+-----END EC PRIVATE KEY-----`)
+ cert, err := tls.X509KeyPair(certPem, keyPem)
+ if err != nil {
+ log.Fatal(err)
+ }
+ cfg := &tls.Config{Certificates: []tls.Certificate{cert}}
+ srv := &http.Server{
+ TLSConfig: cfg,
+ ReadTimeout: time.Minute,
+ WriteTimeout: time.Minute,
+ }
+ log.Fatal(srv.ListenAndServeTLS("", ""))
+}
+
+func ExampleConfig_verifyConnection() {
+ // VerifyConnection can be used to replace and customize connection
+ // verification. This example shows a VerifyConnection implementation that
+ // will be approximately equivalent to what crypto/tls does normally to
+ // verify the peer's certificate.
+
+ // Client side configuration.
+ _ = &tls.Config{
+ // Set InsecureSkipVerify to skip the default validation we are
+ // replacing. This will not disable VerifyConnection.
+ InsecureSkipVerify: true,
+ VerifyConnection: func(cs tls.ConnectionState) error {
+ opts := x509.VerifyOptions{
+ DNSName: cs.ServerName,
+ Intermediates: x509.NewCertPool(),
+ }
+ for _, cert := range cs.PeerCertificates[1:] {
+ opts.Intermediates.AddCert(cert)
+ }
+ _, err := cs.PeerCertificates[0].Verify(opts)
+ return err
+ },
+ }
+
+ // Server side configuration.
+ _ = &tls.Config{
+ // Require client certificates (or VerifyConnection will run anyway and
+ // panic accessing cs.PeerCertificates[0]) but don't verify them with the
+ // default verifier. This will not disable VerifyConnection.
+ ClientAuth: tls.RequireAnyClientCert,
+ VerifyConnection: func(cs tls.ConnectionState) error {
+ opts := x509.VerifyOptions{
+ DNSName: cs.ServerName,
+ Intermediates: x509.NewCertPool(),
+ KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
+ }
+ for _, cert := range cs.PeerCertificates[1:] {
+ opts.Intermediates.AddCert(cert)
+ }
+ _, err := cs.PeerCertificates[0].Verify(opts)
+ return err
+ },
+ }
+
+ // Note that when certificates are not handled by the default verifier
+ // ConnectionState.VerifiedChains will be nil.
+}
diff --git a/src/crypto/tls/fipsonly/fipsonly.go b/src/crypto/tls/fipsonly/fipsonly.go
new file mode 100644
index 0000000..e5e4783
--- /dev/null
+++ b/src/crypto/tls/fipsonly/fipsonly.go
@@ -0,0 +1,29 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build boringcrypto
+
+// Package fipsonly restricts all TLS configuration to FIPS-approved settings.
+//
+// The effect is triggered by importing the package anywhere in a program, as in:
+//
+// import _ "crypto/tls/fipsonly"
+//
+// This package only exists when using Go compiled with GOEXPERIMENT=boringcrypto.
+package fipsonly
+
+// This functionality is provided as a side effect of an import to make
+// it trivial to add to an existing program. It requires only a single line
+// added to an existing source file, or it can be done by adding a whole
+// new source file and not modifying any existing source files.
+
+import (
+ "crypto/internal/boring/fipstls"
+ "crypto/internal/boring/sig"
+)
+
+func init() {
+ fipstls.Force()
+ sig.FIPSOnly()
+}
diff --git a/src/crypto/tls/fipsonly/fipsonly_test.go b/src/crypto/tls/fipsonly/fipsonly_test.go
new file mode 100644
index 0000000..f8485dc
--- /dev/null
+++ b/src/crypto/tls/fipsonly/fipsonly_test.go
@@ -0,0 +1,18 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build boringcrypto
+
+package fipsonly
+
+import (
+ "crypto/internal/boring/fipstls"
+ "testing"
+)
+
+func Test(t *testing.T) {
+ if !fipstls.Required() {
+ t.Fatal("fipstls.Required() = false, must be true")
+ }
+}
diff --git a/src/crypto/tls/generate_cert.go b/src/crypto/tls/generate_cert.go
new file mode 100644
index 0000000..cd4bfc5
--- /dev/null
+++ b/src/crypto/tls/generate_cert.go
@@ -0,0 +1,171 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build ignore
+
+// Generate a self-signed X.509 certificate for a TLS server. Outputs to
+// 'cert.pem' and 'key.pem' and will overwrite existing files.
+
+package main
+
+import (
+ "crypto/ecdsa"
+ "crypto/ed25519"
+ "crypto/elliptic"
+ "crypto/rand"
+ "crypto/rsa"
+ "crypto/x509"
+ "crypto/x509/pkix"
+ "encoding/pem"
+ "flag"
+ "log"
+ "math/big"
+ "net"
+ "os"
+ "strings"
+ "time"
+)
+
+var (
+ host = flag.String("host", "", "Comma-separated hostnames and IPs to generate a certificate for")
+ validFrom = flag.String("start-date", "", "Creation date formatted as Jan 1 15:04:05 2011")
+ validFor = flag.Duration("duration", 365*24*time.Hour, "Duration that certificate is valid for")
+ isCA = flag.Bool("ca", false, "whether this cert should be its own Certificate Authority")
+ rsaBits = flag.Int("rsa-bits", 2048, "Size of RSA key to generate. Ignored if --ecdsa-curve is set")
+ ecdsaCurve = flag.String("ecdsa-curve", "", "ECDSA curve to use to generate a key. Valid values are P224, P256 (recommended), P384, P521")
+ ed25519Key = flag.Bool("ed25519", false, "Generate an Ed25519 key")
+)
+
+func publicKey(priv any) any {
+ switch k := priv.(type) {
+ case *rsa.PrivateKey:
+ return &k.PublicKey
+ case *ecdsa.PrivateKey:
+ return &k.PublicKey
+ case ed25519.PrivateKey:
+ return k.Public().(ed25519.PublicKey)
+ default:
+ return nil
+ }
+}
+
+func main() {
+ flag.Parse()
+
+ if len(*host) == 0 {
+ log.Fatalf("Missing required --host parameter")
+ }
+
+ var priv any
+ var err error
+ switch *ecdsaCurve {
+ case "":
+ if *ed25519Key {
+ _, priv, err = ed25519.GenerateKey(rand.Reader)
+ } else {
+ priv, err = rsa.GenerateKey(rand.Reader, *rsaBits)
+ }
+ case "P224":
+ priv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader)
+ case "P256":
+ priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+ case "P384":
+ priv, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
+ case "P521":
+ priv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
+ default:
+ log.Fatalf("Unrecognized elliptic curve: %q", *ecdsaCurve)
+ }
+ if err != nil {
+ log.Fatalf("Failed to generate private key: %v", err)
+ }
+
+ // ECDSA, ED25519 and RSA subject keys should have the DigitalSignature
+ // KeyUsage bits set in the x509.Certificate template
+ keyUsage := x509.KeyUsageDigitalSignature
+ // Only RSA subject keys should have the KeyEncipherment KeyUsage bits set. In
+ // the context of TLS this KeyUsage is particular to RSA key exchange and
+ // authentication.
+ if _, isRSA := priv.(*rsa.PrivateKey); isRSA {
+ keyUsage |= x509.KeyUsageKeyEncipherment
+ }
+
+ var notBefore time.Time
+ if len(*validFrom) == 0 {
+ notBefore = time.Now()
+ } else {
+ notBefore, err = time.Parse("Jan 2 15:04:05 2006", *validFrom)
+ if err != nil {
+ log.Fatalf("Failed to parse creation date: %v", err)
+ }
+ }
+
+ notAfter := notBefore.Add(*validFor)
+
+ serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
+ serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
+ if err != nil {
+ log.Fatalf("Failed to generate serial number: %v", err)
+ }
+
+ template := x509.Certificate{
+ SerialNumber: serialNumber,
+ Subject: pkix.Name{
+ Organization: []string{"Acme Co"},
+ },
+ NotBefore: notBefore,
+ NotAfter: notAfter,
+
+ KeyUsage: keyUsage,
+ ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
+ BasicConstraintsValid: true,
+ }
+
+ hosts := strings.Split(*host, ",")
+ for _, h := range hosts {
+ if ip := net.ParseIP(h); ip != nil {
+ template.IPAddresses = append(template.IPAddresses, ip)
+ } else {
+ template.DNSNames = append(template.DNSNames, h)
+ }
+ }
+
+ if *isCA {
+ template.IsCA = true
+ template.KeyUsage |= x509.KeyUsageCertSign
+ }
+
+ derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv)
+ if err != nil {
+ log.Fatalf("Failed to create certificate: %v", err)
+ }
+
+ certOut, err := os.Create("cert.pem")
+ if err != nil {
+ log.Fatalf("Failed to open cert.pem for writing: %v", err)
+ }
+ if err := pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil {
+ log.Fatalf("Failed to write data to cert.pem: %v", err)
+ }
+ if err := certOut.Close(); err != nil {
+ log.Fatalf("Error closing cert.pem: %v", err)
+ }
+ log.Print("wrote cert.pem\n")
+
+ keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
+ if err != nil {
+ log.Fatalf("Failed to open key.pem for writing: %v", err)
+ }
+ privBytes, err := x509.MarshalPKCS8PrivateKey(priv)
+ if err != nil {
+ log.Fatalf("Unable to marshal private key: %v", err)
+ }
+ if err := pem.Encode(keyOut, &pem.Block{Type: "PRIVATE KEY", Bytes: privBytes}); err != nil {
+ log.Fatalf("Failed to write data to key.pem: %v", err)
+ }
+ if err := keyOut.Close(); err != nil {
+ log.Fatalf("Error closing key.pem: %v", err)
+ }
+ log.Print("wrote key.pem\n")
+}
diff --git a/src/crypto/tls/handshake_client.go b/src/crypto/tls/handshake_client.go
new file mode 100644
index 0000000..4649f36
--- /dev/null
+++ b/src/crypto/tls/handshake_client.go
@@ -0,0 +1,1140 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+ "bytes"
+ "context"
+ "crypto"
+ "crypto/ecdh"
+ "crypto/ecdsa"
+ "crypto/ed25519"
+ "crypto/rsa"
+ "crypto/subtle"
+ "crypto/x509"
+ "errors"
+ "fmt"
+ "hash"
+ "internal/godebug"
+ "io"
+ "net"
+ "strconv"
+ "strings"
+ "time"
+)
+
+type clientHandshakeState struct {
+ c *Conn
+ ctx context.Context
+ serverHello *serverHelloMsg
+ hello *clientHelloMsg
+ suite *cipherSuite
+ finishedHash finishedHash
+ masterSecret []byte
+ session *SessionState // the session being resumed
+ ticket []byte // a fresh ticket received during this handshake
+}
+
+var testingOnlyForceClientHelloSignatureAlgorithms []SignatureScheme
+
+func (c *Conn) makeClientHello() (*clientHelloMsg, *ecdh.PrivateKey, error) {
+ config := c.config
+ if len(config.ServerName) == 0 && !config.InsecureSkipVerify {
+ return nil, nil, errors.New("tls: either ServerName or InsecureSkipVerify must be specified in the tls.Config")
+ }
+
+ nextProtosLength := 0
+ for _, proto := range config.NextProtos {
+ if l := len(proto); l == 0 || l > 255 {
+ return nil, nil, errors.New("tls: invalid NextProtos value")
+ } else {
+ nextProtosLength += 1 + l
+ }
+ }
+ if nextProtosLength > 0xffff {
+ return nil, nil, errors.New("tls: NextProtos values too large")
+ }
+
+ supportedVersions := config.supportedVersions(roleClient)
+ if len(supportedVersions) == 0 {
+ return nil, nil, errors.New("tls: no supported versions satisfy MinVersion and MaxVersion")
+ }
+
+ clientHelloVersion := config.maxSupportedVersion(roleClient)
+ // The version at the beginning of the ClientHello was capped at TLS 1.2
+ // for compatibility reasons. The supported_versions extension is used
+ // to negotiate versions now. See RFC 8446, Section 4.2.1.
+ if clientHelloVersion > VersionTLS12 {
+ clientHelloVersion = VersionTLS12
+ }
+
+ hello := &clientHelloMsg{
+ vers: clientHelloVersion,
+ compressionMethods: []uint8{compressionNone},
+ random: make([]byte, 32),
+ extendedMasterSecret: true,
+ ocspStapling: true,
+ scts: true,
+ serverName: hostnameInSNI(config.ServerName),
+ supportedCurves: config.curvePreferences(),
+ supportedPoints: []uint8{pointFormatUncompressed},
+ secureRenegotiationSupported: true,
+ alpnProtocols: config.NextProtos,
+ supportedVersions: supportedVersions,
+ }
+
+ if c.handshakes > 0 {
+ hello.secureRenegotiation = c.clientFinished[:]
+ }
+
+ preferenceOrder := cipherSuitesPreferenceOrder
+ if !hasAESGCMHardwareSupport {
+ preferenceOrder = cipherSuitesPreferenceOrderNoAES
+ }
+ configCipherSuites := config.cipherSuites()
+ hello.cipherSuites = make([]uint16, 0, len(configCipherSuites))
+
+ for _, suiteId := range preferenceOrder {
+ suite := mutualCipherSuite(configCipherSuites, suiteId)
+ if suite == nil {
+ continue
+ }
+ // Don't advertise TLS 1.2-only cipher suites unless
+ // we're attempting TLS 1.2.
+ if hello.vers < VersionTLS12 && suite.flags&suiteTLS12 != 0 {
+ continue
+ }
+ hello.cipherSuites = append(hello.cipherSuites, suiteId)
+ }
+
+ _, err := io.ReadFull(config.rand(), hello.random)
+ if err != nil {
+ return nil, nil, errors.New("tls: short read from Rand: " + err.Error())
+ }
+
+ // A random session ID is used to detect when the server accepted a ticket
+ // and is resuming a session (see RFC 5077). In TLS 1.3, it's always set as
+ // a compatibility measure (see RFC 8446, Section 4.1.2).
+ //
+ // The session ID is not set for QUIC connections (see RFC 9001, Section 8.4).
+ if c.quic == nil {
+ hello.sessionId = make([]byte, 32)
+ if _, err := io.ReadFull(config.rand(), hello.sessionId); err != nil {
+ return nil, nil, errors.New("tls: short read from Rand: " + err.Error())
+ }
+ }
+
+ if hello.vers >= VersionTLS12 {
+ hello.supportedSignatureAlgorithms = supportedSignatureAlgorithms()
+ }
+ if testingOnlyForceClientHelloSignatureAlgorithms != nil {
+ hello.supportedSignatureAlgorithms = testingOnlyForceClientHelloSignatureAlgorithms
+ }
+
+ var key *ecdh.PrivateKey
+ if hello.supportedVersions[0] == VersionTLS13 {
+ // Reset the list of ciphers when the client only supports TLS 1.3.
+ if len(hello.supportedVersions) == 1 {
+ hello.cipherSuites = nil
+ }
+ if hasAESGCMHardwareSupport {
+ hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13...)
+ } else {
+ hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13NoAES...)
+ }
+
+ curveID := config.curvePreferences()[0]
+ if _, ok := curveForCurveID(curveID); !ok {
+ return nil, nil, errors.New("tls: CurvePreferences includes unsupported curve")
+ }
+ key, err = generateECDHEKey(config.rand(), curveID)
+ if err != nil {
+ return nil, nil, err
+ }
+ hello.keyShares = []keyShare{{group: curveID, data: key.PublicKey().Bytes()}}
+ }
+
+ if c.quic != nil {
+ p, err := c.quicGetTransportParameters()
+ if err != nil {
+ return nil, nil, err
+ }
+ if p == nil {
+ p = []byte{}
+ }
+ hello.quicTransportParameters = p
+ }
+
+ return hello, key, nil
+}
+
+func (c *Conn) clientHandshake(ctx context.Context) (err error) {
+ if c.config == nil {
+ c.config = defaultConfig()
+ }
+
+ // This may be a renegotiation handshake, in which case some fields
+ // need to be reset.
+ c.didResume = false
+
+ hello, ecdheKey, err := c.makeClientHello()
+ if err != nil {
+ return err
+ }
+ c.serverName = hello.serverName
+
+ session, earlySecret, binderKey, err := c.loadSession(hello)
+ if err != nil {
+ return err
+ }
+ if session != nil {
+ defer func() {
+ // If we got a handshake failure when resuming a session, throw away
+ // the session ticket. See RFC 5077, Section 3.2.
+ //
+ // RFC 8446 makes no mention of dropping tickets on failure, but it
+ // does require servers to abort on invalid binders, so we need to
+ // delete tickets to recover from a corrupted PSK.
+ if err != nil {
+ if cacheKey := c.clientSessionCacheKey(); cacheKey != "" {
+ c.config.ClientSessionCache.Put(cacheKey, nil)
+ }
+ }
+ }()
+ }
+
+ if _, err := c.writeHandshakeRecord(hello, nil); err != nil {
+ return err
+ }
+
+ if hello.earlyData {
+ suite := cipherSuiteTLS13ByID(session.cipherSuite)
+ transcript := suite.hash.New()
+ if err := transcriptMsg(hello, transcript); err != nil {
+ return err
+ }
+ earlyTrafficSecret := suite.deriveSecret(earlySecret, clientEarlyTrafficLabel, transcript)
+ c.quicSetWriteSecret(QUICEncryptionLevelEarly, suite.id, earlyTrafficSecret)
+ }
+
+ // serverHelloMsg is not included in the transcript
+ msg, err := c.readHandshake(nil)
+ if err != nil {
+ return err
+ }
+
+ serverHello, ok := msg.(*serverHelloMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(serverHello, msg)
+ }
+
+ if err := c.pickTLSVersion(serverHello); err != nil {
+ return err
+ }
+
+ // If we are negotiating a protocol version that's lower than what we
+ // support, check for the server downgrade canaries.
+ // See RFC 8446, Section 4.1.3.
+ maxVers := c.config.maxSupportedVersion(roleClient)
+ tls12Downgrade := string(serverHello.random[24:]) == downgradeCanaryTLS12
+ tls11Downgrade := string(serverHello.random[24:]) == downgradeCanaryTLS11
+ if maxVers == VersionTLS13 && c.vers <= VersionTLS12 && (tls12Downgrade || tls11Downgrade) ||
+ maxVers == VersionTLS12 && c.vers <= VersionTLS11 && tls11Downgrade {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: downgrade attempt detected, possibly due to a MitM attack or a broken middlebox")
+ }
+
+ if c.vers == VersionTLS13 {
+ hs := &clientHandshakeStateTLS13{
+ c: c,
+ ctx: ctx,
+ serverHello: serverHello,
+ hello: hello,
+ ecdheKey: ecdheKey,
+ session: session,
+ earlySecret: earlySecret,
+ binderKey: binderKey,
+ }
+
+ // In TLS 1.3, session tickets are delivered after the handshake.
+ return hs.handshake()
+ }
+
+ hs := &clientHandshakeState{
+ c: c,
+ ctx: ctx,
+ serverHello: serverHello,
+ hello: hello,
+ session: session,
+ }
+
+ if err := hs.handshake(); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (c *Conn) loadSession(hello *clientHelloMsg) (
+ session *SessionState, earlySecret, binderKey []byte, err error) {
+ if c.config.SessionTicketsDisabled || c.config.ClientSessionCache == nil {
+ return nil, nil, nil, nil
+ }
+
+ hello.ticketSupported = true
+
+ if hello.supportedVersions[0] == VersionTLS13 {
+ // Require DHE on resumption as it guarantees forward secrecy against
+ // compromise of the session ticket key. See RFC 8446, Section 4.2.9.
+ hello.pskModes = []uint8{pskModeDHE}
+ }
+
+ // Session resumption is not allowed if renegotiating because
+ // renegotiation is primarily used to allow a client to send a client
+ // certificate, which would be skipped if session resumption occurred.
+ if c.handshakes != 0 {
+ return nil, nil, nil, nil
+ }
+
+ // Try to resume a previously negotiated TLS session, if available.
+ cacheKey := c.clientSessionCacheKey()
+ if cacheKey == "" {
+ return nil, nil, nil, nil
+ }
+ cs, ok := c.config.ClientSessionCache.Get(cacheKey)
+ if !ok || cs == nil {
+ return nil, nil, nil, nil
+ }
+ session = cs.session
+
+ // Check that version used for the previous session is still valid.
+ versOk := false
+ for _, v := range hello.supportedVersions {
+ if v == session.version {
+ versOk = true
+ break
+ }
+ }
+ if !versOk {
+ return nil, nil, nil, nil
+ }
+
+ // Check that the cached server certificate is not expired, and that it's
+ // valid for the ServerName. This should be ensured by the cache key, but
+ // protect the application from a faulty ClientSessionCache implementation.
+ if c.config.time().After(session.peerCertificates[0].NotAfter) {
+ // Expired certificate, delete the entry.
+ c.config.ClientSessionCache.Put(cacheKey, nil)
+ return nil, nil, nil, nil
+ }
+ if !c.config.InsecureSkipVerify {
+ if len(session.verifiedChains) == 0 {
+ // The original connection had InsecureSkipVerify, while this doesn't.
+ return nil, nil, nil, nil
+ }
+ if err := session.peerCertificates[0].VerifyHostname(c.config.ServerName); err != nil {
+ return nil, nil, nil, nil
+ }
+ }
+
+ if session.version != VersionTLS13 {
+ // In TLS 1.2 the cipher suite must match the resumed session. Ensure we
+ // are still offering it.
+ if mutualCipherSuite(hello.cipherSuites, session.cipherSuite) == nil {
+ return nil, nil, nil, nil
+ }
+
+ hello.sessionTicket = cs.ticket
+ return
+ }
+
+ // Check that the session ticket is not expired.
+ if c.config.time().After(time.Unix(int64(session.useBy), 0)) {
+ c.config.ClientSessionCache.Put(cacheKey, nil)
+ return nil, nil, nil, nil
+ }
+
+ // In TLS 1.3 the KDF hash must match the resumed session. Ensure we
+ // offer at least one cipher suite with that hash.
+ cipherSuite := cipherSuiteTLS13ByID(session.cipherSuite)
+ if cipherSuite == nil {
+ return nil, nil, nil, nil
+ }
+ cipherSuiteOk := false
+ for _, offeredID := range hello.cipherSuites {
+ offeredSuite := cipherSuiteTLS13ByID(offeredID)
+ if offeredSuite != nil && offeredSuite.hash == cipherSuite.hash {
+ cipherSuiteOk = true
+ break
+ }
+ }
+ if !cipherSuiteOk {
+ return nil, nil, nil, nil
+ }
+
+ if c.quic != nil && session.EarlyData {
+ // For 0-RTT, the cipher suite has to match exactly, and we need to be
+ // offering the same ALPN.
+ if mutualCipherSuiteTLS13(hello.cipherSuites, session.cipherSuite) != nil {
+ for _, alpn := range hello.alpnProtocols {
+ if alpn == session.alpnProtocol {
+ hello.earlyData = true
+ break
+ }
+ }
+ }
+ }
+
+ // Set the pre_shared_key extension. See RFC 8446, Section 4.2.11.1.
+ ticketAge := c.config.time().Sub(time.Unix(int64(session.createdAt), 0))
+ identity := pskIdentity{
+ label: cs.ticket,
+ obfuscatedTicketAge: uint32(ticketAge/time.Millisecond) + session.ageAdd,
+ }
+ hello.pskIdentities = []pskIdentity{identity}
+ hello.pskBinders = [][]byte{make([]byte, cipherSuite.hash.Size())}
+
+ // Compute the PSK binders. See RFC 8446, Section 4.2.11.2.
+ earlySecret = cipherSuite.extract(session.secret, nil)
+ binderKey = cipherSuite.deriveSecret(earlySecret, resumptionBinderLabel, nil)
+ transcript := cipherSuite.hash.New()
+ helloBytes, err := hello.marshalWithoutBinders()
+ if err != nil {
+ return nil, nil, nil, err
+ }
+ transcript.Write(helloBytes)
+ pskBinders := [][]byte{cipherSuite.finishedHash(binderKey, transcript)}
+ if err := hello.updateBinders(pskBinders); err != nil {
+ return nil, nil, nil, err
+ }
+
+ return
+}
+
+func (c *Conn) pickTLSVersion(serverHello *serverHelloMsg) error {
+ peerVersion := serverHello.vers
+ if serverHello.supportedVersion != 0 {
+ peerVersion = serverHello.supportedVersion
+ }
+
+ vers, ok := c.config.mutualVersion(roleClient, []uint16{peerVersion})
+ if !ok {
+ c.sendAlert(alertProtocolVersion)
+ return fmt.Errorf("tls: server selected unsupported protocol version %x", peerVersion)
+ }
+
+ c.vers = vers
+ c.haveVers = true
+ c.in.version = vers
+ c.out.version = vers
+
+ return nil
+}
+
+// Does the handshake, either a full one or resumes old session. Requires hs.c,
+// hs.hello, hs.serverHello, and, optionally, hs.session to be set.
+func (hs *clientHandshakeState) handshake() error {
+ c := hs.c
+
+ isResume, err := hs.processServerHello()
+ if err != nil {
+ return err
+ }
+
+ hs.finishedHash = newFinishedHash(c.vers, hs.suite)
+
+ // No signatures of the handshake are needed in a resumption.
+ // Otherwise, in a full handshake, if we don't have any certificates
+ // configured then we will never send a CertificateVerify message and
+ // thus no signatures are needed in that case either.
+ if isResume || (len(c.config.Certificates) == 0 && c.config.GetClientCertificate == nil) {
+ hs.finishedHash.discardHandshakeBuffer()
+ }
+
+ if err := transcriptMsg(hs.hello, &hs.finishedHash); err != nil {
+ return err
+ }
+ if err := transcriptMsg(hs.serverHello, &hs.finishedHash); err != nil {
+ return err
+ }
+
+ c.buffering = true
+ c.didResume = isResume
+ if isResume {
+ if err := hs.establishKeys(); err != nil {
+ return err
+ }
+ if err := hs.readSessionTicket(); err != nil {
+ return err
+ }
+ if err := hs.readFinished(c.serverFinished[:]); err != nil {
+ return err
+ }
+ c.clientFinishedIsFirst = false
+ // Make sure the connection is still being verified whether or not this
+ // is a resumption. Resumptions currently don't reverify certificates so
+ // they don't call verifyServerCertificate. See Issue 31641.
+ if c.config.VerifyConnection != nil {
+ if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
+ c.sendAlert(alertBadCertificate)
+ return err
+ }
+ }
+ if err := hs.sendFinished(c.clientFinished[:]); err != nil {
+ return err
+ }
+ if _, err := c.flush(); err != nil {
+ return err
+ }
+ } else {
+ if err := hs.doFullHandshake(); err != nil {
+ return err
+ }
+ if err := hs.establishKeys(); err != nil {
+ return err
+ }
+ if err := hs.sendFinished(c.clientFinished[:]); err != nil {
+ return err
+ }
+ if _, err := c.flush(); err != nil {
+ return err
+ }
+ c.clientFinishedIsFirst = true
+ if err := hs.readSessionTicket(); err != nil {
+ return err
+ }
+ if err := hs.readFinished(c.serverFinished[:]); err != nil {
+ return err
+ }
+ }
+ if err := hs.saveSessionTicket(); err != nil {
+ return err
+ }
+
+ c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random)
+ c.isHandshakeComplete.Store(true)
+
+ return nil
+}
+
+func (hs *clientHandshakeState) pickCipherSuite() error {
+ if hs.suite = mutualCipherSuite(hs.hello.cipherSuites, hs.serverHello.cipherSuite); hs.suite == nil {
+ hs.c.sendAlert(alertHandshakeFailure)
+ return errors.New("tls: server chose an unconfigured cipher suite")
+ }
+
+ hs.c.cipherSuite = hs.suite.id
+ return nil
+}
+
+func (hs *clientHandshakeState) doFullHandshake() error {
+ c := hs.c
+
+ msg, err := c.readHandshake(&hs.finishedHash)
+ if err != nil {
+ return err
+ }
+ certMsg, ok := msg.(*certificateMsg)
+ if !ok || len(certMsg.certificates) == 0 {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(certMsg, msg)
+ }
+
+ msg, err = c.readHandshake(&hs.finishedHash)
+ if err != nil {
+ return err
+ }
+
+ cs, ok := msg.(*certificateStatusMsg)
+ if ok {
+ // RFC4366 on Certificate Status Request:
+ // The server MAY return a "certificate_status" message.
+
+ if !hs.serverHello.ocspStapling {
+ // If a server returns a "CertificateStatus" message, then the
+ // server MUST have included an extension of type "status_request"
+ // with empty "extension_data" in the extended server hello.
+
+ c.sendAlert(alertUnexpectedMessage)
+ return errors.New("tls: received unexpected CertificateStatus message")
+ }
+
+ c.ocspResponse = cs.response
+
+ msg, err = c.readHandshake(&hs.finishedHash)
+ if err != nil {
+ return err
+ }
+ }
+
+ if c.handshakes == 0 {
+ // If this is the first handshake on a connection, process and
+ // (optionally) verify the server's certificates.
+ if err := c.verifyServerCertificate(certMsg.certificates); err != nil {
+ return err
+ }
+ } else {
+ // This is a renegotiation handshake. We require that the
+ // server's identity (i.e. leaf certificate) is unchanged and
+ // thus any previous trust decision is still valid.
+ //
+ // See https://mitls.org/pages/attacks/3SHAKE for the
+ // motivation behind this requirement.
+ if !bytes.Equal(c.peerCertificates[0].Raw, certMsg.certificates[0]) {
+ c.sendAlert(alertBadCertificate)
+ return errors.New("tls: server's identity changed during renegotiation")
+ }
+ }
+
+ keyAgreement := hs.suite.ka(c.vers)
+
+ skx, ok := msg.(*serverKeyExchangeMsg)
+ if ok {
+ err = keyAgreement.processServerKeyExchange(c.config, hs.hello, hs.serverHello, c.peerCertificates[0], skx)
+ if err != nil {
+ c.sendAlert(alertUnexpectedMessage)
+ return err
+ }
+
+ msg, err = c.readHandshake(&hs.finishedHash)
+ if err != nil {
+ return err
+ }
+ }
+
+ var chainToSend *Certificate
+ var certRequested bool
+ certReq, ok := msg.(*certificateRequestMsg)
+ if ok {
+ certRequested = true
+
+ cri := certificateRequestInfoFromMsg(hs.ctx, c.vers, certReq)
+ if chainToSend, err = c.getClientCertificate(cri); err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+
+ msg, err = c.readHandshake(&hs.finishedHash)
+ if err != nil {
+ return err
+ }
+ }
+
+ shd, ok := msg.(*serverHelloDoneMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(shd, msg)
+ }
+
+ // If the server requested a certificate then we have to send a
+ // Certificate message, even if it's empty because we don't have a
+ // certificate to send.
+ if certRequested {
+ certMsg = new(certificateMsg)
+ certMsg.certificates = chainToSend.Certificate
+ if _, err := hs.c.writeHandshakeRecord(certMsg, &hs.finishedHash); err != nil {
+ return err
+ }
+ }
+
+ preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hs.hello, c.peerCertificates[0])
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+ if ckx != nil {
+ if _, err := hs.c.writeHandshakeRecord(ckx, &hs.finishedHash); err != nil {
+ return err
+ }
+ }
+
+ if hs.serverHello.extendedMasterSecret {
+ c.extMasterSecret = true
+ hs.masterSecret = extMasterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret,
+ hs.finishedHash.Sum())
+ } else {
+ hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret,
+ hs.hello.random, hs.serverHello.random)
+ }
+ if err := c.config.writeKeyLog(keyLogLabelTLS12, hs.hello.random, hs.masterSecret); err != nil {
+ c.sendAlert(alertInternalError)
+ return errors.New("tls: failed to write to key log: " + err.Error())
+ }
+
+ if chainToSend != nil && len(chainToSend.Certificate) > 0 {
+ certVerify := &certificateVerifyMsg{}
+
+ key, ok := chainToSend.PrivateKey.(crypto.Signer)
+ if !ok {
+ c.sendAlert(alertInternalError)
+ return fmt.Errorf("tls: client certificate private key of type %T does not implement crypto.Signer", chainToSend.PrivateKey)
+ }
+
+ var sigType uint8
+ var sigHash crypto.Hash
+ if c.vers >= VersionTLS12 {
+ signatureAlgorithm, err := selectSignatureScheme(c.vers, chainToSend, certReq.supportedSignatureAlgorithms)
+ if err != nil {
+ c.sendAlert(alertIllegalParameter)
+ return err
+ }
+ sigType, sigHash, err = typeAndHashFromSignatureScheme(signatureAlgorithm)
+ if err != nil {
+ return c.sendAlert(alertInternalError)
+ }
+ certVerify.hasSignatureAlgorithm = true
+ certVerify.signatureAlgorithm = signatureAlgorithm
+ } else {
+ sigType, sigHash, err = legacyTypeAndHashFromPublicKey(key.Public())
+ if err != nil {
+ c.sendAlert(alertIllegalParameter)
+ return err
+ }
+ }
+
+ signed := hs.finishedHash.hashForClientCertificate(sigType, sigHash)
+ signOpts := crypto.SignerOpts(sigHash)
+ if sigType == signatureRSAPSS {
+ signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash}
+ }
+ certVerify.signature, err = key.Sign(c.config.rand(), signed, signOpts)
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+
+ if _, err := hs.c.writeHandshakeRecord(certVerify, &hs.finishedHash); err != nil {
+ return err
+ }
+ }
+
+ hs.finishedHash.discardHandshakeBuffer()
+
+ return nil
+}
+
+func (hs *clientHandshakeState) establishKeys() error {
+ c := hs.c
+
+ clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
+ keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
+ var clientCipher, serverCipher any
+ var clientHash, serverHash hash.Hash
+ if hs.suite.cipher != nil {
+ clientCipher = hs.suite.cipher(clientKey, clientIV, false /* not for reading */)
+ clientHash = hs.suite.mac(clientMAC)
+ serverCipher = hs.suite.cipher(serverKey, serverIV, true /* for reading */)
+ serverHash = hs.suite.mac(serverMAC)
+ } else {
+ clientCipher = hs.suite.aead(clientKey, clientIV)
+ serverCipher = hs.suite.aead(serverKey, serverIV)
+ }
+
+ c.in.prepareCipherSpec(c.vers, serverCipher, serverHash)
+ c.out.prepareCipherSpec(c.vers, clientCipher, clientHash)
+ return nil
+}
+
+func (hs *clientHandshakeState) serverResumedSession() bool {
+ // If the server responded with the same sessionId then it means the
+ // sessionTicket is being used to resume a TLS session.
+ return hs.session != nil && hs.hello.sessionId != nil &&
+ bytes.Equal(hs.serverHello.sessionId, hs.hello.sessionId)
+}
+
+func (hs *clientHandshakeState) processServerHello() (bool, error) {
+ c := hs.c
+
+ if err := hs.pickCipherSuite(); err != nil {
+ return false, err
+ }
+
+ if hs.serverHello.compressionMethod != compressionNone {
+ c.sendAlert(alertUnexpectedMessage)
+ return false, errors.New("tls: server selected unsupported compression format")
+ }
+
+ if c.handshakes == 0 && hs.serverHello.secureRenegotiationSupported {
+ c.secureRenegotiation = true
+ if len(hs.serverHello.secureRenegotiation) != 0 {
+ c.sendAlert(alertHandshakeFailure)
+ return false, errors.New("tls: initial handshake had non-empty renegotiation extension")
+ }
+ }
+
+ if c.handshakes > 0 && c.secureRenegotiation {
+ var expectedSecureRenegotiation [24]byte
+ copy(expectedSecureRenegotiation[:], c.clientFinished[:])
+ copy(expectedSecureRenegotiation[12:], c.serverFinished[:])
+ if !bytes.Equal(hs.serverHello.secureRenegotiation, expectedSecureRenegotiation[:]) {
+ c.sendAlert(alertHandshakeFailure)
+ return false, errors.New("tls: incorrect renegotiation extension contents")
+ }
+ }
+
+ if err := checkALPN(hs.hello.alpnProtocols, hs.serverHello.alpnProtocol, false); err != nil {
+ c.sendAlert(alertUnsupportedExtension)
+ return false, err
+ }
+ c.clientProtocol = hs.serverHello.alpnProtocol
+
+ c.scts = hs.serverHello.scts
+
+ if !hs.serverResumedSession() {
+ return false, nil
+ }
+
+ if hs.session.version != c.vers {
+ c.sendAlert(alertHandshakeFailure)
+ return false, errors.New("tls: server resumed a session with a different version")
+ }
+
+ if hs.session.cipherSuite != hs.suite.id {
+ c.sendAlert(alertHandshakeFailure)
+ return false, errors.New("tls: server resumed a session with a different cipher suite")
+ }
+
+ // RFC 7627, Section 5.3
+ if hs.session.extMasterSecret != hs.serverHello.extendedMasterSecret {
+ c.sendAlert(alertHandshakeFailure)
+ return false, errors.New("tls: server resumed a session with a different EMS extension")
+ }
+
+ // Restore master secret and certificates from previous state
+ hs.masterSecret = hs.session.secret
+ c.extMasterSecret = hs.session.extMasterSecret
+ c.peerCertificates = hs.session.peerCertificates
+ c.activeCertHandles = hs.c.activeCertHandles
+ c.verifiedChains = hs.session.verifiedChains
+ c.ocspResponse = hs.session.ocspResponse
+ // Let the ServerHello SCTs override the session SCTs from the original
+ // connection, if any are provided
+ if len(c.scts) == 0 && len(hs.session.scts) != 0 {
+ c.scts = hs.session.scts
+ }
+
+ return true, nil
+}
+
+// checkALPN ensure that the server's choice of ALPN protocol is compatible with
+// the protocols that we advertised in the Client Hello.
+func checkALPN(clientProtos []string, serverProto string, quic bool) error {
+ if serverProto == "" {
+ if quic && len(clientProtos) > 0 {
+ // RFC 9001, Section 8.1
+ return errors.New("tls: server did not select an ALPN protocol")
+ }
+ return nil
+ }
+ if len(clientProtos) == 0 {
+ return errors.New("tls: server advertised unrequested ALPN extension")
+ }
+ for _, proto := range clientProtos {
+ if proto == serverProto {
+ return nil
+ }
+ }
+ return errors.New("tls: server selected unadvertised ALPN protocol")
+}
+
+func (hs *clientHandshakeState) readFinished(out []byte) error {
+ c := hs.c
+
+ if err := c.readChangeCipherSpec(); err != nil {
+ return err
+ }
+
+ // finishedMsg is included in the transcript, but not until after we
+ // check the client version, since the state before this message was
+ // sent is used during verification.
+ msg, err := c.readHandshake(nil)
+ if err != nil {
+ return err
+ }
+ serverFinished, ok := msg.(*finishedMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(serverFinished, msg)
+ }
+
+ verify := hs.finishedHash.serverSum(hs.masterSecret)
+ if len(verify) != len(serverFinished.verifyData) ||
+ subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 {
+ c.sendAlert(alertHandshakeFailure)
+ return errors.New("tls: server's Finished message was incorrect")
+ }
+
+ if err := transcriptMsg(serverFinished, &hs.finishedHash); err != nil {
+ return err
+ }
+
+ copy(out, verify)
+ return nil
+}
+
+func (hs *clientHandshakeState) readSessionTicket() error {
+ if !hs.serverHello.ticketSupported {
+ return nil
+ }
+ c := hs.c
+
+ if !hs.hello.ticketSupported {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: server sent unrequested session ticket")
+ }
+
+ msg, err := c.readHandshake(&hs.finishedHash)
+ if err != nil {
+ return err
+ }
+ sessionTicketMsg, ok := msg.(*newSessionTicketMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(sessionTicketMsg, msg)
+ }
+
+ hs.ticket = sessionTicketMsg.ticket
+ return nil
+}
+
+func (hs *clientHandshakeState) saveSessionTicket() error {
+ if hs.ticket == nil {
+ return nil
+ }
+ c := hs.c
+
+ cacheKey := c.clientSessionCacheKey()
+ if cacheKey == "" {
+ return nil
+ }
+
+ session, err := c.sessionState()
+ if err != nil {
+ return err
+ }
+ session.secret = hs.masterSecret
+
+ cs := &ClientSessionState{ticket: hs.ticket, session: session}
+ c.config.ClientSessionCache.Put(cacheKey, cs)
+ return nil
+}
+
+func (hs *clientHandshakeState) sendFinished(out []byte) error {
+ c := hs.c
+
+ if err := c.writeChangeCipherRecord(); err != nil {
+ return err
+ }
+
+ finished := new(finishedMsg)
+ finished.verifyData = hs.finishedHash.clientSum(hs.masterSecret)
+ if _, err := hs.c.writeHandshakeRecord(finished, &hs.finishedHash); err != nil {
+ return err
+ }
+ copy(out, finished.verifyData)
+ return nil
+}
+
+// defaultMaxRSAKeySize is the maximum RSA key size in bits that we are willing
+// to verify the signatures of during a TLS handshake.
+const defaultMaxRSAKeySize = 8192
+
+var tlsmaxrsasize = godebug.New("tlsmaxrsasize")
+
+func checkKeySize(n int) (max int, ok bool) {
+ if v := tlsmaxrsasize.Value(); v != "" {
+ if max, err := strconv.Atoi(v); err == nil {
+ if (n <= max) != (n <= defaultMaxRSAKeySize) {
+ tlsmaxrsasize.IncNonDefault()
+ }
+ return max, n <= max
+ }
+ }
+ return defaultMaxRSAKeySize, n <= defaultMaxRSAKeySize
+}
+
+// verifyServerCertificate parses and verifies the provided chain, setting
+// c.verifiedChains and c.peerCertificates or sending the appropriate alert.
+func (c *Conn) verifyServerCertificate(certificates [][]byte) error {
+ activeHandles := make([]*activeCert, len(certificates))
+ certs := make([]*x509.Certificate, len(certificates))
+ for i, asn1Data := range certificates {
+ cert, err := globalCertCache.newCert(asn1Data)
+ if err != nil {
+ c.sendAlert(alertBadCertificate)
+ return errors.New("tls: failed to parse certificate from server: " + err.Error())
+ }
+ if cert.cert.PublicKeyAlgorithm == x509.RSA {
+ n := cert.cert.PublicKey.(*rsa.PublicKey).N.BitLen()
+ if max, ok := checkKeySize(n); !ok {
+ c.sendAlert(alertBadCertificate)
+ return fmt.Errorf("tls: server sent certificate containing RSA key larger than %d bits", max)
+ }
+ }
+ activeHandles[i] = cert
+ certs[i] = cert.cert
+ }
+
+ if !c.config.InsecureSkipVerify {
+ opts := x509.VerifyOptions{
+ Roots: c.config.RootCAs,
+ CurrentTime: c.config.time(),
+ DNSName: c.config.ServerName,
+ Intermediates: x509.NewCertPool(),
+ }
+
+ for _, cert := range certs[1:] {
+ opts.Intermediates.AddCert(cert)
+ }
+ var err error
+ c.verifiedChains, err = certs[0].Verify(opts)
+ if err != nil {
+ c.sendAlert(alertBadCertificate)
+ return &CertificateVerificationError{UnverifiedCertificates: certs, Err: err}
+ }
+ }
+
+ switch certs[0].PublicKey.(type) {
+ case *rsa.PublicKey, *ecdsa.PublicKey, ed25519.PublicKey:
+ break
+ default:
+ c.sendAlert(alertUnsupportedCertificate)
+ return fmt.Errorf("tls: server's certificate contains an unsupported type of public key: %T", certs[0].PublicKey)
+ }
+
+ c.activeCertHandles = activeHandles
+ c.peerCertificates = certs
+
+ if c.config.VerifyPeerCertificate != nil {
+ if err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil {
+ c.sendAlert(alertBadCertificate)
+ return err
+ }
+ }
+
+ if c.config.VerifyConnection != nil {
+ if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
+ c.sendAlert(alertBadCertificate)
+ return err
+ }
+ }
+
+ return nil
+}
+
+// certificateRequestInfoFromMsg generates a CertificateRequestInfo from a TLS
+// <= 1.2 CertificateRequest, making an effort to fill in missing information.
+func certificateRequestInfoFromMsg(ctx context.Context, vers uint16, certReq *certificateRequestMsg) *CertificateRequestInfo {
+ cri := &CertificateRequestInfo{
+ AcceptableCAs: certReq.certificateAuthorities,
+ Version: vers,
+ ctx: ctx,
+ }
+
+ var rsaAvail, ecAvail bool
+ for _, certType := range certReq.certificateTypes {
+ switch certType {
+ case certTypeRSASign:
+ rsaAvail = true
+ case certTypeECDSASign:
+ ecAvail = true
+ }
+ }
+
+ if !certReq.hasSignatureAlgorithm {
+ // Prior to TLS 1.2, signature schemes did not exist. In this case we
+ // make up a list based on the acceptable certificate types, to help
+ // GetClientCertificate and SupportsCertificate select the right certificate.
+ // The hash part of the SignatureScheme is a lie here, because
+ // TLS 1.0 and 1.1 always use MD5+SHA1 for RSA and SHA1 for ECDSA.
+ switch {
+ case rsaAvail && ecAvail:
+ cri.SignatureSchemes = []SignatureScheme{
+ ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512,
+ PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512, PKCS1WithSHA1,
+ }
+ case rsaAvail:
+ cri.SignatureSchemes = []SignatureScheme{
+ PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512, PKCS1WithSHA1,
+ }
+ case ecAvail:
+ cri.SignatureSchemes = []SignatureScheme{
+ ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512,
+ }
+ }
+ return cri
+ }
+
+ // Filter the signature schemes based on the certificate types.
+ // See RFC 5246, Section 7.4.4 (where it calls this "somewhat complicated").
+ cri.SignatureSchemes = make([]SignatureScheme, 0, len(certReq.supportedSignatureAlgorithms))
+ for _, sigScheme := range certReq.supportedSignatureAlgorithms {
+ sigType, _, err := typeAndHashFromSignatureScheme(sigScheme)
+ if err != nil {
+ continue
+ }
+ switch sigType {
+ case signatureECDSA, signatureEd25519:
+ if ecAvail {
+ cri.SignatureSchemes = append(cri.SignatureSchemes, sigScheme)
+ }
+ case signatureRSAPSS, signaturePKCS1v15:
+ if rsaAvail {
+ cri.SignatureSchemes = append(cri.SignatureSchemes, sigScheme)
+ }
+ }
+ }
+
+ return cri
+}
+
+func (c *Conn) getClientCertificate(cri *CertificateRequestInfo) (*Certificate, error) {
+ if c.config.GetClientCertificate != nil {
+ return c.config.GetClientCertificate(cri)
+ }
+
+ for _, chain := range c.config.Certificates {
+ if err := cri.SupportsCertificate(&chain); err != nil {
+ continue
+ }
+ return &chain, nil
+ }
+
+ // No acceptable certificate found. Don't send a certificate.
+ return new(Certificate), nil
+}
+
+// clientSessionCacheKey returns a key used to cache sessionTickets that could
+// be used to resume previously negotiated TLS sessions with a server.
+func (c *Conn) clientSessionCacheKey() string {
+ if len(c.config.ServerName) > 0 {
+ return c.config.ServerName
+ }
+ if c.conn != nil {
+ return c.conn.RemoteAddr().String()
+ }
+ return ""
+}
+
+// hostnameInSNI converts name into an appropriate hostname for SNI.
+// Literal IP addresses and absolute FQDNs are not permitted as SNI values.
+// See RFC 6066, Section 3.
+func hostnameInSNI(name string) string {
+ host := name
+ if len(host) > 0 && host[0] == '[' && host[len(host)-1] == ']' {
+ host = host[1 : len(host)-1]
+ }
+ if i := strings.LastIndex(host, "%"); i > 0 {
+ host = host[:i]
+ }
+ if net.ParseIP(host) != nil {
+ return ""
+ }
+ for len(name) > 0 && name[len(name)-1] == '.' {
+ name = name[:len(name)-1]
+ }
+ return name
+}
diff --git a/src/crypto/tls/handshake_client_test.go b/src/crypto/tls/handshake_client_test.go
new file mode 100644
index 0000000..a2052ce
--- /dev/null
+++ b/src/crypto/tls/handshake_client_test.go
@@ -0,0 +1,2826 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+ "bytes"
+ "context"
+ "crypto/rsa"
+ "crypto/x509"
+ "encoding/base64"
+ "encoding/binary"
+ "encoding/pem"
+ "errors"
+ "fmt"
+ "io"
+ "math/big"
+ "net"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "reflect"
+ "runtime"
+ "strconv"
+ "strings"
+ "testing"
+ "time"
+)
+
+// Note: see comment in handshake_test.go for details of how the reference
+// tests work.
+
+// opensslInputEvent enumerates possible inputs that can be sent to an `openssl
+// s_client` process.
+type opensslInputEvent int
+
+const (
+ // opensslRenegotiate causes OpenSSL to request a renegotiation of the
+ // connection.
+ opensslRenegotiate opensslInputEvent = iota
+
+ // opensslSendBanner causes OpenSSL to send the contents of
+ // opensslSentinel on the connection.
+ opensslSendSentinel
+
+ // opensslKeyUpdate causes OpenSSL to send a key update message to the
+ // client and request one back.
+ opensslKeyUpdate
+)
+
+const opensslSentinel = "SENTINEL\n"
+
+type opensslInput chan opensslInputEvent
+
+func (i opensslInput) Read(buf []byte) (n int, err error) {
+ for event := range i {
+ switch event {
+ case opensslRenegotiate:
+ return copy(buf, []byte("R\n")), nil
+ case opensslKeyUpdate:
+ return copy(buf, []byte("K\n")), nil
+ case opensslSendSentinel:
+ return copy(buf, []byte(opensslSentinel)), nil
+ default:
+ panic("unknown event")
+ }
+ }
+
+ return 0, io.EOF
+}
+
+// opensslOutputSink is an io.Writer that receives the stdout and stderr from an
+// `openssl` process and sends a value to handshakeComplete or readKeyUpdate
+// when certain messages are seen.
+type opensslOutputSink struct {
+ handshakeComplete chan struct{}
+ readKeyUpdate chan struct{}
+ all []byte
+ line []byte
+}
+
+func newOpensslOutputSink() *opensslOutputSink {
+ return &opensslOutputSink{make(chan struct{}), make(chan struct{}), nil, nil}
+}
+
+// opensslEndOfHandshake is a message that the “openssl s_server” tool will
+// print when a handshake completes if run with “-state”.
+const opensslEndOfHandshake = "SSL_accept:SSLv3/TLS write finished"
+
+// opensslReadKeyUpdate is a message that the “openssl s_server” tool will
+// print when a KeyUpdate message is received if run with “-state”.
+const opensslReadKeyUpdate = "SSL_accept:TLSv1.3 read client key update"
+
+func (o *opensslOutputSink) Write(data []byte) (n int, err error) {
+ o.line = append(o.line, data...)
+ o.all = append(o.all, data...)
+
+ for {
+ line, next, ok := bytes.Cut(o.line, []byte("\n"))
+ if !ok {
+ break
+ }
+
+ if bytes.Equal([]byte(opensslEndOfHandshake), line) {
+ o.handshakeComplete <- struct{}{}
+ }
+ if bytes.Equal([]byte(opensslReadKeyUpdate), line) {
+ o.readKeyUpdate <- struct{}{}
+ }
+ o.line = next
+ }
+
+ return len(data), nil
+}
+
+func (o *opensslOutputSink) String() string {
+ return string(o.all)
+}
+
+// clientTest represents a test of the TLS client handshake against a reference
+// implementation.
+type clientTest struct {
+ // name is a freeform string identifying the test and the file in which
+ // the expected results will be stored.
+ name string
+ // args, if not empty, contains a series of arguments for the
+ // command to run for the reference server.
+ args []string
+ // config, if not nil, contains a custom Config to use for this test.
+ config *Config
+ // cert, if not empty, contains a DER-encoded certificate for the
+ // reference server.
+ cert []byte
+ // key, if not nil, contains either a *rsa.PrivateKey, ed25519.PrivateKey or
+ // *ecdsa.PrivateKey which is the private key for the reference server.
+ key any
+ // extensions, if not nil, contains a list of extension data to be returned
+ // from the ServerHello. The data should be in standard TLS format with
+ // a 2-byte uint16 type, 2-byte data length, followed by the extension data.
+ extensions [][]byte
+ // validate, if not nil, is a function that will be called with the
+ // ConnectionState of the resulting connection. It returns a non-nil
+ // error if the ConnectionState is unacceptable.
+ validate func(ConnectionState) error
+ // numRenegotiations is the number of times that the connection will be
+ // renegotiated.
+ numRenegotiations int
+ // renegotiationExpectedToFail, if not zero, is the number of the
+ // renegotiation attempt that is expected to fail.
+ renegotiationExpectedToFail int
+ // checkRenegotiationError, if not nil, is called with any error
+ // arising from renegotiation. It can map expected errors to nil to
+ // ignore them.
+ checkRenegotiationError func(renegotiationNum int, err error) error
+ // sendKeyUpdate will cause the server to send a KeyUpdate message.
+ sendKeyUpdate bool
+}
+
+var serverCommand = []string{"openssl", "s_server", "-no_ticket", "-num_tickets", "0"}
+
+// connFromCommand starts the reference server process, connects to it and
+// returns a recordingConn for the connection. The stdin return value is an
+// opensslInput for the stdin of the child process. It must be closed before
+// Waiting for child.
+func (test *clientTest) connFromCommand() (conn *recordingConn, child *exec.Cmd, stdin opensslInput, stdout *opensslOutputSink, err error) {
+ cert := testRSACertificate
+ if len(test.cert) > 0 {
+ cert = test.cert
+ }
+ certPath := tempFile(string(cert))
+ defer os.Remove(certPath)
+
+ var key any = testRSAPrivateKey
+ if test.key != nil {
+ key = test.key
+ }
+ derBytes, err := x509.MarshalPKCS8PrivateKey(key)
+ if err != nil {
+ panic(err)
+ }
+
+ var pemOut bytes.Buffer
+ pem.Encode(&pemOut, &pem.Block{Type: "PRIVATE KEY", Bytes: derBytes})
+
+ keyPath := tempFile(pemOut.String())
+ defer os.Remove(keyPath)
+
+ var command []string
+ command = append(command, serverCommand...)
+ command = append(command, test.args...)
+ command = append(command, "-cert", certPath, "-certform", "DER", "-key", keyPath)
+ // serverPort contains the port that OpenSSL will listen on. OpenSSL
+ // can't take "0" as an argument here so we have to pick a number and
+ // hope that it's not in use on the machine. Since this only occurs
+ // when -update is given and thus when there's a human watching the
+ // test, this isn't too bad.
+ const serverPort = 24323
+ command = append(command, "-accept", strconv.Itoa(serverPort))
+
+ if len(test.extensions) > 0 {
+ var serverInfo bytes.Buffer
+ for _, ext := range test.extensions {
+ pem.Encode(&serverInfo, &pem.Block{
+ Type: fmt.Sprintf("SERVERINFO FOR EXTENSION %d", binary.BigEndian.Uint16(ext)),
+ Bytes: ext,
+ })
+ }
+ serverInfoPath := tempFile(serverInfo.String())
+ defer os.Remove(serverInfoPath)
+ command = append(command, "-serverinfo", serverInfoPath)
+ }
+
+ if test.numRenegotiations > 0 || test.sendKeyUpdate {
+ found := false
+ for _, flag := range command[1:] {
+ if flag == "-state" {
+ found = true
+ break
+ }
+ }
+
+ if !found {
+ panic("-state flag missing to OpenSSL, you need this if testing renegotiation or KeyUpdate")
+ }
+ }
+
+ cmd := exec.Command(command[0], command[1:]...)
+ stdin = opensslInput(make(chan opensslInputEvent))
+ cmd.Stdin = stdin
+ out := newOpensslOutputSink()
+ cmd.Stdout = out
+ cmd.Stderr = out
+ if err := cmd.Start(); err != nil {
+ return nil, nil, nil, nil, err
+ }
+
+ // OpenSSL does print an "ACCEPT" banner, but it does so *before*
+ // opening the listening socket, so we can't use that to wait until it
+ // has started listening. Thus we are forced to poll until we get a
+ // connection.
+ var tcpConn net.Conn
+ for i := uint(0); i < 5; i++ {
+ tcpConn, err = net.DialTCP("tcp", nil, &net.TCPAddr{
+ IP: net.IPv4(127, 0, 0, 1),
+ Port: serverPort,
+ })
+ if err == nil {
+ break
+ }
+ time.Sleep((1 << i) * 5 * time.Millisecond)
+ }
+ if err != nil {
+ close(stdin)
+ cmd.Process.Kill()
+ err = fmt.Errorf("error connecting to the OpenSSL server: %v (%v)\n\n%s", err, cmd.Wait(), out)
+ return nil, nil, nil, nil, err
+ }
+
+ record := &recordingConn{
+ Conn: tcpConn,
+ }
+
+ return record, cmd, stdin, out, nil
+}
+
+func (test *clientTest) dataPath() string {
+ return filepath.Join("testdata", "Client-"+test.name)
+}
+
+func (test *clientTest) loadData() (flows [][]byte, err error) {
+ in, err := os.Open(test.dataPath())
+ if err != nil {
+ return nil, err
+ }
+ defer in.Close()
+ return parseTestData(in)
+}
+
+func (test *clientTest) run(t *testing.T, write bool) {
+ var clientConn, serverConn net.Conn
+ var recordingConn *recordingConn
+ var childProcess *exec.Cmd
+ var stdin opensslInput
+ var stdout *opensslOutputSink
+
+ if write {
+ var err error
+ recordingConn, childProcess, stdin, stdout, err = test.connFromCommand()
+ if err != nil {
+ t.Fatalf("Failed to start subcommand: %s", err)
+ }
+ clientConn = recordingConn
+ defer func() {
+ if t.Failed() {
+ t.Logf("OpenSSL output:\n\n%s", stdout.all)
+ }
+ }()
+ } else {
+ clientConn, serverConn = localPipe(t)
+ }
+
+ doneChan := make(chan bool)
+ defer func() {
+ clientConn.Close()
+ <-doneChan
+ }()
+ go func() {
+ defer close(doneChan)
+
+ config := test.config
+ if config == nil {
+ config = testConfig
+ }
+ client := Client(clientConn, config)
+ defer client.Close()
+
+ if _, err := client.Write([]byte("hello\n")); err != nil {
+ t.Errorf("Client.Write failed: %s", err)
+ return
+ }
+
+ for i := 1; i <= test.numRenegotiations; i++ {
+ // The initial handshake will generate a
+ // handshakeComplete signal which needs to be quashed.
+ if i == 1 && write {
+ <-stdout.handshakeComplete
+ }
+
+ // OpenSSL will try to interleave application data and
+ // a renegotiation if we send both concurrently.
+ // Therefore: ask OpensSSL to start a renegotiation, run
+ // a goroutine to call client.Read and thus process the
+ // renegotiation request, watch for OpenSSL's stdout to
+ // indicate that the handshake is complete and,
+ // finally, have OpenSSL write something to cause
+ // client.Read to complete.
+ if write {
+ stdin <- opensslRenegotiate
+ }
+
+ signalChan := make(chan struct{})
+
+ go func() {
+ defer close(signalChan)
+
+ buf := make([]byte, 256)
+ n, err := client.Read(buf)
+
+ if test.checkRenegotiationError != nil {
+ newErr := test.checkRenegotiationError(i, err)
+ if err != nil && newErr == nil {
+ return
+ }
+ err = newErr
+ }
+
+ if err != nil {
+ t.Errorf("Client.Read failed after renegotiation #%d: %s", i, err)
+ return
+ }
+
+ buf = buf[:n]
+ if !bytes.Equal([]byte(opensslSentinel), buf) {
+ t.Errorf("Client.Read returned %q, but wanted %q", string(buf), opensslSentinel)
+ }
+
+ if expected := i + 1; client.handshakes != expected {
+ t.Errorf("client should have recorded %d handshakes, but believes that %d have occurred", expected, client.handshakes)
+ }
+ }()
+
+ if write && test.renegotiationExpectedToFail != i {
+ <-stdout.handshakeComplete
+ stdin <- opensslSendSentinel
+ }
+ <-signalChan
+ }
+
+ if test.sendKeyUpdate {
+ if write {
+ <-stdout.handshakeComplete
+ stdin <- opensslKeyUpdate
+ }
+
+ doneRead := make(chan struct{})
+
+ go func() {
+ defer close(doneRead)
+
+ buf := make([]byte, 256)
+ n, err := client.Read(buf)
+
+ if err != nil {
+ t.Errorf("Client.Read failed after KeyUpdate: %s", err)
+ return
+ }
+
+ buf = buf[:n]
+ if !bytes.Equal([]byte(opensslSentinel), buf) {
+ t.Errorf("Client.Read returned %q, but wanted %q", string(buf), opensslSentinel)
+ }
+ }()
+
+ if write {
+ // There's no real reason to wait for the client KeyUpdate to
+ // send data with the new server keys, except that s_server
+ // drops writes if they are sent at the wrong time.
+ <-stdout.readKeyUpdate
+ stdin <- opensslSendSentinel
+ }
+ <-doneRead
+
+ if _, err := client.Write([]byte("hello again\n")); err != nil {
+ t.Errorf("Client.Write failed: %s", err)
+ return
+ }
+ }
+
+ if test.validate != nil {
+ if err := test.validate(client.ConnectionState()); err != nil {
+ t.Errorf("validate callback returned error: %s", err)
+ }
+ }
+
+ // If the server sent us an alert after our last flight, give it a
+ // chance to arrive.
+ if write && test.renegotiationExpectedToFail == 0 {
+ if err := peekError(client); err != nil {
+ t.Errorf("final Read returned an error: %s", err)
+ }
+ }
+ }()
+
+ if !write {
+ flows, err := test.loadData()
+ if err != nil {
+ t.Fatalf("%s: failed to load data from %s: %v", test.name, test.dataPath(), err)
+ }
+ for i, b := range flows {
+ if i%2 == 1 {
+ if *fast {
+ serverConn.SetWriteDeadline(time.Now().Add(1 * time.Second))
+ } else {
+ serverConn.SetWriteDeadline(time.Now().Add(1 * time.Minute))
+ }
+ serverConn.Write(b)
+ continue
+ }
+ bb := make([]byte, len(b))
+ if *fast {
+ serverConn.SetReadDeadline(time.Now().Add(1 * time.Second))
+ } else {
+ serverConn.SetReadDeadline(time.Now().Add(1 * time.Minute))
+ }
+ _, err := io.ReadFull(serverConn, bb)
+ if err != nil {
+ t.Fatalf("%s, flow %d: %s", test.name, i+1, err)
+ }
+ if !bytes.Equal(b, bb) {
+ t.Fatalf("%s, flow %d: mismatch on read: got:%x want:%x", test.name, i+1, bb, b)
+ }
+ }
+ }
+
+ <-doneChan
+ if !write {
+ serverConn.Close()
+ }
+
+ if write {
+ path := test.dataPath()
+ out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
+ if err != nil {
+ t.Fatalf("Failed to create output file: %s", err)
+ }
+ defer out.Close()
+ recordingConn.Close()
+ close(stdin)
+ childProcess.Process.Kill()
+ childProcess.Wait()
+ if len(recordingConn.flows) < 3 {
+ t.Fatalf("Client connection didn't work")
+ }
+ recordingConn.WriteTo(out)
+ t.Logf("Wrote %s\n", path)
+ }
+}
+
+// peekError does a read with a short timeout to check if the next read would
+// cause an error, for example if there is an alert waiting on the wire.
+func peekError(conn net.Conn) error {
+ conn.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
+ if n, err := conn.Read(make([]byte, 1)); n != 0 {
+ return errors.New("unexpectedly read data")
+ } else if err != nil {
+ if netErr, ok := err.(net.Error); !ok || !netErr.Timeout() {
+ return err
+ }
+ }
+ return nil
+}
+
+func runClientTestForVersion(t *testing.T, template *clientTest, version, option string) {
+ // Make a deep copy of the template before going parallel.
+ test := *template
+ if template.config != nil {
+ test.config = template.config.Clone()
+ }
+ test.name = version + "-" + test.name
+ test.args = append([]string{option}, test.args...)
+
+ runTestAndUpdateIfNeeded(t, version, test.run, false)
+}
+
+func runClientTestTLS10(t *testing.T, template *clientTest) {
+ runClientTestForVersion(t, template, "TLSv10", "-tls1")
+}
+
+func runClientTestTLS11(t *testing.T, template *clientTest) {
+ runClientTestForVersion(t, template, "TLSv11", "-tls1_1")
+}
+
+func runClientTestTLS12(t *testing.T, template *clientTest) {
+ runClientTestForVersion(t, template, "TLSv12", "-tls1_2")
+}
+
+func runClientTestTLS13(t *testing.T, template *clientTest) {
+ runClientTestForVersion(t, template, "TLSv13", "-tls1_3")
+}
+
+func TestHandshakeClientRSARC4(t *testing.T) {
+ test := &clientTest{
+ name: "RSA-RC4",
+ args: []string{"-cipher", "RC4-SHA"},
+ }
+ runClientTestTLS10(t, test)
+ runClientTestTLS11(t, test)
+ runClientTestTLS12(t, test)
+}
+
+func TestHandshakeClientRSAAES128GCM(t *testing.T) {
+ test := &clientTest{
+ name: "AES128-GCM-SHA256",
+ args: []string{"-cipher", "AES128-GCM-SHA256"},
+ }
+ runClientTestTLS12(t, test)
+}
+
+func TestHandshakeClientRSAAES256GCM(t *testing.T) {
+ test := &clientTest{
+ name: "AES256-GCM-SHA384",
+ args: []string{"-cipher", "AES256-GCM-SHA384"},
+ }
+ runClientTestTLS12(t, test)
+}
+
+func TestHandshakeClientECDHERSAAES(t *testing.T) {
+ test := &clientTest{
+ name: "ECDHE-RSA-AES",
+ args: []string{"-cipher", "ECDHE-RSA-AES128-SHA"},
+ }
+ runClientTestTLS10(t, test)
+ runClientTestTLS11(t, test)
+ runClientTestTLS12(t, test)
+}
+
+func TestHandshakeClientECDHEECDSAAES(t *testing.T) {
+ test := &clientTest{
+ name: "ECDHE-ECDSA-AES",
+ args: []string{"-cipher", "ECDHE-ECDSA-AES128-SHA"},
+ cert: testECDSACertificate,
+ key: testECDSAPrivateKey,
+ }
+ runClientTestTLS10(t, test)
+ runClientTestTLS11(t, test)
+ runClientTestTLS12(t, test)
+}
+
+func TestHandshakeClientECDHEECDSAAESGCM(t *testing.T) {
+ test := &clientTest{
+ name: "ECDHE-ECDSA-AES-GCM",
+ args: []string{"-cipher", "ECDHE-ECDSA-AES128-GCM-SHA256"},
+ cert: testECDSACertificate,
+ key: testECDSAPrivateKey,
+ }
+ runClientTestTLS12(t, test)
+}
+
+func TestHandshakeClientAES256GCMSHA384(t *testing.T) {
+ test := &clientTest{
+ name: "ECDHE-ECDSA-AES256-GCM-SHA384",
+ args: []string{"-cipher", "ECDHE-ECDSA-AES256-GCM-SHA384"},
+ cert: testECDSACertificate,
+ key: testECDSAPrivateKey,
+ }
+ runClientTestTLS12(t, test)
+}
+
+func TestHandshakeClientAES128CBCSHA256(t *testing.T) {
+ test := &clientTest{
+ name: "AES128-SHA256",
+ args: []string{"-cipher", "AES128-SHA256"},
+ }
+ runClientTestTLS12(t, test)
+}
+
+func TestHandshakeClientECDHERSAAES128CBCSHA256(t *testing.T) {
+ test := &clientTest{
+ name: "ECDHE-RSA-AES128-SHA256",
+ args: []string{"-cipher", "ECDHE-RSA-AES128-SHA256"},
+ }
+ runClientTestTLS12(t, test)
+}
+
+func TestHandshakeClientECDHEECDSAAES128CBCSHA256(t *testing.T) {
+ test := &clientTest{
+ name: "ECDHE-ECDSA-AES128-SHA256",
+ args: []string{"-cipher", "ECDHE-ECDSA-AES128-SHA256"},
+ cert: testECDSACertificate,
+ key: testECDSAPrivateKey,
+ }
+ runClientTestTLS12(t, test)
+}
+
+func TestHandshakeClientX25519(t *testing.T) {
+ config := testConfig.Clone()
+ config.CurvePreferences = []CurveID{X25519}
+
+ test := &clientTest{
+ name: "X25519-ECDHE",
+ args: []string{"-cipher", "ECDHE-RSA-AES128-GCM-SHA256", "-curves", "X25519"},
+ config: config,
+ }
+
+ runClientTestTLS12(t, test)
+ runClientTestTLS13(t, test)
+}
+
+func TestHandshakeClientP256(t *testing.T) {
+ config := testConfig.Clone()
+ config.CurvePreferences = []CurveID{CurveP256}
+
+ test := &clientTest{
+ name: "P256-ECDHE",
+ args: []string{"-cipher", "ECDHE-RSA-AES128-GCM-SHA256", "-curves", "P-256"},
+ config: config,
+ }
+
+ runClientTestTLS12(t, test)
+ runClientTestTLS13(t, test)
+}
+
+func TestHandshakeClientHelloRetryRequest(t *testing.T) {
+ config := testConfig.Clone()
+ config.CurvePreferences = []CurveID{X25519, CurveP256}
+
+ test := &clientTest{
+ name: "HelloRetryRequest",
+ args: []string{"-cipher", "ECDHE-RSA-AES128-GCM-SHA256", "-curves", "P-256"},
+ config: config,
+ }
+
+ runClientTestTLS13(t, test)
+}
+
+func TestHandshakeClientECDHERSAChaCha20(t *testing.T) {
+ config := testConfig.Clone()
+ config.CipherSuites = []uint16{TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305}
+
+ test := &clientTest{
+ name: "ECDHE-RSA-CHACHA20-POLY1305",
+ args: []string{"-cipher", "ECDHE-RSA-CHACHA20-POLY1305"},
+ config: config,
+ }
+
+ runClientTestTLS12(t, test)
+}
+
+func TestHandshakeClientECDHEECDSAChaCha20(t *testing.T) {
+ config := testConfig.Clone()
+ config.CipherSuites = []uint16{TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305}
+
+ test := &clientTest{
+ name: "ECDHE-ECDSA-CHACHA20-POLY1305",
+ args: []string{"-cipher", "ECDHE-ECDSA-CHACHA20-POLY1305"},
+ config: config,
+ cert: testECDSACertificate,
+ key: testECDSAPrivateKey,
+ }
+
+ runClientTestTLS12(t, test)
+}
+
+func TestHandshakeClientAES128SHA256(t *testing.T) {
+ test := &clientTest{
+ name: "AES128-SHA256",
+ args: []string{"-ciphersuites", "TLS_AES_128_GCM_SHA256"},
+ }
+ runClientTestTLS13(t, test)
+}
+func TestHandshakeClientAES256SHA384(t *testing.T) {
+ test := &clientTest{
+ name: "AES256-SHA384",
+ args: []string{"-ciphersuites", "TLS_AES_256_GCM_SHA384"},
+ }
+ runClientTestTLS13(t, test)
+}
+func TestHandshakeClientCHACHA20SHA256(t *testing.T) {
+ test := &clientTest{
+ name: "CHACHA20-SHA256",
+ args: []string{"-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256"},
+ }
+ runClientTestTLS13(t, test)
+}
+
+func TestHandshakeClientECDSATLS13(t *testing.T) {
+ test := &clientTest{
+ name: "ECDSA",
+ cert: testECDSACertificate,
+ key: testECDSAPrivateKey,
+ }
+ runClientTestTLS13(t, test)
+}
+
+func TestHandshakeClientEd25519(t *testing.T) {
+ test := &clientTest{
+ name: "Ed25519",
+ cert: testEd25519Certificate,
+ key: testEd25519PrivateKey,
+ }
+ runClientTestTLS12(t, test)
+ runClientTestTLS13(t, test)
+
+ config := testConfig.Clone()
+ cert, _ := X509KeyPair([]byte(clientEd25519CertificatePEM), []byte(clientEd25519KeyPEM))
+ config.Certificates = []Certificate{cert}
+
+ test = &clientTest{
+ name: "ClientCert-Ed25519",
+ args: []string{"-Verify", "1"},
+ config: config,
+ }
+
+ runClientTestTLS12(t, test)
+ runClientTestTLS13(t, test)
+}
+
+func TestHandshakeClientCertRSA(t *testing.T) {
+ config := testConfig.Clone()
+ cert, _ := X509KeyPair([]byte(clientCertificatePEM), []byte(clientKeyPEM))
+ config.Certificates = []Certificate{cert}
+
+ test := &clientTest{
+ name: "ClientCert-RSA-RSA",
+ args: []string{"-cipher", "AES128", "-Verify", "1"},
+ config: config,
+ }
+
+ runClientTestTLS10(t, test)
+ runClientTestTLS12(t, test)
+
+ test = &clientTest{
+ name: "ClientCert-RSA-ECDSA",
+ args: []string{"-cipher", "ECDHE-ECDSA-AES128-SHA", "-Verify", "1"},
+ config: config,
+ cert: testECDSACertificate,
+ key: testECDSAPrivateKey,
+ }
+
+ runClientTestTLS10(t, test)
+ runClientTestTLS12(t, test)
+ runClientTestTLS13(t, test)
+
+ test = &clientTest{
+ name: "ClientCert-RSA-AES256-GCM-SHA384",
+ args: []string{"-cipher", "ECDHE-RSA-AES256-GCM-SHA384", "-Verify", "1"},
+ config: config,
+ cert: testRSACertificate,
+ key: testRSAPrivateKey,
+ }
+
+ runClientTestTLS12(t, test)
+}
+
+func TestHandshakeClientCertECDSA(t *testing.T) {
+ config := testConfig.Clone()
+ cert, _ := X509KeyPair([]byte(clientECDSACertificatePEM), []byte(clientECDSAKeyPEM))
+ config.Certificates = []Certificate{cert}
+
+ test := &clientTest{
+ name: "ClientCert-ECDSA-RSA",
+ args: []string{"-cipher", "AES128", "-Verify", "1"},
+ config: config,
+ }
+
+ runClientTestTLS10(t, test)
+ runClientTestTLS12(t, test)
+ runClientTestTLS13(t, test)
+
+ test = &clientTest{
+ name: "ClientCert-ECDSA-ECDSA",
+ args: []string{"-cipher", "ECDHE-ECDSA-AES128-SHA", "-Verify", "1"},
+ config: config,
+ cert: testECDSACertificate,
+ key: testECDSAPrivateKey,
+ }
+
+ runClientTestTLS10(t, test)
+ runClientTestTLS12(t, test)
+}
+
+// TestHandshakeClientCertRSAPSS tests rsa_pss_rsae_sha256 signatures from both
+// client and server certificates. It also serves from both sides a certificate
+// signed itself with RSA-PSS, mostly to check that crypto/x509 chain validation
+// works.
+func TestHandshakeClientCertRSAPSS(t *testing.T) {
+ cert, err := x509.ParseCertificate(testRSAPSSCertificate)
+ if err != nil {
+ panic(err)
+ }
+ rootCAs := x509.NewCertPool()
+ rootCAs.AddCert(cert)
+
+ config := testConfig.Clone()
+ // Use GetClientCertificate to bypass the client certificate selection logic.
+ config.GetClientCertificate = func(*CertificateRequestInfo) (*Certificate, error) {
+ return &Certificate{
+ Certificate: [][]byte{testRSAPSSCertificate},
+ PrivateKey: testRSAPrivateKey,
+ }, nil
+ }
+ config.RootCAs = rootCAs
+
+ test := &clientTest{
+ name: "ClientCert-RSA-RSAPSS",
+ args: []string{"-cipher", "AES128", "-Verify", "1", "-client_sigalgs",
+ "rsa_pss_rsae_sha256", "-sigalgs", "rsa_pss_rsae_sha256"},
+ config: config,
+ cert: testRSAPSSCertificate,
+ key: testRSAPrivateKey,
+ }
+ runClientTestTLS12(t, test)
+ runClientTestTLS13(t, test)
+}
+
+func TestHandshakeClientCertRSAPKCS1v15(t *testing.T) {
+ config := testConfig.Clone()
+ cert, _ := X509KeyPair([]byte(clientCertificatePEM), []byte(clientKeyPEM))
+ config.Certificates = []Certificate{cert}
+
+ test := &clientTest{
+ name: "ClientCert-RSA-RSAPKCS1v15",
+ args: []string{"-cipher", "AES128", "-Verify", "1", "-client_sigalgs",
+ "rsa_pkcs1_sha256", "-sigalgs", "rsa_pkcs1_sha256"},
+ config: config,
+ }
+
+ runClientTestTLS12(t, test)
+}
+
+func TestClientKeyUpdate(t *testing.T) {
+ test := &clientTest{
+ name: "KeyUpdate",
+ args: []string{"-state"},
+ sendKeyUpdate: true,
+ }
+ runClientTestTLS13(t, test)
+}
+
+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) {
+ if testing.Short() {
+ t.Skip("skipping in -short mode")
+ }
+ serverConfig := &Config{
+ MaxVersion: version,
+ CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA},
+ Certificates: testConfig.Certificates,
+ }
+
+ issuer, err := x509.ParseCertificate(testRSACertificateIssuer)
+ if err != nil {
+ panic(err)
+ }
+
+ rootCAs := x509.NewCertPool()
+ rootCAs.AddCert(issuer)
+
+ clientConfig := &Config{
+ MaxVersion: version,
+ CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+ ClientSessionCache: NewLRUClientSessionCache(32),
+ RootCAs: rootCAs,
+ ServerName: "example.golang",
+ }
+
+ testResumeState := func(test string, didResume bool) {
+ t.Helper()
+ _, hs, err := testHandshake(t, clientConfig, serverConfig)
+ if err != nil {
+ t.Fatalf("%s: handshake failed: %s", test, err)
+ }
+ if hs.DidResume != didResume {
+ t.Fatalf("%s resumed: %v, expected: %v", test, hs.DidResume, didResume)
+ }
+ if didResume && (hs.PeerCertificates == nil || hs.VerifiedChains == nil) {
+ t.Fatalf("expected non-nil certificates after resumption. Got peerCertificates: %#v, verifiedCertificates: %#v", hs.PeerCertificates, hs.VerifiedChains)
+ }
+ if got, want := hs.ServerName, clientConfig.ServerName; got != want {
+ t.Errorf("%s: server name %s, want %s", test, got, want)
+ }
+ }
+
+ getTicket := func() []byte {
+ return clientConfig.ClientSessionCache.(*lruSessionCache).q.Front().Value.(*lruSessionCacheEntry).state.ticket
+ }
+ deleteTicket := func() {
+ ticketKey := clientConfig.ClientSessionCache.(*lruSessionCache).q.Front().Value.(*lruSessionCacheEntry).sessionKey
+ clientConfig.ClientSessionCache.Put(ticketKey, nil)
+ }
+ corruptTicket := func() {
+ clientConfig.ClientSessionCache.(*lruSessionCache).q.Front().Value.(*lruSessionCacheEntry).state.session.secret[0] ^= 0xff
+ }
+ randomKey := func() [32]byte {
+ var k [32]byte
+ if _, err := io.ReadFull(serverConfig.rand(), k[:]); err != nil {
+ t.Fatalf("Failed to read new SessionTicketKey: %s", err)
+ }
+ return k
+ }
+
+ testResumeState("Handshake", false)
+ ticket := getTicket()
+ testResumeState("Resume", true)
+ if bytes.Equal(ticket, getTicket()) {
+ t.Fatal("ticket didn't change after resumption")
+ }
+
+ // An old session ticket is replaced with a ticket encrypted with a fresh key.
+ ticket = getTicket()
+ serverConfig.Time = func() time.Time { return time.Now().Add(24*time.Hour + time.Minute) }
+ testResumeState("ResumeWithOldTicket", true)
+ if bytes.Equal(ticket, getTicket()) {
+ t.Fatal("old first ticket matches the fresh one")
+ }
+
+ // Once the session master secret is expired, a full handshake should occur.
+ ticket = getTicket()
+ serverConfig.Time = func() time.Time { return time.Now().Add(24*8*time.Hour + time.Minute) }
+ testResumeState("ResumeWithExpiredTicket", false)
+ if bytes.Equal(ticket, getTicket()) {
+ t.Fatal("expired first ticket matches the fresh one")
+ }
+
+ serverConfig.Time = func() time.Time { return time.Now() } // reset the time back
+ key1 := randomKey()
+ serverConfig.SetSessionTicketKeys([][32]byte{key1})
+
+ testResumeState("InvalidSessionTicketKey", false)
+ testResumeState("ResumeAfterInvalidSessionTicketKey", true)
+
+ key2 := randomKey()
+ serverConfig.SetSessionTicketKeys([][32]byte{key2, key1})
+ ticket = getTicket()
+ testResumeState("KeyChange", true)
+ if bytes.Equal(ticket, getTicket()) {
+ t.Fatal("new ticket wasn't included while resuming")
+ }
+ testResumeState("KeyChangeFinish", true)
+
+ // Age the session ticket a bit, but not yet expired.
+ serverConfig.Time = func() time.Time { return time.Now().Add(24*time.Hour + time.Minute) }
+ testResumeState("OldSessionTicket", true)
+ ticket = getTicket()
+ // Expire the session ticket, which would force a full handshake.
+ serverConfig.Time = func() time.Time { return time.Now().Add(24*8*time.Hour + time.Minute) }
+ testResumeState("ExpiredSessionTicket", false)
+ if bytes.Equal(ticket, getTicket()) {
+ t.Fatal("new ticket wasn't provided after old ticket expired")
+ }
+
+ // Age the session ticket a bit at a time, but don't expire it.
+ d := 0 * time.Hour
+ serverConfig.Time = func() time.Time { return time.Now().Add(d) }
+ deleteTicket()
+ testResumeState("GetFreshSessionTicket", false)
+ for i := 0; i < 13; i++ {
+ d += 12 * time.Hour
+ testResumeState("OldSessionTicket", true)
+ }
+ // Expire it (now a little more than 7 days) and make sure a full
+ // handshake occurs for TLS 1.2. Resumption should still occur for
+ // TLS 1.3 since the client should be using a fresh ticket sent over
+ // by the server.
+ d += 12 * time.Hour
+ if version == VersionTLS13 {
+ testResumeState("ExpiredSessionTicket", true)
+ } else {
+ testResumeState("ExpiredSessionTicket", false)
+ }
+ if bytes.Equal(ticket, getTicket()) {
+ t.Fatal("new ticket wasn't provided after old ticket expired")
+ }
+
+ // 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,
+ }
+ serverConfig.SetSessionTicketKeys([][32]byte{key2})
+
+ 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)
+
+ // In TLS 1.3, HelloRetryRequest is sent after incorrect key share.
+ // See https://www.rfc-editor.org/rfc/rfc8446#page-14.
+ if version == VersionTLS13 {
+ deleteTicket()
+ serverConfig = &Config{
+ // Use a different curve than the client to force a HelloRetryRequest.
+ CurvePreferences: []CurveID{CurveP521, CurveP384, CurveP256},
+ MaxVersion: version,
+ Certificates: testConfig.Certificates,
+ }
+ testResumeState("InitialHandshake", false)
+ testResumeState("WithHelloRetryRequest", true)
+
+ // Reset serverConfig back.
+ serverConfig = &Config{
+ MaxVersion: version,
+ CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA},
+ Certificates: testConfig.Certificates,
+ }
+ }
+
+ // Session resumption should work when using client certificates
+ deleteTicket()
+ serverConfig.ClientCAs = rootCAs
+ serverConfig.ClientAuth = RequireAndVerifyClientCert
+ clientConfig.Certificates = serverConfig.Certificates
+ testResumeState("InitialHandshake", false)
+ testResumeState("WithClientCertificates", true)
+ serverConfig.ClientAuth = NoClientCert
+
+ // Tickets should be removed from the session cache on TLS handshake
+ // failure, and the client should recover from a corrupted PSK
+ testResumeState("FetchTicketToCorrupt", false)
+ corruptTicket()
+ _, _, err = testHandshake(t, clientConfig, serverConfig)
+ if err == nil {
+ t.Fatalf("handshake did not fail with a corrupted client secret")
+ }
+ testResumeState("AfterHandshakeFailure", false)
+
+ clientConfig.ClientSessionCache = nil
+ testResumeState("WithoutSessionCache", false)
+
+ clientConfig.ClientSessionCache = &serializingClientCache{t: t}
+ testResumeState("BeforeSerializingCache", false)
+ testResumeState("WithSerializingCache", true)
+}
+
+type serializingClientCache struct {
+ t *testing.T
+
+ ticket, state []byte
+}
+
+func (c *serializingClientCache) Get(sessionKey string) (session *ClientSessionState, ok bool) {
+ if c.ticket == nil {
+ return nil, false
+ }
+ state, err := ParseSessionState(c.state)
+ if err != nil {
+ c.t.Error(err)
+ return nil, false
+ }
+ cs, err := NewResumptionState(c.ticket, state)
+ if err != nil {
+ c.t.Error(err)
+ return nil, false
+ }
+ return cs, true
+}
+
+func (c *serializingClientCache) Put(sessionKey string, cs *ClientSessionState) {
+ ticket, state, err := cs.ResumptionState()
+ if err != nil {
+ c.t.Error(err)
+ return
+ }
+ stateBytes, err := state.Bytes()
+ if err != nil {
+ c.t.Error(err)
+ return
+ }
+ c.ticket, c.state = ticket, stateBytes
+}
+
+func TestLRUClientSessionCache(t *testing.T) {
+ // Initialize cache of capacity 4.
+ cache := NewLRUClientSessionCache(4)
+ cs := make([]ClientSessionState, 6)
+ keys := []string{"0", "1", "2", "3", "4", "5", "6"}
+
+ // Add 4 entries to the cache and look them up.
+ for i := 0; i < 4; i++ {
+ cache.Put(keys[i], &cs[i])
+ }
+ for i := 0; i < 4; i++ {
+ if s, ok := cache.Get(keys[i]); !ok || s != &cs[i] {
+ t.Fatalf("session cache failed lookup for added key: %s", keys[i])
+ }
+ }
+
+ // Add 2 more entries to the cache. First 2 should be evicted.
+ for i := 4; i < 6; i++ {
+ cache.Put(keys[i], &cs[i])
+ }
+ for i := 0; i < 2; i++ {
+ if s, ok := cache.Get(keys[i]); ok || s != nil {
+ t.Fatalf("session cache should have evicted key: %s", keys[i])
+ }
+ }
+
+ // Touch entry 2. LRU should evict 3 next.
+ cache.Get(keys[2])
+ cache.Put(keys[0], &cs[0])
+ if s, ok := cache.Get(keys[3]); ok || s != nil {
+ t.Fatalf("session cache should have evicted key 3")
+ }
+
+ // Update entry 0 in place.
+ cache.Put(keys[0], &cs[3])
+ if s, ok := cache.Get(keys[0]); !ok || s != &cs[3] {
+ t.Fatalf("session cache failed update for key 0")
+ }
+
+ // Calling Put with a nil entry deletes the key.
+ cache.Put(keys[0], nil)
+ if _, ok := cache.Get(keys[0]); ok {
+ t.Fatalf("session cache failed to delete key 0")
+ }
+
+ // Delete entry 2. LRU should keep 4 and 5
+ cache.Put(keys[2], nil)
+ if _, ok := cache.Get(keys[2]); ok {
+ t.Fatalf("session cache failed to delete key 4")
+ }
+ for i := 4; i < 6; i++ {
+ if s, ok := cache.Get(keys[i]); !ok || s != &cs[i] {
+ t.Fatalf("session cache should not have deleted key: %s", keys[i])
+ }
+ }
+}
+
+func TestKeyLogTLS12(t *testing.T) {
+ var serverBuf, clientBuf bytes.Buffer
+
+ clientConfig := testConfig.Clone()
+ clientConfig.KeyLogWriter = &clientBuf
+ clientConfig.MaxVersion = VersionTLS12
+
+ serverConfig := testConfig.Clone()
+ serverConfig.KeyLogWriter = &serverBuf
+ serverConfig.MaxVersion = VersionTLS12
+
+ c, s := localPipe(t)
+ done := make(chan bool)
+
+ go func() {
+ defer close(done)
+
+ if err := Server(s, serverConfig).Handshake(); err != nil {
+ t.Errorf("server: %s", err)
+ return
+ }
+ s.Close()
+ }()
+
+ if err := Client(c, clientConfig).Handshake(); err != nil {
+ t.Fatalf("client: %s", err)
+ }
+
+ c.Close()
+ <-done
+
+ checkKeylogLine := func(side, loggedLine string) {
+ if len(loggedLine) == 0 {
+ t.Fatalf("%s: no keylog line was produced", side)
+ }
+ const expectedLen = 13 /* "CLIENT_RANDOM" */ +
+ 1 /* space */ +
+ 32*2 /* hex client nonce */ +
+ 1 /* space */ +
+ 48*2 /* hex master secret */ +
+ 1 /* new line */
+ if len(loggedLine) != expectedLen {
+ t.Fatalf("%s: keylog line has incorrect length (want %d, got %d): %q", side, expectedLen, len(loggedLine), loggedLine)
+ }
+ if !strings.HasPrefix(loggedLine, "CLIENT_RANDOM "+strings.Repeat("0", 64)+" ") {
+ t.Fatalf("%s: keylog line has incorrect structure or nonce: %q", side, loggedLine)
+ }
+ }
+
+ checkKeylogLine("client", clientBuf.String())
+ checkKeylogLine("server", serverBuf.String())
+}
+
+func TestKeyLogTLS13(t *testing.T) {
+ var serverBuf, clientBuf bytes.Buffer
+
+ clientConfig := testConfig.Clone()
+ clientConfig.KeyLogWriter = &clientBuf
+
+ serverConfig := testConfig.Clone()
+ serverConfig.KeyLogWriter = &serverBuf
+
+ c, s := localPipe(t)
+ done := make(chan bool)
+
+ go func() {
+ defer close(done)
+
+ if err := Server(s, serverConfig).Handshake(); err != nil {
+ t.Errorf("server: %s", err)
+ return
+ }
+ s.Close()
+ }()
+
+ if err := Client(c, clientConfig).Handshake(); err != nil {
+ t.Fatalf("client: %s", err)
+ }
+
+ c.Close()
+ <-done
+
+ checkKeylogLines := func(side, loggedLines string) {
+ loggedLines = strings.TrimSpace(loggedLines)
+ lines := strings.Split(loggedLines, "\n")
+ if len(lines) != 4 {
+ t.Errorf("Expected the %s to log 4 lines, got %d", side, len(lines))
+ }
+ }
+
+ checkKeylogLines("client", clientBuf.String())
+ checkKeylogLines("server", serverBuf.String())
+}
+
+func TestHandshakeClientALPNMatch(t *testing.T) {
+ config := testConfig.Clone()
+ config.NextProtos = []string{"proto2", "proto1"}
+
+ test := &clientTest{
+ name: "ALPN",
+ // Note that this needs OpenSSL 1.0.2 because that is the first
+ // version that supports the -alpn flag.
+ args: []string{"-alpn", "proto1,proto2"},
+ config: config,
+ validate: func(state ConnectionState) error {
+ // The server's preferences should override the client.
+ if state.NegotiatedProtocol != "proto1" {
+ return fmt.Errorf("Got protocol %q, wanted proto1", state.NegotiatedProtocol)
+ }
+ return nil
+ },
+ }
+ runClientTestTLS12(t, test)
+ runClientTestTLS13(t, test)
+}
+
+func TestServerSelectingUnconfiguredApplicationProtocol(t *testing.T) {
+ // This checks that the server can't select an application protocol that the
+ // client didn't offer.
+
+ c, s := localPipe(t)
+ errChan := make(chan error, 1)
+
+ go func() {
+ client := Client(c, &Config{
+ ServerName: "foo",
+ CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
+ NextProtos: []string{"http", "something-else"},
+ })
+ errChan <- client.Handshake()
+ }()
+
+ var header [5]byte
+ if _, err := io.ReadFull(s, header[:]); err != nil {
+ t.Fatal(err)
+ }
+ recordLen := int(header[3])<<8 | int(header[4])
+
+ record := make([]byte, recordLen)
+ if _, err := io.ReadFull(s, record); err != nil {
+ t.Fatal(err)
+ }
+
+ serverHello := &serverHelloMsg{
+ vers: VersionTLS12,
+ random: make([]byte, 32),
+ cipherSuite: TLS_RSA_WITH_AES_128_GCM_SHA256,
+ alpnProtocol: "how-about-this",
+ }
+ serverHelloBytes := mustMarshal(t, serverHello)
+
+ s.Write([]byte{
+ byte(recordTypeHandshake),
+ byte(VersionTLS12 >> 8),
+ byte(VersionTLS12 & 0xff),
+ byte(len(serverHelloBytes) >> 8),
+ byte(len(serverHelloBytes)),
+ })
+ s.Write(serverHelloBytes)
+ s.Close()
+
+ if err := <-errChan; !strings.Contains(err.Error(), "server selected unadvertised ALPN protocol") {
+ t.Fatalf("Expected error about unconfigured cipher suite but got %q", err)
+ }
+}
+
+// sctsBase64 contains data from `openssl s_client -serverinfo 18 -connect ritter.vg:443`
+const sctsBase64 = "ABIBaQFnAHUApLkJkLQYWBSHuxOizGdwCjw1mAT5G9+443fNDsgN3BAAAAFHl5nuFgAABAMARjBEAiAcS4JdlW5nW9sElUv2zvQyPoZ6ejKrGGB03gjaBZFMLwIgc1Qbbn+hsH0RvObzhS+XZhr3iuQQJY8S9G85D9KeGPAAdgBo9pj4H2SCvjqM7rkoHUz8cVFdZ5PURNEKZ6y7T0/7xAAAAUeX4bVwAAAEAwBHMEUCIDIhFDgG2HIuADBkGuLobU5a4dlCHoJLliWJ1SYT05z6AiEAjxIoZFFPRNWMGGIjskOTMwXzQ1Wh2e7NxXE1kd1J0QsAdgDuS723dc5guuFCaR+r4Z5mow9+X7By2IMAxHuJeqj9ywAAAUhcZIqHAAAEAwBHMEUCICmJ1rBT09LpkbzxtUC+Hi7nXLR0J+2PmwLp+sJMuqK+AiEAr0NkUnEVKVhAkccIFpYDqHOlZaBsuEhWWrYpg2RtKp0="
+
+func TestHandshakClientSCTs(t *testing.T) {
+ config := testConfig.Clone()
+
+ scts, err := base64.StdEncoding.DecodeString(sctsBase64)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ // Note that this needs OpenSSL 1.0.2 because that is the first
+ // version that supports the -serverinfo flag.
+ test := &clientTest{
+ name: "SCT",
+ config: config,
+ extensions: [][]byte{scts},
+ validate: func(state ConnectionState) error {
+ expectedSCTs := [][]byte{
+ scts[8:125],
+ scts[127:245],
+ scts[247:],
+ }
+ if n := len(state.SignedCertificateTimestamps); n != len(expectedSCTs) {
+ return fmt.Errorf("Got %d scts, wanted %d", n, len(expectedSCTs))
+ }
+ for i, expected := range expectedSCTs {
+ if sct := state.SignedCertificateTimestamps[i]; !bytes.Equal(sct, expected) {
+ return fmt.Errorf("SCT #%d contained %x, expected %x", i, sct, expected)
+ }
+ }
+ return nil
+ },
+ }
+ runClientTestTLS12(t, test)
+
+ // TLS 1.3 moved SCTs to the Certificate extensions and -serverinfo only
+ // supports ServerHello extensions.
+}
+
+func TestRenegotiationRejected(t *testing.T) {
+ config := testConfig.Clone()
+ test := &clientTest{
+ name: "RenegotiationRejected",
+ args: []string{"-state"},
+ config: config,
+ numRenegotiations: 1,
+ renegotiationExpectedToFail: 1,
+ checkRenegotiationError: func(renegotiationNum int, err error) error {
+ if err == nil {
+ return errors.New("expected error from renegotiation but got nil")
+ }
+ if !strings.Contains(err.Error(), "no renegotiation") {
+ return fmt.Errorf("expected renegotiation to be rejected but got %q", err)
+ }
+ return nil
+ },
+ }
+ runClientTestTLS12(t, test)
+}
+
+func TestRenegotiateOnce(t *testing.T) {
+ config := testConfig.Clone()
+ config.Renegotiation = RenegotiateOnceAsClient
+
+ test := &clientTest{
+ name: "RenegotiateOnce",
+ args: []string{"-state"},
+ config: config,
+ numRenegotiations: 1,
+ }
+
+ runClientTestTLS12(t, test)
+}
+
+func TestRenegotiateTwice(t *testing.T) {
+ config := testConfig.Clone()
+ config.Renegotiation = RenegotiateFreelyAsClient
+
+ test := &clientTest{
+ name: "RenegotiateTwice",
+ args: []string{"-state"},
+ config: config,
+ numRenegotiations: 2,
+ }
+
+ runClientTestTLS12(t, test)
+}
+
+func TestRenegotiateTwiceRejected(t *testing.T) {
+ config := testConfig.Clone()
+ config.Renegotiation = RenegotiateOnceAsClient
+
+ test := &clientTest{
+ name: "RenegotiateTwiceRejected",
+ args: []string{"-state"},
+ config: config,
+ numRenegotiations: 2,
+ renegotiationExpectedToFail: 2,
+ checkRenegotiationError: func(renegotiationNum int, err error) error {
+ if renegotiationNum == 1 {
+ return err
+ }
+
+ if err == nil {
+ return errors.New("expected error from renegotiation but got nil")
+ }
+ if !strings.Contains(err.Error(), "no renegotiation") {
+ return fmt.Errorf("expected renegotiation to be rejected but got %q", err)
+ }
+ return nil
+ },
+ }
+
+ runClientTestTLS12(t, test)
+}
+
+func TestHandshakeClientExportKeyingMaterial(t *testing.T) {
+ test := &clientTest{
+ name: "ExportKeyingMaterial",
+ config: testConfig.Clone(),
+ validate: func(state ConnectionState) error {
+ if km, err := state.ExportKeyingMaterial("test", nil, 42); err != nil {
+ return fmt.Errorf("ExportKeyingMaterial failed: %v", err)
+ } else if len(km) != 42 {
+ return fmt.Errorf("Got %d bytes from ExportKeyingMaterial, wanted %d", len(km), 42)
+ }
+ return nil
+ },
+ }
+ runClientTestTLS10(t, test)
+ runClientTestTLS12(t, test)
+ runClientTestTLS13(t, test)
+}
+
+var hostnameInSNITests = []struct {
+ in, out string
+}{
+ // Opaque string
+ {"", ""},
+ {"localhost", "localhost"},
+ {"foo, bar, baz and qux", "foo, bar, baz and qux"},
+
+ // DNS hostname
+ {"golang.org", "golang.org"},
+ {"golang.org.", "golang.org"},
+
+ // Literal IPv4 address
+ {"1.2.3.4", ""},
+
+ // Literal IPv6 address
+ {"::1", ""},
+ {"::1%lo0", ""}, // with zone identifier
+ {"[::1]", ""}, // as per RFC 5952 we allow the [] style as IPv6 literal
+ {"[::1%lo0]", ""},
+}
+
+func TestHostnameInSNI(t *testing.T) {
+ for _, tt := range hostnameInSNITests {
+ c, s := localPipe(t)
+
+ go func(host string) {
+ Client(c, &Config{ServerName: host, InsecureSkipVerify: true}).Handshake()
+ }(tt.in)
+
+ var header [5]byte
+ if _, err := io.ReadFull(s, header[:]); err != nil {
+ t.Fatal(err)
+ }
+ recordLen := int(header[3])<<8 | int(header[4])
+
+ record := make([]byte, recordLen)
+ if _, err := io.ReadFull(s, record[:]); err != nil {
+ t.Fatal(err)
+ }
+
+ c.Close()
+ s.Close()
+
+ var m clientHelloMsg
+ if !m.unmarshal(record) {
+ t.Errorf("unmarshaling ClientHello for %q failed", tt.in)
+ continue
+ }
+ if tt.in != tt.out && m.serverName == tt.in {
+ t.Errorf("prohibited %q found in ClientHello: %x", tt.in, record)
+ }
+ if m.serverName != tt.out {
+ t.Errorf("expected %q not found in ClientHello: %x", tt.out, record)
+ }
+ }
+}
+
+func TestServerSelectingUnconfiguredCipherSuite(t *testing.T) {
+ // This checks that the server can't select a cipher suite that the
+ // client didn't offer. See #13174.
+
+ c, s := localPipe(t)
+ errChan := make(chan error, 1)
+
+ go func() {
+ client := Client(c, &Config{
+ ServerName: "foo",
+ CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
+ })
+ errChan <- client.Handshake()
+ }()
+
+ var header [5]byte
+ if _, err := io.ReadFull(s, header[:]); err != nil {
+ t.Fatal(err)
+ }
+ recordLen := int(header[3])<<8 | int(header[4])
+
+ record := make([]byte, recordLen)
+ if _, err := io.ReadFull(s, record); err != nil {
+ t.Fatal(err)
+ }
+
+ // Create a ServerHello that selects a different cipher suite than the
+ // sole one that the client offered.
+ serverHello := &serverHelloMsg{
+ vers: VersionTLS12,
+ random: make([]byte, 32),
+ cipherSuite: TLS_RSA_WITH_AES_256_GCM_SHA384,
+ }
+ serverHelloBytes := mustMarshal(t, serverHello)
+
+ s.Write([]byte{
+ byte(recordTypeHandshake),
+ byte(VersionTLS12 >> 8),
+ byte(VersionTLS12 & 0xff),
+ byte(len(serverHelloBytes) >> 8),
+ byte(len(serverHelloBytes)),
+ })
+ s.Write(serverHelloBytes)
+ s.Close()
+
+ if err := <-errChan; !strings.Contains(err.Error(), "unconfigured cipher") {
+ t.Fatalf("Expected error about unconfigured cipher suite but got %q", err)
+ }
+}
+
+func TestVerifyConnection(t *testing.T) {
+ t.Run("TLSv12", func(t *testing.T) { testVerifyConnection(t, VersionTLS12) })
+ t.Run("TLSv13", func(t *testing.T) { testVerifyConnection(t, VersionTLS13) })
+}
+
+func testVerifyConnection(t *testing.T, version uint16) {
+ checkFields := func(c ConnectionState, called *int, errorType string) error {
+ if c.Version != version {
+ return fmt.Errorf("%s: got Version %v, want %v", errorType, c.Version, version)
+ }
+ if c.HandshakeComplete {
+ return fmt.Errorf("%s: got HandshakeComplete, want false", errorType)
+ }
+ if c.ServerName != "example.golang" {
+ return fmt.Errorf("%s: got ServerName %s, want %s", errorType, c.ServerName, "example.golang")
+ }
+ if c.NegotiatedProtocol != "protocol1" {
+ return fmt.Errorf("%s: got NegotiatedProtocol %s, want %s", errorType, c.NegotiatedProtocol, "protocol1")
+ }
+ if c.CipherSuite == 0 {
+ return fmt.Errorf("%s: got CipherSuite 0, want non-zero", errorType)
+ }
+ wantDidResume := false
+ if *called == 2 { // if this is the second time, then it should be a resumption
+ wantDidResume = true
+ }
+ if c.DidResume != wantDidResume {
+ return fmt.Errorf("%s: got DidResume %t, want %t", errorType, c.DidResume, wantDidResume)
+ }
+ return nil
+ }
+
+ tests := []struct {
+ name string
+ configureServer func(*Config, *int)
+ configureClient func(*Config, *int)
+ }{
+ {
+ name: "RequireAndVerifyClientCert",
+ configureServer: func(config *Config, called *int) {
+ config.ClientAuth = RequireAndVerifyClientCert
+ config.VerifyConnection = func(c ConnectionState) error {
+ *called++
+ if l := len(c.PeerCertificates); l != 1 {
+ return fmt.Errorf("server: got len(PeerCertificates) = %d, wanted 1", l)
+ }
+ if len(c.VerifiedChains) == 0 {
+ return fmt.Errorf("server: got len(VerifiedChains) = 0, wanted non-zero")
+ }
+ return checkFields(c, called, "server")
+ }
+ },
+ configureClient: func(config *Config, called *int) {
+ config.VerifyConnection = func(c ConnectionState) error {
+ *called++
+ if l := len(c.PeerCertificates); l != 1 {
+ return fmt.Errorf("client: got len(PeerCertificates) = %d, wanted 1", l)
+ }
+ if len(c.VerifiedChains) == 0 {
+ return fmt.Errorf("client: got len(VerifiedChains) = 0, wanted non-zero")
+ }
+ if c.DidResume {
+ return nil
+ // The SCTs and OCSP Response are dropped on resumption.
+ // See http://golang.org/issue/39075.
+ }
+ if len(c.OCSPResponse) == 0 {
+ return fmt.Errorf("client: got len(OCSPResponse) = 0, wanted non-zero")
+ }
+ if len(c.SignedCertificateTimestamps) == 0 {
+ return fmt.Errorf("client: got len(SignedCertificateTimestamps) = 0, wanted non-zero")
+ }
+ return checkFields(c, called, "client")
+ }
+ },
+ },
+ {
+ name: "InsecureSkipVerify",
+ configureServer: func(config *Config, called *int) {
+ config.ClientAuth = RequireAnyClientCert
+ config.InsecureSkipVerify = true
+ config.VerifyConnection = func(c ConnectionState) error {
+ *called++
+ if l := len(c.PeerCertificates); l != 1 {
+ return fmt.Errorf("server: got len(PeerCertificates) = %d, wanted 1", l)
+ }
+ if c.VerifiedChains != nil {
+ return fmt.Errorf("server: got Verified Chains %v, want nil", c.VerifiedChains)
+ }
+ return checkFields(c, called, "server")
+ }
+ },
+ configureClient: func(config *Config, called *int) {
+ config.InsecureSkipVerify = true
+ config.VerifyConnection = func(c ConnectionState) error {
+ *called++
+ if l := len(c.PeerCertificates); l != 1 {
+ return fmt.Errorf("client: got len(PeerCertificates) = %d, wanted 1", l)
+ }
+ if c.VerifiedChains != nil {
+ return fmt.Errorf("server: got Verified Chains %v, want nil", c.VerifiedChains)
+ }
+ if c.DidResume {
+ return nil
+ // The SCTs and OCSP Response are dropped on resumption.
+ // See http://golang.org/issue/39075.
+ }
+ if len(c.OCSPResponse) == 0 {
+ return fmt.Errorf("client: got len(OCSPResponse) = 0, wanted non-zero")
+ }
+ if len(c.SignedCertificateTimestamps) == 0 {
+ return fmt.Errorf("client: got len(SignedCertificateTimestamps) = 0, wanted non-zero")
+ }
+ return checkFields(c, called, "client")
+ }
+ },
+ },
+ {
+ name: "NoClientCert",
+ configureServer: func(config *Config, called *int) {
+ config.ClientAuth = NoClientCert
+ config.VerifyConnection = func(c ConnectionState) error {
+ *called++
+ return checkFields(c, called, "server")
+ }
+ },
+ configureClient: func(config *Config, called *int) {
+ config.VerifyConnection = func(c ConnectionState) error {
+ *called++
+ return checkFields(c, called, "client")
+ }
+ },
+ },
+ {
+ name: "RequestClientCert",
+ configureServer: func(config *Config, called *int) {
+ config.ClientAuth = RequestClientCert
+ config.VerifyConnection = func(c ConnectionState) error {
+ *called++
+ return checkFields(c, called, "server")
+ }
+ },
+ configureClient: func(config *Config, called *int) {
+ config.Certificates = nil // clear the client cert
+ config.VerifyConnection = func(c ConnectionState) error {
+ *called++
+ if l := len(c.PeerCertificates); l != 1 {
+ return fmt.Errorf("client: got len(PeerCertificates) = %d, wanted 1", l)
+ }
+ if len(c.VerifiedChains) == 0 {
+ return fmt.Errorf("client: got len(VerifiedChains) = 0, wanted non-zero")
+ }
+ if c.DidResume {
+ return nil
+ // The SCTs and OCSP Response are dropped on resumption.
+ // See http://golang.org/issue/39075.
+ }
+ if len(c.OCSPResponse) == 0 {
+ return fmt.Errorf("client: got len(OCSPResponse) = 0, wanted non-zero")
+ }
+ if len(c.SignedCertificateTimestamps) == 0 {
+ return fmt.Errorf("client: got len(SignedCertificateTimestamps) = 0, wanted non-zero")
+ }
+ return checkFields(c, called, "client")
+ }
+ },
+ },
+ }
+ for _, test := range tests {
+ issuer, err := x509.ParseCertificate(testRSACertificateIssuer)
+ if err != nil {
+ panic(err)
+ }
+ rootCAs := x509.NewCertPool()
+ rootCAs.AddCert(issuer)
+
+ var serverCalled, clientCalled int
+
+ serverConfig := &Config{
+ MaxVersion: version,
+ Certificates: []Certificate{testConfig.Certificates[0]},
+ ClientCAs: rootCAs,
+ NextProtos: []string{"protocol1"},
+ }
+ serverConfig.Certificates[0].SignedCertificateTimestamps = [][]byte{[]byte("dummy sct 1"), []byte("dummy sct 2")}
+ serverConfig.Certificates[0].OCSPStaple = []byte("dummy ocsp")
+ test.configureServer(serverConfig, &serverCalled)
+
+ clientConfig := &Config{
+ MaxVersion: version,
+ ClientSessionCache: NewLRUClientSessionCache(32),
+ RootCAs: rootCAs,
+ ServerName: "example.golang",
+ Certificates: []Certificate{testConfig.Certificates[0]},
+ NextProtos: []string{"protocol1"},
+ }
+ test.configureClient(clientConfig, &clientCalled)
+
+ testHandshakeState := func(name string, didResume bool) {
+ _, hs, err := testHandshake(t, clientConfig, serverConfig)
+ if err != nil {
+ t.Fatalf("%s: handshake failed: %s", name, err)
+ }
+ if hs.DidResume != didResume {
+ t.Errorf("%s: resumed: %v, expected: %v", name, hs.DidResume, didResume)
+ }
+ wantCalled := 1
+ if didResume {
+ wantCalled = 2 // resumption would mean this is the second time it was called in this test
+ }
+ if clientCalled != wantCalled {
+ t.Errorf("%s: expected client VerifyConnection called %d times, did %d times", name, wantCalled, clientCalled)
+ }
+ if serverCalled != wantCalled {
+ t.Errorf("%s: expected server VerifyConnection called %d times, did %d times", name, wantCalled, serverCalled)
+ }
+ }
+ testHandshakeState(fmt.Sprintf("%s-FullHandshake", test.name), false)
+ testHandshakeState(fmt.Sprintf("%s-Resumption", test.name), true)
+ }
+}
+
+func TestVerifyPeerCertificate(t *testing.T) {
+ t.Run("TLSv12", func(t *testing.T) { testVerifyPeerCertificate(t, VersionTLS12) })
+ t.Run("TLSv13", func(t *testing.T) { testVerifyPeerCertificate(t, VersionTLS13) })
+}
+
+func testVerifyPeerCertificate(t *testing.T, version uint16) {
+ issuer, err := x509.ParseCertificate(testRSACertificateIssuer)
+ if err != nil {
+ panic(err)
+ }
+
+ rootCAs := x509.NewCertPool()
+ rootCAs.AddCert(issuer)
+
+ now := func() time.Time { return time.Unix(1476984729, 0) }
+
+ sentinelErr := errors.New("TestVerifyPeerCertificate")
+
+ verifyPeerCertificateCallback := func(called *bool, rawCerts [][]byte, validatedChains [][]*x509.Certificate) error {
+ if l := len(rawCerts); l != 1 {
+ return fmt.Errorf("got len(rawCerts) = %d, wanted 1", l)
+ }
+ if len(validatedChains) == 0 {
+ return errors.New("got len(validatedChains) = 0, wanted non-zero")
+ }
+ *called = true
+ return nil
+ }
+ verifyConnectionCallback := func(called *bool, isClient bool, c ConnectionState) error {
+ if l := len(c.PeerCertificates); l != 1 {
+ return fmt.Errorf("got len(PeerCertificates) = %d, wanted 1", l)
+ }
+ if len(c.VerifiedChains) == 0 {
+ return fmt.Errorf("got len(VerifiedChains) = 0, wanted non-zero")
+ }
+ if isClient && len(c.OCSPResponse) == 0 {
+ return fmt.Errorf("got len(OCSPResponse) = 0, wanted non-zero")
+ }
+ *called = true
+ return nil
+ }
+
+ tests := []struct {
+ configureServer func(*Config, *bool)
+ configureClient func(*Config, *bool)
+ validate func(t *testing.T, testNo int, clientCalled, serverCalled bool, clientErr, serverErr error)
+ }{
+ {
+ configureServer: func(config *Config, called *bool) {
+ config.InsecureSkipVerify = false
+ config.VerifyPeerCertificate = func(rawCerts [][]byte, validatedChains [][]*x509.Certificate) error {
+ return verifyPeerCertificateCallback(called, rawCerts, validatedChains)
+ }
+ },
+ configureClient: func(config *Config, called *bool) {
+ config.InsecureSkipVerify = false
+ config.VerifyPeerCertificate = func(rawCerts [][]byte, validatedChains [][]*x509.Certificate) error {
+ return verifyPeerCertificateCallback(called, rawCerts, validatedChains)
+ }
+ },
+ validate: func(t *testing.T, testNo int, clientCalled, serverCalled bool, clientErr, serverErr error) {
+ if clientErr != nil {
+ t.Errorf("test[%d]: client handshake failed: %v", testNo, clientErr)
+ }
+ if serverErr != nil {
+ t.Errorf("test[%d]: server handshake failed: %v", testNo, serverErr)
+ }
+ if !clientCalled {
+ t.Errorf("test[%d]: client did not call callback", testNo)
+ }
+ if !serverCalled {
+ t.Errorf("test[%d]: server did not call callback", testNo)
+ }
+ },
+ },
+ {
+ configureServer: func(config *Config, called *bool) {
+ config.InsecureSkipVerify = false
+ config.VerifyPeerCertificate = func(rawCerts [][]byte, validatedChains [][]*x509.Certificate) error {
+ return sentinelErr
+ }
+ },
+ configureClient: func(config *Config, called *bool) {
+ config.VerifyPeerCertificate = nil
+ },
+ validate: func(t *testing.T, testNo int, clientCalled, serverCalled bool, clientErr, serverErr error) {
+ if serverErr != sentinelErr {
+ t.Errorf("#%d: got server error %v, wanted sentinelErr", testNo, serverErr)
+ }
+ },
+ },
+ {
+ configureServer: func(config *Config, called *bool) {
+ config.InsecureSkipVerify = false
+ },
+ configureClient: func(config *Config, called *bool) {
+ config.VerifyPeerCertificate = func(rawCerts [][]byte, validatedChains [][]*x509.Certificate) error {
+ return sentinelErr
+ }
+ },
+ validate: func(t *testing.T, testNo int, clientCalled, serverCalled bool, clientErr, serverErr error) {
+ if clientErr != sentinelErr {
+ t.Errorf("#%d: got client error %v, wanted sentinelErr", testNo, clientErr)
+ }
+ },
+ },
+ {
+ configureServer: func(config *Config, called *bool) {
+ config.InsecureSkipVerify = false
+ },
+ configureClient: func(config *Config, called *bool) {
+ config.InsecureSkipVerify = true
+ config.VerifyPeerCertificate = func(rawCerts [][]byte, validatedChains [][]*x509.Certificate) error {
+ if l := len(rawCerts); l != 1 {
+ return fmt.Errorf("got len(rawCerts) = %d, wanted 1", l)
+ }
+ // With InsecureSkipVerify set, this
+ // callback should still be called but
+ // validatedChains must be empty.
+ if l := len(validatedChains); l != 0 {
+ return fmt.Errorf("got len(validatedChains) = %d, wanted zero", l)
+ }
+ *called = true
+ return nil
+ }
+ },
+ validate: func(t *testing.T, testNo int, clientCalled, serverCalled bool, clientErr, serverErr error) {
+ if clientErr != nil {
+ t.Errorf("test[%d]: client handshake failed: %v", testNo, clientErr)
+ }
+ if serverErr != nil {
+ t.Errorf("test[%d]: server handshake failed: %v", testNo, serverErr)
+ }
+ if !clientCalled {
+ t.Errorf("test[%d]: client did not call callback", testNo)
+ }
+ },
+ },
+ {
+ configureServer: func(config *Config, called *bool) {
+ config.InsecureSkipVerify = false
+ config.VerifyConnection = func(c ConnectionState) error {
+ return verifyConnectionCallback(called, false, c)
+ }
+ },
+ configureClient: func(config *Config, called *bool) {
+ config.InsecureSkipVerify = false
+ config.VerifyConnection = func(c ConnectionState) error {
+ return verifyConnectionCallback(called, true, c)
+ }
+ },
+ validate: func(t *testing.T, testNo int, clientCalled, serverCalled bool, clientErr, serverErr error) {
+ if clientErr != nil {
+ t.Errorf("test[%d]: client handshake failed: %v", testNo, clientErr)
+ }
+ if serverErr != nil {
+ t.Errorf("test[%d]: server handshake failed: %v", testNo, serverErr)
+ }
+ if !clientCalled {
+ t.Errorf("test[%d]: client did not call callback", testNo)
+ }
+ if !serverCalled {
+ t.Errorf("test[%d]: server did not call callback", testNo)
+ }
+ },
+ },
+ {
+ configureServer: func(config *Config, called *bool) {
+ config.InsecureSkipVerify = false
+ config.VerifyConnection = func(c ConnectionState) error {
+ return sentinelErr
+ }
+ },
+ configureClient: func(config *Config, called *bool) {
+ config.InsecureSkipVerify = false
+ config.VerifyConnection = nil
+ },
+ validate: func(t *testing.T, testNo int, clientCalled, serverCalled bool, clientErr, serverErr error) {
+ if serverErr != sentinelErr {
+ t.Errorf("#%d: got server error %v, wanted sentinelErr", testNo, serverErr)
+ }
+ },
+ },
+ {
+ configureServer: func(config *Config, called *bool) {
+ config.InsecureSkipVerify = false
+ config.VerifyConnection = nil
+ },
+ configureClient: func(config *Config, called *bool) {
+ config.InsecureSkipVerify = false
+ config.VerifyConnection = func(c ConnectionState) error {
+ return sentinelErr
+ }
+ },
+ validate: func(t *testing.T, testNo int, clientCalled, serverCalled bool, clientErr, serverErr error) {
+ if clientErr != sentinelErr {
+ t.Errorf("#%d: got client error %v, wanted sentinelErr", testNo, clientErr)
+ }
+ },
+ },
+ {
+ configureServer: func(config *Config, called *bool) {
+ config.InsecureSkipVerify = false
+ config.VerifyPeerCertificate = func(rawCerts [][]byte, validatedChains [][]*x509.Certificate) error {
+ return verifyPeerCertificateCallback(called, rawCerts, validatedChains)
+ }
+ config.VerifyConnection = func(c ConnectionState) error {
+ return sentinelErr
+ }
+ },
+ configureClient: func(config *Config, called *bool) {
+ config.InsecureSkipVerify = false
+ config.VerifyPeerCertificate = nil
+ config.VerifyConnection = nil
+ },
+ validate: func(t *testing.T, testNo int, clientCalled, serverCalled bool, clientErr, serverErr error) {
+ if serverErr != sentinelErr {
+ t.Errorf("#%d: got server error %v, wanted sentinelErr", testNo, serverErr)
+ }
+ if !serverCalled {
+ t.Errorf("test[%d]: server did not call callback", testNo)
+ }
+ },
+ },
+ {
+ configureServer: func(config *Config, called *bool) {
+ config.InsecureSkipVerify = false
+ config.VerifyPeerCertificate = nil
+ config.VerifyConnection = nil
+ },
+ configureClient: func(config *Config, called *bool) {
+ config.InsecureSkipVerify = false
+ config.VerifyPeerCertificate = func(rawCerts [][]byte, validatedChains [][]*x509.Certificate) error {
+ return verifyPeerCertificateCallback(called, rawCerts, validatedChains)
+ }
+ config.VerifyConnection = func(c ConnectionState) error {
+ return sentinelErr
+ }
+ },
+ validate: func(t *testing.T, testNo int, clientCalled, serverCalled bool, clientErr, serverErr error) {
+ if clientErr != sentinelErr {
+ t.Errorf("#%d: got client error %v, wanted sentinelErr", testNo, clientErr)
+ }
+ if !clientCalled {
+ t.Errorf("test[%d]: client did not call callback", testNo)
+ }
+ },
+ },
+ }
+
+ for i, test := range tests {
+ c, s := localPipe(t)
+ done := make(chan error)
+
+ var clientCalled, serverCalled bool
+
+ go func() {
+ config := testConfig.Clone()
+ config.ServerName = "example.golang"
+ config.ClientAuth = RequireAndVerifyClientCert
+ config.ClientCAs = rootCAs
+ config.Time = now
+ config.MaxVersion = version
+ config.Certificates = make([]Certificate, 1)
+ config.Certificates[0].Certificate = [][]byte{testRSACertificate}
+ config.Certificates[0].PrivateKey = testRSAPrivateKey
+ config.Certificates[0].SignedCertificateTimestamps = [][]byte{[]byte("dummy sct 1"), []byte("dummy sct 2")}
+ config.Certificates[0].OCSPStaple = []byte("dummy ocsp")
+ test.configureServer(config, &serverCalled)
+
+ err = Server(s, config).Handshake()
+ s.Close()
+ done <- err
+ }()
+
+ config := testConfig.Clone()
+ config.ServerName = "example.golang"
+ config.RootCAs = rootCAs
+ config.Time = now
+ config.MaxVersion = version
+ test.configureClient(config, &clientCalled)
+ clientErr := Client(c, config).Handshake()
+ c.Close()
+ serverErr := <-done
+
+ test.validate(t, i, clientCalled, serverCalled, clientErr, serverErr)
+ }
+}
+
+// brokenConn wraps a net.Conn and causes all Writes after a certain number to
+// fail with brokenConnErr.
+type brokenConn struct {
+ net.Conn
+
+ // breakAfter is the number of successful writes that will be allowed
+ // before all subsequent writes fail.
+ breakAfter int
+
+ // numWrites is the number of writes that have been done.
+ numWrites int
+}
+
+// brokenConnErr is the error that brokenConn returns once exhausted.
+var brokenConnErr = errors.New("too many writes to brokenConn")
+
+func (b *brokenConn) Write(data []byte) (int, error) {
+ if b.numWrites >= b.breakAfter {
+ return 0, brokenConnErr
+ }
+
+ b.numWrites++
+ return b.Conn.Write(data)
+}
+
+func TestFailedWrite(t *testing.T) {
+ // Test that a write error during the handshake is returned.
+ for _, breakAfter := range []int{0, 1} {
+ c, s := localPipe(t)
+ done := make(chan bool)
+
+ go func() {
+ Server(s, testConfig).Handshake()
+ s.Close()
+ done <- true
+ }()
+
+ brokenC := &brokenConn{Conn: c, breakAfter: breakAfter}
+ err := Client(brokenC, testConfig).Handshake()
+ if err != brokenConnErr {
+ t.Errorf("#%d: expected error from brokenConn but got %q", breakAfter, err)
+ }
+ brokenC.Close()
+
+ <-done
+ }
+}
+
+// writeCountingConn wraps a net.Conn and counts the number of Write calls.
+type writeCountingConn struct {
+ net.Conn
+
+ // numWrites is the number of writes that have been done.
+ numWrites int
+}
+
+func (wcc *writeCountingConn) Write(data []byte) (int, error) {
+ wcc.numWrites++
+ return wcc.Conn.Write(data)
+}
+
+func TestBuffering(t *testing.T) {
+ t.Run("TLSv12", func(t *testing.T) { testBuffering(t, VersionTLS12) })
+ t.Run("TLSv13", func(t *testing.T) { testBuffering(t, VersionTLS13) })
+}
+
+func testBuffering(t *testing.T, version uint16) {
+ c, s := localPipe(t)
+ done := make(chan bool)
+
+ clientWCC := &writeCountingConn{Conn: c}
+ serverWCC := &writeCountingConn{Conn: s}
+
+ go func() {
+ config := testConfig.Clone()
+ config.MaxVersion = version
+ Server(serverWCC, config).Handshake()
+ serverWCC.Close()
+ done <- true
+ }()
+
+ err := Client(clientWCC, testConfig).Handshake()
+ if err != nil {
+ t.Fatal(err)
+ }
+ clientWCC.Close()
+ <-done
+
+ var expectedClient, expectedServer int
+ if version == VersionTLS13 {
+ expectedClient = 2
+ expectedServer = 1
+ } else {
+ expectedClient = 2
+ expectedServer = 2
+ }
+
+ if n := clientWCC.numWrites; n != expectedClient {
+ t.Errorf("expected client handshake to complete with %d writes, but saw %d", expectedClient, n)
+ }
+
+ if n := serverWCC.numWrites; n != expectedServer {
+ t.Errorf("expected server handshake to complete with %d writes, but saw %d", expectedServer, n)
+ }
+}
+
+func TestAlertFlushing(t *testing.T) {
+ c, s := localPipe(t)
+ done := make(chan bool)
+
+ clientWCC := &writeCountingConn{Conn: c}
+ serverWCC := &writeCountingConn{Conn: s}
+
+ serverConfig := testConfig.Clone()
+
+ // Cause a signature-time error
+ brokenKey := rsa.PrivateKey{PublicKey: testRSAPrivateKey.PublicKey}
+ brokenKey.D = big.NewInt(42)
+ serverConfig.Certificates = []Certificate{{
+ Certificate: [][]byte{testRSACertificate},
+ PrivateKey: &brokenKey,
+ }}
+
+ go func() {
+ Server(serverWCC, serverConfig).Handshake()
+ serverWCC.Close()
+ done <- true
+ }()
+
+ err := Client(clientWCC, testConfig).Handshake()
+ if err == nil {
+ t.Fatal("client unexpectedly returned no error")
+ }
+
+ const expectedError = "remote error: tls: internal error"
+ if e := err.Error(); !strings.Contains(e, expectedError) {
+ t.Fatalf("expected to find %q in error but error was %q", expectedError, e)
+ }
+ clientWCC.Close()
+ <-done
+
+ if n := serverWCC.numWrites; n != 1 {
+ t.Errorf("expected server handshake to complete with one write, but saw %d", n)
+ }
+}
+
+func TestHandshakeRace(t *testing.T) {
+ if testing.Short() {
+ t.Skip("skipping in -short mode")
+ }
+ t.Parallel()
+ // This test races a Read and Write to try and complete a handshake in
+ // order to provide some evidence that there are no races or deadlocks
+ // in the handshake locking.
+ for i := 0; i < 32; i++ {
+ c, s := localPipe(t)
+
+ go func() {
+ server := Server(s, testConfig)
+ if err := server.Handshake(); err != nil {
+ panic(err)
+ }
+
+ var request [1]byte
+ if n, err := server.Read(request[:]); err != nil || n != 1 {
+ panic(err)
+ }
+
+ server.Write(request[:])
+ server.Close()
+ }()
+
+ startWrite := make(chan struct{})
+ startRead := make(chan struct{})
+ readDone := make(chan struct{}, 1)
+
+ client := Client(c, testConfig)
+ go func() {
+ <-startWrite
+ var request [1]byte
+ client.Write(request[:])
+ }()
+
+ go func() {
+ <-startRead
+ var reply [1]byte
+ if _, err := io.ReadFull(client, reply[:]); err != nil {
+ panic(err)
+ }
+ c.Close()
+ readDone <- struct{}{}
+ }()
+
+ if i&1 == 1 {
+ startWrite <- struct{}{}
+ startRead <- struct{}{}
+ } else {
+ startRead <- struct{}{}
+ startWrite <- struct{}{}
+ }
+ <-readDone
+ }
+}
+
+var getClientCertificateTests = []struct {
+ setup func(*Config, *Config)
+ expectedClientError string
+ verify func(*testing.T, int, *ConnectionState)
+}{
+ {
+ func(clientConfig, serverConfig *Config) {
+ // Returning a Certificate with no certificate data
+ // should result in an empty message being sent to the
+ // server.
+ serverConfig.ClientCAs = nil
+ clientConfig.GetClientCertificate = func(cri *CertificateRequestInfo) (*Certificate, error) {
+ if len(cri.SignatureSchemes) == 0 {
+ panic("empty SignatureSchemes")
+ }
+ if len(cri.AcceptableCAs) != 0 {
+ panic("AcceptableCAs should have been empty")
+ }
+ return new(Certificate), nil
+ }
+ },
+ "",
+ func(t *testing.T, testNum int, cs *ConnectionState) {
+ if l := len(cs.PeerCertificates); l != 0 {
+ t.Errorf("#%d: expected no certificates but got %d", testNum, l)
+ }
+ },
+ },
+ {
+ func(clientConfig, serverConfig *Config) {
+ // With TLS 1.1, the SignatureSchemes should be
+ // synthesised from the supported certificate types.
+ clientConfig.MaxVersion = VersionTLS11
+ clientConfig.GetClientCertificate = func(cri *CertificateRequestInfo) (*Certificate, error) {
+ if len(cri.SignatureSchemes) == 0 {
+ panic("empty SignatureSchemes")
+ }
+ return new(Certificate), nil
+ }
+ },
+ "",
+ func(t *testing.T, testNum int, cs *ConnectionState) {
+ if l := len(cs.PeerCertificates); l != 0 {
+ t.Errorf("#%d: expected no certificates but got %d", testNum, l)
+ }
+ },
+ },
+ {
+ func(clientConfig, serverConfig *Config) {
+ // Returning an error should abort the handshake with
+ // that error.
+ clientConfig.GetClientCertificate = func(cri *CertificateRequestInfo) (*Certificate, error) {
+ return nil, errors.New("GetClientCertificate")
+ }
+ },
+ "GetClientCertificate",
+ func(t *testing.T, testNum int, cs *ConnectionState) {
+ },
+ },
+ {
+ func(clientConfig, serverConfig *Config) {
+ clientConfig.GetClientCertificate = func(cri *CertificateRequestInfo) (*Certificate, error) {
+ if len(cri.AcceptableCAs) == 0 {
+ panic("empty AcceptableCAs")
+ }
+ cert := &Certificate{
+ Certificate: [][]byte{testRSACertificate},
+ PrivateKey: testRSAPrivateKey,
+ }
+ return cert, nil
+ }
+ },
+ "",
+ func(t *testing.T, testNum int, cs *ConnectionState) {
+ if len(cs.VerifiedChains) == 0 {
+ t.Errorf("#%d: expected some verified chains, but found none", testNum)
+ }
+ },
+ },
+}
+
+func TestGetClientCertificate(t *testing.T) {
+ t.Run("TLSv12", func(t *testing.T) { testGetClientCertificate(t, VersionTLS12) })
+ t.Run("TLSv13", func(t *testing.T) { testGetClientCertificate(t, VersionTLS13) })
+}
+
+func testGetClientCertificate(t *testing.T, version uint16) {
+ issuer, err := x509.ParseCertificate(testRSACertificateIssuer)
+ if err != nil {
+ panic(err)
+ }
+
+ for i, test := range getClientCertificateTests {
+ serverConfig := testConfig.Clone()
+ serverConfig.ClientAuth = VerifyClientCertIfGiven
+ serverConfig.RootCAs = x509.NewCertPool()
+ serverConfig.RootCAs.AddCert(issuer)
+ serverConfig.ClientCAs = serverConfig.RootCAs
+ serverConfig.Time = func() time.Time { return time.Unix(1476984729, 0) }
+ serverConfig.MaxVersion = version
+
+ clientConfig := testConfig.Clone()
+ clientConfig.MaxVersion = version
+
+ test.setup(clientConfig, serverConfig)
+
+ type serverResult struct {
+ cs ConnectionState
+ err error
+ }
+
+ c, s := localPipe(t)
+ done := make(chan serverResult)
+
+ go func() {
+ defer s.Close()
+ server := Server(s, serverConfig)
+ err := server.Handshake()
+
+ var cs ConnectionState
+ if err == nil {
+ cs = server.ConnectionState()
+ }
+ done <- serverResult{cs, err}
+ }()
+
+ clientErr := Client(c, clientConfig).Handshake()
+ c.Close()
+
+ result := <-done
+
+ if clientErr != nil {
+ if len(test.expectedClientError) == 0 {
+ t.Errorf("#%d: client error: %v", i, clientErr)
+ } else if got := clientErr.Error(); got != test.expectedClientError {
+ t.Errorf("#%d: expected client error %q, but got %q", i, test.expectedClientError, got)
+ } else {
+ test.verify(t, i, &result.cs)
+ }
+ } else if len(test.expectedClientError) > 0 {
+ t.Errorf("#%d: expected client error %q, but got no error", i, test.expectedClientError)
+ } else if err := result.err; err != nil {
+ t.Errorf("#%d: server error: %v", i, err)
+ } else {
+ test.verify(t, i, &result.cs)
+ }
+ }
+}
+
+func TestRSAPSSKeyError(t *testing.T) {
+ // crypto/tls does not support the rsa_pss_pss_* SignatureSchemes. If support for
+ // public keys with OID RSASSA-PSS is added to crypto/x509, they will be misused with
+ // the rsa_pss_rsae_* SignatureSchemes. Assert that RSASSA-PSS certificates don't
+ // parse, or that they don't carry *rsa.PublicKey keys.
+ b, _ := pem.Decode([]byte(`
+-----BEGIN CERTIFICATE-----
+MIIDZTCCAhygAwIBAgIUCF2x0FyTgZG0CC9QTDjGWkB5vgEwPgYJKoZIhvcNAQEK
+MDGgDTALBglghkgBZQMEAgGhGjAYBgkqhkiG9w0BAQgwCwYJYIZIAWUDBAIBogQC
+AgDeMBIxEDAOBgNVBAMMB1JTQS1QU1MwHhcNMTgwNjI3MjI0NDM2WhcNMTgwNzI3
+MjI0NDM2WjASMRAwDgYDVQQDDAdSU0EtUFNTMIIBIDALBgkqhkiG9w0BAQoDggEP
+ADCCAQoCggEBANxDm0f76JdI06YzsjB3AmmjIYkwUEGxePlafmIASFjDZl/elD0Z
+/a7xLX468b0qGxLS5al7XCcEprSdsDR6DF5L520+pCbpfLyPOjuOvGmk9KzVX4x5
+b05YXYuXdsQ0Kjxcx2i3jjCday6scIhMJVgBZxTEyMj1thPQM14SHzKCd/m6HmCL
+QmswpH2yMAAcBRWzRpp/vdH5DeOJEB3aelq7094no731mrLUCHRiZ1htq8BDB3ou
+czwqgwspbqZ4dnMXl2MvfySQ5wJUxQwILbiuAKO2lVVPUbFXHE9pgtznNoPvKwQT
+JNcX8ee8WIZc2SEGzofjk3NpjR+2ADB2u3sCAwEAAaNTMFEwHQYDVR0OBBYEFNEz
+AdyJ2f+fU+vSCS6QzohnOnprMB8GA1UdIwQYMBaAFNEzAdyJ2f+fU+vSCS6Qzohn
+OnprMA8GA1UdEwEB/wQFMAMBAf8wPgYJKoZIhvcNAQEKMDGgDTALBglghkgBZQME
+AgGhGjAYBgkqhkiG9w0BAQgwCwYJYIZIAWUDBAIBogQCAgDeA4IBAQCjEdrR5aab
+sZmCwrMeKidXgfkmWvfuLDE+TCbaqDZp7BMWcMQXT9O0UoUT5kqgKj2ARm2pEW0Z
+H3Z1vj3bbds72qcDIJXp+l0fekyLGeCrX/CbgnMZXEP7+/+P416p34ChR1Wz4dU1
+KD3gdsUuTKKeMUog3plxlxQDhRQmiL25ygH1LmjLd6dtIt0GVRGr8lj3euVeprqZ
+bZ3Uq5eLfsn8oPgfC57gpO6yiN+UURRTlK3bgYvLh4VWB3XXk9UaQZ7Mq1tpXjoD
+HYFybkWzibkZp4WRo+Fa28rirH+/wHt0vfeN7UCceURZEx4JaxIIfe4ku7uDRhJi
+RwBA9Xk1KBNF
+-----END CERTIFICATE-----`))
+ if b == nil {
+ t.Fatal("Failed to decode certificate")
+ }
+ cert, err := x509.ParseCertificate(b.Bytes)
+ if err != nil {
+ return
+ }
+ if _, ok := cert.PublicKey.(*rsa.PublicKey); ok {
+ t.Error("A RSASSA-PSS certificate was parsed like a PKCS#1 v1.5 one, and it will be mistakenly used with rsa_pss_rsae_* signature algorithms")
+ }
+}
+
+func TestCloseClientConnectionOnIdleServer(t *testing.T) {
+ clientConn, serverConn := localPipe(t)
+ client := Client(clientConn, testConfig.Clone())
+ go func() {
+ var b [1]byte
+ serverConn.Read(b[:])
+ client.Close()
+ }()
+ client.SetWriteDeadline(time.Now().Add(time.Minute))
+ err := client.Handshake()
+ if err != nil {
+ if err, ok := err.(net.Error); ok && err.Timeout() {
+ t.Errorf("Expected a closed network connection error but got '%s'", err.Error())
+ }
+ } else {
+ t.Errorf("Error expected, but no error returned")
+ }
+}
+
+func testDowngradeCanary(t *testing.T, clientVersion, serverVersion uint16) error {
+ defer func() { testingOnlyForceDowngradeCanary = false }()
+ testingOnlyForceDowngradeCanary = true
+
+ clientConfig := testConfig.Clone()
+ clientConfig.MaxVersion = clientVersion
+ serverConfig := testConfig.Clone()
+ serverConfig.MaxVersion = serverVersion
+ _, _, err := testHandshake(t, clientConfig, serverConfig)
+ return err
+}
+
+func TestDowngradeCanary(t *testing.T) {
+ if err := testDowngradeCanary(t, VersionTLS13, VersionTLS12); err == nil {
+ t.Errorf("downgrade from TLS 1.3 to TLS 1.2 was not detected")
+ }
+ if testing.Short() {
+ t.Skip("skipping the rest of the checks in short mode")
+ }
+ if err := testDowngradeCanary(t, VersionTLS13, VersionTLS11); err == nil {
+ t.Errorf("downgrade from TLS 1.3 to TLS 1.1 was not detected")
+ }
+ if err := testDowngradeCanary(t, VersionTLS13, VersionTLS10); err == nil {
+ t.Errorf("downgrade from TLS 1.3 to TLS 1.0 was not detected")
+ }
+ if err := testDowngradeCanary(t, VersionTLS12, VersionTLS11); err == nil {
+ t.Errorf("downgrade from TLS 1.2 to TLS 1.1 was not detected")
+ }
+ if err := testDowngradeCanary(t, VersionTLS12, VersionTLS10); err == nil {
+ t.Errorf("downgrade from TLS 1.2 to TLS 1.0 was not detected")
+ }
+ if err := testDowngradeCanary(t, VersionTLS13, VersionTLS13); err != nil {
+ t.Errorf("server unexpectedly sent downgrade canary for TLS 1.3")
+ }
+ if err := testDowngradeCanary(t, VersionTLS12, VersionTLS12); err != nil {
+ t.Errorf("client didn't ignore expected TLS 1.2 canary")
+ }
+ if err := testDowngradeCanary(t, VersionTLS11, VersionTLS11); err != nil {
+ t.Errorf("client unexpectedly reacted to a canary in TLS 1.1")
+ }
+ if err := testDowngradeCanary(t, VersionTLS10, VersionTLS10); err != nil {
+ t.Errorf("client unexpectedly reacted to a canary in TLS 1.0")
+ }
+}
+
+func TestResumptionKeepsOCSPAndSCT(t *testing.T) {
+ t.Run("TLSv12", func(t *testing.T) { testResumptionKeepsOCSPAndSCT(t, VersionTLS12) })
+ t.Run("TLSv13", func(t *testing.T) { testResumptionKeepsOCSPAndSCT(t, VersionTLS13) })
+}
+
+func testResumptionKeepsOCSPAndSCT(t *testing.T, ver uint16) {
+ issuer, err := x509.ParseCertificate(testRSACertificateIssuer)
+ if err != nil {
+ t.Fatalf("failed to parse test issuer")
+ }
+ roots := x509.NewCertPool()
+ roots.AddCert(issuer)
+ clientConfig := &Config{
+ MaxVersion: ver,
+ ClientSessionCache: NewLRUClientSessionCache(32),
+ ServerName: "example.golang",
+ RootCAs: roots,
+ }
+ serverConfig := testConfig.Clone()
+ serverConfig.MaxVersion = ver
+ serverConfig.Certificates[0].OCSPStaple = []byte{1, 2, 3}
+ serverConfig.Certificates[0].SignedCertificateTimestamps = [][]byte{{4, 5, 6}}
+
+ _, ccs, err := testHandshake(t, clientConfig, serverConfig)
+ if err != nil {
+ t.Fatalf("handshake failed: %s", err)
+ }
+ // after a new session we expect to see OCSPResponse and
+ // SignedCertificateTimestamps populated as usual
+ if !bytes.Equal(ccs.OCSPResponse, serverConfig.Certificates[0].OCSPStaple) {
+ t.Errorf("client ConnectionState contained unexpected OCSPResponse: wanted %v, got %v",
+ serverConfig.Certificates[0].OCSPStaple, ccs.OCSPResponse)
+ }
+ if !reflect.DeepEqual(ccs.SignedCertificateTimestamps, serverConfig.Certificates[0].SignedCertificateTimestamps) {
+ t.Errorf("client ConnectionState contained unexpected SignedCertificateTimestamps: wanted %v, got %v",
+ serverConfig.Certificates[0].SignedCertificateTimestamps, ccs.SignedCertificateTimestamps)
+ }
+
+ // if the server doesn't send any SCTs, repopulate the old SCTs
+ oldSCTs := serverConfig.Certificates[0].SignedCertificateTimestamps
+ serverConfig.Certificates[0].SignedCertificateTimestamps = nil
+ _, ccs, err = testHandshake(t, clientConfig, serverConfig)
+ if err != nil {
+ t.Fatalf("handshake failed: %s", err)
+ }
+ if !ccs.DidResume {
+ t.Fatalf("expected session to be resumed")
+ }
+ // after a resumed session we also expect to see OCSPResponse
+ // and SignedCertificateTimestamps populated
+ if !bytes.Equal(ccs.OCSPResponse, serverConfig.Certificates[0].OCSPStaple) {
+ t.Errorf("client ConnectionState contained unexpected OCSPResponse after resumption: wanted %v, got %v",
+ serverConfig.Certificates[0].OCSPStaple, ccs.OCSPResponse)
+ }
+ if !reflect.DeepEqual(ccs.SignedCertificateTimestamps, oldSCTs) {
+ t.Errorf("client ConnectionState contained unexpected SignedCertificateTimestamps after resumption: wanted %v, got %v",
+ oldSCTs, ccs.SignedCertificateTimestamps)
+ }
+
+ // Only test overriding the SCTs for TLS 1.2, since in 1.3
+ // the server won't send the message containing them
+ if ver == VersionTLS13 {
+ return
+ }
+
+ // if the server changes the SCTs it sends, they should override the saved SCTs
+ serverConfig.Certificates[0].SignedCertificateTimestamps = [][]byte{{7, 8, 9}}
+ _, ccs, err = testHandshake(t, clientConfig, serverConfig)
+ if err != nil {
+ t.Fatalf("handshake failed: %s", err)
+ }
+ if !ccs.DidResume {
+ t.Fatalf("expected session to be resumed")
+ }
+ if !reflect.DeepEqual(ccs.SignedCertificateTimestamps, serverConfig.Certificates[0].SignedCertificateTimestamps) {
+ t.Errorf("client ConnectionState contained unexpected SignedCertificateTimestamps after resumption: wanted %v, got %v",
+ serverConfig.Certificates[0].SignedCertificateTimestamps, ccs.SignedCertificateTimestamps)
+ }
+}
+
+// TestClientHandshakeContextCancellation tests that canceling
+// the context given to the client side conn.HandshakeContext
+// interrupts the in-progress handshake.
+func TestClientHandshakeContextCancellation(t *testing.T) {
+ c, s := localPipe(t)
+ ctx, cancel := context.WithCancel(context.Background())
+ unblockServer := make(chan struct{})
+ defer close(unblockServer)
+ go func() {
+ cancel()
+ <-unblockServer
+ _ = s.Close()
+ }()
+ cli := Client(c, testConfig)
+ // Initiates client side handshake, which will block until the client hello is read
+ // by the server, unless the cancellation works.
+ err := cli.HandshakeContext(ctx)
+ if err == nil {
+ t.Fatal("Client handshake did not error when the context was canceled")
+ }
+ if err != context.Canceled {
+ t.Errorf("Unexpected client handshake error: %v", err)
+ }
+ if runtime.GOARCH == "wasm" {
+ t.Skip("conn.Close does not error as expected when called multiple times on WASM")
+ }
+ err = cli.Close()
+ if err == nil {
+ t.Error("Client connection was not closed when the context was canceled")
+ }
+}
+
+// TestTLS13OnlyClientHelloCipherSuite tests that when a client states that
+// it only supports TLS 1.3, it correctly advertises only TLS 1.3 ciphers.
+func TestTLS13OnlyClientHelloCipherSuite(t *testing.T) {
+ tls13Tests := []struct {
+ name string
+ ciphers []uint16
+ }{
+ {
+ name: "nil",
+ ciphers: nil,
+ },
+ {
+ name: "empty",
+ ciphers: []uint16{},
+ },
+ {
+ name: "some TLS 1.2 cipher",
+ ciphers: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
+ },
+ {
+ name: "some TLS 1.3 cipher",
+ ciphers: []uint16{TLS_AES_128_GCM_SHA256},
+ },
+ {
+ name: "some TLS 1.2 and 1.3 ciphers",
+ ciphers: []uint16{TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_AES_256_GCM_SHA384},
+ },
+ }
+ for _, tt := range tls13Tests {
+ tt := tt
+ t.Run(tt.name, func(t *testing.T) {
+ t.Parallel()
+ testTLS13OnlyClientHelloCipherSuite(t, tt.ciphers)
+ })
+ }
+}
+
+func testTLS13OnlyClientHelloCipherSuite(t *testing.T, ciphers []uint16) {
+ serverConfig := &Config{
+ Certificates: testConfig.Certificates,
+ GetConfigForClient: func(chi *ClientHelloInfo) (*Config, error) {
+ if len(chi.CipherSuites) != len(defaultCipherSuitesTLS13NoAES) {
+ t.Errorf("only TLS 1.3 suites should be advertised, got=%x", chi.CipherSuites)
+ } else {
+ for i := range defaultCipherSuitesTLS13NoAES {
+ if want, got := defaultCipherSuitesTLS13NoAES[i], chi.CipherSuites[i]; want != got {
+ t.Errorf("cipher at index %d does not match, want=%x, got=%x", i, want, got)
+ }
+ }
+ }
+ return nil, nil
+ },
+ }
+ clientConfig := &Config{
+ MinVersion: VersionTLS13, // client only supports TLS 1.3
+ CipherSuites: ciphers,
+ InsecureSkipVerify: true,
+ }
+ if _, _, err := testHandshake(t, clientConfig, serverConfig); err != nil {
+ t.Fatalf("handshake failed: %s", err)
+ }
+}
+
+// discardConn wraps a net.Conn but discards all writes, but reports that they happened.
+type discardConn struct {
+ net.Conn
+}
+
+func (dc *discardConn) Write(data []byte) (int, error) {
+ return len(data), nil
+}
+
+// largeRSAKeyCertPEM contains a 8193 bit RSA key
+const largeRSAKeyCertPEM = `-----BEGIN CERTIFICATE-----
+MIIInjCCBIWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDEwd0ZXN0
+aW5nMB4XDTIzMDYwNzIxMjMzNloXDTIzMDYwNzIzMjMzNlowEjEQMA4GA1UEAxMH
+dGVzdGluZzCCBCIwDQYJKoZIhvcNAQEBBQADggQPADCCBAoCggQBAWdHsf6Rh2Ca
+n2SQwn4t4OQrOjbLLdGE1pM6TBKKrHUFy62uEL8atNjlcfXIsa4aEu3xNGiqxqur
+ZectlkZbm0FkaaQ1Wr9oikDY3KfjuaXdPdO/XC/h8AKNxlDOylyXwUSK/CuYb+1j
+gy8yF5QFvVfwW/xwTlHmhUeSkVSQPosfQ6yXNNsmMzkd+ZPWLrfq4R+wiNtwYGu0
+WSBcI/M9o8/vrNLnIppoiBJJ13j9CR1ToEAzOFh9wwRWLY10oZhoh1ONN1KQURx4
+qedzvvP2DSjZbUccdvl2rBGvZpzfOiFdm1FCnxB0c72Cqx+GTHXBFf8bsa7KHky9
+sNO1GUanbq17WoDNgwbY6H51bfShqv0CErxatwWox3we4EcAmFHPVTCYL1oWVMGo
+a3Eth91NZj+b/nGhF9lhHKGzXSv9brmLLkfvM1jA6XhNhA7BQ5Vz67lj2j3XfXdh
+t/BU5pBXbL4Ut4mIhT1YnKXAjX2/LF5RHQTE8Vwkx5JAEKZyUEGOReD/B+7GOrLp
+HduMT9vZAc5aR2k9I8qq1zBAzsL69lyQNAPaDYd1BIAjUety9gAYaSQffCgAgpRO
+Gt+DYvxS+7AT/yEd5h74MU2AH7KrAkbXOtlwupiGwhMVTstncDJWXMJqbBhyHPF8
+3UmZH0hbL4PYmzSj9LDWQQXI2tv6vrCpfts3Cqhqxz9vRpgY7t1Wu6l/r+KxYYz3
+1pcGpPvRmPh0DJm7cPTiXqPnZcPt+ulSaSdlxmd19OnvG5awp0fXhxryZVwuiT8G
+VDkhyARrxYrdjlINsZJZbQjO0t8ketXAELJOnbFXXzeCOosyOHkLwsqOO96AVJA8
+45ZVL5m95ClGy0RSrjVIkXsxTAMVG6SPAqKwk6vmTdRGuSPS4rhgckPVDHmccmuq
+dfnT2YkX+wB2/M3oCgU+s30fAHGkbGZ0pCdNbFYFZLiH0iiMbTDl/0L/z7IdK0nH
+GLHVE7apPraKC6xl6rPWsD2iSfrmtIPQa0+rqbIVvKP5JdfJ8J4alI+OxFw/znQe
+V0/Rez0j22Fe119LZFFSXhRv+ZSvcq20xDwh00mzcumPWpYuCVPozA18yIhC9tNn
+ALHndz0tDseIdy9vC71jQWy9iwri3ueN0DekMMF8JGzI1Z6BAFzgyAx3DkHtwHg7
+B7qD0jPG5hJ5+yt323fYgJsuEAYoZ8/jzZ01pkX8bt+UsVN0DGnSGsI2ktnIIk3J
+l+8krjmUy6EaW79nITwoOqaeHOIp8m3UkjEcoKOYrzHRKqRy+A09rY+m/cAQaafW
+4xp0Zv7qZPLwnu0jsqB4jD8Ll9yPB02ndsoV6U5PeHzTkVhPml19jKUAwFfs7TJg
+kXy+/xFhYVUCAwEAATANBgkqhkiG9w0BAQsFAAOCBAIAAQnZY77pMNeypfpba2WK
+aDasT7dk2JqP0eukJCVPTN24Zca+xJNPdzuBATm/8SdZK9lddIbjSnWRsKvTnO2r
+/rYdlPf3jM5uuJtb8+Uwwe1s+gszelGS9G/lzzq+ehWicRIq2PFcs8o3iQMfENiv
+qILJ+xjcrvms5ZPDNahWkfRx3KCg8Q+/at2n5p7XYjMPYiLKHnDC+RE2b1qT20IZ
+FhuK/fTWLmKbfYFNNga6GC4qcaZJ7x0pbm4SDTYp0tkhzcHzwKhidfNB5J2vNz6l
+Ur6wiYwamFTLqcOwWo7rdvI+sSn05WQBv0QZlzFX+OAu0l7WQ7yU+noOxBhjvHds
+14+r9qcQZg2q9kG+evopYZqYXRUNNlZKo9MRBXhfrISulFAc5lRFQIXMXnglvAu+
+Ipz2gomEAOcOPNNVldhKAU94GAMJd/KfN0ZP7gX3YvPzuYU6XDhag5RTohXLm18w
+5AF+ES3DOQ6ixu3DTf0D+6qrDuK+prdX8ivcdTQVNOQ+MIZeGSc6NWWOTaMGJ3lg
+aZIxJUGdo6E7GBGiC1YTjgFKFbHzek1LRTh/LX3vbSudxwaG0HQxwsU9T4DWiMqa
+Fkf2KteLEUA6HrR+0XlAZrhwoqAmrJ+8lCFX3V0gE9lpENfVHlFXDGyx10DpTB28
+DdjnY3F7EPWNzwf9P3oNT69CKW3Bk6VVr3ROOJtDxVu1ioWo3TaXltQ0VOnap2Pu
+sa5wfrpfwBDuAS9JCDg4ttNp2nW3F7tgXC6xPqw5pvGwUppEw9XNrqV8TZrxduuv
+rQ3NyZ7KSzIpmFlD3UwV/fGfz3UQmHS6Ng1evrUID9DjfYNfRqSGIGjDfxGtYD+j
+Z1gLJZuhjJpNtwBkKRtlNtrCWCJK2hidK/foxwD7kwAPo2I9FjpltxCRywZUs07X
+KwXTfBR9v6ij1LV6K58hFS+8ezZyZ05CeVBFkMQdclTOSfuPxlMkQOtjp8QWDj+F
+j/MYziT5KBkHvcbrjdRtUJIAi4N7zCsPZtjik918AK1WBNRVqPbrgq/XSEXMfuvs
+6JbfK0B76vdBDRtJFC1JsvnIrGbUztxXzyQwFLaR/AjVJqpVlysLWzPKWVX6/+SJ
+u1NQOl2E8P6ycyBsuGnO89p0S4F8cMRcI2X1XQsZ7/q0NBrOMaEp5T3SrWo9GiQ3
+o2SBdbs3Y6MBPBtTu977Z/0RO63J3M5i2tjUiDfrFy7+VRLKr7qQ7JibohyB8QaR
+9tedgjn2f+of7PnP/PEl1cCphUZeHM7QKUMPT8dbqwmKtlYY43EHXcvNOT5IBk3X
+9lwJoZk/B2i+ZMRNSP34ztAwtxmasPt6RAWGQpWCn9qmttAHAnMfDqe7F7jVR6rS
+u58=
+-----END CERTIFICATE-----`
+
+func TestHandshakeRSATooBig(t *testing.T) {
+ for _, tc := range []struct {
+ name string
+ godebug string
+ expectedServerErr string
+ expectedClientErr string
+ }{
+ {
+ name: "key too large",
+ expectedServerErr: "tls: server sent certificate containing RSA key larger than 8192 bits",
+ expectedClientErr: "tls: client sent certificate containing RSA key larger than 8192 bits",
+ },
+ {
+ name: "acceptable key (GODEBUG=tlsmaxrsasize=8193)",
+ godebug: "tlsmaxrsasize=8193",
+ },
+ } {
+ t.Run(tc.name, func(t *testing.T) {
+ if tc.godebug != "" {
+ t.Setenv("GODEBUG", tc.godebug)
+ }
+
+ testCert, _ := pem.Decode([]byte(largeRSAKeyCertPEM))
+
+ c := &Conn{conn: &discardConn{}, config: testConfig.Clone()}
+
+ err := c.verifyServerCertificate([][]byte{testCert.Bytes})
+ if tc.expectedServerErr == "" && err != nil {
+ t.Errorf("Conn.verifyServerCertificate unexpected error: %s", err)
+ } else if tc.expectedServerErr != "" && (err == nil || err.Error() != tc.expectedServerErr) {
+ t.Errorf("Conn.verifyServerCertificate unexpected error: want %q, got %q", tc.expectedServerErr, err)
+ }
+
+ err = c.processCertsFromClient(Certificate{Certificate: [][]byte{testCert.Bytes}})
+ if tc.expectedClientErr == "" && err != nil {
+ t.Errorf("Conn.processCertsFromClient unexpected error: %s", err)
+ } else if tc.expectedClientErr != "" && (err == nil || err.Error() != tc.expectedClientErr) {
+ t.Errorf("Conn.processCertsFromClient unexpected error: want %q, got %q", tc.expectedClientErr, err)
+ }
+ })
+ }
+}
diff --git a/src/crypto/tls/handshake_client_tls13.go b/src/crypto/tls/handshake_client_tls13.go
new file mode 100644
index 0000000..2f59f68
--- /dev/null
+++ b/src/crypto/tls/handshake_client_tls13.go
@@ -0,0 +1,772 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+ "bytes"
+ "context"
+ "crypto"
+ "crypto/ecdh"
+ "crypto/hmac"
+ "crypto/rsa"
+ "errors"
+ "hash"
+ "time"
+)
+
+type clientHandshakeStateTLS13 struct {
+ c *Conn
+ ctx context.Context
+ serverHello *serverHelloMsg
+ hello *clientHelloMsg
+ ecdheKey *ecdh.PrivateKey
+
+ session *SessionState
+ earlySecret []byte
+ binderKey []byte
+
+ certReq *certificateRequestMsgTLS13
+ usingPSK bool
+ sentDummyCCS bool
+ suite *cipherSuiteTLS13
+ transcript hash.Hash
+ masterSecret []byte
+ trafficSecret []byte // client_application_traffic_secret_0
+}
+
+// handshake requires hs.c, hs.hello, hs.serverHello, hs.ecdheKey, and,
+// optionally, hs.session, hs.earlySecret and hs.binderKey to be set.
+func (hs *clientHandshakeStateTLS13) handshake() error {
+ c := hs.c
+
+ if needFIPS() {
+ return errors.New("tls: internal error: TLS 1.3 reached in FIPS mode")
+ }
+
+ // The server must not select TLS 1.3 in a renegotiation. See RFC 8446,
+ // sections 4.1.2 and 4.1.3.
+ if c.handshakes > 0 {
+ c.sendAlert(alertProtocolVersion)
+ return errors.New("tls: server selected TLS 1.3 in a renegotiation")
+ }
+
+ // Consistency check on the presence of a keyShare and its parameters.
+ if hs.ecdheKey == nil || len(hs.hello.keyShares) != 1 {
+ return c.sendAlert(alertInternalError)
+ }
+
+ if err := hs.checkServerHelloOrHRR(); err != nil {
+ return err
+ }
+
+ hs.transcript = hs.suite.hash.New()
+
+ if err := transcriptMsg(hs.hello, hs.transcript); err != nil {
+ return err
+ }
+
+ if bytes.Equal(hs.serverHello.random, helloRetryRequestRandom) {
+ if err := hs.sendDummyChangeCipherSpec(); err != nil {
+ return err
+ }
+ if err := hs.processHelloRetryRequest(); err != nil {
+ return err
+ }
+ }
+
+ if err := transcriptMsg(hs.serverHello, hs.transcript); err != nil {
+ return err
+ }
+
+ c.buffering = true
+ if err := hs.processServerHello(); err != nil {
+ return err
+ }
+ if err := hs.sendDummyChangeCipherSpec(); err != nil {
+ return err
+ }
+ if err := hs.establishHandshakeKeys(); err != nil {
+ return err
+ }
+ if err := hs.readServerParameters(); err != nil {
+ return err
+ }
+ if err := hs.readServerCertificate(); err != nil {
+ return err
+ }
+ if err := hs.readServerFinished(); err != nil {
+ return err
+ }
+ if err := hs.sendClientCertificate(); err != nil {
+ return err
+ }
+ if err := hs.sendClientFinished(); err != nil {
+ return err
+ }
+ if _, err := c.flush(); err != nil {
+ return err
+ }
+
+ c.isHandshakeComplete.Store(true)
+
+ return nil
+}
+
+// checkServerHelloOrHRR does validity checks that apply to both ServerHello and
+// HelloRetryRequest messages. It sets hs.suite.
+func (hs *clientHandshakeStateTLS13) checkServerHelloOrHRR() error {
+ c := hs.c
+
+ if hs.serverHello.supportedVersion == 0 {
+ c.sendAlert(alertMissingExtension)
+ return errors.New("tls: server selected TLS 1.3 using the legacy version field")
+ }
+
+ if hs.serverHello.supportedVersion != VersionTLS13 {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: server selected an invalid version after a HelloRetryRequest")
+ }
+
+ if hs.serverHello.vers != VersionTLS12 {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: server sent an incorrect legacy version")
+ }
+
+ if hs.serverHello.ocspStapling ||
+ hs.serverHello.ticketSupported ||
+ hs.serverHello.extendedMasterSecret ||
+ hs.serverHello.secureRenegotiationSupported ||
+ len(hs.serverHello.secureRenegotiation) != 0 ||
+ len(hs.serverHello.alpnProtocol) != 0 ||
+ len(hs.serverHello.scts) != 0 {
+ c.sendAlert(alertUnsupportedExtension)
+ return errors.New("tls: server sent a ServerHello extension forbidden in TLS 1.3")
+ }
+
+ if !bytes.Equal(hs.hello.sessionId, hs.serverHello.sessionId) {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: server did not echo the legacy session ID")
+ }
+
+ if hs.serverHello.compressionMethod != compressionNone {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: server selected unsupported compression format")
+ }
+
+ selectedSuite := mutualCipherSuiteTLS13(hs.hello.cipherSuites, hs.serverHello.cipherSuite)
+ if hs.suite != nil && selectedSuite != hs.suite {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: server changed cipher suite after a HelloRetryRequest")
+ }
+ if selectedSuite == nil {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: server chose an unconfigured cipher suite")
+ }
+ hs.suite = selectedSuite
+ c.cipherSuite = hs.suite.id
+
+ return nil
+}
+
+// sendDummyChangeCipherSpec sends a ChangeCipherSpec record for compatibility
+// with middleboxes that didn't implement TLS correctly. See RFC 8446, Appendix D.4.
+func (hs *clientHandshakeStateTLS13) sendDummyChangeCipherSpec() error {
+ if hs.c.quic != nil {
+ return nil
+ }
+ if hs.sentDummyCCS {
+ return nil
+ }
+ hs.sentDummyCCS = true
+
+ return hs.c.writeChangeCipherRecord()
+}
+
+// processHelloRetryRequest handles the HRR in hs.serverHello, modifies and
+// resends hs.hello, and reads the new ServerHello into hs.serverHello.
+func (hs *clientHandshakeStateTLS13) processHelloRetryRequest() error {
+ c := hs.c
+
+ // The first ClientHello gets double-hashed into the transcript upon a
+ // HelloRetryRequest. (The idea is that the server might offload transcript
+ // storage to the client in the cookie.) See RFC 8446, Section 4.4.1.
+ chHash := hs.transcript.Sum(nil)
+ hs.transcript.Reset()
+ hs.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))})
+ hs.transcript.Write(chHash)
+ if err := transcriptMsg(hs.serverHello, hs.transcript); err != nil {
+ return err
+ }
+
+ // The only HelloRetryRequest extensions we support are key_share and
+ // cookie, and clients must abort the handshake if the HRR would not result
+ // in any change in the ClientHello.
+ if hs.serverHello.selectedGroup == 0 && hs.serverHello.cookie == nil {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: server sent an unnecessary HelloRetryRequest message")
+ }
+
+ if hs.serverHello.cookie != nil {
+ hs.hello.cookie = hs.serverHello.cookie
+ }
+
+ if hs.serverHello.serverShare.group != 0 {
+ c.sendAlert(alertDecodeError)
+ return errors.New("tls: received malformed key_share extension")
+ }
+
+ // If the server sent a key_share extension selecting a group, ensure it's
+ // a group we advertised but did not send a key share for, and send a key
+ // share for it this time.
+ if curveID := hs.serverHello.selectedGroup; curveID != 0 {
+ curveOK := false
+ for _, id := range hs.hello.supportedCurves {
+ if id == curveID {
+ curveOK = true
+ break
+ }
+ }
+ if !curveOK {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: server selected unsupported group")
+ }
+ if sentID, _ := curveIDForCurve(hs.ecdheKey.Curve()); sentID == curveID {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: server sent an unnecessary HelloRetryRequest key_share")
+ }
+ if _, ok := curveForCurveID(curveID); !ok {
+ c.sendAlert(alertInternalError)
+ return errors.New("tls: CurvePreferences includes unsupported curve")
+ }
+ key, err := generateECDHEKey(c.config.rand(), curveID)
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+ hs.ecdheKey = key
+ hs.hello.keyShares = []keyShare{{group: curveID, data: key.PublicKey().Bytes()}}
+ }
+
+ hs.hello.raw = nil
+ if len(hs.hello.pskIdentities) > 0 {
+ pskSuite := cipherSuiteTLS13ByID(hs.session.cipherSuite)
+ if pskSuite == nil {
+ return c.sendAlert(alertInternalError)
+ }
+ if pskSuite.hash == hs.suite.hash {
+ // Update binders and obfuscated_ticket_age.
+ ticketAge := c.config.time().Sub(time.Unix(int64(hs.session.createdAt), 0))
+ hs.hello.pskIdentities[0].obfuscatedTicketAge = uint32(ticketAge/time.Millisecond) + hs.session.ageAdd
+
+ transcript := hs.suite.hash.New()
+ transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))})
+ transcript.Write(chHash)
+ if err := transcriptMsg(hs.serverHello, transcript); err != nil {
+ return err
+ }
+ helloBytes, err := hs.hello.marshalWithoutBinders()
+ if err != nil {
+ return err
+ }
+ transcript.Write(helloBytes)
+ pskBinders := [][]byte{hs.suite.finishedHash(hs.binderKey, transcript)}
+ if err := hs.hello.updateBinders(pskBinders); err != nil {
+ return err
+ }
+ } else {
+ // Server selected a cipher suite incompatible with the PSK.
+ hs.hello.pskIdentities = nil
+ hs.hello.pskBinders = nil
+ }
+ }
+
+ if hs.hello.earlyData {
+ hs.hello.earlyData = false
+ c.quicRejectedEarlyData()
+ }
+
+ if _, err := hs.c.writeHandshakeRecord(hs.hello, hs.transcript); err != nil {
+ return err
+ }
+
+ // serverHelloMsg is not included in the transcript
+ msg, err := c.readHandshake(nil)
+ if err != nil {
+ return err
+ }
+
+ serverHello, ok := msg.(*serverHelloMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(serverHello, msg)
+ }
+ hs.serverHello = serverHello
+
+ if err := hs.checkServerHelloOrHRR(); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (hs *clientHandshakeStateTLS13) processServerHello() error {
+ c := hs.c
+
+ if bytes.Equal(hs.serverHello.random, helloRetryRequestRandom) {
+ c.sendAlert(alertUnexpectedMessage)
+ return errors.New("tls: server sent two HelloRetryRequest messages")
+ }
+
+ if len(hs.serverHello.cookie) != 0 {
+ c.sendAlert(alertUnsupportedExtension)
+ return errors.New("tls: server sent a cookie in a normal ServerHello")
+ }
+
+ if hs.serverHello.selectedGroup != 0 {
+ c.sendAlert(alertDecodeError)
+ return errors.New("tls: malformed key_share extension")
+ }
+
+ if hs.serverHello.serverShare.group == 0 {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: server did not send a key share")
+ }
+ if sentID, _ := curveIDForCurve(hs.ecdheKey.Curve()); hs.serverHello.serverShare.group != sentID {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: server selected unsupported group")
+ }
+
+ if !hs.serverHello.selectedIdentityPresent {
+ return nil
+ }
+
+ if int(hs.serverHello.selectedIdentity) >= len(hs.hello.pskIdentities) {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: server selected an invalid PSK")
+ }
+
+ if len(hs.hello.pskIdentities) != 1 || hs.session == nil {
+ return c.sendAlert(alertInternalError)
+ }
+ pskSuite := cipherSuiteTLS13ByID(hs.session.cipherSuite)
+ if pskSuite == nil {
+ return c.sendAlert(alertInternalError)
+ }
+ if pskSuite.hash != hs.suite.hash {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: server selected an invalid PSK and cipher suite pair")
+ }
+
+ hs.usingPSK = true
+ c.didResume = true
+ c.peerCertificates = hs.session.peerCertificates
+ c.activeCertHandles = hs.session.activeCertHandles
+ c.verifiedChains = hs.session.verifiedChains
+ c.ocspResponse = hs.session.ocspResponse
+ c.scts = hs.session.scts
+ return nil
+}
+
+func (hs *clientHandshakeStateTLS13) establishHandshakeKeys() error {
+ c := hs.c
+
+ peerKey, err := hs.ecdheKey.Curve().NewPublicKey(hs.serverHello.serverShare.data)
+ if err != nil {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: invalid server key share")
+ }
+ sharedKey, err := hs.ecdheKey.ECDH(peerKey)
+ if err != nil {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: invalid server key share")
+ }
+
+ earlySecret := hs.earlySecret
+ if !hs.usingPSK {
+ earlySecret = hs.suite.extract(nil, nil)
+ }
+
+ handshakeSecret := hs.suite.extract(sharedKey,
+ hs.suite.deriveSecret(earlySecret, "derived", nil))
+
+ clientSecret := hs.suite.deriveSecret(handshakeSecret,
+ clientHandshakeTrafficLabel, hs.transcript)
+ c.out.setTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, clientSecret)
+ serverSecret := hs.suite.deriveSecret(handshakeSecret,
+ serverHandshakeTrafficLabel, hs.transcript)
+ c.in.setTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, serverSecret)
+
+ if c.quic != nil {
+ if c.hand.Len() != 0 {
+ c.sendAlert(alertUnexpectedMessage)
+ }
+ c.quicSetWriteSecret(QUICEncryptionLevelHandshake, hs.suite.id, clientSecret)
+ c.quicSetReadSecret(QUICEncryptionLevelHandshake, hs.suite.id, serverSecret)
+ }
+
+ err = c.config.writeKeyLog(keyLogLabelClientHandshake, hs.hello.random, clientSecret)
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+ err = c.config.writeKeyLog(keyLogLabelServerHandshake, hs.hello.random, serverSecret)
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+
+ hs.masterSecret = hs.suite.extract(nil,
+ hs.suite.deriveSecret(handshakeSecret, "derived", nil))
+
+ return nil
+}
+
+func (hs *clientHandshakeStateTLS13) readServerParameters() error {
+ c := hs.c
+
+ msg, err := c.readHandshake(hs.transcript)
+ if err != nil {
+ return err
+ }
+
+ encryptedExtensions, ok := msg.(*encryptedExtensionsMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(encryptedExtensions, msg)
+ }
+
+ if err := checkALPN(hs.hello.alpnProtocols, encryptedExtensions.alpnProtocol, c.quic != nil); err != nil {
+ // RFC 8446 specifies that no_application_protocol is sent by servers, but
+ // does not specify how clients handle the selection of an incompatible protocol.
+ // RFC 9001 Section 8.1 specifies that QUIC clients send no_application_protocol
+ // in this case. Always sending no_application_protocol seems reasonable.
+ c.sendAlert(alertNoApplicationProtocol)
+ return err
+ }
+ c.clientProtocol = encryptedExtensions.alpnProtocol
+
+ if c.quic != nil {
+ if encryptedExtensions.quicTransportParameters == nil {
+ // RFC 9001 Section 8.2.
+ c.sendAlert(alertMissingExtension)
+ return errors.New("tls: server did not send a quic_transport_parameters extension")
+ }
+ c.quicSetTransportParameters(encryptedExtensions.quicTransportParameters)
+ } else {
+ if encryptedExtensions.quicTransportParameters != nil {
+ c.sendAlert(alertUnsupportedExtension)
+ return errors.New("tls: server sent an unexpected quic_transport_parameters extension")
+ }
+ }
+
+ if !hs.hello.earlyData && encryptedExtensions.earlyData {
+ c.sendAlert(alertUnsupportedExtension)
+ return errors.New("tls: server sent an unexpected early_data extension")
+ }
+ if hs.hello.earlyData && !encryptedExtensions.earlyData {
+ c.quicRejectedEarlyData()
+ }
+ if encryptedExtensions.earlyData {
+ if hs.session.cipherSuite != c.cipherSuite {
+ c.sendAlert(alertHandshakeFailure)
+ return errors.New("tls: server accepted 0-RTT with the wrong cipher suite")
+ }
+ if hs.session.alpnProtocol != c.clientProtocol {
+ c.sendAlert(alertHandshakeFailure)
+ return errors.New("tls: server accepted 0-RTT with the wrong ALPN")
+ }
+ }
+
+ return nil
+}
+
+func (hs *clientHandshakeStateTLS13) readServerCertificate() error {
+ c := hs.c
+
+ // Either a PSK or a certificate is always used, but not both.
+ // See RFC 8446, Section 4.1.1.
+ if hs.usingPSK {
+ // Make sure the connection is still being verified whether or not this
+ // is a resumption. Resumptions currently don't reverify certificates so
+ // they don't call verifyServerCertificate. See Issue 31641.
+ if c.config.VerifyConnection != nil {
+ if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
+ c.sendAlert(alertBadCertificate)
+ return err
+ }
+ }
+ return nil
+ }
+
+ msg, err := c.readHandshake(hs.transcript)
+ if err != nil {
+ return err
+ }
+
+ certReq, ok := msg.(*certificateRequestMsgTLS13)
+ if ok {
+ hs.certReq = certReq
+
+ msg, err = c.readHandshake(hs.transcript)
+ if err != nil {
+ return err
+ }
+ }
+
+ certMsg, ok := msg.(*certificateMsgTLS13)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(certMsg, msg)
+ }
+ if len(certMsg.certificate.Certificate) == 0 {
+ c.sendAlert(alertDecodeError)
+ return errors.New("tls: received empty certificates message")
+ }
+
+ c.scts = certMsg.certificate.SignedCertificateTimestamps
+ c.ocspResponse = certMsg.certificate.OCSPStaple
+
+ if err := c.verifyServerCertificate(certMsg.certificate.Certificate); err != nil {
+ return err
+ }
+
+ // certificateVerifyMsg is included in the transcript, but not until
+ // after we verify the handshake signature, since the state before
+ // this message was sent is used.
+ msg, err = c.readHandshake(nil)
+ if err != nil {
+ return err
+ }
+
+ certVerify, ok := msg.(*certificateVerifyMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(certVerify, msg)
+ }
+
+ // See RFC 8446, Section 4.4.3.
+ if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms()) {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: certificate used with invalid signature algorithm")
+ }
+ sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm)
+ if err != nil {
+ return c.sendAlert(alertInternalError)
+ }
+ if sigType == signaturePKCS1v15 || sigHash == crypto.SHA1 {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: certificate used with invalid signature algorithm")
+ }
+ signed := signedMessage(sigHash, serverSignatureContext, hs.transcript)
+ if err := verifyHandshakeSignature(sigType, c.peerCertificates[0].PublicKey,
+ sigHash, signed, certVerify.signature); err != nil {
+ c.sendAlert(alertDecryptError)
+ return errors.New("tls: invalid signature by the server certificate: " + err.Error())
+ }
+
+ if err := transcriptMsg(certVerify, hs.transcript); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (hs *clientHandshakeStateTLS13) readServerFinished() error {
+ c := hs.c
+
+ // finishedMsg is included in the transcript, but not until after we
+ // check the client version, since the state before this message was
+ // sent is used during verification.
+ msg, err := c.readHandshake(nil)
+ if err != nil {
+ return err
+ }
+
+ finished, ok := msg.(*finishedMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(finished, msg)
+ }
+
+ expectedMAC := hs.suite.finishedHash(c.in.trafficSecret, hs.transcript)
+ if !hmac.Equal(expectedMAC, finished.verifyData) {
+ c.sendAlert(alertDecryptError)
+ return errors.New("tls: invalid server finished hash")
+ }
+
+ if err := transcriptMsg(finished, hs.transcript); err != nil {
+ return err
+ }
+
+ // Derive secrets that take context through the server Finished.
+
+ hs.trafficSecret = hs.suite.deriveSecret(hs.masterSecret,
+ clientApplicationTrafficLabel, hs.transcript)
+ serverSecret := hs.suite.deriveSecret(hs.masterSecret,
+ serverApplicationTrafficLabel, hs.transcript)
+ c.in.setTrafficSecret(hs.suite, QUICEncryptionLevelApplication, serverSecret)
+
+ err = c.config.writeKeyLog(keyLogLabelClientTraffic, hs.hello.random, hs.trafficSecret)
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+ err = c.config.writeKeyLog(keyLogLabelServerTraffic, hs.hello.random, serverSecret)
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+
+ c.ekm = hs.suite.exportKeyingMaterial(hs.masterSecret, hs.transcript)
+
+ return nil
+}
+
+func (hs *clientHandshakeStateTLS13) sendClientCertificate() error {
+ c := hs.c
+
+ if hs.certReq == nil {
+ return nil
+ }
+
+ cert, err := c.getClientCertificate(&CertificateRequestInfo{
+ AcceptableCAs: hs.certReq.certificateAuthorities,
+ SignatureSchemes: hs.certReq.supportedSignatureAlgorithms,
+ Version: c.vers,
+ ctx: hs.ctx,
+ })
+ if err != nil {
+ return err
+ }
+
+ certMsg := new(certificateMsgTLS13)
+
+ certMsg.certificate = *cert
+ certMsg.scts = hs.certReq.scts && len(cert.SignedCertificateTimestamps) > 0
+ certMsg.ocspStapling = hs.certReq.ocspStapling && len(cert.OCSPStaple) > 0
+
+ if _, err := hs.c.writeHandshakeRecord(certMsg, hs.transcript); err != nil {
+ return err
+ }
+
+ // If we sent an empty certificate message, skip the CertificateVerify.
+ if len(cert.Certificate) == 0 {
+ return nil
+ }
+
+ certVerifyMsg := new(certificateVerifyMsg)
+ certVerifyMsg.hasSignatureAlgorithm = true
+
+ certVerifyMsg.signatureAlgorithm, err = selectSignatureScheme(c.vers, cert, hs.certReq.supportedSignatureAlgorithms)
+ if err != nil {
+ // getClientCertificate returned a certificate incompatible with the
+ // CertificateRequestInfo supported signature algorithms.
+ c.sendAlert(alertHandshakeFailure)
+ return err
+ }
+
+ sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerifyMsg.signatureAlgorithm)
+ if err != nil {
+ return c.sendAlert(alertInternalError)
+ }
+
+ signed := signedMessage(sigHash, clientSignatureContext, hs.transcript)
+ signOpts := crypto.SignerOpts(sigHash)
+ if sigType == signatureRSAPSS {
+ signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash}
+ }
+ sig, err := cert.PrivateKey.(crypto.Signer).Sign(c.config.rand(), signed, signOpts)
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return errors.New("tls: failed to sign handshake: " + err.Error())
+ }
+ certVerifyMsg.signature = sig
+
+ if _, err := hs.c.writeHandshakeRecord(certVerifyMsg, hs.transcript); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (hs *clientHandshakeStateTLS13) sendClientFinished() error {
+ c := hs.c
+
+ finished := &finishedMsg{
+ verifyData: hs.suite.finishedHash(c.out.trafficSecret, hs.transcript),
+ }
+
+ if _, err := hs.c.writeHandshakeRecord(finished, hs.transcript); err != nil {
+ return err
+ }
+
+ c.out.setTrafficSecret(hs.suite, QUICEncryptionLevelApplication, hs.trafficSecret)
+
+ if !c.config.SessionTicketsDisabled && c.config.ClientSessionCache != nil {
+ c.resumptionSecret = hs.suite.deriveSecret(hs.masterSecret,
+ resumptionLabel, hs.transcript)
+ }
+
+ if c.quic != nil {
+ if c.hand.Len() != 0 {
+ c.sendAlert(alertUnexpectedMessage)
+ }
+ c.quicSetWriteSecret(QUICEncryptionLevelApplication, hs.suite.id, hs.trafficSecret)
+ }
+
+ return nil
+}
+
+func (c *Conn) handleNewSessionTicket(msg *newSessionTicketMsgTLS13) error {
+ if !c.isClient {
+ c.sendAlert(alertUnexpectedMessage)
+ return errors.New("tls: received new session ticket from a client")
+ }
+
+ if c.config.SessionTicketsDisabled || c.config.ClientSessionCache == nil {
+ return nil
+ }
+
+ // See RFC 8446, Section 4.6.1.
+ if msg.lifetime == 0 {
+ return nil
+ }
+ lifetime := time.Duration(msg.lifetime) * time.Second
+ if lifetime > maxSessionTicketLifetime {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: received a session ticket with invalid lifetime")
+ }
+
+ // RFC 9001, Section 4.6.1
+ if c.quic != nil && msg.maxEarlyData != 0 && msg.maxEarlyData != 0xffffffff {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: invalid early data for QUIC connection")
+ }
+
+ cipherSuite := cipherSuiteTLS13ByID(c.cipherSuite)
+ if cipherSuite == nil || c.resumptionSecret == nil {
+ return c.sendAlert(alertInternalError)
+ }
+
+ psk := cipherSuite.expandLabel(c.resumptionSecret, "resumption",
+ msg.nonce, cipherSuite.hash.Size())
+
+ session, err := c.sessionState()
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+ session.secret = psk
+ session.useBy = uint64(c.config.time().Add(lifetime).Unix())
+ session.ageAdd = msg.ageAdd
+ session.EarlyData = c.quic != nil && msg.maxEarlyData == 0xffffffff // RFC 9001, Section 4.6.1
+ cs := &ClientSessionState{ticket: msg.label, session: session}
+
+ if cacheKey := c.clientSessionCacheKey(); cacheKey != "" {
+ c.config.ClientSessionCache.Put(cacheKey, cs)
+ }
+
+ return nil
+}
diff --git a/src/crypto/tls/handshake_messages.go b/src/crypto/tls/handshake_messages.go
new file mode 100644
index 0000000..a86055a
--- /dev/null
+++ b/src/crypto/tls/handshake_messages.go
@@ -0,0 +1,1903 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+ "errors"
+ "fmt"
+ "strings"
+
+ "golang.org/x/crypto/cryptobyte"
+)
+
+// The marshalingFunction type is an adapter to allow the use of ordinary
+// functions as cryptobyte.MarshalingValue.
+type marshalingFunction func(b *cryptobyte.Builder) error
+
+func (f marshalingFunction) Marshal(b *cryptobyte.Builder) error {
+ return f(b)
+}
+
+// addBytesWithLength appends a sequence of bytes to the cryptobyte.Builder. If
+// the length of the sequence is not the value specified, it produces an error.
+func addBytesWithLength(b *cryptobyte.Builder, v []byte, n int) {
+ b.AddValue(marshalingFunction(func(b *cryptobyte.Builder) error {
+ if len(v) != n {
+ return fmt.Errorf("invalid value length: expected %d, got %d", n, len(v))
+ }
+ b.AddBytes(v)
+ return nil
+ }))
+}
+
+// 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 {
+ return s.ReadUint8LengthPrefixed((*cryptobyte.String)(out))
+}
+
+// readUint16LengthPrefixed acts like s.ReadUint16LengthPrefixed, but targets a
+// []byte instead of a cryptobyte.String.
+func readUint16LengthPrefixed(s *cryptobyte.String, out *[]byte) bool {
+ return s.ReadUint16LengthPrefixed((*cryptobyte.String)(out))
+}
+
+// readUint24LengthPrefixed acts like s.ReadUint24LengthPrefixed, but targets a
+// []byte instead of a cryptobyte.String.
+func readUint24LengthPrefixed(s *cryptobyte.String, out *[]byte) bool {
+ return s.ReadUint24LengthPrefixed((*cryptobyte.String)(out))
+}
+
+type clientHelloMsg struct {
+ raw []byte
+ vers uint16
+ random []byte
+ sessionId []byte
+ cipherSuites []uint16
+ compressionMethods []uint8
+ serverName string
+ ocspStapling bool
+ supportedCurves []CurveID
+ supportedPoints []uint8
+ ticketSupported bool
+ sessionTicket []uint8
+ supportedSignatureAlgorithms []SignatureScheme
+ supportedSignatureAlgorithmsCert []SignatureScheme
+ secureRenegotiationSupported bool
+ secureRenegotiation []byte
+ extendedMasterSecret bool
+ alpnProtocols []string
+ scts bool
+ supportedVersions []uint16
+ cookie []byte
+ keyShares []keyShare
+ earlyData bool
+ pskModes []uint8
+ pskIdentities []pskIdentity
+ pskBinders [][]byte
+ quicTransportParameters []byte
+}
+
+func (m *clientHelloMsg) marshal() ([]byte, error) {
+ if m.raw != nil {
+ return m.raw, nil
+ }
+
+ var exts cryptobyte.Builder
+ if len(m.serverName) > 0 {
+ // RFC 6066, Section 3
+ exts.AddUint16(extensionServerName)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint8(0) // name_type = host_name
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes([]byte(m.serverName))
+ })
+ })
+ })
+ }
+ if m.ocspStapling {
+ // RFC 4366, Section 3.6
+ exts.AddUint16(extensionStatusRequest)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint8(1) // status_type = ocsp
+ exts.AddUint16(0) // empty responder_id_list
+ exts.AddUint16(0) // empty request_extensions
+ })
+ }
+ if len(m.supportedCurves) > 0 {
+ // RFC 4492, sections 5.1.1 and RFC 8446, Section 4.2.7
+ exts.AddUint16(extensionSupportedCurves)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ for _, curve := range m.supportedCurves {
+ exts.AddUint16(uint16(curve))
+ }
+ })
+ })
+ }
+ if len(m.supportedPoints) > 0 {
+ // RFC 4492, Section 5.1.2
+ exts.AddUint16(extensionSupportedPoints)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes(m.supportedPoints)
+ })
+ })
+ }
+ if m.ticketSupported {
+ // RFC 5077, Section 3.2
+ exts.AddUint16(extensionSessionTicket)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes(m.sessionTicket)
+ })
+ }
+ if len(m.supportedSignatureAlgorithms) > 0 {
+ // RFC 5246, Section 7.4.1.4.1
+ exts.AddUint16(extensionSignatureAlgorithms)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ for _, sigAlgo := range m.supportedSignatureAlgorithms {
+ exts.AddUint16(uint16(sigAlgo))
+ }
+ })
+ })
+ }
+ if len(m.supportedSignatureAlgorithmsCert) > 0 {
+ // RFC 8446, Section 4.2.3
+ exts.AddUint16(extensionSignatureAlgorithmsCert)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ for _, sigAlgo := range m.supportedSignatureAlgorithmsCert {
+ exts.AddUint16(uint16(sigAlgo))
+ }
+ })
+ })
+ }
+ if m.secureRenegotiationSupported {
+ // RFC 5746, Section 3.2
+ exts.AddUint16(extensionRenegotiationInfo)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes(m.secureRenegotiation)
+ })
+ })
+ }
+ if m.extendedMasterSecret {
+ // RFC 7627
+ exts.AddUint16(extensionExtendedMasterSecret)
+ exts.AddUint16(0) // empty extension_data
+ }
+ if len(m.alpnProtocols) > 0 {
+ // RFC 7301, Section 3.1
+ exts.AddUint16(extensionALPN)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ for _, proto := range m.alpnProtocols {
+ exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes([]byte(proto))
+ })
+ }
+ })
+ })
+ }
+ if m.scts {
+ // RFC 6962, Section 3.3.1
+ exts.AddUint16(extensionSCT)
+ exts.AddUint16(0) // empty extension_data
+ }
+ if len(m.supportedVersions) > 0 {
+ // RFC 8446, Section 4.2.1
+ exts.AddUint16(extensionSupportedVersions)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
+ for _, vers := range m.supportedVersions {
+ exts.AddUint16(vers)
+ }
+ })
+ })
+ }
+ if len(m.cookie) > 0 {
+ // RFC 8446, Section 4.2.2
+ exts.AddUint16(extensionCookie)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes(m.cookie)
+ })
+ })
+ }
+ if len(m.keyShares) > 0 {
+ // RFC 8446, Section 4.2.8
+ exts.AddUint16(extensionKeyShare)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ for _, ks := range m.keyShares {
+ exts.AddUint16(uint16(ks.group))
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes(ks.data)
+ })
+ }
+ })
+ })
+ }
+ if m.earlyData {
+ // RFC 8446, Section 4.2.10
+ exts.AddUint16(extensionEarlyData)
+ exts.AddUint16(0) // empty extension_data
+ }
+ if len(m.pskModes) > 0 {
+ // RFC 8446, Section 4.2.9
+ exts.AddUint16(extensionPSKModes)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes(m.pskModes)
+ })
+ })
+ }
+ if m.quicTransportParameters != nil { // marshal zero-length parameters when present
+ // RFC 9001, Section 8.2
+ exts.AddUint16(extensionQUICTransportParameters)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes(m.quicTransportParameters)
+ })
+ }
+ if len(m.pskIdentities) > 0 { // pre_shared_key must be the last extension
+ // RFC 8446, Section 4.2.11
+ exts.AddUint16(extensionPreSharedKey)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ for _, psk := range m.pskIdentities {
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes(psk.label)
+ })
+ exts.AddUint32(psk.obfuscatedTicketAge)
+ }
+ })
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ for _, binder := range m.pskBinders {
+ exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes(binder)
+ })
+ }
+ })
+ })
+ }
+ extBytes, err := exts.Bytes()
+ if err != nil {
+ return nil, err
+ }
+
+ var b cryptobyte.Builder
+ b.AddUint8(typeClientHello)
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddUint16(m.vers)
+ addBytesWithLength(b, m.random, 32)
+ b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(m.sessionId)
+ })
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ for _, suite := range m.cipherSuites {
+ b.AddUint16(suite)
+ }
+ })
+ b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(m.compressionMethods)
+ })
+
+ if len(extBytes) > 0 {
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(extBytes)
+ })
+ }
+ })
+
+ m.raw, err = b.Bytes()
+ return m.raw, err
+}
+
+// marshalWithoutBinders returns the ClientHello through the
+// PreSharedKeyExtension.identities field, according to RFC 8446, Section
+// 4.2.11.2. Note that m.pskBinders must be set to slices of the correct length.
+func (m *clientHelloMsg) marshalWithoutBinders() ([]byte, error) {
+ bindersLen := 2 // uint16 length prefix
+ for _, binder := range m.pskBinders {
+ bindersLen += 1 // uint8 length prefix
+ bindersLen += len(binder)
+ }
+
+ fullMessage, err := m.marshal()
+ if err != nil {
+ return nil, err
+ }
+ return fullMessage[:len(fullMessage)-bindersLen], nil
+}
+
+// updateBinders updates the m.pskBinders field, if necessary updating the
+// cached marshaled representation. The supplied binders must have the same
+// length as the current m.pskBinders.
+func (m *clientHelloMsg) updateBinders(pskBinders [][]byte) error {
+ if len(pskBinders) != len(m.pskBinders) {
+ return errors.New("tls: internal error: pskBinders length mismatch")
+ }
+ for i := range m.pskBinders {
+ if len(pskBinders[i]) != len(m.pskBinders[i]) {
+ return errors.New("tls: internal error: pskBinders length mismatch")
+ }
+ }
+ m.pskBinders = pskBinders
+ if m.raw != nil {
+ helloBytes, err := m.marshalWithoutBinders()
+ if err != nil {
+ return err
+ }
+ lenWithoutBinders := len(helloBytes)
+ b := cryptobyte.NewFixedBuilder(m.raw[:lenWithoutBinders])
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ for _, binder := range m.pskBinders {
+ b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(binder)
+ })
+ }
+ })
+ if out, err := b.Bytes(); err != nil || len(out) != len(m.raw) {
+ return errors.New("tls: internal error: failed to update binders")
+ }
+ }
+
+ return nil
+}
+
+func (m *clientHelloMsg) unmarshal(data []byte) bool {
+ *m = clientHelloMsg{raw: data}
+ s := cryptobyte.String(data)
+
+ if !s.Skip(4) || // message type and uint24 length field
+ !s.ReadUint16(&m.vers) || !s.ReadBytes(&m.random, 32) ||
+ !readUint8LengthPrefixed(&s, &m.sessionId) {
+ return false
+ }
+
+ var cipherSuites cryptobyte.String
+ if !s.ReadUint16LengthPrefixed(&cipherSuites) {
+ return false
+ }
+ m.cipherSuites = []uint16{}
+ m.secureRenegotiationSupported = false
+ for !cipherSuites.Empty() {
+ var suite uint16
+ if !cipherSuites.ReadUint16(&suite) {
+ return false
+ }
+ if suite == scsvRenegotiation {
+ m.secureRenegotiationSupported = true
+ }
+ m.cipherSuites = append(m.cipherSuites, suite)
+ }
+
+ if !readUint8LengthPrefixed(&s, &m.compressionMethods) {
+ return false
+ }
+
+ if s.Empty() {
+ // ClientHello is optionally followed by extension data
+ return true
+ }
+
+ var extensions cryptobyte.String
+ if !s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() {
+ return false
+ }
+
+ seenExts := make(map[uint16]bool)
+ for !extensions.Empty() {
+ var extension uint16
+ var extData cryptobyte.String
+ if !extensions.ReadUint16(&extension) ||
+ !extensions.ReadUint16LengthPrefixed(&extData) {
+ return false
+ }
+
+ if seenExts[extension] {
+ return false
+ }
+ seenExts[extension] = true
+
+ switch extension {
+ case extensionServerName:
+ // RFC 6066, Section 3
+ var nameList cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&nameList) || nameList.Empty() {
+ return false
+ }
+ for !nameList.Empty() {
+ var nameType uint8
+ var serverName cryptobyte.String
+ if !nameList.ReadUint8(&nameType) ||
+ !nameList.ReadUint16LengthPrefixed(&serverName) ||
+ serverName.Empty() {
+ return false
+ }
+ if nameType != 0 {
+ continue
+ }
+ if len(m.serverName) != 0 {
+ // Multiple names of the same name_type are prohibited.
+ return false
+ }
+ m.serverName = string(serverName)
+ // An SNI value may not include a trailing dot.
+ if strings.HasSuffix(m.serverName, ".") {
+ return false
+ }
+ }
+ case extensionStatusRequest:
+ // RFC 4366, Section 3.6
+ var statusType uint8
+ var ignored cryptobyte.String
+ if !extData.ReadUint8(&statusType) ||
+ !extData.ReadUint16LengthPrefixed(&ignored) ||
+ !extData.ReadUint16LengthPrefixed(&ignored) {
+ return false
+ }
+ m.ocspStapling = statusType == statusTypeOCSP
+ case extensionSupportedCurves:
+ // RFC 4492, sections 5.1.1 and RFC 8446, Section 4.2.7
+ var curves cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&curves) || curves.Empty() {
+ return false
+ }
+ for !curves.Empty() {
+ var curve uint16
+ if !curves.ReadUint16(&curve) {
+ return false
+ }
+ m.supportedCurves = append(m.supportedCurves, CurveID(curve))
+ }
+ case extensionSupportedPoints:
+ // RFC 4492, Section 5.1.2
+ if !readUint8LengthPrefixed(&extData, &m.supportedPoints) ||
+ len(m.supportedPoints) == 0 {
+ return false
+ }
+ case extensionSessionTicket:
+ // RFC 5077, Section 3.2
+ m.ticketSupported = true
+ extData.ReadBytes(&m.sessionTicket, len(extData))
+ case extensionSignatureAlgorithms:
+ // RFC 5246, Section 7.4.1.4.1
+ var sigAndAlgs cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() {
+ return false
+ }
+ for !sigAndAlgs.Empty() {
+ var sigAndAlg uint16
+ if !sigAndAlgs.ReadUint16(&sigAndAlg) {
+ return false
+ }
+ m.supportedSignatureAlgorithms = append(
+ m.supportedSignatureAlgorithms, SignatureScheme(sigAndAlg))
+ }
+ case extensionSignatureAlgorithmsCert:
+ // RFC 8446, Section 4.2.3
+ var sigAndAlgs cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() {
+ return false
+ }
+ for !sigAndAlgs.Empty() {
+ var sigAndAlg uint16
+ if !sigAndAlgs.ReadUint16(&sigAndAlg) {
+ return false
+ }
+ m.supportedSignatureAlgorithmsCert = append(
+ m.supportedSignatureAlgorithmsCert, SignatureScheme(sigAndAlg))
+ }
+ case extensionRenegotiationInfo:
+ // RFC 5746, Section 3.2
+ if !readUint8LengthPrefixed(&extData, &m.secureRenegotiation) {
+ return false
+ }
+ m.secureRenegotiationSupported = true
+ case extensionExtendedMasterSecret:
+ // RFC 7627
+ m.extendedMasterSecret = true
+ case extensionALPN:
+ // RFC 7301, Section 3.1
+ var protoList cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&protoList) || protoList.Empty() {
+ return false
+ }
+ for !protoList.Empty() {
+ var proto cryptobyte.String
+ if !protoList.ReadUint8LengthPrefixed(&proto) || proto.Empty() {
+ return false
+ }
+ m.alpnProtocols = append(m.alpnProtocols, string(proto))
+ }
+ case extensionSCT:
+ // RFC 6962, Section 3.3.1
+ m.scts = true
+ case extensionSupportedVersions:
+ // RFC 8446, Section 4.2.1
+ var versList cryptobyte.String
+ if !extData.ReadUint8LengthPrefixed(&versList) || versList.Empty() {
+ return false
+ }
+ for !versList.Empty() {
+ var vers uint16
+ if !versList.ReadUint16(&vers) {
+ return false
+ }
+ m.supportedVersions = append(m.supportedVersions, vers)
+ }
+ case extensionCookie:
+ // RFC 8446, Section 4.2.2
+ if !readUint16LengthPrefixed(&extData, &m.cookie) ||
+ len(m.cookie) == 0 {
+ return false
+ }
+ case extensionKeyShare:
+ // RFC 8446, Section 4.2.8
+ var clientShares cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&clientShares) {
+ return false
+ }
+ for !clientShares.Empty() {
+ var ks keyShare
+ if !clientShares.ReadUint16((*uint16)(&ks.group)) ||
+ !readUint16LengthPrefixed(&clientShares, &ks.data) ||
+ len(ks.data) == 0 {
+ return false
+ }
+ m.keyShares = append(m.keyShares, ks)
+ }
+ case extensionEarlyData:
+ // RFC 8446, Section 4.2.10
+ m.earlyData = true
+ case extensionPSKModes:
+ // RFC 8446, Section 4.2.9
+ if !readUint8LengthPrefixed(&extData, &m.pskModes) {
+ return false
+ }
+ case extensionQUICTransportParameters:
+ m.quicTransportParameters = make([]byte, len(extData))
+ if !extData.CopyBytes(m.quicTransportParameters) {
+ return false
+ }
+ case extensionPreSharedKey:
+ // RFC 8446, Section 4.2.11
+ if !extensions.Empty() {
+ return false // pre_shared_key must be the last extension
+ }
+ var identities cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&identities) || identities.Empty() {
+ return false
+ }
+ for !identities.Empty() {
+ var psk pskIdentity
+ if !readUint16LengthPrefixed(&identities, &psk.label) ||
+ !identities.ReadUint32(&psk.obfuscatedTicketAge) ||
+ len(psk.label) == 0 {
+ return false
+ }
+ m.pskIdentities = append(m.pskIdentities, psk)
+ }
+ var binders cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&binders) || binders.Empty() {
+ return false
+ }
+ for !binders.Empty() {
+ var binder []byte
+ if !readUint8LengthPrefixed(&binders, &binder) ||
+ len(binder) == 0 {
+ return false
+ }
+ m.pskBinders = append(m.pskBinders, binder)
+ }
+ default:
+ // Ignore unknown extensions.
+ continue
+ }
+
+ if !extData.Empty() {
+ return false
+ }
+ }
+
+ return true
+}
+
+type serverHelloMsg struct {
+ raw []byte
+ vers uint16
+ random []byte
+ sessionId []byte
+ cipherSuite uint16
+ compressionMethod uint8
+ ocspStapling bool
+ ticketSupported bool
+ secureRenegotiationSupported bool
+ secureRenegotiation []byte
+ extendedMasterSecret bool
+ alpnProtocol string
+ scts [][]byte
+ supportedVersion uint16
+ serverShare keyShare
+ selectedIdentityPresent bool
+ selectedIdentity uint16
+ supportedPoints []uint8
+
+ // HelloRetryRequest extensions
+ cookie []byte
+ selectedGroup CurveID
+}
+
+func (m *serverHelloMsg) marshal() ([]byte, error) {
+ if m.raw != nil {
+ return m.raw, nil
+ }
+
+ var exts cryptobyte.Builder
+ if m.ocspStapling {
+ exts.AddUint16(extensionStatusRequest)
+ exts.AddUint16(0) // empty extension_data
+ }
+ if m.ticketSupported {
+ exts.AddUint16(extensionSessionTicket)
+ exts.AddUint16(0) // empty extension_data
+ }
+ if m.secureRenegotiationSupported {
+ exts.AddUint16(extensionRenegotiationInfo)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes(m.secureRenegotiation)
+ })
+ })
+ }
+ if m.extendedMasterSecret {
+ exts.AddUint16(extensionExtendedMasterSecret)
+ exts.AddUint16(0) // empty extension_data
+ }
+ if len(m.alpnProtocol) > 0 {
+ exts.AddUint16(extensionALPN)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes([]byte(m.alpnProtocol))
+ })
+ })
+ })
+ }
+ if len(m.scts) > 0 {
+ exts.AddUint16(extensionSCT)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ for _, sct := range m.scts {
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes(sct)
+ })
+ }
+ })
+ })
+ }
+ if m.supportedVersion != 0 {
+ exts.AddUint16(extensionSupportedVersions)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint16(m.supportedVersion)
+ })
+ }
+ if m.serverShare.group != 0 {
+ exts.AddUint16(extensionKeyShare)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint16(uint16(m.serverShare.group))
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes(m.serverShare.data)
+ })
+ })
+ }
+ if m.selectedIdentityPresent {
+ exts.AddUint16(extensionPreSharedKey)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint16(m.selectedIdentity)
+ })
+ }
+
+ if len(m.cookie) > 0 {
+ exts.AddUint16(extensionCookie)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes(m.cookie)
+ })
+ })
+ }
+ if m.selectedGroup != 0 {
+ exts.AddUint16(extensionKeyShare)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint16(uint16(m.selectedGroup))
+ })
+ }
+ if len(m.supportedPoints) > 0 {
+ exts.AddUint16(extensionSupportedPoints)
+ exts.AddUint16LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddUint8LengthPrefixed(func(exts *cryptobyte.Builder) {
+ exts.AddBytes(m.supportedPoints)
+ })
+ })
+ }
+
+ extBytes, err := exts.Bytes()
+ if err != nil {
+ return nil, err
+ }
+
+ var b cryptobyte.Builder
+ b.AddUint8(typeServerHello)
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddUint16(m.vers)
+ addBytesWithLength(b, m.random, 32)
+ b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(m.sessionId)
+ })
+ b.AddUint16(m.cipherSuite)
+ b.AddUint8(m.compressionMethod)
+
+ if len(extBytes) > 0 {
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(extBytes)
+ })
+ }
+ })
+
+ m.raw, err = b.Bytes()
+ return m.raw, err
+}
+
+func (m *serverHelloMsg) unmarshal(data []byte) bool {
+ *m = serverHelloMsg{raw: data}
+ s := cryptobyte.String(data)
+
+ if !s.Skip(4) || // message type and uint24 length field
+ !s.ReadUint16(&m.vers) || !s.ReadBytes(&m.random, 32) ||
+ !readUint8LengthPrefixed(&s, &m.sessionId) ||
+ !s.ReadUint16(&m.cipherSuite) ||
+ !s.ReadUint8(&m.compressionMethod) {
+ return false
+ }
+
+ if s.Empty() {
+ // ServerHello is optionally followed by extension data
+ return true
+ }
+
+ var extensions cryptobyte.String
+ if !s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() {
+ return false
+ }
+
+ seenExts := make(map[uint16]bool)
+ for !extensions.Empty() {
+ var extension uint16
+ var extData cryptobyte.String
+ if !extensions.ReadUint16(&extension) ||
+ !extensions.ReadUint16LengthPrefixed(&extData) {
+ return false
+ }
+
+ if seenExts[extension] {
+ return false
+ }
+ seenExts[extension] = true
+
+ switch extension {
+ case extensionStatusRequest:
+ m.ocspStapling = true
+ case extensionSessionTicket:
+ m.ticketSupported = true
+ case extensionRenegotiationInfo:
+ if !readUint8LengthPrefixed(&extData, &m.secureRenegotiation) {
+ return false
+ }
+ m.secureRenegotiationSupported = true
+ case extensionExtendedMasterSecret:
+ m.extendedMasterSecret = true
+ case extensionALPN:
+ var protoList cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&protoList) || protoList.Empty() {
+ return false
+ }
+ var proto cryptobyte.String
+ if !protoList.ReadUint8LengthPrefixed(&proto) ||
+ proto.Empty() || !protoList.Empty() {
+ return false
+ }
+ m.alpnProtocol = string(proto)
+ case extensionSCT:
+ var sctList cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&sctList) || sctList.Empty() {
+ return false
+ }
+ for !sctList.Empty() {
+ var sct []byte
+ if !readUint16LengthPrefixed(&sctList, &sct) ||
+ len(sct) == 0 {
+ return false
+ }
+ m.scts = append(m.scts, sct)
+ }
+ case extensionSupportedVersions:
+ if !extData.ReadUint16(&m.supportedVersion) {
+ return false
+ }
+ case extensionCookie:
+ if !readUint16LengthPrefixed(&extData, &m.cookie) ||
+ len(m.cookie) == 0 {
+ return false
+ }
+ case extensionKeyShare:
+ // This extension has different formats in SH and HRR, accept either
+ // and let the handshake logic decide. See RFC 8446, Section 4.2.8.
+ if len(extData) == 2 {
+ if !extData.ReadUint16((*uint16)(&m.selectedGroup)) {
+ return false
+ }
+ } else {
+ if !extData.ReadUint16((*uint16)(&m.serverShare.group)) ||
+ !readUint16LengthPrefixed(&extData, &m.serverShare.data) {
+ return false
+ }
+ }
+ case extensionPreSharedKey:
+ m.selectedIdentityPresent = true
+ if !extData.ReadUint16(&m.selectedIdentity) {
+ return false
+ }
+ case extensionSupportedPoints:
+ // RFC 4492, Section 5.1.2
+ if !readUint8LengthPrefixed(&extData, &m.supportedPoints) ||
+ len(m.supportedPoints) == 0 {
+ return false
+ }
+ default:
+ // Ignore unknown extensions.
+ continue
+ }
+
+ if !extData.Empty() {
+ return false
+ }
+ }
+
+ return true
+}
+
+type encryptedExtensionsMsg struct {
+ raw []byte
+ alpnProtocol string
+ quicTransportParameters []byte
+ earlyData bool
+}
+
+func (m *encryptedExtensionsMsg) marshal() ([]byte, error) {
+ if m.raw != nil {
+ return m.raw, nil
+ }
+
+ var b cryptobyte.Builder
+ b.AddUint8(typeEncryptedExtensions)
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ if len(m.alpnProtocol) > 0 {
+ b.AddUint16(extensionALPN)
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes([]byte(m.alpnProtocol))
+ })
+ })
+ })
+ }
+ if m.quicTransportParameters != nil { // marshal zero-length parameters when present
+ // draft-ietf-quic-tls-32, Section 8.2
+ b.AddUint16(extensionQUICTransportParameters)
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(m.quicTransportParameters)
+ })
+ }
+ if m.earlyData {
+ // RFC 8446, Section 4.2.10
+ b.AddUint16(extensionEarlyData)
+ b.AddUint16(0) // empty extension_data
+ }
+ })
+ })
+
+ var err error
+ m.raw, err = b.Bytes()
+ return m.raw, err
+}
+
+func (m *encryptedExtensionsMsg) unmarshal(data []byte) bool {
+ *m = encryptedExtensionsMsg{raw: data}
+ s := cryptobyte.String(data)
+
+ var extensions cryptobyte.String
+ if !s.Skip(4) || // message type and uint24 length field
+ !s.ReadUint16LengthPrefixed(&extensions) || !s.Empty() {
+ return false
+ }
+
+ for !extensions.Empty() {
+ var extension uint16
+ var extData cryptobyte.String
+ if !extensions.ReadUint16(&extension) ||
+ !extensions.ReadUint16LengthPrefixed(&extData) {
+ return false
+ }
+
+ switch extension {
+ case extensionALPN:
+ var protoList cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&protoList) || protoList.Empty() {
+ return false
+ }
+ var proto cryptobyte.String
+ if !protoList.ReadUint8LengthPrefixed(&proto) ||
+ proto.Empty() || !protoList.Empty() {
+ return false
+ }
+ m.alpnProtocol = string(proto)
+ case extensionQUICTransportParameters:
+ m.quicTransportParameters = make([]byte, len(extData))
+ if !extData.CopyBytes(m.quicTransportParameters) {
+ return false
+ }
+ case extensionEarlyData:
+ // RFC 8446, Section 4.2.10
+ m.earlyData = true
+ default:
+ // Ignore unknown extensions.
+ continue
+ }
+
+ if !extData.Empty() {
+ return false
+ }
+ }
+
+ return true
+}
+
+type endOfEarlyDataMsg struct{}
+
+func (m *endOfEarlyDataMsg) marshal() ([]byte, error) {
+ x := make([]byte, 4)
+ x[0] = typeEndOfEarlyData
+ return x, nil
+}
+
+func (m *endOfEarlyDataMsg) unmarshal(data []byte) bool {
+ return len(data) == 4
+}
+
+type keyUpdateMsg struct {
+ raw []byte
+ updateRequested bool
+}
+
+func (m *keyUpdateMsg) marshal() ([]byte, error) {
+ if m.raw != nil {
+ return m.raw, nil
+ }
+
+ var b cryptobyte.Builder
+ b.AddUint8(typeKeyUpdate)
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ if m.updateRequested {
+ b.AddUint8(1)
+ } else {
+ b.AddUint8(0)
+ }
+ })
+
+ var err error
+ m.raw, err = b.Bytes()
+ return m.raw, err
+}
+
+func (m *keyUpdateMsg) unmarshal(data []byte) bool {
+ m.raw = data
+ s := cryptobyte.String(data)
+
+ var updateRequested uint8
+ if !s.Skip(4) || // message type and uint24 length field
+ !s.ReadUint8(&updateRequested) || !s.Empty() {
+ return false
+ }
+ switch updateRequested {
+ case 0:
+ m.updateRequested = false
+ case 1:
+ m.updateRequested = true
+ default:
+ return false
+ }
+ return true
+}
+
+type newSessionTicketMsgTLS13 struct {
+ raw []byte
+ lifetime uint32
+ ageAdd uint32
+ nonce []byte
+ label []byte
+ maxEarlyData uint32
+}
+
+func (m *newSessionTicketMsgTLS13) marshal() ([]byte, error) {
+ if m.raw != nil {
+ return m.raw, nil
+ }
+
+ var b cryptobyte.Builder
+ b.AddUint8(typeNewSessionTicket)
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddUint32(m.lifetime)
+ b.AddUint32(m.ageAdd)
+ b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(m.nonce)
+ })
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(m.label)
+ })
+
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ if m.maxEarlyData > 0 {
+ b.AddUint16(extensionEarlyData)
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddUint32(m.maxEarlyData)
+ })
+ }
+ })
+ })
+
+ var err error
+ m.raw, err = b.Bytes()
+ return m.raw, err
+}
+
+func (m *newSessionTicketMsgTLS13) unmarshal(data []byte) bool {
+ *m = newSessionTicketMsgTLS13{raw: data}
+ s := cryptobyte.String(data)
+
+ var extensions cryptobyte.String
+ if !s.Skip(4) || // message type and uint24 length field
+ !s.ReadUint32(&m.lifetime) ||
+ !s.ReadUint32(&m.ageAdd) ||
+ !readUint8LengthPrefixed(&s, &m.nonce) ||
+ !readUint16LengthPrefixed(&s, &m.label) ||
+ !s.ReadUint16LengthPrefixed(&extensions) ||
+ !s.Empty() {
+ return false
+ }
+
+ for !extensions.Empty() {
+ var extension uint16
+ var extData cryptobyte.String
+ if !extensions.ReadUint16(&extension) ||
+ !extensions.ReadUint16LengthPrefixed(&extData) {
+ return false
+ }
+
+ switch extension {
+ case extensionEarlyData:
+ if !extData.ReadUint32(&m.maxEarlyData) {
+ return false
+ }
+ default:
+ // Ignore unknown extensions.
+ continue
+ }
+
+ if !extData.Empty() {
+ return false
+ }
+ }
+
+ return true
+}
+
+type certificateRequestMsgTLS13 struct {
+ raw []byte
+ ocspStapling bool
+ scts bool
+ supportedSignatureAlgorithms []SignatureScheme
+ supportedSignatureAlgorithmsCert []SignatureScheme
+ certificateAuthorities [][]byte
+}
+
+func (m *certificateRequestMsgTLS13) marshal() ([]byte, error) {
+ if m.raw != nil {
+ return m.raw, nil
+ }
+
+ var b cryptobyte.Builder
+ b.AddUint8(typeCertificateRequest)
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ // certificate_request_context (SHALL be zero length unless used for
+ // post-handshake authentication)
+ b.AddUint8(0)
+
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ if m.ocspStapling {
+ b.AddUint16(extensionStatusRequest)
+ b.AddUint16(0) // empty extension_data
+ }
+ if m.scts {
+ // RFC 8446, Section 4.4.2.1 makes no mention of
+ // signed_certificate_timestamp in CertificateRequest, but
+ // "Extensions in the Certificate message from the client MUST
+ // correspond to extensions in the CertificateRequest message
+ // from the server." and it appears in the table in Section 4.2.
+ b.AddUint16(extensionSCT)
+ b.AddUint16(0) // empty extension_data
+ }
+ if len(m.supportedSignatureAlgorithms) > 0 {
+ b.AddUint16(extensionSignatureAlgorithms)
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ for _, sigAlgo := range m.supportedSignatureAlgorithms {
+ b.AddUint16(uint16(sigAlgo))
+ }
+ })
+ })
+ }
+ if len(m.supportedSignatureAlgorithmsCert) > 0 {
+ b.AddUint16(extensionSignatureAlgorithmsCert)
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ for _, sigAlgo := range m.supportedSignatureAlgorithmsCert {
+ b.AddUint16(uint16(sigAlgo))
+ }
+ })
+ })
+ }
+ if len(m.certificateAuthorities) > 0 {
+ b.AddUint16(extensionCertificateAuthorities)
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ for _, ca := range m.certificateAuthorities {
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(ca)
+ })
+ }
+ })
+ })
+ }
+ })
+ })
+
+ var err error
+ m.raw, err = b.Bytes()
+ return m.raw, err
+}
+
+func (m *certificateRequestMsgTLS13) unmarshal(data []byte) bool {
+ *m = certificateRequestMsgTLS13{raw: data}
+ s := cryptobyte.String(data)
+
+ var context, extensions cryptobyte.String
+ if !s.Skip(4) || // message type and uint24 length field
+ !s.ReadUint8LengthPrefixed(&context) || !context.Empty() ||
+ !s.ReadUint16LengthPrefixed(&extensions) ||
+ !s.Empty() {
+ return false
+ }
+
+ for !extensions.Empty() {
+ var extension uint16
+ var extData cryptobyte.String
+ if !extensions.ReadUint16(&extension) ||
+ !extensions.ReadUint16LengthPrefixed(&extData) {
+ return false
+ }
+
+ switch extension {
+ case extensionStatusRequest:
+ m.ocspStapling = true
+ case extensionSCT:
+ m.scts = true
+ case extensionSignatureAlgorithms:
+ var sigAndAlgs cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() {
+ return false
+ }
+ for !sigAndAlgs.Empty() {
+ var sigAndAlg uint16
+ if !sigAndAlgs.ReadUint16(&sigAndAlg) {
+ return false
+ }
+ m.supportedSignatureAlgorithms = append(
+ m.supportedSignatureAlgorithms, SignatureScheme(sigAndAlg))
+ }
+ case extensionSignatureAlgorithmsCert:
+ var sigAndAlgs cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&sigAndAlgs) || sigAndAlgs.Empty() {
+ return false
+ }
+ for !sigAndAlgs.Empty() {
+ var sigAndAlg uint16
+ if !sigAndAlgs.ReadUint16(&sigAndAlg) {
+ return false
+ }
+ m.supportedSignatureAlgorithmsCert = append(
+ m.supportedSignatureAlgorithmsCert, SignatureScheme(sigAndAlg))
+ }
+ case extensionCertificateAuthorities:
+ var auths cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&auths) || auths.Empty() {
+ return false
+ }
+ for !auths.Empty() {
+ var ca []byte
+ if !readUint16LengthPrefixed(&auths, &ca) || len(ca) == 0 {
+ return false
+ }
+ m.certificateAuthorities = append(m.certificateAuthorities, ca)
+ }
+ default:
+ // Ignore unknown extensions.
+ continue
+ }
+
+ if !extData.Empty() {
+ return false
+ }
+ }
+
+ return true
+}
+
+type certificateMsg struct {
+ raw []byte
+ certificates [][]byte
+}
+
+func (m *certificateMsg) marshal() ([]byte, error) {
+ if m.raw != nil {
+ return m.raw, nil
+ }
+
+ var i int
+ for _, slice := range m.certificates {
+ i += len(slice)
+ }
+
+ length := 3 + 3*len(m.certificates) + i
+ x := make([]byte, 4+length)
+ x[0] = typeCertificate
+ x[1] = uint8(length >> 16)
+ x[2] = uint8(length >> 8)
+ x[3] = uint8(length)
+
+ certificateOctets := length - 3
+ x[4] = uint8(certificateOctets >> 16)
+ x[5] = uint8(certificateOctets >> 8)
+ x[6] = uint8(certificateOctets)
+
+ y := x[7:]
+ for _, slice := range m.certificates {
+ y[0] = uint8(len(slice) >> 16)
+ y[1] = uint8(len(slice) >> 8)
+ y[2] = uint8(len(slice))
+ copy(y[3:], slice)
+ y = y[3+len(slice):]
+ }
+
+ m.raw = x
+ return m.raw, nil
+}
+
+func (m *certificateMsg) unmarshal(data []byte) bool {
+ if len(data) < 7 {
+ return false
+ }
+
+ m.raw = data
+ certsLen := uint32(data[4])<<16 | uint32(data[5])<<8 | uint32(data[6])
+ if uint32(len(data)) != certsLen+7 {
+ return false
+ }
+
+ numCerts := 0
+ d := data[7:]
+ for certsLen > 0 {
+ if len(d) < 4 {
+ return false
+ }
+ certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
+ if uint32(len(d)) < 3+certLen {
+ return false
+ }
+ d = d[3+certLen:]
+ certsLen -= 3 + certLen
+ numCerts++
+ }
+
+ m.certificates = make([][]byte, numCerts)
+ d = data[7:]
+ for i := 0; i < numCerts; i++ {
+ certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2])
+ m.certificates[i] = d[3 : 3+certLen]
+ d = d[3+certLen:]
+ }
+
+ return true
+}
+
+type certificateMsgTLS13 struct {
+ raw []byte
+ certificate Certificate
+ ocspStapling bool
+ scts bool
+}
+
+func (m *certificateMsgTLS13) marshal() ([]byte, error) {
+ if m.raw != nil {
+ return m.raw, nil
+ }
+
+ var b cryptobyte.Builder
+ 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)
+ })
+
+ var err error
+ m.raw, err = b.Bytes()
+ return m.raw, err
+}
+
+func marshalCertificate(b *cryptobyte.Builder, certificate Certificate) {
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ for i, cert := range certificate.Certificate {
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(cert)
+ })
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ if i > 0 {
+ // This library only supports OCSP and SCT for leaf certificates.
+ return
+ }
+ if certificate.OCSPStaple != nil {
+ b.AddUint16(extensionStatusRequest)
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddUint8(statusTypeOCSP)
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(certificate.OCSPStaple)
+ })
+ })
+ }
+ if certificate.SignedCertificateTimestamps != nil {
+ b.AddUint16(extensionSCT)
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ for _, sct := range certificate.SignedCertificateTimestamps {
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(sct)
+ })
+ }
+ })
+ })
+ }
+ })
+ }
+ })
+}
+
+func (m *certificateMsgTLS13) unmarshal(data []byte) bool {
+ *m = certificateMsgTLS13{raw: data}
+ s := cryptobyte.String(data)
+
+ var context cryptobyte.String
+ if !s.Skip(4) || // message type and uint24 length field
+ !s.ReadUint8LengthPrefixed(&context) || !context.Empty() ||
+ !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
+ if !readUint24LengthPrefixed(&certList, &cert) ||
+ !certList.ReadUint16LengthPrefixed(&extensions) {
+ return false
+ }
+ certificate.Certificate = append(certificate.Certificate, cert)
+ for !extensions.Empty() {
+ var extension uint16
+ var extData cryptobyte.String
+ if !extensions.ReadUint16(&extension) ||
+ !extensions.ReadUint16LengthPrefixed(&extData) {
+ return false
+ }
+ if len(certificate.Certificate) > 1 {
+ // This library only supports OCSP and SCT for leaf certificates.
+ continue
+ }
+
+ switch extension {
+ case extensionStatusRequest:
+ var statusType uint8
+ if !extData.ReadUint8(&statusType) || statusType != statusTypeOCSP ||
+ !readUint24LengthPrefixed(&extData, &certificate.OCSPStaple) ||
+ len(certificate.OCSPStaple) == 0 {
+ return false
+ }
+ case extensionSCT:
+ var sctList cryptobyte.String
+ if !extData.ReadUint16LengthPrefixed(&sctList) || sctList.Empty() {
+ return false
+ }
+ for !sctList.Empty() {
+ var sct []byte
+ if !readUint16LengthPrefixed(&sctList, &sct) ||
+ len(sct) == 0 {
+ return false
+ }
+ certificate.SignedCertificateTimestamps = append(
+ certificate.SignedCertificateTimestamps, sct)
+ }
+ default:
+ // Ignore unknown extensions.
+ continue
+ }
+
+ if !extData.Empty() {
+ return false
+ }
+ }
+ }
+ return true
+}
+
+type serverKeyExchangeMsg struct {
+ raw []byte
+ key []byte
+}
+
+func (m *serverKeyExchangeMsg) marshal() ([]byte, error) {
+ if m.raw != nil {
+ return m.raw, nil
+ }
+ length := len(m.key)
+ x := make([]byte, length+4)
+ x[0] = typeServerKeyExchange
+ x[1] = uint8(length >> 16)
+ x[2] = uint8(length >> 8)
+ x[3] = uint8(length)
+ copy(x[4:], m.key)
+
+ m.raw = x
+ return x, nil
+}
+
+func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool {
+ m.raw = data
+ if len(data) < 4 {
+ return false
+ }
+ m.key = data[4:]
+ return true
+}
+
+type certificateStatusMsg struct {
+ raw []byte
+ response []byte
+}
+
+func (m *certificateStatusMsg) marshal() ([]byte, error) {
+ if m.raw != nil {
+ return m.raw, nil
+ }
+
+ var b cryptobyte.Builder
+ b.AddUint8(typeCertificateStatus)
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddUint8(statusTypeOCSP)
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(m.response)
+ })
+ })
+
+ var err error
+ m.raw, err = b.Bytes()
+ return m.raw, err
+}
+
+func (m *certificateStatusMsg) unmarshal(data []byte) bool {
+ m.raw = data
+ s := cryptobyte.String(data)
+
+ var statusType uint8
+ if !s.Skip(4) || // message type and uint24 length field
+ !s.ReadUint8(&statusType) || statusType != statusTypeOCSP ||
+ !readUint24LengthPrefixed(&s, &m.response) ||
+ len(m.response) == 0 || !s.Empty() {
+ return false
+ }
+ return true
+}
+
+type serverHelloDoneMsg struct{}
+
+func (m *serverHelloDoneMsg) marshal() ([]byte, error) {
+ x := make([]byte, 4)
+ x[0] = typeServerHelloDone
+ return x, nil
+}
+
+func (m *serverHelloDoneMsg) unmarshal(data []byte) bool {
+ return len(data) == 4
+}
+
+type clientKeyExchangeMsg struct {
+ raw []byte
+ ciphertext []byte
+}
+
+func (m *clientKeyExchangeMsg) marshal() ([]byte, error) {
+ if m.raw != nil {
+ return m.raw, nil
+ }
+ length := len(m.ciphertext)
+ x := make([]byte, length+4)
+ x[0] = typeClientKeyExchange
+ x[1] = uint8(length >> 16)
+ x[2] = uint8(length >> 8)
+ x[3] = uint8(length)
+ copy(x[4:], m.ciphertext)
+
+ m.raw = x
+ return x, nil
+}
+
+func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool {
+ m.raw = data
+ if len(data) < 4 {
+ return false
+ }
+ l := int(data[1])<<16 | int(data[2])<<8 | int(data[3])
+ if l != len(data)-4 {
+ return false
+ }
+ m.ciphertext = data[4:]
+ return true
+}
+
+type finishedMsg struct {
+ raw []byte
+ verifyData []byte
+}
+
+func (m *finishedMsg) marshal() ([]byte, error) {
+ if m.raw != nil {
+ return m.raw, nil
+ }
+
+ var b cryptobyte.Builder
+ b.AddUint8(typeFinished)
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(m.verifyData)
+ })
+
+ var err error
+ m.raw, err = b.Bytes()
+ return m.raw, err
+}
+
+func (m *finishedMsg) unmarshal(data []byte) bool {
+ m.raw = data
+ s := cryptobyte.String(data)
+ return s.Skip(1) &&
+ readUint24LengthPrefixed(&s, &m.verifyData) &&
+ s.Empty()
+}
+
+type certificateRequestMsg struct {
+ raw []byte
+ // hasSignatureAlgorithm indicates whether this message includes a list of
+ // supported signature algorithms. This change was introduced with TLS 1.2.
+ hasSignatureAlgorithm bool
+
+ certificateTypes []byte
+ supportedSignatureAlgorithms []SignatureScheme
+ certificateAuthorities [][]byte
+}
+
+func (m *certificateRequestMsg) marshal() ([]byte, error) {
+ if m.raw != nil {
+ return m.raw, nil
+ }
+
+ // See RFC 4346, Section 7.4.4.
+ length := 1 + len(m.certificateTypes) + 2
+ casLength := 0
+ for _, ca := range m.certificateAuthorities {
+ casLength += 2 + len(ca)
+ }
+ length += casLength
+
+ if m.hasSignatureAlgorithm {
+ length += 2 + 2*len(m.supportedSignatureAlgorithms)
+ }
+
+ x := make([]byte, 4+length)
+ x[0] = typeCertificateRequest
+ x[1] = uint8(length >> 16)
+ x[2] = uint8(length >> 8)
+ x[3] = uint8(length)
+
+ x[4] = uint8(len(m.certificateTypes))
+
+ copy(x[5:], m.certificateTypes)
+ y := x[5+len(m.certificateTypes):]
+
+ if m.hasSignatureAlgorithm {
+ n := len(m.supportedSignatureAlgorithms) * 2
+ y[0] = uint8(n >> 8)
+ y[1] = uint8(n)
+ y = y[2:]
+ for _, sigAlgo := range m.supportedSignatureAlgorithms {
+ y[0] = uint8(sigAlgo >> 8)
+ y[1] = uint8(sigAlgo)
+ y = y[2:]
+ }
+ }
+
+ y[0] = uint8(casLength >> 8)
+ y[1] = uint8(casLength)
+ y = y[2:]
+ for _, ca := range m.certificateAuthorities {
+ y[0] = uint8(len(ca) >> 8)
+ y[1] = uint8(len(ca))
+ y = y[2:]
+ copy(y, ca)
+ y = y[len(ca):]
+ }
+
+ m.raw = x
+ return m.raw, nil
+}
+
+func (m *certificateRequestMsg) unmarshal(data []byte) bool {
+ m.raw = data
+
+ if len(data) < 5 {
+ return false
+ }
+
+ length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
+ if uint32(len(data))-4 != length {
+ return false
+ }
+
+ numCertTypes := int(data[4])
+ data = data[5:]
+ if numCertTypes == 0 || len(data) <= numCertTypes {
+ return false
+ }
+
+ m.certificateTypes = make([]byte, numCertTypes)
+ if copy(m.certificateTypes, data) != numCertTypes {
+ return false
+ }
+
+ data = data[numCertTypes:]
+
+ if m.hasSignatureAlgorithm {
+ if len(data) < 2 {
+ return false
+ }
+ sigAndHashLen := uint16(data[0])<<8 | uint16(data[1])
+ data = data[2:]
+ if sigAndHashLen&1 != 0 {
+ return false
+ }
+ if len(data) < int(sigAndHashLen) {
+ return false
+ }
+ numSigAlgos := sigAndHashLen / 2
+ m.supportedSignatureAlgorithms = make([]SignatureScheme, numSigAlgos)
+ for i := range m.supportedSignatureAlgorithms {
+ m.supportedSignatureAlgorithms[i] = SignatureScheme(data[0])<<8 | SignatureScheme(data[1])
+ data = data[2:]
+ }
+ }
+
+ if len(data) < 2 {
+ return false
+ }
+ casLength := uint16(data[0])<<8 | uint16(data[1])
+ data = data[2:]
+ if len(data) < int(casLength) {
+ return false
+ }
+ cas := make([]byte, casLength)
+ copy(cas, data)
+ data = data[casLength:]
+
+ m.certificateAuthorities = nil
+ for len(cas) > 0 {
+ if len(cas) < 2 {
+ return false
+ }
+ caLen := uint16(cas[0])<<8 | uint16(cas[1])
+ cas = cas[2:]
+
+ if len(cas) < int(caLen) {
+ return false
+ }
+
+ m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen])
+ cas = cas[caLen:]
+ }
+
+ return len(data) == 0
+}
+
+type certificateVerifyMsg struct {
+ raw []byte
+ hasSignatureAlgorithm bool // format change introduced in TLS 1.2
+ signatureAlgorithm SignatureScheme
+ signature []byte
+}
+
+func (m *certificateVerifyMsg) marshal() ([]byte, error) {
+ if m.raw != nil {
+ return m.raw, nil
+ }
+
+ var b cryptobyte.Builder
+ b.AddUint8(typeCertificateVerify)
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ if m.hasSignatureAlgorithm {
+ b.AddUint16(uint16(m.signatureAlgorithm))
+ }
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(m.signature)
+ })
+ })
+
+ var err error
+ m.raw, err = b.Bytes()
+ return m.raw, err
+}
+
+func (m *certificateVerifyMsg) unmarshal(data []byte) bool {
+ m.raw = data
+ s := cryptobyte.String(data)
+
+ if !s.Skip(4) { // message type and uint24 length field
+ return false
+ }
+ if m.hasSignatureAlgorithm {
+ if !s.ReadUint16((*uint16)(&m.signatureAlgorithm)) {
+ return false
+ }
+ }
+ return readUint16LengthPrefixed(&s, &m.signature) && s.Empty()
+}
+
+type newSessionTicketMsg struct {
+ raw []byte
+ ticket []byte
+}
+
+func (m *newSessionTicketMsg) marshal() ([]byte, error) {
+ if m.raw != nil {
+ return m.raw, nil
+ }
+
+ // See RFC 5077, Section 3.3.
+ ticketLen := len(m.ticket)
+ length := 2 + 4 + ticketLen
+ x := make([]byte, 4+length)
+ x[0] = typeNewSessionTicket
+ x[1] = uint8(length >> 16)
+ x[2] = uint8(length >> 8)
+ x[3] = uint8(length)
+ x[8] = uint8(ticketLen >> 8)
+ x[9] = uint8(ticketLen)
+ copy(x[10:], m.ticket)
+
+ m.raw = x
+
+ return m.raw, nil
+}
+
+func (m *newSessionTicketMsg) unmarshal(data []byte) bool {
+ m.raw = data
+
+ if len(data) < 10 {
+ return false
+ }
+
+ length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3])
+ if uint32(len(data))-4 != length {
+ return false
+ }
+
+ ticketLen := int(data[8])<<8 + int(data[9])
+ if len(data)-10 != ticketLen {
+ return false
+ }
+
+ m.ticket = data[10:]
+
+ return true
+}
+
+type helloRequestMsg struct {
+}
+
+func (*helloRequestMsg) marshal() ([]byte, error) {
+ return []byte{typeHelloRequest, 0, 0, 0}, nil
+}
+
+func (*helloRequestMsg) unmarshal(data []byte) bool {
+ return len(data) == 4
+}
+
+type transcriptHash interface {
+ Write([]byte) (int, error)
+}
+
+// transcriptMsg is a helper used to marshal and hash messages which typically
+// are not written to the wire, and as such aren't hashed during Conn.writeRecord.
+func transcriptMsg(msg handshakeMessage, h transcriptHash) error {
+ data, err := msg.marshal()
+ if err != nil {
+ return err
+ }
+ h.Write(data)
+ return nil
+}
diff --git a/src/crypto/tls/handshake_messages_test.go b/src/crypto/tls/handshake_messages_test.go
new file mode 100644
index 0000000..72e8bd8
--- /dev/null
+++ b/src/crypto/tls/handshake_messages_test.go
@@ -0,0 +1,558 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+ "bytes"
+ "crypto/x509"
+ "encoding/hex"
+ "math"
+ "math/rand"
+ "reflect"
+ "strings"
+ "testing"
+ "testing/quick"
+ "time"
+)
+
+var tests = []handshakeMessage{
+ &clientHelloMsg{},
+ &serverHelloMsg{},
+ &finishedMsg{},
+
+ &certificateMsg{},
+ &certificateRequestMsg{},
+ &certificateVerifyMsg{
+ hasSignatureAlgorithm: true,
+ },
+ &certificateStatusMsg{},
+ &clientKeyExchangeMsg{},
+ &newSessionTicketMsg{},
+ &encryptedExtensionsMsg{},
+ &endOfEarlyDataMsg{},
+ &keyUpdateMsg{},
+ &newSessionTicketMsgTLS13{},
+ &certificateRequestMsgTLS13{},
+ &certificateMsgTLS13{},
+ &SessionState{},
+}
+
+func mustMarshal(t *testing.T, msg handshakeMessage) []byte {
+ t.Helper()
+ b, err := msg.marshal()
+ if err != nil {
+ t.Fatal(err)
+ }
+ return b
+}
+
+func TestMarshalUnmarshal(t *testing.T) {
+ rand := rand.New(rand.NewSource(time.Now().UnixNano()))
+
+ for i, m := range tests {
+ ty := reflect.ValueOf(m).Type()
+
+ n := 100
+ if testing.Short() {
+ n = 5
+ }
+ for j := 0; j < n; j++ {
+ v, ok := quick.Value(ty, rand)
+ if !ok {
+ t.Errorf("#%d: failed to create value", i)
+ break
+ }
+
+ m1 := v.Interface().(handshakeMessage)
+ marshaled := mustMarshal(t, m1)
+ if !m.unmarshal(marshaled) {
+ t.Errorf("#%d failed to unmarshal %#v %x", i, m1, marshaled)
+ break
+ }
+ m.marshal() // to fill any marshal cache in the message
+
+ if m, ok := m.(*SessionState); ok {
+ m.activeCertHandles = nil
+ }
+
+ if !reflect.DeepEqual(m1, m) {
+ t.Errorf("#%d got:%#v want:%#v %x", i, m, m1, marshaled)
+ break
+ }
+
+ if i >= 3 {
+ // The first three message types (ClientHello,
+ // ServerHello and Finished) are allowed to
+ // have parsable prefixes because the extension
+ // data is optional and the length of the
+ // Finished varies across versions.
+ for j := 0; j < len(marshaled); j++ {
+ if m.unmarshal(marshaled[0:j]) {
+ t.Errorf("#%d unmarshaled a prefix of length %d of %#v", i, j, m1)
+ break
+ }
+ }
+ }
+ }
+ }
+}
+
+func TestFuzz(t *testing.T) {
+ rand := rand.New(rand.NewSource(0))
+ for _, m := range tests {
+ for j := 0; j < 1000; j++ {
+ len := rand.Intn(1000)
+ bytes := randomBytes(len, rand)
+ // This just looks for crashes due to bounds errors etc.
+ m.unmarshal(bytes)
+ }
+ }
+}
+
+func randomBytes(n int, rand *rand.Rand) []byte {
+ r := make([]byte, n)
+ if _, err := rand.Read(r); err != nil {
+ panic("rand.Read failed: " + err.Error())
+ }
+ return r
+}
+
+func randomString(n int, rand *rand.Rand) string {
+ b := randomBytes(n, rand)
+ return string(b)
+}
+
+func (*clientHelloMsg) Generate(rand *rand.Rand, size int) reflect.Value {
+ m := &clientHelloMsg{}
+ m.vers = uint16(rand.Intn(65536))
+ m.random = randomBytes(32, rand)
+ m.sessionId = randomBytes(rand.Intn(32), rand)
+ m.cipherSuites = make([]uint16, rand.Intn(63)+1)
+ for i := 0; i < len(m.cipherSuites); i++ {
+ cs := uint16(rand.Int31())
+ if cs == scsvRenegotiation {
+ cs += 1
+ }
+ m.cipherSuites[i] = cs
+ }
+ m.compressionMethods = randomBytes(rand.Intn(63)+1, rand)
+ if rand.Intn(10) > 5 {
+ m.serverName = randomString(rand.Intn(255), rand)
+ for strings.HasSuffix(m.serverName, ".") {
+ m.serverName = m.serverName[:len(m.serverName)-1]
+ }
+ }
+ m.ocspStapling = rand.Intn(10) > 5
+ m.supportedPoints = randomBytes(rand.Intn(5)+1, rand)
+ m.supportedCurves = make([]CurveID, rand.Intn(5)+1)
+ for i := range m.supportedCurves {
+ m.supportedCurves[i] = CurveID(rand.Intn(30000) + 1)
+ }
+ if rand.Intn(10) > 5 {
+ m.ticketSupported = true
+ if rand.Intn(10) > 5 {
+ m.sessionTicket = randomBytes(rand.Intn(300), rand)
+ } else {
+ m.sessionTicket = make([]byte, 0)
+ }
+ }
+ if rand.Intn(10) > 5 {
+ m.supportedSignatureAlgorithms = supportedSignatureAlgorithms()
+ }
+ if rand.Intn(10) > 5 {
+ m.supportedSignatureAlgorithmsCert = supportedSignatureAlgorithms()
+ }
+ for i := 0; i < rand.Intn(5); i++ {
+ m.alpnProtocols = append(m.alpnProtocols, randomString(rand.Intn(20)+1, rand))
+ }
+ if rand.Intn(10) > 5 {
+ m.scts = true
+ }
+ if rand.Intn(10) > 5 {
+ m.secureRenegotiationSupported = true
+ m.secureRenegotiation = randomBytes(rand.Intn(50)+1, rand)
+ }
+ if rand.Intn(10) > 5 {
+ m.extendedMasterSecret = true
+ }
+ for i := 0; i < rand.Intn(5); i++ {
+ m.supportedVersions = append(m.supportedVersions, uint16(rand.Intn(0xffff)+1))
+ }
+ if rand.Intn(10) > 5 {
+ m.cookie = randomBytes(rand.Intn(500)+1, rand)
+ }
+ for i := 0; i < rand.Intn(5); i++ {
+ var ks keyShare
+ ks.group = CurveID(rand.Intn(30000) + 1)
+ ks.data = randomBytes(rand.Intn(200)+1, rand)
+ m.keyShares = append(m.keyShares, ks)
+ }
+ switch rand.Intn(3) {
+ case 1:
+ m.pskModes = []uint8{pskModeDHE}
+ case 2:
+ m.pskModes = []uint8{pskModeDHE, pskModePlain}
+ }
+ for i := 0; i < rand.Intn(5); i++ {
+ var psk pskIdentity
+ psk.obfuscatedTicketAge = uint32(rand.Intn(500000))
+ psk.label = randomBytes(rand.Intn(500)+1, rand)
+ m.pskIdentities = append(m.pskIdentities, psk)
+ m.pskBinders = append(m.pskBinders, randomBytes(rand.Intn(50)+32, rand))
+ }
+ if rand.Intn(10) > 5 {
+ m.quicTransportParameters = randomBytes(rand.Intn(500), rand)
+ }
+ if rand.Intn(10) > 5 {
+ m.earlyData = true
+ }
+
+ return reflect.ValueOf(m)
+}
+
+func (*serverHelloMsg) Generate(rand *rand.Rand, size int) reflect.Value {
+ m := &serverHelloMsg{}
+ m.vers = uint16(rand.Intn(65536))
+ m.random = randomBytes(32, rand)
+ m.sessionId = randomBytes(rand.Intn(32), rand)
+ m.cipherSuite = uint16(rand.Int31())
+ m.compressionMethod = uint8(rand.Intn(256))
+ m.supportedPoints = randomBytes(rand.Intn(5)+1, rand)
+
+ if rand.Intn(10) > 5 {
+ m.ocspStapling = true
+ }
+ if rand.Intn(10) > 5 {
+ m.ticketSupported = true
+ }
+ if rand.Intn(10) > 5 {
+ m.alpnProtocol = randomString(rand.Intn(32)+1, rand)
+ }
+
+ for i := 0; i < rand.Intn(4); i++ {
+ m.scts = append(m.scts, randomBytes(rand.Intn(500)+1, rand))
+ }
+
+ if rand.Intn(10) > 5 {
+ m.secureRenegotiationSupported = true
+ m.secureRenegotiation = randomBytes(rand.Intn(50)+1, rand)
+ }
+ if rand.Intn(10) > 5 {
+ m.extendedMasterSecret = true
+ }
+ if rand.Intn(10) > 5 {
+ m.supportedVersion = uint16(rand.Intn(0xffff) + 1)
+ }
+ if rand.Intn(10) > 5 {
+ m.cookie = randomBytes(rand.Intn(500)+1, rand)
+ }
+ if rand.Intn(10) > 5 {
+ for i := 0; i < rand.Intn(5); i++ {
+ m.serverShare.group = CurveID(rand.Intn(30000) + 1)
+ m.serverShare.data = randomBytes(rand.Intn(200)+1, rand)
+ }
+ } else if rand.Intn(10) > 5 {
+ m.selectedGroup = CurveID(rand.Intn(30000) + 1)
+ }
+ if rand.Intn(10) > 5 {
+ m.selectedIdentityPresent = true
+ m.selectedIdentity = uint16(rand.Intn(0xffff))
+ }
+
+ return reflect.ValueOf(m)
+}
+
+func (*encryptedExtensionsMsg) Generate(rand *rand.Rand, size int) reflect.Value {
+ m := &encryptedExtensionsMsg{}
+
+ if rand.Intn(10) > 5 {
+ m.alpnProtocol = randomString(rand.Intn(32)+1, rand)
+ }
+ if rand.Intn(10) > 5 {
+ m.earlyData = true
+ }
+
+ return reflect.ValueOf(m)
+}
+
+func (*certificateMsg) Generate(rand *rand.Rand, size int) reflect.Value {
+ m := &certificateMsg{}
+ numCerts := rand.Intn(20)
+ m.certificates = make([][]byte, numCerts)
+ for i := 0; i < numCerts; i++ {
+ m.certificates[i] = randomBytes(rand.Intn(10)+1, rand)
+ }
+ return reflect.ValueOf(m)
+}
+
+func (*certificateRequestMsg) Generate(rand *rand.Rand, size int) reflect.Value {
+ m := &certificateRequestMsg{}
+ m.certificateTypes = randomBytes(rand.Intn(5)+1, rand)
+ for i := 0; i < rand.Intn(100); i++ {
+ m.certificateAuthorities = append(m.certificateAuthorities, randomBytes(rand.Intn(15)+1, rand))
+ }
+ return reflect.ValueOf(m)
+}
+
+func (*certificateVerifyMsg) Generate(rand *rand.Rand, size int) reflect.Value {
+ m := &certificateVerifyMsg{}
+ m.hasSignatureAlgorithm = true
+ m.signatureAlgorithm = SignatureScheme(rand.Intn(30000))
+ m.signature = randomBytes(rand.Intn(15)+1, rand)
+ return reflect.ValueOf(m)
+}
+
+func (*certificateStatusMsg) Generate(rand *rand.Rand, size int) reflect.Value {
+ m := &certificateStatusMsg{}
+ m.response = randomBytes(rand.Intn(10)+1, rand)
+ return reflect.ValueOf(m)
+}
+
+func (*clientKeyExchangeMsg) Generate(rand *rand.Rand, size int) reflect.Value {
+ m := &clientKeyExchangeMsg{}
+ m.ciphertext = randomBytes(rand.Intn(1000)+1, rand)
+ return reflect.ValueOf(m)
+}
+
+func (*finishedMsg) Generate(rand *rand.Rand, size int) reflect.Value {
+ m := &finishedMsg{}
+ m.verifyData = randomBytes(12, rand)
+ return reflect.ValueOf(m)
+}
+
+func (*newSessionTicketMsg) Generate(rand *rand.Rand, size int) reflect.Value {
+ m := &newSessionTicketMsg{}
+ m.ticket = randomBytes(rand.Intn(4), rand)
+ return reflect.ValueOf(m)
+}
+
+var sessionTestCerts []*x509.Certificate
+
+func init() {
+ cert, err := x509.ParseCertificate(testRSACertificate)
+ if err != nil {
+ panic(err)
+ }
+ sessionTestCerts = append(sessionTestCerts, cert)
+ cert, err = x509.ParseCertificate(testRSACertificateIssuer)
+ if err != nil {
+ panic(err)
+ }
+ sessionTestCerts = append(sessionTestCerts, cert)
+}
+
+func (*SessionState) Generate(rand *rand.Rand, size int) reflect.Value {
+ s := &SessionState{}
+ isTLS13 := rand.Intn(10) > 5
+ if isTLS13 {
+ s.version = VersionTLS13
+ } else {
+ s.version = uint16(rand.Intn(VersionTLS13))
+ }
+ s.isClient = rand.Intn(10) > 5
+ s.cipherSuite = uint16(rand.Intn(math.MaxUint16))
+ s.createdAt = uint64(rand.Int63())
+ s.secret = randomBytes(rand.Intn(100)+1, 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
+ }
+ if rand.Intn(10) > 5 {
+ s.extMasterSecret = true
+ }
+ if s.isClient || rand.Intn(10) > 5 {
+ if rand.Intn(10) > 5 {
+ s.peerCertificates = sessionTestCerts
+ } else {
+ s.peerCertificates = sessionTestCerts[:1]
+ }
+ }
+ if rand.Intn(10) > 5 && s.peerCertificates != nil {
+ s.ocspResponse = randomBytes(rand.Intn(100)+1, rand)
+ }
+ if rand.Intn(10) > 5 && s.peerCertificates != nil {
+ for i := 0; i < rand.Intn(2)+1; i++ {
+ s.scts = append(s.scts, randomBytes(rand.Intn(500)+1, rand))
+ }
+ }
+ if len(s.peerCertificates) > 0 {
+ for i := 0; i < rand.Intn(3); i++ {
+ if rand.Intn(10) > 5 {
+ s.verifiedChains = append(s.verifiedChains, s.peerCertificates)
+ } else {
+ s.verifiedChains = append(s.verifiedChains, s.peerCertificates[:1])
+ }
+ }
+ }
+ if rand.Intn(10) > 5 && s.EarlyData {
+ s.alpnProtocol = string(randomBytes(rand.Intn(10), rand))
+ }
+ if s.isClient {
+ if isTLS13 {
+ s.useBy = uint64(rand.Int63())
+ s.ageAdd = uint32(rand.Int63() & math.MaxUint32)
+ }
+ }
+ return reflect.ValueOf(s)
+}
+
+func (s *SessionState) marshal() ([]byte, error) { return s.Bytes() }
+func (s *SessionState) unmarshal(b []byte) bool {
+ ss, err := ParseSessionState(b)
+ if err != nil {
+ return false
+ }
+ *s = *ss
+ return true
+}
+
+func (*endOfEarlyDataMsg) Generate(rand *rand.Rand, size int) reflect.Value {
+ m := &endOfEarlyDataMsg{}
+ return reflect.ValueOf(m)
+}
+
+func (*keyUpdateMsg) Generate(rand *rand.Rand, size int) reflect.Value {
+ m := &keyUpdateMsg{}
+ m.updateRequested = rand.Intn(10) > 5
+ return reflect.ValueOf(m)
+}
+
+func (*newSessionTicketMsgTLS13) Generate(rand *rand.Rand, size int) reflect.Value {
+ m := &newSessionTicketMsgTLS13{}
+ m.lifetime = uint32(rand.Intn(500000))
+ m.ageAdd = uint32(rand.Intn(500000))
+ m.nonce = randomBytes(rand.Intn(100), rand)
+ m.label = randomBytes(rand.Intn(1000), rand)
+ if rand.Intn(10) > 5 {
+ m.maxEarlyData = uint32(rand.Intn(500000))
+ }
+ return reflect.ValueOf(m)
+}
+
+func (*certificateRequestMsgTLS13) Generate(rand *rand.Rand, size int) reflect.Value {
+ m := &certificateRequestMsgTLS13{}
+ if rand.Intn(10) > 5 {
+ m.ocspStapling = true
+ }
+ if rand.Intn(10) > 5 {
+ m.scts = true
+ }
+ if rand.Intn(10) > 5 {
+ m.supportedSignatureAlgorithms = supportedSignatureAlgorithms()
+ }
+ if rand.Intn(10) > 5 {
+ m.supportedSignatureAlgorithmsCert = supportedSignatureAlgorithms()
+ }
+ if rand.Intn(10) > 5 {
+ m.certificateAuthorities = make([][]byte, 3)
+ for i := 0; i < 3; i++ {
+ m.certificateAuthorities[i] = randomBytes(rand.Intn(10)+1, rand)
+ }
+ }
+ return reflect.ValueOf(m)
+}
+
+func (*certificateMsgTLS13) Generate(rand *rand.Rand, size int) reflect.Value {
+ m := &certificateMsgTLS13{}
+ for i := 0; i < rand.Intn(2)+1; i++ {
+ m.certificate.Certificate = append(
+ m.certificate.Certificate, randomBytes(rand.Intn(500)+1, rand))
+ }
+ if rand.Intn(10) > 5 {
+ m.ocspStapling = true
+ m.certificate.OCSPStaple = randomBytes(rand.Intn(100)+1, rand)
+ }
+ if rand.Intn(10) > 5 {
+ m.scts = true
+ for i := 0; i < rand.Intn(2)+1; i++ {
+ m.certificate.SignedCertificateTimestamps = append(
+ m.certificate.SignedCertificateTimestamps, randomBytes(rand.Intn(500)+1, rand))
+ }
+ }
+ return reflect.ValueOf(m)
+}
+
+func TestRejectEmptySCTList(t *testing.T) {
+ // RFC 6962, Section 3.3.1 specifies that empty SCT lists are invalid.
+
+ var random [32]byte
+ sct := []byte{0x42, 0x42, 0x42, 0x42}
+ serverHello := &serverHelloMsg{
+ vers: VersionTLS12,
+ random: random[:],
+ scts: [][]byte{sct},
+ }
+ serverHelloBytes := mustMarshal(t, serverHello)
+
+ var serverHelloCopy serverHelloMsg
+ if !serverHelloCopy.unmarshal(serverHelloBytes) {
+ t.Fatal("Failed to unmarshal initial message")
+ }
+
+ // Change serverHelloBytes so that the SCT list is empty
+ i := bytes.Index(serverHelloBytes, sct)
+ if i < 0 {
+ t.Fatal("Cannot find SCT in ServerHello")
+ }
+
+ var serverHelloEmptySCT []byte
+ serverHelloEmptySCT = append(serverHelloEmptySCT, serverHelloBytes[:i-6]...)
+ // Append the extension length and SCT list length for an empty list.
+ serverHelloEmptySCT = append(serverHelloEmptySCT, []byte{0, 2, 0, 0}...)
+ serverHelloEmptySCT = append(serverHelloEmptySCT, serverHelloBytes[i+4:]...)
+
+ // Update the handshake message length.
+ serverHelloEmptySCT[1] = byte((len(serverHelloEmptySCT) - 4) >> 16)
+ serverHelloEmptySCT[2] = byte((len(serverHelloEmptySCT) - 4) >> 8)
+ serverHelloEmptySCT[3] = byte(len(serverHelloEmptySCT) - 4)
+
+ // Update the extensions length
+ serverHelloEmptySCT[42] = byte((len(serverHelloEmptySCT) - 44) >> 8)
+ serverHelloEmptySCT[43] = byte((len(serverHelloEmptySCT) - 44))
+
+ if serverHelloCopy.unmarshal(serverHelloEmptySCT) {
+ t.Fatal("Unmarshaled ServerHello with empty SCT list")
+ }
+}
+
+func TestRejectEmptySCT(t *testing.T) {
+ // Not only must the SCT list be non-empty, but the SCT elements must
+ // not be zero length.
+
+ var random [32]byte
+ serverHello := &serverHelloMsg{
+ vers: VersionTLS12,
+ random: random[:],
+ scts: [][]byte{nil},
+ }
+ serverHelloBytes := mustMarshal(t, serverHello)
+
+ var serverHelloCopy serverHelloMsg
+ if serverHelloCopy.unmarshal(serverHelloBytes) {
+ t.Fatal("Unmarshaled ServerHello with zero-length SCT")
+ }
+}
+
+func TestRejectDuplicateExtensions(t *testing.T) {
+ clientHelloBytes, err := hex.DecodeString("010000440303000000000000000000000000000000000000000000000000000000000000000000000000001c0000000a000800000568656c6c6f0000000a000800000568656c6c6f")
+ if err != nil {
+ t.Fatalf("failed to decode test ClientHello: %s", err)
+ }
+ var clientHelloCopy clientHelloMsg
+ if clientHelloCopy.unmarshal(clientHelloBytes) {
+ t.Error("Unmarshaled ClientHello with duplicate extensions")
+ }
+
+ serverHelloBytes, err := hex.DecodeString("02000030030300000000000000000000000000000000000000000000000000000000000000000000000000080005000000050000")
+ if err != nil {
+ t.Fatalf("failed to decode test ServerHello: %s", err)
+ }
+ var serverHelloCopy serverHelloMsg
+ if serverHelloCopy.unmarshal(serverHelloBytes) {
+ t.Fatal("Unmarshaled ServerHello with duplicate extensions")
+ }
+}
diff --git a/src/crypto/tls/handshake_server.go b/src/crypto/tls/handshake_server.go
new file mode 100644
index 0000000..996b23b
--- /dev/null
+++ b/src/crypto/tls/handshake_server.go
@@ -0,0 +1,954 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+ "context"
+ "crypto"
+ "crypto/ecdsa"
+ "crypto/ed25519"
+ "crypto/rsa"
+ "crypto/subtle"
+ "crypto/x509"
+ "errors"
+ "fmt"
+ "hash"
+ "io"
+ "time"
+)
+
+// serverHandshakeState contains details of a server handshake in progress.
+// It's discarded once the handshake has completed.
+type serverHandshakeState struct {
+ c *Conn
+ ctx context.Context
+ clientHello *clientHelloMsg
+ hello *serverHelloMsg
+ suite *cipherSuite
+ ecdheOk bool
+ ecSignOk bool
+ rsaDecryptOk bool
+ rsaSignOk bool
+ sessionState *SessionState
+ finishedHash finishedHash
+ masterSecret []byte
+ cert *Certificate
+}
+
+// serverHandshake performs a TLS handshake as a server.
+func (c *Conn) serverHandshake(ctx context.Context) error {
+ clientHello, err := c.readClientHello(ctx)
+ if err != nil {
+ return err
+ }
+
+ if c.vers == VersionTLS13 {
+ hs := serverHandshakeStateTLS13{
+ c: c,
+ ctx: ctx,
+ clientHello: clientHello,
+ }
+ return hs.handshake()
+ }
+
+ hs := serverHandshakeState{
+ c: c,
+ ctx: ctx,
+ clientHello: clientHello,
+ }
+ return hs.handshake()
+}
+
+func (hs *serverHandshakeState) handshake() error {
+ c := hs.c
+
+ if err := hs.processClientHello(); err != nil {
+ return err
+ }
+
+ // For an overview of TLS handshaking, see RFC 5246, Section 7.3.
+ c.buffering = true
+ if err := hs.checkForResumption(); err != nil {
+ return err
+ }
+ if hs.sessionState != nil {
+ // The client has included a session ticket and so we do an abbreviated handshake.
+ if err := hs.doResumeHandshake(); err != nil {
+ return err
+ }
+ if err := hs.establishKeys(); err != nil {
+ return err
+ }
+ if err := hs.sendSessionTicket(); err != nil {
+ return err
+ }
+ if err := hs.sendFinished(c.serverFinished[:]); err != nil {
+ return err
+ }
+ if _, err := c.flush(); err != nil {
+ return err
+ }
+ c.clientFinishedIsFirst = false
+ if err := hs.readFinished(nil); err != nil {
+ return err
+ }
+ } else {
+ // The client didn't include a session ticket, or it wasn't
+ // valid so we do a full handshake.
+ if err := hs.pickCipherSuite(); err != nil {
+ return err
+ }
+ if err := hs.doFullHandshake(); err != nil {
+ return err
+ }
+ if err := hs.establishKeys(); err != nil {
+ return err
+ }
+ if err := hs.readFinished(c.clientFinished[:]); err != nil {
+ return err
+ }
+ c.clientFinishedIsFirst = true
+ c.buffering = true
+ if err := hs.sendSessionTicket(); err != nil {
+ return err
+ }
+ if err := hs.sendFinished(nil); err != nil {
+ return err
+ }
+ if _, err := c.flush(); err != nil {
+ return err
+ }
+ }
+
+ c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random)
+ c.isHandshakeComplete.Store(true)
+
+ return nil
+}
+
+// readClientHello reads a ClientHello message and selects the protocol version.
+func (c *Conn) readClientHello(ctx context.Context) (*clientHelloMsg, error) {
+ // clientHelloMsg is included in the transcript, but we haven't initialized
+ // it yet. The respective handshake functions will record it themselves.
+ msg, err := c.readHandshake(nil)
+ if err != nil {
+ return nil, err
+ }
+ clientHello, ok := msg.(*clientHelloMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return nil, unexpectedMessageError(clientHello, msg)
+ }
+
+ var configForClient *Config
+ originalConfig := c.config
+ if c.config.GetConfigForClient != nil {
+ chi := clientHelloInfo(ctx, c, clientHello)
+ if configForClient, err = c.config.GetConfigForClient(chi); err != nil {
+ c.sendAlert(alertInternalError)
+ return nil, err
+ } else if configForClient != nil {
+ c.config = configForClient
+ }
+ }
+ c.ticketKeys = originalConfig.ticketKeys(configForClient)
+
+ clientVersions := clientHello.supportedVersions
+ if len(clientHello.supportedVersions) == 0 {
+ clientVersions = supportedVersionsFromMax(clientHello.vers)
+ }
+ c.vers, ok = c.config.mutualVersion(roleServer, clientVersions)
+ if !ok {
+ c.sendAlert(alertProtocolVersion)
+ return nil, fmt.Errorf("tls: client offered only unsupported versions: %x", clientVersions)
+ }
+ c.haveVers = true
+ c.in.version = c.vers
+ c.out.version = c.vers
+
+ return clientHello, nil
+}
+
+func (hs *serverHandshakeState) processClientHello() error {
+ c := hs.c
+
+ hs.hello = new(serverHelloMsg)
+ hs.hello.vers = c.vers
+
+ foundCompression := false
+ // We only support null compression, so check that the client offered it.
+ for _, compression := range hs.clientHello.compressionMethods {
+ if compression == compressionNone {
+ foundCompression = true
+ break
+ }
+ }
+
+ if !foundCompression {
+ c.sendAlert(alertHandshakeFailure)
+ return errors.New("tls: client does not support uncompressed connections")
+ }
+
+ hs.hello.random = make([]byte, 32)
+ serverRandom := hs.hello.random
+ // Downgrade protection canaries. See RFC 8446, Section 4.1.3.
+ maxVers := c.config.maxSupportedVersion(roleServer)
+ if maxVers >= VersionTLS12 && c.vers < maxVers || testingOnlyForceDowngradeCanary {
+ if c.vers == VersionTLS12 {
+ copy(serverRandom[24:], downgradeCanaryTLS12)
+ } else {
+ copy(serverRandom[24:], downgradeCanaryTLS11)
+ }
+ serverRandom = serverRandom[:24]
+ }
+ _, err := io.ReadFull(c.config.rand(), serverRandom)
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+
+ if len(hs.clientHello.secureRenegotiation) != 0 {
+ c.sendAlert(alertHandshakeFailure)
+ return errors.New("tls: initial handshake had non-empty renegotiation extension")
+ }
+
+ hs.hello.extendedMasterSecret = hs.clientHello.extendedMasterSecret
+ hs.hello.secureRenegotiationSupported = hs.clientHello.secureRenegotiationSupported
+ hs.hello.compressionMethod = compressionNone
+ if len(hs.clientHello.serverName) > 0 {
+ c.serverName = hs.clientHello.serverName
+ }
+
+ selectedProto, err := negotiateALPN(c.config.NextProtos, hs.clientHello.alpnProtocols, false)
+ if err != nil {
+ c.sendAlert(alertNoApplicationProtocol)
+ return err
+ }
+ hs.hello.alpnProtocol = selectedProto
+ c.clientProtocol = selectedProto
+
+ hs.cert, err = c.config.getCertificate(clientHelloInfo(hs.ctx, c, hs.clientHello))
+ if err != nil {
+ if err == errNoCertificates {
+ c.sendAlert(alertUnrecognizedName)
+ } else {
+ c.sendAlert(alertInternalError)
+ }
+ return err
+ }
+ if hs.clientHello.scts {
+ hs.hello.scts = hs.cert.SignedCertificateTimestamps
+ }
+
+ hs.ecdheOk = supportsECDHE(c.config, hs.clientHello.supportedCurves, hs.clientHello.supportedPoints)
+
+ if hs.ecdheOk && len(hs.clientHello.supportedPoints) > 0 {
+ // Although omitting the ec_point_formats extension is permitted, some
+ // old OpenSSL version will refuse to handshake if not present.
+ //
+ // Per RFC 4492, section 5.1.2, implementations MUST support the
+ // uncompressed point format. See golang.org/issue/31943.
+ hs.hello.supportedPoints = []uint8{pointFormatUncompressed}
+ }
+
+ if priv, ok := hs.cert.PrivateKey.(crypto.Signer); ok {
+ switch priv.Public().(type) {
+ case *ecdsa.PublicKey:
+ hs.ecSignOk = true
+ case ed25519.PublicKey:
+ hs.ecSignOk = true
+ case *rsa.PublicKey:
+ hs.rsaSignOk = true
+ default:
+ c.sendAlert(alertInternalError)
+ return fmt.Errorf("tls: unsupported signing key type (%T)", priv.Public())
+ }
+ }
+ if priv, ok := hs.cert.PrivateKey.(crypto.Decrypter); ok {
+ switch priv.Public().(type) {
+ case *rsa.PublicKey:
+ hs.rsaDecryptOk = true
+ default:
+ c.sendAlert(alertInternalError)
+ return fmt.Errorf("tls: unsupported decryption key type (%T)", priv.Public())
+ }
+ }
+
+ return nil
+}
+
+// negotiateALPN picks a shared ALPN protocol that both sides support in server
+// preference order. If ALPN is not configured or the peer doesn't support it,
+// it returns "" and no error.
+func negotiateALPN(serverProtos, clientProtos []string, quic bool) (string, error) {
+ if len(serverProtos) == 0 || len(clientProtos) == 0 {
+ if quic && len(serverProtos) != 0 {
+ // RFC 9001, Section 8.1
+ return "", fmt.Errorf("tls: client did not request an application protocol")
+ }
+ return "", nil
+ }
+ var http11fallback bool
+ for _, s := range serverProtos {
+ for _, c := range clientProtos {
+ if s == c {
+ return s, nil
+ }
+ if s == "h2" && c == "http/1.1" {
+ http11fallback = true
+ }
+ }
+ }
+ // As a special case, let http/1.1 clients connect to h2 servers as if they
+ // didn't support ALPN. We used not to enforce protocol overlap, so over
+ // time a number of HTTP servers were configured with only "h2", but
+ // expected to accept connections from "http/1.1" clients. See Issue 46310.
+ if http11fallback {
+ return "", nil
+ }
+ return "", fmt.Errorf("tls: client requested unsupported application protocols (%s)", clientProtos)
+}
+
+// supportsECDHE returns whether ECDHE key exchanges can be used with this
+// pre-TLS 1.3 client.
+func supportsECDHE(c *Config, supportedCurves []CurveID, supportedPoints []uint8) bool {
+ supportsCurve := false
+ for _, curve := range supportedCurves {
+ if c.supportsCurve(curve) {
+ supportsCurve = true
+ break
+ }
+ }
+
+ supportsPointFormat := false
+ for _, pointFormat := range supportedPoints {
+ if pointFormat == pointFormatUncompressed {
+ supportsPointFormat = true
+ break
+ }
+ }
+ // Per RFC 8422, Section 5.1.2, if the Supported Point Formats extension is
+ // missing, uncompressed points are supported. If supportedPoints is empty,
+ // the extension must be missing, as an empty extension body is rejected by
+ // the parser. See https://go.dev/issue/49126.
+ if len(supportedPoints) == 0 {
+ supportsPointFormat = true
+ }
+
+ return supportsCurve && supportsPointFormat
+}
+
+func (hs *serverHandshakeState) pickCipherSuite() error {
+ c := hs.c
+
+ preferenceOrder := cipherSuitesPreferenceOrder
+ if !hasAESGCMHardwareSupport || !aesgcmPreferred(hs.clientHello.cipherSuites) {
+ preferenceOrder = cipherSuitesPreferenceOrderNoAES
+ }
+
+ configCipherSuites := c.config.cipherSuites()
+ preferenceList := make([]uint16, 0, len(configCipherSuites))
+ for _, suiteID := range preferenceOrder {
+ for _, id := range configCipherSuites {
+ if id == suiteID {
+ preferenceList = append(preferenceList, id)
+ break
+ }
+ }
+ }
+
+ hs.suite = selectCipherSuite(preferenceList, hs.clientHello.cipherSuites, hs.cipherSuiteOk)
+ if hs.suite == nil {
+ c.sendAlert(alertHandshakeFailure)
+ return errors.New("tls: no cipher suite supported by both client and server")
+ }
+ c.cipherSuite = hs.suite.id
+
+ for _, id := range hs.clientHello.cipherSuites {
+ if id == TLS_FALLBACK_SCSV {
+ // The client is doing a fallback connection. See RFC 7507.
+ if hs.clientHello.vers < c.config.maxSupportedVersion(roleServer) {
+ c.sendAlert(alertInappropriateFallback)
+ return errors.New("tls: client using inappropriate protocol fallback")
+ }
+ break
+ }
+ }
+
+ return nil
+}
+
+func (hs *serverHandshakeState) cipherSuiteOk(c *cipherSuite) bool {
+ if c.flags&suiteECDHE != 0 {
+ if !hs.ecdheOk {
+ return false
+ }
+ if c.flags&suiteECSign != 0 {
+ if !hs.ecSignOk {
+ return false
+ }
+ } else if !hs.rsaSignOk {
+ return false
+ }
+ } else if !hs.rsaDecryptOk {
+ return false
+ }
+ if hs.c.vers < VersionTLS12 && c.flags&suiteTLS12 != 0 {
+ return false
+ }
+ return true
+}
+
+// checkForResumption reports whether we should perform resumption on this connection.
+func (hs *serverHandshakeState) checkForResumption() error {
+ c := hs.c
+
+ if c.config.SessionTicketsDisabled {
+ return nil
+ }
+
+ var sessionState *SessionState
+ if c.config.UnwrapSession != nil {
+ ss, err := c.config.UnwrapSession(hs.clientHello.sessionTicket, c.connectionStateLocked())
+ if err != nil {
+ return err
+ }
+ if ss == nil {
+ return nil
+ }
+ sessionState = ss
+ } else {
+ plaintext := c.config.decryptTicket(hs.clientHello.sessionTicket, c.ticketKeys)
+ if plaintext == nil {
+ return nil
+ }
+ ss, err := ParseSessionState(plaintext)
+ if err != nil {
+ return nil
+ }
+ sessionState = ss
+ }
+
+ // TLS 1.2 tickets don't natively have a lifetime, but we want to avoid
+ // re-wrapping the same master secret in different tickets over and over for
+ // too long, weakening forward secrecy.
+ createdAt := time.Unix(int64(sessionState.createdAt), 0)
+ if c.config.time().Sub(createdAt) > maxSessionTicketLifetime {
+ return nil
+ }
+
+ // Never resume a session for a different TLS version.
+ if c.vers != sessionState.version {
+ return nil
+ }
+
+ cipherSuiteOk := false
+ // Check that the client is still offering the ciphersuite in the session.
+ for _, id := range hs.clientHello.cipherSuites {
+ if id == sessionState.cipherSuite {
+ cipherSuiteOk = true
+ break
+ }
+ }
+ if !cipherSuiteOk {
+ return nil
+ }
+
+ // Check that we also support the ciphersuite from the session.
+ suite := selectCipherSuite([]uint16{sessionState.cipherSuite},
+ c.config.cipherSuites(), hs.cipherSuiteOk)
+ if suite == nil {
+ return nil
+ }
+
+ sessionHasClientCerts := len(sessionState.peerCertificates) != 0
+ needClientCerts := requiresClientCert(c.config.ClientAuth)
+ if needClientCerts && !sessionHasClientCerts {
+ return nil
+ }
+ if sessionHasClientCerts && c.config.ClientAuth == NoClientCert {
+ return nil
+ }
+ if sessionHasClientCerts && c.config.time().After(sessionState.peerCertificates[0].NotAfter) {
+ return nil
+ }
+ if sessionHasClientCerts && c.config.ClientAuth >= VerifyClientCertIfGiven &&
+ len(sessionState.verifiedChains) == 0 {
+ return nil
+ }
+
+ // RFC 7627, Section 5.3
+ if !sessionState.extMasterSecret && hs.clientHello.extendedMasterSecret {
+ return nil
+ }
+ if sessionState.extMasterSecret && !hs.clientHello.extendedMasterSecret {
+ // Aborting is somewhat harsh, but it's a MUST and it would indicate a
+ // weird downgrade in client capabilities.
+ return errors.New("tls: session supported extended_master_secret but client does not")
+ }
+
+ c.peerCertificates = sessionState.peerCertificates
+ c.ocspResponse = sessionState.ocspResponse
+ c.scts = sessionState.scts
+ c.verifiedChains = sessionState.verifiedChains
+ c.extMasterSecret = sessionState.extMasterSecret
+ hs.sessionState = sessionState
+ hs.suite = suite
+ c.didResume = true
+ return nil
+}
+
+func (hs *serverHandshakeState) doResumeHandshake() error {
+ c := hs.c
+
+ hs.hello.cipherSuite = hs.suite.id
+ c.cipherSuite = hs.suite.id
+ // We echo the client's session ID in the ServerHello to let it know
+ // that we're doing a resumption.
+ hs.hello.sessionId = hs.clientHello.sessionId
+ // We always send a new session ticket, even if it wraps the same master
+ // secret and it's potentially encrypted with the same key, to help the
+ // client avoid cross-connection tracking from a network observer.
+ hs.hello.ticketSupported = true
+ hs.finishedHash = newFinishedHash(c.vers, hs.suite)
+ hs.finishedHash.discardHandshakeBuffer()
+ if err := transcriptMsg(hs.clientHello, &hs.finishedHash); err != nil {
+ return err
+ }
+ if _, err := hs.c.writeHandshakeRecord(hs.hello, &hs.finishedHash); err != nil {
+ return err
+ }
+
+ if c.config.VerifyConnection != nil {
+ if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
+ c.sendAlert(alertBadCertificate)
+ return err
+ }
+ }
+
+ hs.masterSecret = hs.sessionState.secret
+
+ return nil
+}
+
+func (hs *serverHandshakeState) doFullHandshake() error {
+ c := hs.c
+
+ if hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0 {
+ hs.hello.ocspStapling = true
+ }
+
+ hs.hello.ticketSupported = hs.clientHello.ticketSupported && !c.config.SessionTicketsDisabled
+ hs.hello.cipherSuite = hs.suite.id
+
+ hs.finishedHash = newFinishedHash(hs.c.vers, hs.suite)
+ if c.config.ClientAuth == NoClientCert {
+ // No need to keep a full record of the handshake if client
+ // certificates won't be used.
+ hs.finishedHash.discardHandshakeBuffer()
+ }
+ if err := transcriptMsg(hs.clientHello, &hs.finishedHash); err != nil {
+ return err
+ }
+ if _, err := hs.c.writeHandshakeRecord(hs.hello, &hs.finishedHash); err != nil {
+ return err
+ }
+
+ certMsg := new(certificateMsg)
+ certMsg.certificates = hs.cert.Certificate
+ if _, err := hs.c.writeHandshakeRecord(certMsg, &hs.finishedHash); err != nil {
+ return err
+ }
+
+ if hs.hello.ocspStapling {
+ certStatus := new(certificateStatusMsg)
+ certStatus.response = hs.cert.OCSPStaple
+ if _, err := hs.c.writeHandshakeRecord(certStatus, &hs.finishedHash); err != nil {
+ return err
+ }
+ }
+
+ keyAgreement := hs.suite.ka(c.vers)
+ skx, err := keyAgreement.generateServerKeyExchange(c.config, hs.cert, hs.clientHello, hs.hello)
+ if err != nil {
+ c.sendAlert(alertHandshakeFailure)
+ return err
+ }
+ if skx != nil {
+ if _, err := hs.c.writeHandshakeRecord(skx, &hs.finishedHash); err != nil {
+ return err
+ }
+ }
+
+ var certReq *certificateRequestMsg
+ if c.config.ClientAuth >= RequestClientCert {
+ // Request a client certificate
+ certReq = new(certificateRequestMsg)
+ certReq.certificateTypes = []byte{
+ byte(certTypeRSASign),
+ byte(certTypeECDSASign),
+ }
+ if c.vers >= VersionTLS12 {
+ certReq.hasSignatureAlgorithm = true
+ certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms()
+ }
+
+ // An empty list of certificateAuthorities signals to
+ // the client that it may send any certificate in response
+ // to our request. When we know the CAs we trust, then
+ // we can send them down, so that the client can choose
+ // an appropriate certificate to give to us.
+ if c.config.ClientCAs != nil {
+ certReq.certificateAuthorities = c.config.ClientCAs.Subjects()
+ }
+ if _, err := hs.c.writeHandshakeRecord(certReq, &hs.finishedHash); err != nil {
+ return err
+ }
+ }
+
+ helloDone := new(serverHelloDoneMsg)
+ if _, err := hs.c.writeHandshakeRecord(helloDone, &hs.finishedHash); err != nil {
+ return err
+ }
+
+ if _, err := c.flush(); err != nil {
+ return err
+ }
+
+ var pub crypto.PublicKey // public key for client auth, if any
+
+ msg, err := c.readHandshake(&hs.finishedHash)
+ if err != nil {
+ return err
+ }
+
+ // If we requested a client certificate, then the client must send a
+ // certificate message, even if it's empty.
+ if c.config.ClientAuth >= RequestClientCert {
+ certMsg, ok := msg.(*certificateMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(certMsg, msg)
+ }
+
+ if err := c.processCertsFromClient(Certificate{
+ Certificate: certMsg.certificates,
+ }); err != nil {
+ return err
+ }
+ if len(certMsg.certificates) != 0 {
+ pub = c.peerCertificates[0].PublicKey
+ }
+
+ msg, err = c.readHandshake(&hs.finishedHash)
+ if err != nil {
+ return err
+ }
+ }
+ if c.config.VerifyConnection != nil {
+ if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
+ c.sendAlert(alertBadCertificate)
+ return err
+ }
+ }
+
+ // Get client key exchange
+ ckx, ok := msg.(*clientKeyExchangeMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(ckx, msg)
+ }
+
+ preMasterSecret, err := keyAgreement.processClientKeyExchange(c.config, hs.cert, ckx, c.vers)
+ if err != nil {
+ c.sendAlert(alertHandshakeFailure)
+ return err
+ }
+ if hs.hello.extendedMasterSecret {
+ c.extMasterSecret = true
+ hs.masterSecret = extMasterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret,
+ hs.finishedHash.Sum())
+ } else {
+ hs.masterSecret = masterFromPreMasterSecret(c.vers, hs.suite, preMasterSecret,
+ hs.clientHello.random, hs.hello.random)
+ }
+ if err := c.config.writeKeyLog(keyLogLabelTLS12, hs.clientHello.random, hs.masterSecret); err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+
+ // If we received a client cert in response to our certificate request message,
+ // the client will send us a certificateVerifyMsg immediately after the
+ // clientKeyExchangeMsg. This message is a digest of all preceding
+ // handshake-layer messages that is signed using the private key corresponding
+ // to the client's certificate. This allows us to verify that the client is in
+ // possession of the private key of the certificate.
+ if len(c.peerCertificates) > 0 {
+ // certificateVerifyMsg is included in the transcript, but not until
+ // after we verify the handshake signature, since the state before
+ // this message was sent is used.
+ msg, err = c.readHandshake(nil)
+ if err != nil {
+ return err
+ }
+ certVerify, ok := msg.(*certificateVerifyMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(certVerify, msg)
+ }
+
+ var sigType uint8
+ var sigHash crypto.Hash
+ if c.vers >= VersionTLS12 {
+ if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, certReq.supportedSignatureAlgorithms) {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: client certificate used with invalid signature algorithm")
+ }
+ sigType, sigHash, err = typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm)
+ if err != nil {
+ return c.sendAlert(alertInternalError)
+ }
+ } else {
+ sigType, sigHash, err = legacyTypeAndHashFromPublicKey(pub)
+ if err != nil {
+ c.sendAlert(alertIllegalParameter)
+ return err
+ }
+ }
+
+ signed := hs.finishedHash.hashForClientCertificate(sigType, sigHash)
+ if err := verifyHandshakeSignature(sigType, pub, sigHash, signed, certVerify.signature); err != nil {
+ c.sendAlert(alertDecryptError)
+ return errors.New("tls: invalid signature by the client certificate: " + err.Error())
+ }
+
+ if err := transcriptMsg(certVerify, &hs.finishedHash); err != nil {
+ return err
+ }
+ }
+
+ hs.finishedHash.discardHandshakeBuffer()
+
+ return nil
+}
+
+func (hs *serverHandshakeState) establishKeys() error {
+ c := hs.c
+
+ clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV :=
+ keysFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen)
+
+ var clientCipher, serverCipher any
+ var clientHash, serverHash hash.Hash
+
+ if hs.suite.aead == nil {
+ clientCipher = hs.suite.cipher(clientKey, clientIV, true /* for reading */)
+ clientHash = hs.suite.mac(clientMAC)
+ serverCipher = hs.suite.cipher(serverKey, serverIV, false /* not for reading */)
+ serverHash = hs.suite.mac(serverMAC)
+ } else {
+ clientCipher = hs.suite.aead(clientKey, clientIV)
+ serverCipher = hs.suite.aead(serverKey, serverIV)
+ }
+
+ c.in.prepareCipherSpec(c.vers, clientCipher, clientHash)
+ c.out.prepareCipherSpec(c.vers, serverCipher, serverHash)
+
+ return nil
+}
+
+func (hs *serverHandshakeState) readFinished(out []byte) error {
+ c := hs.c
+
+ if err := c.readChangeCipherSpec(); err != nil {
+ return err
+ }
+
+ // finishedMsg is included in the transcript, but not until after we
+ // check the client version, since the state before this message was
+ // sent is used during verification.
+ msg, err := c.readHandshake(nil)
+ if err != nil {
+ return err
+ }
+ clientFinished, ok := msg.(*finishedMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(clientFinished, msg)
+ }
+
+ verify := hs.finishedHash.clientSum(hs.masterSecret)
+ if len(verify) != len(clientFinished.verifyData) ||
+ subtle.ConstantTimeCompare(verify, clientFinished.verifyData) != 1 {
+ c.sendAlert(alertHandshakeFailure)
+ return errors.New("tls: client's Finished message is incorrect")
+ }
+
+ if err := transcriptMsg(clientFinished, &hs.finishedHash); err != nil {
+ return err
+ }
+
+ copy(out, verify)
+ return nil
+}
+
+func (hs *serverHandshakeState) sendSessionTicket() error {
+ if !hs.hello.ticketSupported {
+ return nil
+ }
+
+ c := hs.c
+ m := new(newSessionTicketMsg)
+
+ state, err := c.sessionState()
+ if err != nil {
+ return err
+ }
+ state.secret = hs.masterSecret
+ if hs.sessionState != nil {
+ // If this is re-wrapping an old key, then keep
+ // the original time it was created.
+ state.createdAt = hs.sessionState.createdAt
+ }
+ if c.config.WrapSession != nil {
+ m.ticket, err = c.config.WrapSession(c.connectionStateLocked(), state)
+ if err != nil {
+ return err
+ }
+ } else {
+ stateBytes, err := state.Bytes()
+ if err != nil {
+ return err
+ }
+ m.ticket, err = c.config.encryptTicket(stateBytes, c.ticketKeys)
+ if err != nil {
+ return err
+ }
+ }
+
+ if _, err := hs.c.writeHandshakeRecord(m, &hs.finishedHash); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (hs *serverHandshakeState) sendFinished(out []byte) error {
+ c := hs.c
+
+ if err := c.writeChangeCipherRecord(); err != nil {
+ return err
+ }
+
+ finished := new(finishedMsg)
+ finished.verifyData = hs.finishedHash.serverSum(hs.masterSecret)
+ if _, err := hs.c.writeHandshakeRecord(finished, &hs.finishedHash); err != nil {
+ return err
+ }
+
+ copy(out, finished.verifyData)
+
+ return nil
+}
+
+// processCertsFromClient takes a chain of client certificates either from a
+// Certificates message and verifies them.
+func (c *Conn) processCertsFromClient(certificate Certificate) error {
+ certificates := certificate.Certificate
+ certs := make([]*x509.Certificate, len(certificates))
+ var err error
+ for i, asn1Data := range certificates {
+ if certs[i], err = x509.ParseCertificate(asn1Data); err != nil {
+ c.sendAlert(alertBadCertificate)
+ return errors.New("tls: failed to parse client certificate: " + err.Error())
+ }
+ if certs[i].PublicKeyAlgorithm == x509.RSA {
+ n := certs[i].PublicKey.(*rsa.PublicKey).N.BitLen()
+ if max, ok := checkKeySize(n); !ok {
+ c.sendAlert(alertBadCertificate)
+ return fmt.Errorf("tls: client sent certificate containing RSA key larger than %d bits", max)
+ }
+ }
+ }
+
+ if len(certs) == 0 && requiresClientCert(c.config.ClientAuth) {
+ if c.vers == VersionTLS13 {
+ c.sendAlert(alertCertificateRequired)
+ } else {
+ c.sendAlert(alertBadCertificate)
+ }
+ return errors.New("tls: client didn't provide a certificate")
+ }
+
+ if c.config.ClientAuth >= VerifyClientCertIfGiven && len(certs) > 0 {
+ opts := x509.VerifyOptions{
+ Roots: c.config.ClientCAs,
+ CurrentTime: c.config.time(),
+ Intermediates: x509.NewCertPool(),
+ KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
+ }
+
+ for _, cert := range certs[1:] {
+ opts.Intermediates.AddCert(cert)
+ }
+
+ chains, err := certs[0].Verify(opts)
+ if err != nil {
+ var errCertificateInvalid x509.CertificateInvalidError
+ if errors.As(err, &x509.UnknownAuthorityError{}) {
+ c.sendAlert(alertUnknownCA)
+ } else if errors.As(err, &errCertificateInvalid) && errCertificateInvalid.Reason == x509.Expired {
+ c.sendAlert(alertCertificateExpired)
+ } else {
+ c.sendAlert(alertBadCertificate)
+ }
+ return &CertificateVerificationError{UnverifiedCertificates: certs, Err: err}
+ }
+
+ c.verifiedChains = chains
+ }
+
+ c.peerCertificates = certs
+ c.ocspResponse = certificate.OCSPStaple
+ c.scts = certificate.SignedCertificateTimestamps
+
+ if len(certs) > 0 {
+ switch certs[0].PublicKey.(type) {
+ case *ecdsa.PublicKey, *rsa.PublicKey, ed25519.PublicKey:
+ default:
+ c.sendAlert(alertUnsupportedCertificate)
+ return fmt.Errorf("tls: client certificate contains an unsupported public key of type %T", certs[0].PublicKey)
+ }
+ }
+
+ if c.config.VerifyPeerCertificate != nil {
+ if err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil {
+ c.sendAlert(alertBadCertificate)
+ return err
+ }
+ }
+
+ return nil
+}
+
+func clientHelloInfo(ctx context.Context, c *Conn, clientHello *clientHelloMsg) *ClientHelloInfo {
+ supportedVersions := clientHello.supportedVersions
+ if len(clientHello.supportedVersions) == 0 {
+ supportedVersions = supportedVersionsFromMax(clientHello.vers)
+ }
+
+ return &ClientHelloInfo{
+ CipherSuites: clientHello.cipherSuites,
+ ServerName: clientHello.serverName,
+ SupportedCurves: clientHello.supportedCurves,
+ SupportedPoints: clientHello.supportedPoints,
+ SignatureSchemes: clientHello.supportedSignatureAlgorithms,
+ SupportedProtos: clientHello.alpnProtocols,
+ SupportedVersions: supportedVersions,
+ Conn: c.conn,
+ config: c.config,
+ ctx: ctx,
+ }
+}
diff --git a/src/crypto/tls/handshake_server_test.go b/src/crypto/tls/handshake_server_test.go
new file mode 100644
index 0000000..04abdcc
--- /dev/null
+++ b/src/crypto/tls/handshake_server_test.go
@@ -0,0 +1,2047 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+ "bytes"
+ "context"
+ "crypto"
+ "crypto/ecdh"
+ "crypto/elliptic"
+ "crypto/rand"
+ "crypto/x509"
+ "encoding/pem"
+ "errors"
+ "fmt"
+ "io"
+ "net"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "runtime"
+ "strings"
+ "testing"
+ "time"
+)
+
+func testClientHello(t *testing.T, serverConfig *Config, m handshakeMessage) {
+ testClientHelloFailure(t, serverConfig, m, "")
+}
+
+// testFatal is a hack to prevent the compiler from complaining that there is a
+// call to t.Fatal from a non-test goroutine
+func testFatal(t *testing.T, err error) {
+ t.Helper()
+ t.Fatal(err)
+}
+
+func testClientHelloFailure(t *testing.T, serverConfig *Config, m handshakeMessage, expectedSubStr string) {
+ c, s := localPipe(t)
+ go func() {
+ cli := Client(c, testConfig)
+ if ch, ok := m.(*clientHelloMsg); ok {
+ cli.vers = ch.vers
+ }
+ if _, err := cli.writeHandshakeRecord(m, nil); err != nil {
+ testFatal(t, err)
+ }
+ c.Close()
+ }()
+ ctx := context.Background()
+ conn := Server(s, serverConfig)
+ ch, err := conn.readClientHello(ctx)
+ hs := serverHandshakeState{
+ c: conn,
+ ctx: ctx,
+ clientHello: ch,
+ }
+ if err == nil {
+ err = hs.processClientHello()
+ }
+ if err == nil {
+ err = hs.pickCipherSuite()
+ }
+ s.Close()
+ if len(expectedSubStr) == 0 {
+ if err != nil && err != io.EOF {
+ t.Errorf("Got error: %s; expected to succeed", err)
+ }
+ } else if err == nil || !strings.Contains(err.Error(), expectedSubStr) {
+ t.Errorf("Got error: %v; expected to match substring '%s'", err, expectedSubStr)
+ }
+}
+
+func TestSimpleError(t *testing.T) {
+ testClientHelloFailure(t, testConfig, &serverHelloDoneMsg{}, "unexpected handshake message")
+}
+
+var badProtocolVersions = []uint16{0x0000, 0x0005, 0x0100, 0x0105, 0x0200, 0x0205, VersionSSL30}
+
+func TestRejectBadProtocolVersion(t *testing.T) {
+ config := testConfig.Clone()
+ config.MinVersion = VersionSSL30
+ for _, v := range badProtocolVersions {
+ testClientHelloFailure(t, config, &clientHelloMsg{
+ vers: v,
+ random: make([]byte, 32),
+ }, "unsupported versions")
+ }
+ testClientHelloFailure(t, config, &clientHelloMsg{
+ vers: VersionTLS12,
+ supportedVersions: badProtocolVersions,
+ random: make([]byte, 32),
+ }, "unsupported versions")
+}
+
+func TestNoSuiteOverlap(t *testing.T) {
+ clientHello := &clientHelloMsg{
+ vers: VersionTLS10,
+ random: make([]byte, 32),
+ cipherSuites: []uint16{0xff00},
+ compressionMethods: []uint8{compressionNone},
+ }
+ testClientHelloFailure(t, testConfig, clientHello, "no cipher suite supported by both client and server")
+}
+
+func TestNoCompressionOverlap(t *testing.T) {
+ clientHello := &clientHelloMsg{
+ vers: VersionTLS10,
+ random: make([]byte, 32),
+ cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+ compressionMethods: []uint8{0xff},
+ }
+ testClientHelloFailure(t, testConfig, clientHello, "client does not support uncompressed connections")
+}
+
+func TestNoRC4ByDefault(t *testing.T) {
+ clientHello := &clientHelloMsg{
+ vers: VersionTLS10,
+ random: make([]byte, 32),
+ cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+ compressionMethods: []uint8{compressionNone},
+ }
+ serverConfig := testConfig.Clone()
+ // Reset the enabled cipher suites to nil in order to test the
+ // defaults.
+ serverConfig.CipherSuites = nil
+ testClientHelloFailure(t, serverConfig, clientHello, "no cipher suite supported by both client and server")
+}
+
+func TestRejectSNIWithTrailingDot(t *testing.T) {
+ testClientHelloFailure(t, testConfig, &clientHelloMsg{
+ vers: VersionTLS12,
+ random: make([]byte, 32),
+ serverName: "foo.com.",
+ }, "unexpected message")
+}
+
+func TestDontSelectECDSAWithRSAKey(t *testing.T) {
+ // Test that, even when both sides support an ECDSA cipher suite, it
+ // won't be selected if the server's private key doesn't support it.
+ clientHello := &clientHelloMsg{
+ vers: VersionTLS10,
+ random: make([]byte, 32),
+ cipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA},
+ compressionMethods: []uint8{compressionNone},
+ supportedCurves: []CurveID{CurveP256},
+ supportedPoints: []uint8{pointFormatUncompressed},
+ }
+ serverConfig := testConfig.Clone()
+ serverConfig.CipherSuites = clientHello.cipherSuites
+ serverConfig.Certificates = make([]Certificate, 1)
+ serverConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate}
+ serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey
+ serverConfig.BuildNameToCertificate()
+ // First test that it *does* work when the server's key is ECDSA.
+ testClientHello(t, serverConfig, clientHello)
+
+ // Now test that switching to an RSA key causes the expected error (and
+ // not an internal error about a signing failure).
+ serverConfig.Certificates = testConfig.Certificates
+ testClientHelloFailure(t, serverConfig, clientHello, "no cipher suite supported by both client and server")
+}
+
+func TestDontSelectRSAWithECDSAKey(t *testing.T) {
+ // Test that, even when both sides support an RSA cipher suite, it
+ // won't be selected if the server's private key doesn't support it.
+ clientHello := &clientHelloMsg{
+ vers: VersionTLS10,
+ random: make([]byte, 32),
+ cipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA},
+ compressionMethods: []uint8{compressionNone},
+ supportedCurves: []CurveID{CurveP256},
+ supportedPoints: []uint8{pointFormatUncompressed},
+ }
+ serverConfig := testConfig.Clone()
+ serverConfig.CipherSuites = clientHello.cipherSuites
+ // First test that it *does* work when the server's key is RSA.
+ testClientHello(t, serverConfig, clientHello)
+
+ // Now test that switching to an ECDSA key causes the expected error
+ // (and not an internal error about a signing failure).
+ serverConfig.Certificates = make([]Certificate, 1)
+ serverConfig.Certificates[0].Certificate = [][]byte{testECDSACertificate}
+ serverConfig.Certificates[0].PrivateKey = testECDSAPrivateKey
+ serverConfig.BuildNameToCertificate()
+ testClientHelloFailure(t, serverConfig, clientHello, "no cipher suite supported by both client and server")
+}
+
+func TestRenegotiationExtension(t *testing.T) {
+ clientHello := &clientHelloMsg{
+ vers: VersionTLS12,
+ compressionMethods: []uint8{compressionNone},
+ random: make([]byte, 32),
+ secureRenegotiationSupported: true,
+ cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+ }
+
+ bufChan := make(chan []byte, 1)
+ c, s := localPipe(t)
+
+ go func() {
+ cli := Client(c, testConfig)
+ cli.vers = clientHello.vers
+ if _, err := cli.writeHandshakeRecord(clientHello, nil); err != nil {
+ testFatal(t, err)
+ }
+
+ buf := make([]byte, 1024)
+ n, err := c.Read(buf)
+ if err != nil {
+ t.Errorf("Server read returned error: %s", err)
+ return
+ }
+ c.Close()
+ bufChan <- buf[:n]
+ }()
+
+ Server(s, testConfig).Handshake()
+ buf := <-bufChan
+
+ if len(buf) < 5+4 {
+ t.Fatalf("Server returned short message of length %d", len(buf))
+ }
+ // buf contains a TLS record, with a 5 byte record header and a 4 byte
+ // handshake header. The length of the ServerHello is taken from the
+ // handshake header.
+ serverHelloLen := int(buf[6])<<16 | int(buf[7])<<8 | int(buf[8])
+
+ var serverHello serverHelloMsg
+ // unmarshal expects to be given the handshake header, but
+ // serverHelloLen doesn't include it.
+ if !serverHello.unmarshal(buf[5 : 9+serverHelloLen]) {
+ t.Fatalf("Failed to parse ServerHello")
+ }
+
+ if !serverHello.secureRenegotiationSupported {
+ t.Errorf("Secure renegotiation extension was not echoed.")
+ }
+}
+
+func TestTLS12OnlyCipherSuites(t *testing.T) {
+ // Test that a Server doesn't select a TLS 1.2-only cipher suite when
+ // the client negotiates TLS 1.1.
+ clientHello := &clientHelloMsg{
+ vers: VersionTLS11,
+ random: make([]byte, 32),
+ cipherSuites: []uint16{
+ // The Server, by default, will use the client's
+ // preference order. So the GCM cipher suite
+ // will be selected unless it's excluded because
+ // of the version in this ClientHello.
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_RSA_WITH_RC4_128_SHA,
+ },
+ compressionMethods: []uint8{compressionNone},
+ supportedCurves: []CurveID{CurveP256, CurveP384, CurveP521},
+ supportedPoints: []uint8{pointFormatUncompressed},
+ }
+
+ c, s := localPipe(t)
+ replyChan := make(chan any)
+ go func() {
+ cli := Client(c, testConfig)
+ cli.vers = clientHello.vers
+ if _, err := cli.writeHandshakeRecord(clientHello, nil); err != nil {
+ testFatal(t, err)
+ }
+ reply, err := cli.readHandshake(nil)
+ c.Close()
+ if err != nil {
+ replyChan <- err
+ } else {
+ replyChan <- reply
+ }
+ }()
+ config := testConfig.Clone()
+ config.CipherSuites = clientHello.cipherSuites
+ Server(s, config).Handshake()
+ s.Close()
+ reply := <-replyChan
+ if err, ok := reply.(error); ok {
+ t.Fatal(err)
+ }
+ serverHello, ok := reply.(*serverHelloMsg)
+ if !ok {
+ t.Fatalf("didn't get ServerHello message in reply. Got %v\n", reply)
+ }
+ if s := serverHello.cipherSuite; s != TLS_RSA_WITH_RC4_128_SHA {
+ t.Fatalf("bad cipher suite from server: %x", s)
+ }
+}
+
+func TestTLSPointFormats(t *testing.T) {
+ // Test that a Server returns the ec_point_format extension when ECC is
+ // negotiated, and not on a RSA handshake or if ec_point_format is missing.
+ tests := []struct {
+ name string
+ cipherSuites []uint16
+ supportedCurves []CurveID
+ supportedPoints []uint8
+ wantSupportedPoints bool
+ }{
+ {"ECC", []uint16{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}, []CurveID{CurveP256}, []uint8{pointFormatUncompressed}, true},
+ {"ECC without ec_point_format", []uint16{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}, []CurveID{CurveP256}, nil, false},
+ {"ECC with extra values", []uint16{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA}, []CurveID{CurveP256}, []uint8{13, 37, pointFormatUncompressed, 42}, true},
+ {"RSA", []uint16{TLS_RSA_WITH_AES_256_GCM_SHA384}, nil, nil, false},
+ {"RSA with ec_point_format", []uint16{TLS_RSA_WITH_AES_256_GCM_SHA384}, nil, []uint8{pointFormatUncompressed}, false},
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ clientHello := &clientHelloMsg{
+ vers: VersionTLS12,
+ random: make([]byte, 32),
+ cipherSuites: tt.cipherSuites,
+ compressionMethods: []uint8{compressionNone},
+ supportedCurves: tt.supportedCurves,
+ supportedPoints: tt.supportedPoints,
+ }
+
+ c, s := localPipe(t)
+ replyChan := make(chan any)
+ go func() {
+ cli := Client(c, testConfig)
+ cli.vers = clientHello.vers
+ if _, err := cli.writeHandshakeRecord(clientHello, nil); err != nil {
+ testFatal(t, err)
+ }
+ reply, err := cli.readHandshake(nil)
+ c.Close()
+ if err != nil {
+ replyChan <- err
+ } else {
+ replyChan <- reply
+ }
+ }()
+ config := testConfig.Clone()
+ config.CipherSuites = clientHello.cipherSuites
+ Server(s, config).Handshake()
+ s.Close()
+ reply := <-replyChan
+ if err, ok := reply.(error); ok {
+ t.Fatal(err)
+ }
+ serverHello, ok := reply.(*serverHelloMsg)
+ if !ok {
+ t.Fatalf("didn't get ServerHello message in reply. Got %v\n", reply)
+ }
+ if tt.wantSupportedPoints {
+ if !bytes.Equal(serverHello.supportedPoints, []uint8{pointFormatUncompressed}) {
+ t.Fatal("incorrect ec_point_format extension from server")
+ }
+ } else {
+ if len(serverHello.supportedPoints) != 0 {
+ t.Fatalf("unexpected ec_point_format extension from server: %v", serverHello.supportedPoints)
+ }
+ }
+ })
+ }
+}
+
+func TestAlertForwarding(t *testing.T) {
+ c, s := localPipe(t)
+ go func() {
+ Client(c, testConfig).sendAlert(alertUnknownCA)
+ c.Close()
+ }()
+
+ err := Server(s, testConfig).Handshake()
+ s.Close()
+ var opErr *net.OpError
+ if !errors.As(err, &opErr) || opErr.Err != error(alertUnknownCA) {
+ t.Errorf("Got error: %s; expected: %s", err, error(alertUnknownCA))
+ }
+}
+
+func TestClose(t *testing.T) {
+ c, s := localPipe(t)
+ go c.Close()
+
+ err := Server(s, testConfig).Handshake()
+ s.Close()
+ if err != io.EOF {
+ t.Errorf("Got error: %s; expected: %s", err, io.EOF)
+ }
+}
+
+func TestVersion(t *testing.T) {
+ serverConfig := &Config{
+ Certificates: testConfig.Certificates,
+ MaxVersion: VersionTLS11,
+ }
+ clientConfig := &Config{
+ InsecureSkipVerify: true,
+ MinVersion: VersionTLS10,
+ }
+ state, _, err := testHandshake(t, clientConfig, serverConfig)
+ if err != nil {
+ t.Fatalf("handshake failed: %s", err)
+ }
+ if state.Version != VersionTLS11 {
+ t.Fatalf("incorrect version %x, should be %x", state.Version, VersionTLS11)
+ }
+
+ clientConfig.MinVersion = 0
+ _, _, err = testHandshake(t, clientConfig, serverConfig)
+ if err == nil {
+ t.Fatalf("expected failure to connect with TLS 1.0/1.1")
+ }
+}
+
+func TestCipherSuitePreference(t *testing.T) {
+ serverConfig := &Config{
+ CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_AES_128_GCM_SHA256,
+ TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
+ Certificates: testConfig.Certificates,
+ MaxVersion: VersionTLS12,
+ GetConfigForClient: func(chi *ClientHelloInfo) (*Config, error) {
+ if chi.CipherSuites[0] != TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 {
+ t.Error("the advertised order should not depend on Config.CipherSuites")
+ }
+ if len(chi.CipherSuites) != 2+len(defaultCipherSuitesTLS13) {
+ t.Error("the advertised TLS 1.2 suites should be filtered by Config.CipherSuites")
+ }
+ return nil, nil
+ },
+ }
+ clientConfig := &Config{
+ CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
+ InsecureSkipVerify: true,
+ }
+ state, _, err := testHandshake(t, clientConfig, serverConfig)
+ if err != nil {
+ t.Fatalf("handshake failed: %s", err)
+ }
+ if state.CipherSuite != TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 {
+ t.Error("the preference order should not depend on Config.CipherSuites")
+ }
+}
+
+func TestSCTHandshake(t *testing.T) {
+ t.Run("TLSv12", func(t *testing.T) { testSCTHandshake(t, VersionTLS12) })
+ t.Run("TLSv13", func(t *testing.T) { testSCTHandshake(t, VersionTLS13) })
+}
+
+func testSCTHandshake(t *testing.T, version uint16) {
+ expected := [][]byte{[]byte("certificate"), []byte("transparency")}
+ serverConfig := &Config{
+ Certificates: []Certificate{{
+ Certificate: [][]byte{testRSACertificate},
+ PrivateKey: testRSAPrivateKey,
+ SignedCertificateTimestamps: expected,
+ }},
+ MaxVersion: version,
+ }
+ clientConfig := &Config{
+ InsecureSkipVerify: true,
+ }
+ _, state, err := testHandshake(t, clientConfig, serverConfig)
+ if err != nil {
+ t.Fatalf("handshake failed: %s", err)
+ }
+ actual := state.SignedCertificateTimestamps
+ if len(actual) != len(expected) {
+ t.Fatalf("got %d scts, want %d", len(actual), len(expected))
+ }
+ for i, sct := range expected {
+ if !bytes.Equal(sct, actual[i]) {
+ t.Fatalf("SCT #%d was %x, but expected %x", i, actual[i], sct)
+ }
+ }
+}
+
+func TestCrossVersionResume(t *testing.T) {
+ t.Run("TLSv12", func(t *testing.T) { testCrossVersionResume(t, VersionTLS12) })
+ t.Run("TLSv13", func(t *testing.T) { testCrossVersionResume(t, VersionTLS13) })
+}
+
+func testCrossVersionResume(t *testing.T, version uint16) {
+ serverConfig := &Config{
+ CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
+ Certificates: testConfig.Certificates,
+ }
+ clientConfig := &Config{
+ CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
+ InsecureSkipVerify: true,
+ ClientSessionCache: NewLRUClientSessionCache(1),
+ ServerName: "servername",
+ MinVersion: VersionTLS10,
+ }
+
+ // Establish a session at TLS 1.1.
+ clientConfig.MaxVersion = VersionTLS11
+ _, _, err := testHandshake(t, clientConfig, serverConfig)
+ if err != nil {
+ t.Fatalf("handshake failed: %s", err)
+ }
+
+ // The client session cache now contains a TLS 1.1 session.
+ state, _, err := testHandshake(t, clientConfig, serverConfig)
+ if err != nil {
+ t.Fatalf("handshake failed: %s", err)
+ }
+ if !state.DidResume {
+ t.Fatalf("handshake did not resume at the same version")
+ }
+
+ // Test that the server will decline to resume at a lower version.
+ clientConfig.MaxVersion = VersionTLS10
+ state, _, err = testHandshake(t, clientConfig, serverConfig)
+ if err != nil {
+ t.Fatalf("handshake failed: %s", err)
+ }
+ if state.DidResume {
+ t.Fatalf("handshake resumed at a lower version")
+ }
+
+ // The client session cache now contains a TLS 1.0 session.
+ state, _, err = testHandshake(t, clientConfig, serverConfig)
+ if err != nil {
+ t.Fatalf("handshake failed: %s", err)
+ }
+ if !state.DidResume {
+ t.Fatalf("handshake did not resume at the same version")
+ }
+
+ // Test that the server will decline to resume at a higher version.
+ clientConfig.MaxVersion = VersionTLS11
+ state, _, err = testHandshake(t, clientConfig, serverConfig)
+ if err != nil {
+ t.Fatalf("handshake failed: %s", err)
+ }
+ if state.DidResume {
+ t.Fatalf("handshake resumed at a higher version")
+ }
+}
+
+// Note: see comment in handshake_test.go for details of how the reference
+// tests work.
+
+// serverTest represents a test of the TLS server handshake against a reference
+// implementation.
+type serverTest struct {
+ // name is a freeform string identifying the test and the file in which
+ // the expected results will be stored.
+ name string
+ // command, if not empty, contains a series of arguments for the
+ // command to run for the reference server.
+ command []string
+ // expectedPeerCerts contains a list of PEM blocks of expected
+ // certificates from the client.
+ expectedPeerCerts []string
+ // config, if not nil, contains a custom Config to use for this test.
+ config *Config
+ // expectHandshakeErrorIncluding, when not empty, contains a string
+ // that must be a substring of the error resulting from the handshake.
+ expectHandshakeErrorIncluding string
+ // validate, if not nil, is a function that will be called with the
+ // ConnectionState of the resulting connection. It returns false if the
+ // ConnectionState is unacceptable.
+ validate func(ConnectionState) error
+ // wait, if true, prevents this subtest from calling t.Parallel.
+ // If false, runServerTest* returns immediately.
+ wait bool
+}
+
+var defaultClientCommand = []string{"openssl", "s_client", "-no_ticket"}
+
+// connFromCommand starts opens a listening socket and starts the reference
+// client to connect to it. It returns a recordingConn that wraps the resulting
+// connection.
+func (test *serverTest) connFromCommand() (conn *recordingConn, child *exec.Cmd, err error) {
+ l, err := net.ListenTCP("tcp", &net.TCPAddr{
+ IP: net.IPv4(127, 0, 0, 1),
+ Port: 0,
+ })
+ if err != nil {
+ return nil, nil, err
+ }
+ defer l.Close()
+
+ port := l.Addr().(*net.TCPAddr).Port
+
+ var command []string
+ command = append(command, test.command...)
+ if len(command) == 0 {
+ command = defaultClientCommand
+ }
+ command = append(command, "-connect")
+ command = append(command, fmt.Sprintf("127.0.0.1:%d", port))
+ cmd := exec.Command(command[0], command[1:]...)
+ cmd.Stdin = nil
+ var output bytes.Buffer
+ cmd.Stdout = &output
+ cmd.Stderr = &output
+ if err := cmd.Start(); err != nil {
+ return nil, nil, err
+ }
+
+ connChan := make(chan any, 1)
+ go func() {
+ tcpConn, err := l.Accept()
+ if err != nil {
+ connChan <- err
+ return
+ }
+ connChan <- tcpConn
+ }()
+
+ var tcpConn net.Conn
+ select {
+ case connOrError := <-connChan:
+ if err, ok := connOrError.(error); ok {
+ return nil, nil, err
+ }
+ tcpConn = connOrError.(net.Conn)
+ case <-time.After(2 * time.Second):
+ return nil, nil, errors.New("timed out waiting for connection from child process")
+ }
+
+ record := &recordingConn{
+ Conn: tcpConn,
+ }
+
+ return record, cmd, nil
+}
+
+func (test *serverTest) dataPath() string {
+ return filepath.Join("testdata", "Server-"+test.name)
+}
+
+func (test *serverTest) loadData() (flows [][]byte, err error) {
+ in, err := os.Open(test.dataPath())
+ if err != nil {
+ return nil, err
+ }
+ defer in.Close()
+ return parseTestData(in)
+}
+
+func (test *serverTest) run(t *testing.T, write bool) {
+ var clientConn, serverConn net.Conn
+ var recordingConn *recordingConn
+ var childProcess *exec.Cmd
+
+ if write {
+ var err error
+ recordingConn, childProcess, err = test.connFromCommand()
+ if err != nil {
+ t.Fatalf("Failed to start subcommand: %s", err)
+ }
+ serverConn = recordingConn
+ defer func() {
+ if t.Failed() {
+ t.Logf("OpenSSL output:\n\n%s", childProcess.Stdout)
+ }
+ }()
+ } else {
+ clientConn, serverConn = localPipe(t)
+ }
+ config := test.config
+ if config == nil {
+ config = testConfig
+ }
+ server := Server(serverConn, config)
+ connStateChan := make(chan ConnectionState, 1)
+ go func() {
+ _, err := server.Write([]byte("hello, world\n"))
+ if len(test.expectHandshakeErrorIncluding) > 0 {
+ if err == nil {
+ t.Errorf("Error expected, but no error returned")
+ } else if s := err.Error(); !strings.Contains(s, test.expectHandshakeErrorIncluding) {
+ t.Errorf("Error expected containing '%s' but got '%s'", test.expectHandshakeErrorIncluding, s)
+ }
+ } else {
+ if err != nil {
+ t.Logf("Error from Server.Write: '%s'", err)
+ }
+ }
+ server.Close()
+ serverConn.Close()
+ connStateChan <- server.ConnectionState()
+ }()
+
+ if !write {
+ flows, err := test.loadData()
+ if err != nil {
+ t.Fatalf("%s: failed to load data from %s", test.name, test.dataPath())
+ }
+ for i, b := range flows {
+ if i%2 == 0 {
+ if *fast {
+ clientConn.SetWriteDeadline(time.Now().Add(1 * time.Second))
+ } else {
+ clientConn.SetWriteDeadline(time.Now().Add(1 * time.Minute))
+ }
+ clientConn.Write(b)
+ continue
+ }
+ bb := make([]byte, len(b))
+ if *fast {
+ clientConn.SetReadDeadline(time.Now().Add(1 * time.Second))
+ } else {
+ clientConn.SetReadDeadline(time.Now().Add(1 * time.Minute))
+ }
+ n, err := io.ReadFull(clientConn, bb)
+ if err != nil {
+ t.Fatalf("%s #%d: %s\nRead %d, wanted %d, got %x, wanted %x\n", test.name, i+1, err, n, len(bb), bb[:n], b)
+ }
+ if !bytes.Equal(b, bb) {
+ t.Fatalf("%s #%d: mismatch on read: got:%x want:%x", test.name, i+1, bb, b)
+ }
+ }
+ clientConn.Close()
+ }
+
+ connState := <-connStateChan
+ peerCerts := connState.PeerCertificates
+ if len(peerCerts) == len(test.expectedPeerCerts) {
+ for i, peerCert := range peerCerts {
+ block, _ := pem.Decode([]byte(test.expectedPeerCerts[i]))
+ if !bytes.Equal(block.Bytes, peerCert.Raw) {
+ t.Fatalf("%s: mismatch on peer cert %d", test.name, i+1)
+ }
+ }
+ } else {
+ t.Fatalf("%s: mismatch on peer list length: %d (wanted) != %d (got)", test.name, len(test.expectedPeerCerts), len(peerCerts))
+ }
+
+ if test.validate != nil {
+ if err := test.validate(connState); err != nil {
+ t.Fatalf("validate callback returned error: %s", err)
+ }
+ }
+
+ if write {
+ path := test.dataPath()
+ out, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
+ if err != nil {
+ t.Fatalf("Failed to create output file: %s", err)
+ }
+ defer out.Close()
+ recordingConn.Close()
+ if len(recordingConn.flows) < 3 {
+ if len(test.expectHandshakeErrorIncluding) == 0 {
+ t.Fatalf("Handshake failed")
+ }
+ }
+ recordingConn.WriteTo(out)
+ t.Logf("Wrote %s\n", path)
+ childProcess.Wait()
+ }
+}
+
+func runServerTestForVersion(t *testing.T, template *serverTest, version, option string) {
+ // Make a deep copy of the template before going parallel.
+ test := *template
+ if template.config != nil {
+ test.config = template.config.Clone()
+ }
+ test.name = version + "-" + test.name
+ if len(test.command) == 0 {
+ test.command = defaultClientCommand
+ }
+ test.command = append([]string(nil), test.command...)
+ test.command = append(test.command, option)
+
+ runTestAndUpdateIfNeeded(t, version, test.run, test.wait)
+}
+
+func runServerTestTLS10(t *testing.T, template *serverTest) {
+ runServerTestForVersion(t, template, "TLSv10", "-tls1")
+}
+
+func runServerTestTLS11(t *testing.T, template *serverTest) {
+ runServerTestForVersion(t, template, "TLSv11", "-tls1_1")
+}
+
+func runServerTestTLS12(t *testing.T, template *serverTest) {
+ runServerTestForVersion(t, template, "TLSv12", "-tls1_2")
+}
+
+func runServerTestTLS13(t *testing.T, template *serverTest) {
+ runServerTestForVersion(t, template, "TLSv13", "-tls1_3")
+}
+
+func TestHandshakeServerRSARC4(t *testing.T) {
+ test := &serverTest{
+ name: "RSA-RC4",
+ command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "RC4-SHA"},
+ }
+ runServerTestTLS10(t, test)
+ runServerTestTLS11(t, test)
+ runServerTestTLS12(t, test)
+}
+
+func TestHandshakeServerRSA3DES(t *testing.T) {
+ test := &serverTest{
+ name: "RSA-3DES",
+ command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "DES-CBC3-SHA"},
+ }
+ runServerTestTLS10(t, test)
+ runServerTestTLS12(t, test)
+}
+
+func TestHandshakeServerRSAAES(t *testing.T) {
+ test := &serverTest{
+ name: "RSA-AES",
+ command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA"},
+ }
+ runServerTestTLS10(t, test)
+ runServerTestTLS12(t, test)
+}
+
+func TestHandshakeServerAESGCM(t *testing.T) {
+ test := &serverTest{
+ name: "RSA-AES-GCM",
+ command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-RSA-AES128-GCM-SHA256"},
+ }
+ runServerTestTLS12(t, test)
+}
+
+func TestHandshakeServerAES256GCMSHA384(t *testing.T) {
+ test := &serverTest{
+ name: "RSA-AES256-GCM-SHA384",
+ command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-RSA-AES256-GCM-SHA384"},
+ }
+ runServerTestTLS12(t, test)
+}
+
+func TestHandshakeServerAES128SHA256(t *testing.T) {
+ test := &serverTest{
+ name: "AES128-SHA256",
+ command: []string{"openssl", "s_client", "-no_ticket", "-ciphersuites", "TLS_AES_128_GCM_SHA256"},
+ }
+ runServerTestTLS13(t, test)
+}
+func TestHandshakeServerAES256SHA384(t *testing.T) {
+ test := &serverTest{
+ name: "AES256-SHA384",
+ command: []string{"openssl", "s_client", "-no_ticket", "-ciphersuites", "TLS_AES_256_GCM_SHA384"},
+ }
+ runServerTestTLS13(t, test)
+}
+func TestHandshakeServerCHACHA20SHA256(t *testing.T) {
+ test := &serverTest{
+ name: "CHACHA20-SHA256",
+ command: []string{"openssl", "s_client", "-no_ticket", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256"},
+ }
+ runServerTestTLS13(t, test)
+}
+
+func TestHandshakeServerECDHEECDSAAES(t *testing.T) {
+ config := testConfig.Clone()
+ config.Certificates = make([]Certificate, 1)
+ config.Certificates[0].Certificate = [][]byte{testECDSACertificate}
+ config.Certificates[0].PrivateKey = testECDSAPrivateKey
+ config.BuildNameToCertificate()
+
+ test := &serverTest{
+ name: "ECDHE-ECDSA-AES",
+ command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-ECDSA-AES256-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256"},
+ config: config,
+ }
+ runServerTestTLS10(t, test)
+ runServerTestTLS12(t, test)
+ runServerTestTLS13(t, test)
+}
+
+func TestHandshakeServerX25519(t *testing.T) {
+ config := testConfig.Clone()
+ config.CurvePreferences = []CurveID{X25519}
+
+ test := &serverTest{
+ name: "X25519",
+ command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256", "-curves", "X25519"},
+ config: config,
+ }
+ runServerTestTLS12(t, test)
+ runServerTestTLS13(t, test)
+}
+
+func TestHandshakeServerP256(t *testing.T) {
+ config := testConfig.Clone()
+ config.CurvePreferences = []CurveID{CurveP256}
+
+ test := &serverTest{
+ name: "P256",
+ command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256", "-curves", "P-256"},
+ config: config,
+ }
+ runServerTestTLS12(t, test)
+ runServerTestTLS13(t, test)
+}
+
+func TestHandshakeServerHelloRetryRequest(t *testing.T) {
+ config := testConfig.Clone()
+ config.CurvePreferences = []CurveID{CurveP256}
+
+ test := &serverTest{
+ name: "HelloRetryRequest",
+ command: []string{"openssl", "s_client", "-no_ticket", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256", "-curves", "X25519:P-256"},
+ config: config,
+ }
+ runServerTestTLS13(t, test)
+}
+
+func TestHandshakeServerALPN(t *testing.T) {
+ config := testConfig.Clone()
+ config.NextProtos = []string{"proto1", "proto2"}
+
+ test := &serverTest{
+ name: "ALPN",
+ // Note that this needs OpenSSL 1.0.2 because that is the first
+ // version that supports the -alpn flag.
+ command: []string{"openssl", "s_client", "-alpn", "proto2,proto1", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256"},
+ config: config,
+ validate: func(state ConnectionState) error {
+ // The server's preferences should override the client.
+ if state.NegotiatedProtocol != "proto1" {
+ return fmt.Errorf("Got protocol %q, wanted proto1", state.NegotiatedProtocol)
+ }
+ return nil
+ },
+ }
+ runServerTestTLS12(t, test)
+ runServerTestTLS13(t, test)
+}
+
+func TestHandshakeServerALPNNoMatch(t *testing.T) {
+ config := testConfig.Clone()
+ config.NextProtos = []string{"proto3"}
+
+ test := &serverTest{
+ name: "ALPN-NoMatch",
+ // Note that this needs OpenSSL 1.0.2 because that is the first
+ // version that supports the -alpn flag.
+ command: []string{"openssl", "s_client", "-alpn", "proto2,proto1", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256"},
+ config: config,
+ expectHandshakeErrorIncluding: "client requested unsupported application protocol",
+ }
+ runServerTestTLS12(t, test)
+ runServerTestTLS13(t, test)
+}
+
+func TestHandshakeServerALPNNotConfigured(t *testing.T) {
+ config := testConfig.Clone()
+ config.NextProtos = nil
+
+ test := &serverTest{
+ name: "ALPN-NotConfigured",
+ // Note that this needs OpenSSL 1.0.2 because that is the first
+ // version that supports the -alpn flag.
+ command: []string{"openssl", "s_client", "-alpn", "proto2,proto1", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256"},
+ config: config,
+ validate: func(state ConnectionState) error {
+ if state.NegotiatedProtocol != "" {
+ return fmt.Errorf("Got protocol %q, wanted nothing", state.NegotiatedProtocol)
+ }
+ return nil
+ },
+ }
+ runServerTestTLS12(t, test)
+ runServerTestTLS13(t, test)
+}
+
+func TestHandshakeServerALPNFallback(t *testing.T) {
+ config := testConfig.Clone()
+ config.NextProtos = []string{"proto1", "h2", "proto2"}
+
+ test := &serverTest{
+ name: "ALPN-Fallback",
+ // Note that this needs OpenSSL 1.0.2 because that is the first
+ // version that supports the -alpn flag.
+ command: []string{"openssl", "s_client", "-alpn", "proto3,http/1.1,proto4", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256"},
+ config: config,
+ validate: func(state ConnectionState) error {
+ if state.NegotiatedProtocol != "" {
+ return fmt.Errorf("Got protocol %q, wanted nothing", state.NegotiatedProtocol)
+ }
+ return nil
+ },
+ }
+ runServerTestTLS12(t, test)
+ runServerTestTLS13(t, test)
+}
+
+// TestHandshakeServerSNI involves a client sending an SNI extension of
+// "snitest.com", which happens to match the CN of testSNICertificate. The test
+// verifies that the server correctly selects that certificate.
+func TestHandshakeServerSNI(t *testing.T) {
+ test := &serverTest{
+ name: "SNI",
+ command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-servername", "snitest.com"},
+ }
+ runServerTestTLS12(t, test)
+}
+
+// TestHandshakeServerSNICertForName is similar to TestHandshakeServerSNI, but
+// tests the dynamic GetCertificate method
+func TestHandshakeServerSNIGetCertificate(t *testing.T) {
+ config := testConfig.Clone()
+
+ // Replace the NameToCertificate map with a GetCertificate function
+ nameToCert := config.NameToCertificate
+ config.NameToCertificate = nil
+ config.GetCertificate = func(clientHello *ClientHelloInfo) (*Certificate, error) {
+ cert := nameToCert[clientHello.ServerName]
+ return cert, nil
+ }
+ test := &serverTest{
+ name: "SNI-GetCertificate",
+ command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-servername", "snitest.com"},
+ config: config,
+ }
+ runServerTestTLS12(t, test)
+}
+
+// TestHandshakeServerSNICertForNameNotFound is similar to
+// TestHandshakeServerSNICertForName, but tests to make sure that when the
+// GetCertificate method doesn't return a cert, we fall back to what's in
+// the NameToCertificate map.
+func TestHandshakeServerSNIGetCertificateNotFound(t *testing.T) {
+ config := testConfig.Clone()
+
+ config.GetCertificate = func(clientHello *ClientHelloInfo) (*Certificate, error) {
+ return nil, nil
+ }
+ test := &serverTest{
+ name: "SNI-GetCertificateNotFound",
+ command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-servername", "snitest.com"},
+ config: config,
+ }
+ runServerTestTLS12(t, test)
+}
+
+// TestHandshakeServerSNICertForNameError tests to make sure that errors in
+// GetCertificate result in a tls alert.
+func TestHandshakeServerSNIGetCertificateError(t *testing.T) {
+ const errMsg = "TestHandshakeServerSNIGetCertificateError error"
+
+ serverConfig := testConfig.Clone()
+ serverConfig.GetCertificate = func(clientHello *ClientHelloInfo) (*Certificate, error) {
+ return nil, errors.New(errMsg)
+ }
+
+ clientHello := &clientHelloMsg{
+ vers: VersionTLS10,
+ random: make([]byte, 32),
+ cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+ compressionMethods: []uint8{compressionNone},
+ serverName: "test",
+ }
+ testClientHelloFailure(t, serverConfig, clientHello, errMsg)
+}
+
+// TestHandshakeServerEmptyCertificates tests that GetCertificates is called in
+// the case that Certificates is empty, even without SNI.
+func TestHandshakeServerEmptyCertificates(t *testing.T) {
+ const errMsg = "TestHandshakeServerEmptyCertificates error"
+
+ serverConfig := testConfig.Clone()
+ serverConfig.GetCertificate = func(clientHello *ClientHelloInfo) (*Certificate, error) {
+ return nil, errors.New(errMsg)
+ }
+ serverConfig.Certificates = nil
+
+ clientHello := &clientHelloMsg{
+ vers: VersionTLS10,
+ random: make([]byte, 32),
+ cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+ compressionMethods: []uint8{compressionNone},
+ }
+ testClientHelloFailure(t, serverConfig, clientHello, errMsg)
+
+ // With an empty Certificates and a nil GetCertificate, the server
+ // should always return a “no certificates” error.
+ serverConfig.GetCertificate = nil
+
+ clientHello = &clientHelloMsg{
+ vers: VersionTLS10,
+ random: make([]byte, 32),
+ cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+ compressionMethods: []uint8{compressionNone},
+ }
+ testClientHelloFailure(t, serverConfig, clientHello, "no certificates")
+}
+
+func TestServerResumption(t *testing.T) {
+ sessionFilePath := tempFile("")
+ defer os.Remove(sessionFilePath)
+
+ testIssue := &serverTest{
+ name: "IssueTicket",
+ command: []string{"openssl", "s_client", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256", "-sess_out", sessionFilePath},
+ wait: true,
+ }
+ testResume := &serverTest{
+ name: "Resume",
+ command: []string{"openssl", "s_client", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256", "-sess_in", sessionFilePath},
+ validate: func(state ConnectionState) error {
+ if !state.DidResume {
+ return errors.New("did not resume")
+ }
+ 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", "-cipher", "AES128-SHA", "-ciphersuites",
+ "TLS_AES_128_GCM_SHA256", "-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 TestServerResumptionDisabled(t *testing.T) {
+ sessionFilePath := tempFile("")
+ defer os.Remove(sessionFilePath)
+
+ config := testConfig.Clone()
+
+ testIssue := &serverTest{
+ name: "IssueTicketPreDisable",
+ command: []string{"openssl", "s_client", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256", "-sess_out", sessionFilePath},
+ config: config,
+ wait: true,
+ }
+ testResume := &serverTest{
+ name: "ResumeDisabled",
+ command: []string{"openssl", "s_client", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256", "-sess_in", sessionFilePath},
+ config: config,
+ validate: func(state ConnectionState) error {
+ if state.DidResume {
+ return errors.New("resumed with SessionTicketsDisabled")
+ }
+ return nil
+ },
+ }
+
+ 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) {
+ serverConfig := Config{
+ Certificates: testConfig.Certificates,
+ }
+ test := &serverTest{
+ name: "FallbackSCSV",
+ config: &serverConfig,
+ // OpenSSL 1.0.1j is needed for the -fallback_scsv option.
+ command: []string{"openssl", "s_client", "-fallback_scsv"},
+ expectHandshakeErrorIncluding: "inappropriate protocol fallback",
+ }
+ runServerTestTLS11(t, test)
+}
+
+func TestHandshakeServerExportKeyingMaterial(t *testing.T) {
+ test := &serverTest{
+ name: "ExportKeyingMaterial",
+ command: []string{"openssl", "s_client", "-cipher", "ECDHE-RSA-AES256-SHA", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256"},
+ config: testConfig.Clone(),
+ validate: func(state ConnectionState) error {
+ if km, err := state.ExportKeyingMaterial("test", nil, 42); err != nil {
+ return fmt.Errorf("ExportKeyingMaterial failed: %v", err)
+ } else if len(km) != 42 {
+ return fmt.Errorf("Got %d bytes from ExportKeyingMaterial, wanted %d", len(km), 42)
+ }
+ return nil
+ },
+ }
+ runServerTestTLS10(t, test)
+ runServerTestTLS12(t, test)
+ runServerTestTLS13(t, test)
+}
+
+func TestHandshakeServerRSAPKCS1v15(t *testing.T) {
+ test := &serverTest{
+ name: "RSA-RSAPKCS1v15",
+ command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-sigalgs", "rsa_pkcs1_sha256"},
+ }
+ runServerTestTLS12(t, test)
+}
+
+func TestHandshakeServerRSAPSS(t *testing.T) {
+ // We send rsa_pss_rsae_sha512 first, as the test key won't fit, and we
+ // verify the server implementation will disregard the client preference in
+ // that case. See Issue 29793.
+ test := &serverTest{
+ name: "RSA-RSAPSS",
+ command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-RSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256", "-sigalgs", "rsa_pss_rsae_sha512:rsa_pss_rsae_sha256"},
+ }
+ runServerTestTLS12(t, test)
+ runServerTestTLS13(t, test)
+
+ test = &serverTest{
+ name: "RSA-RSAPSS-TooSmall",
+ command: []string{"openssl", "s_client", "-no_ticket", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256", "-sigalgs", "rsa_pss_rsae_sha512"},
+ expectHandshakeErrorIncluding: "peer doesn't support any of the certificate's signature algorithms",
+ }
+ runServerTestTLS13(t, test)
+}
+
+func TestHandshakeServerEd25519(t *testing.T) {
+ config := testConfig.Clone()
+ config.Certificates = make([]Certificate, 1)
+ config.Certificates[0].Certificate = [][]byte{testEd25519Certificate}
+ config.Certificates[0].PrivateKey = testEd25519PrivateKey
+ config.BuildNameToCertificate()
+
+ test := &serverTest{
+ name: "Ed25519",
+ command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "ECDHE-ECDSA-CHACHA20-POLY1305", "-ciphersuites", "TLS_CHACHA20_POLY1305_SHA256"},
+ config: config,
+ }
+ runServerTestTLS12(t, test)
+ runServerTestTLS13(t, test)
+}
+
+func benchmarkHandshakeServer(b *testing.B, version uint16, cipherSuite uint16, curve CurveID, cert []byte, key crypto.PrivateKey) {
+ config := testConfig.Clone()
+ config.CipherSuites = []uint16{cipherSuite}
+ config.CurvePreferences = []CurveID{curve}
+ config.Certificates = make([]Certificate, 1)
+ config.Certificates[0].Certificate = [][]byte{cert}
+ config.Certificates[0].PrivateKey = key
+ config.BuildNameToCertificate()
+
+ clientConn, serverConn := localPipe(b)
+ serverConn = &recordingConn{Conn: serverConn}
+ go func() {
+ config := testConfig.Clone()
+ config.MaxVersion = version
+ config.CurvePreferences = []CurveID{curve}
+ client := Client(clientConn, config)
+ client.Handshake()
+ }()
+ server := Server(serverConn, config)
+ if err := server.Handshake(); err != nil {
+ b.Fatalf("handshake failed: %v", err)
+ }
+ serverConn.Close()
+ flows := serverConn.(*recordingConn).flows
+
+ feeder := make(chan struct{})
+ clientConn, serverConn = localPipe(b)
+
+ go func() {
+ for range feeder {
+ for i, f := range flows {
+ if i%2 == 0 {
+ clientConn.Write(f)
+ continue
+ }
+ ff := make([]byte, len(f))
+ n, err := io.ReadFull(clientConn, ff)
+ if err != nil {
+ b.Errorf("#%d: %s\nRead %d, wanted %d, got %x, wanted %x\n", i+1, err, n, len(ff), ff[:n], f)
+ }
+ if !bytes.Equal(f, ff) {
+ b.Errorf("#%d: mismatch on read: got:%x want:%x", i+1, ff, f)
+ }
+ }
+ }
+ }()
+
+ b.ResetTimer()
+ for i := 0; i < b.N; i++ {
+ feeder <- struct{}{}
+ server := Server(serverConn, config)
+ if err := server.Handshake(); err != nil {
+ b.Fatalf("handshake failed: %v", err)
+ }
+ }
+ close(feeder)
+}
+
+func BenchmarkHandshakeServer(b *testing.B) {
+ b.Run("RSA", func(b *testing.B) {
+ benchmarkHandshakeServer(b, VersionTLS12, TLS_RSA_WITH_AES_128_GCM_SHA256,
+ 0, testRSACertificate, testRSAPrivateKey)
+ })
+ b.Run("ECDHE-P256-RSA", func(b *testing.B) {
+ b.Run("TLSv13", func(b *testing.B) {
+ benchmarkHandshakeServer(b, VersionTLS13, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+ CurveP256, testRSACertificate, testRSAPrivateKey)
+ })
+ b.Run("TLSv12", func(b *testing.B) {
+ benchmarkHandshakeServer(b, VersionTLS12, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+ CurveP256, testRSACertificate, testRSAPrivateKey)
+ })
+ })
+ b.Run("ECDHE-P256-ECDSA-P256", func(b *testing.B) {
+ b.Run("TLSv13", func(b *testing.B) {
+ benchmarkHandshakeServer(b, VersionTLS13, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
+ CurveP256, testP256Certificate, testP256PrivateKey)
+ })
+ b.Run("TLSv12", func(b *testing.B) {
+ benchmarkHandshakeServer(b, VersionTLS12, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
+ CurveP256, testP256Certificate, testP256PrivateKey)
+ })
+ })
+ b.Run("ECDHE-X25519-ECDSA-P256", func(b *testing.B) {
+ b.Run("TLSv13", func(b *testing.B) {
+ benchmarkHandshakeServer(b, VersionTLS13, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
+ X25519, testP256Certificate, testP256PrivateKey)
+ })
+ b.Run("TLSv12", func(b *testing.B) {
+ benchmarkHandshakeServer(b, VersionTLS12, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
+ X25519, testP256Certificate, testP256PrivateKey)
+ })
+ })
+ b.Run("ECDHE-P521-ECDSA-P521", func(b *testing.B) {
+ if testECDSAPrivateKey.PublicKey.Curve != elliptic.P521() {
+ b.Fatal("test ECDSA key doesn't use curve P-521")
+ }
+ b.Run("TLSv13", func(b *testing.B) {
+ benchmarkHandshakeServer(b, VersionTLS13, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
+ CurveP521, testECDSACertificate, testECDSAPrivateKey)
+ })
+ b.Run("TLSv12", func(b *testing.B) {
+ benchmarkHandshakeServer(b, VersionTLS12, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
+ CurveP521, testECDSACertificate, testECDSAPrivateKey)
+ })
+ })
+}
+
+func TestClientAuth(t *testing.T) {
+ var certPath, keyPath, ecdsaCertPath, ecdsaKeyPath, ed25519CertPath, ed25519KeyPath string
+
+ if *update {
+ certPath = tempFile(clientCertificatePEM)
+ defer os.Remove(certPath)
+ keyPath = tempFile(clientKeyPEM)
+ defer os.Remove(keyPath)
+ ecdsaCertPath = tempFile(clientECDSACertificatePEM)
+ defer os.Remove(ecdsaCertPath)
+ ecdsaKeyPath = tempFile(clientECDSAKeyPEM)
+ defer os.Remove(ecdsaKeyPath)
+ ed25519CertPath = tempFile(clientEd25519CertificatePEM)
+ defer os.Remove(ed25519CertPath)
+ ed25519KeyPath = tempFile(clientEd25519KeyPEM)
+ defer os.Remove(ed25519KeyPath)
+ } else {
+ t.Parallel()
+ }
+
+ config := testConfig.Clone()
+ config.ClientAuth = RequestClientCert
+
+ test := &serverTest{
+ name: "ClientAuthRequestedNotGiven",
+ command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256"},
+ config: config,
+ }
+ runServerTestTLS12(t, test)
+ runServerTestTLS13(t, test)
+
+ test = &serverTest{
+ name: "ClientAuthRequestedAndGiven",
+ command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256",
+ "-cert", certPath, "-key", keyPath, "-client_sigalgs", "rsa_pss_rsae_sha256"},
+ config: config,
+ expectedPeerCerts: []string{clientCertificatePEM},
+ }
+ runServerTestTLS12(t, test)
+ runServerTestTLS13(t, test)
+
+ test = &serverTest{
+ name: "ClientAuthRequestedAndECDSAGiven",
+ command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256",
+ "-cert", ecdsaCertPath, "-key", ecdsaKeyPath},
+ config: config,
+ expectedPeerCerts: []string{clientECDSACertificatePEM},
+ }
+ runServerTestTLS12(t, test)
+ runServerTestTLS13(t, test)
+
+ test = &serverTest{
+ name: "ClientAuthRequestedAndEd25519Given",
+ command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA", "-ciphersuites", "TLS_AES_128_GCM_SHA256",
+ "-cert", ed25519CertPath, "-key", ed25519KeyPath},
+ config: config,
+ expectedPeerCerts: []string{clientEd25519CertificatePEM},
+ }
+ runServerTestTLS12(t, test)
+ runServerTestTLS13(t, test)
+
+ test = &serverTest{
+ name: "ClientAuthRequestedAndPKCS1v15Given",
+ command: []string{"openssl", "s_client", "-no_ticket", "-cipher", "AES128-SHA",
+ "-cert", certPath, "-key", keyPath, "-client_sigalgs", "rsa_pkcs1_sha256"},
+ config: config,
+ expectedPeerCerts: []string{clientCertificatePEM},
+ }
+ runServerTestTLS12(t, test)
+}
+
+func TestSNIGivenOnFailure(t *testing.T) {
+ const expectedServerName = "test.testing"
+
+ clientHello := &clientHelloMsg{
+ vers: VersionTLS10,
+ random: make([]byte, 32),
+ cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+ compressionMethods: []uint8{compressionNone},
+ serverName: expectedServerName,
+ }
+
+ serverConfig := testConfig.Clone()
+ // Erase the server's cipher suites to ensure the handshake fails.
+ serverConfig.CipherSuites = nil
+
+ c, s := localPipe(t)
+ go func() {
+ cli := Client(c, testConfig)
+ cli.vers = clientHello.vers
+ if _, err := cli.writeHandshakeRecord(clientHello, nil); err != nil {
+ testFatal(t, err)
+ }
+ c.Close()
+ }()
+ conn := Server(s, serverConfig)
+ ctx := context.Background()
+ ch, err := conn.readClientHello(ctx)
+ hs := serverHandshakeState{
+ c: conn,
+ ctx: ctx,
+ clientHello: ch,
+ }
+ if err == nil {
+ err = hs.processClientHello()
+ }
+ if err == nil {
+ err = hs.pickCipherSuite()
+ }
+ defer s.Close()
+
+ if err == nil {
+ t.Error("No error reported from server")
+ }
+
+ cs := hs.c.ConnectionState()
+ if cs.HandshakeComplete {
+ t.Error("Handshake registered as complete")
+ }
+
+ if cs.ServerName != expectedServerName {
+ t.Errorf("Expected ServerName of %q, but got %q", expectedServerName, cs.ServerName)
+ }
+}
+
+var getConfigForClientTests = []struct {
+ setup func(config *Config)
+ callback func(clientHello *ClientHelloInfo) (*Config, error)
+ errorSubstring string
+ verify func(config *Config) error
+}{
+ {
+ nil,
+ func(clientHello *ClientHelloInfo) (*Config, error) {
+ return nil, nil
+ },
+ "",
+ nil,
+ },
+ {
+ nil,
+ func(clientHello *ClientHelloInfo) (*Config, error) {
+ return nil, errors.New("should bubble up")
+ },
+ "should bubble up",
+ nil,
+ },
+ {
+ nil,
+ func(clientHello *ClientHelloInfo) (*Config, error) {
+ config := testConfig.Clone()
+ // Setting a maximum version of TLS 1.1 should cause
+ // the handshake to fail, as the client MinVersion is TLS 1.2.
+ config.MaxVersion = VersionTLS11
+ return config, nil
+ },
+ "client offered only unsupported versions",
+ nil,
+ },
+ {
+ func(config *Config) {
+ for i := range config.SessionTicketKey {
+ config.SessionTicketKey[i] = byte(i)
+ }
+ config.sessionTicketKeys = nil
+ },
+ func(clientHello *ClientHelloInfo) (*Config, error) {
+ config := testConfig.Clone()
+ for i := range config.SessionTicketKey {
+ config.SessionTicketKey[i] = 0
+ }
+ config.sessionTicketKeys = nil
+ return config, nil
+ },
+ "",
+ func(config *Config) error {
+ if config.SessionTicketKey == [32]byte{} {
+ return fmt.Errorf("expected SessionTicketKey to be set")
+ }
+ return nil
+ },
+ },
+ {
+ func(config *Config) {
+ var dummyKey [32]byte
+ for i := range dummyKey {
+ dummyKey[i] = byte(i)
+ }
+
+ config.SetSessionTicketKeys([][32]byte{dummyKey})
+ },
+ func(clientHello *ClientHelloInfo) (*Config, error) {
+ config := testConfig.Clone()
+ config.sessionTicketKeys = nil
+ return config, nil
+ },
+ "",
+ func(config *Config) error {
+ if config.SessionTicketKey == [32]byte{} {
+ return fmt.Errorf("expected SessionTicketKey to be set")
+ }
+ return nil
+ },
+ },
+}
+
+func TestGetConfigForClient(t *testing.T) {
+ serverConfig := testConfig.Clone()
+ clientConfig := testConfig.Clone()
+ clientConfig.MinVersion = VersionTLS12
+
+ for i, test := range getConfigForClientTests {
+ if test.setup != nil {
+ test.setup(serverConfig)
+ }
+
+ var configReturned *Config
+ serverConfig.GetConfigForClient = func(clientHello *ClientHelloInfo) (*Config, error) {
+ config, err := test.callback(clientHello)
+ configReturned = config
+ return config, err
+ }
+ c, s := localPipe(t)
+ done := make(chan error)
+
+ go func() {
+ defer s.Close()
+ done <- Server(s, serverConfig).Handshake()
+ }()
+
+ clientErr := Client(c, clientConfig).Handshake()
+ c.Close()
+
+ serverErr := <-done
+
+ if len(test.errorSubstring) == 0 {
+ if serverErr != nil || clientErr != nil {
+ t.Errorf("test[%d]: expected no error but got serverErr: %q, clientErr: %q", i, serverErr, clientErr)
+ }
+ if test.verify != nil {
+ if err := test.verify(configReturned); err != nil {
+ t.Errorf("test[%d]: verify returned error: %v", i, err)
+ }
+ }
+ } else {
+ if serverErr == nil {
+ t.Errorf("test[%d]: expected error containing %q but got no error", i, test.errorSubstring)
+ } else if !strings.Contains(serverErr.Error(), test.errorSubstring) {
+ t.Errorf("test[%d]: expected error to contain %q but it was %q", i, test.errorSubstring, serverErr)
+ }
+ }
+ }
+}
+
+func TestCloseServerConnectionOnIdleClient(t *testing.T) {
+ clientConn, serverConn := localPipe(t)
+ server := Server(serverConn, testConfig.Clone())
+ go func() {
+ clientConn.Write([]byte{'0'})
+ server.Close()
+ }()
+ server.SetReadDeadline(time.Now().Add(time.Minute))
+ err := server.Handshake()
+ if err != nil {
+ if err, ok := err.(net.Error); ok && err.Timeout() {
+ t.Errorf("Expected a closed network connection error but got '%s'", err.Error())
+ }
+ } else {
+ 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")
+ }
+}
+
+func expectError(t *testing.T, err error, sub string) {
+ if err == nil {
+ t.Errorf(`expected error %q, got nil`, sub)
+ } else if !strings.Contains(err.Error(), sub) {
+ t.Errorf(`expected error %q, got %q`, sub, err)
+ }
+}
+
+func TestKeyTooSmallForRSAPSS(t *testing.T) {
+ cert, err := X509KeyPair([]byte(`-----BEGIN CERTIFICATE-----
+MIIBcTCCARugAwIBAgIQGjQnkCFlUqaFlt6ixyz/tDANBgkqhkiG9w0BAQsFADAS
+MRAwDgYDVQQKEwdBY21lIENvMB4XDTE5MDExODIzMjMyOFoXDTIwMDExODIzMjMy
+OFowEjEQMA4GA1UEChMHQWNtZSBDbzBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDd
+ez1rFUDwax2HTxbcnFUP9AhcgEGMHVV2nn4VVEWFJB6I8C/Nkx0XyyQlrmFYBzEQ
+nIPhKls4T0hFoLvjJnXpAgMBAAGjTTBLMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUE
+DDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMBYGA1UdEQQPMA2CC2V4YW1wbGUu
+Y29tMA0GCSqGSIb3DQEBCwUAA0EAxDuUS+BrrS3c+h+k+fQPOmOScy6yTX9mHw0Q
+KbucGamXYEy0URIwOdO0tQ3LHPc1YGvYSPwkDjkjqECs2Vm/AA==
+-----END CERTIFICATE-----`), []byte(testingKey(`-----BEGIN RSA TESTING KEY-----
+MIIBOgIBAAJBAN17PWsVQPBrHYdPFtycVQ/0CFyAQYwdVXaefhVURYUkHojwL82T
+HRfLJCWuYVgHMRCcg+EqWzhPSEWgu+MmdekCAwEAAQJBALjQYNTdXF4CFBbXwUz/
+yt9QFDYT9B5WT/12jeGAe653gtYS6OOi/+eAkGmzg1GlRnw6fOfn+HYNFDORST7z
+4j0CIQDn2xz9hVWQEu9ee3vecNT3f60huDGTNoRhtqgweQGX0wIhAPSLj1VcRZEz
+nKpbtU22+PbIMSJ+e80fmY9LIPx5N4HTAiAthGSimMR9bloz0EY3GyuUEyqoDgMd
+hXxjuno2WesoJQIgemilbcALXpxsLmZLgcQ2KSmaVr7jb5ECx9R+hYKTw1sCIG4s
+T+E0J8wlH24pgwQHzy7Ko2qLwn1b5PW8ecrlvP1g
+-----END RSA TESTING KEY-----`)))
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ clientConn, serverConn := localPipe(t)
+ client := Client(clientConn, testConfig)
+ done := make(chan struct{})
+ go func() {
+ config := testConfig.Clone()
+ config.Certificates = []Certificate{cert}
+ config.MinVersion = VersionTLS13
+ server := Server(serverConn, config)
+ err := server.Handshake()
+ expectError(t, err, "key size too small")
+ close(done)
+ }()
+ err = client.Handshake()
+ expectError(t, err, "handshake failure")
+ <-done
+}
+
+func TestMultipleCertificates(t *testing.T) {
+ clientConfig := testConfig.Clone()
+ clientConfig.CipherSuites = []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256}
+ clientConfig.MaxVersion = VersionTLS12
+
+ serverConfig := testConfig.Clone()
+ serverConfig.Certificates = []Certificate{{
+ Certificate: [][]byte{testECDSACertificate},
+ PrivateKey: testECDSAPrivateKey,
+ }, {
+ Certificate: [][]byte{testRSACertificate},
+ PrivateKey: testRSAPrivateKey,
+ }}
+
+ _, clientState, err := testHandshake(t, clientConfig, serverConfig)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if got := clientState.PeerCertificates[0].PublicKeyAlgorithm; got != x509.RSA {
+ t.Errorf("expected RSA certificate, got %v", got)
+ }
+}
+
+func TestAESCipherReordering(t *testing.T) {
+ currentAESSupport := hasAESGCMHardwareSupport
+ defer func() { hasAESGCMHardwareSupport = currentAESSupport }()
+
+ tests := []struct {
+ name string
+ clientCiphers []uint16
+ serverHasAESGCM bool
+ serverCiphers []uint16
+ expectedCipher uint16
+ }{
+ {
+ name: "server has hardware AES, client doesn't (pick ChaCha)",
+ clientCiphers: []uint16{
+ TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_RSA_WITH_AES_128_CBC_SHA,
+ },
+ serverHasAESGCM: true,
+ expectedCipher: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+ },
+ {
+ name: "client prefers AES-GCM, server doesn't have hardware AES (pick ChaCha)",
+ clientCiphers: []uint16{
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+ TLS_RSA_WITH_AES_128_CBC_SHA,
+ },
+ serverHasAESGCM: false,
+ expectedCipher: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+ },
+ {
+ name: "client prefers AES-GCM, server has hardware AES (pick AES-GCM)",
+ clientCiphers: []uint16{
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+ TLS_RSA_WITH_AES_128_CBC_SHA,
+ },
+ serverHasAESGCM: true,
+ expectedCipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ },
+ {
+ name: "client prefers AES-GCM and sends GREASE, server has hardware AES (pick AES-GCM)",
+ clientCiphers: []uint16{
+ 0x0A0A, // GREASE value
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+ TLS_RSA_WITH_AES_128_CBC_SHA,
+ },
+ serverHasAESGCM: true,
+ expectedCipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ },
+ {
+ name: "client prefers AES-GCM and doesn't support ChaCha, server doesn't have hardware AES (pick AES-GCM)",
+ clientCiphers: []uint16{
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+ TLS_RSA_WITH_AES_128_CBC_SHA,
+ },
+ serverHasAESGCM: false,
+ expectedCipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ },
+ {
+ name: "client prefers AES-GCM and AES-CBC over ChaCha, server doesn't have hardware AES (pick ChaCha)",
+ clientCiphers: []uint16{
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_RSA_WITH_AES_128_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+ },
+ serverHasAESGCM: false,
+ expectedCipher: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+ },
+ {
+ name: "client prefers AES-GCM over ChaCha and sends GREASE, server doesn't have hardware AES (pick ChaCha)",
+ clientCiphers: []uint16{
+ 0x0A0A, // GREASE value
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+ TLS_RSA_WITH_AES_128_CBC_SHA,
+ },
+ serverHasAESGCM: false,
+ expectedCipher: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+ },
+ {
+ name: "client supports multiple AES-GCM, server doesn't have hardware AES and doesn't support ChaCha (AES-GCM)",
+ clientCiphers: []uint16{
+ TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+ TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ },
+ serverHasAESGCM: false,
+ serverCiphers: []uint16{
+ TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ },
+ expectedCipher: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ },
+ {
+ name: "client prefers AES-GCM, server has hardware but doesn't support AES (pick ChaCha)",
+ clientCiphers: []uint16{
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+ TLS_RSA_WITH_AES_128_CBC_SHA,
+ },
+ serverHasAESGCM: true,
+ serverCiphers: []uint16{
+ TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+ },
+ expectedCipher: TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
+ },
+ }
+
+ for _, tc := range tests {
+ t.Run(tc.name, func(t *testing.T) {
+ hasAESGCMHardwareSupport = tc.serverHasAESGCM
+ hs := &serverHandshakeState{
+ c: &Conn{
+ config: &Config{
+ CipherSuites: tc.serverCiphers,
+ },
+ vers: VersionTLS12,
+ },
+ clientHello: &clientHelloMsg{
+ cipherSuites: tc.clientCiphers,
+ vers: VersionTLS12,
+ },
+ ecdheOk: true,
+ rsaSignOk: true,
+ rsaDecryptOk: true,
+ }
+
+ err := hs.pickCipherSuite()
+ if err != nil {
+ t.Errorf("pickCipherSuite failed: %s", err)
+ }
+
+ if tc.expectedCipher != hs.suite.id {
+ t.Errorf("unexpected cipher chosen: want %d, got %d", tc.expectedCipher, hs.suite.id)
+ }
+ })
+ }
+}
+
+func TestAESCipherReorderingTLS13(t *testing.T) {
+ currentAESSupport := hasAESGCMHardwareSupport
+ defer func() { hasAESGCMHardwareSupport = currentAESSupport }()
+
+ tests := []struct {
+ name string
+ clientCiphers []uint16
+ serverHasAESGCM bool
+ expectedCipher uint16
+ }{
+ {
+ name: "server has hardware AES, client doesn't (pick ChaCha)",
+ clientCiphers: []uint16{
+ TLS_CHACHA20_POLY1305_SHA256,
+ TLS_AES_128_GCM_SHA256,
+ },
+ serverHasAESGCM: true,
+ expectedCipher: TLS_CHACHA20_POLY1305_SHA256,
+ },
+ {
+ name: "neither server nor client have hardware AES (pick ChaCha)",
+ clientCiphers: []uint16{
+ TLS_CHACHA20_POLY1305_SHA256,
+ TLS_AES_128_GCM_SHA256,
+ },
+ serverHasAESGCM: false,
+ expectedCipher: TLS_CHACHA20_POLY1305_SHA256,
+ },
+ {
+ name: "client prefers AES, server doesn't have hardware (pick ChaCha)",
+ clientCiphers: []uint16{
+ TLS_AES_128_GCM_SHA256,
+ TLS_CHACHA20_POLY1305_SHA256,
+ },
+ serverHasAESGCM: false,
+ expectedCipher: TLS_CHACHA20_POLY1305_SHA256,
+ },
+ {
+ name: "client prefers AES and sends GREASE, server doesn't have hardware (pick ChaCha)",
+ clientCiphers: []uint16{
+ 0x0A0A, // GREASE value
+ TLS_AES_128_GCM_SHA256,
+ TLS_CHACHA20_POLY1305_SHA256,
+ },
+ serverHasAESGCM: false,
+ expectedCipher: TLS_CHACHA20_POLY1305_SHA256,
+ },
+ {
+ name: "client prefers AES, server has hardware AES (pick AES)",
+ clientCiphers: []uint16{
+ TLS_AES_128_GCM_SHA256,
+ TLS_CHACHA20_POLY1305_SHA256,
+ },
+ serverHasAESGCM: true,
+ expectedCipher: TLS_AES_128_GCM_SHA256,
+ },
+ {
+ name: "client prefers AES and sends GREASE, server has hardware AES (pick AES)",
+ clientCiphers: []uint16{
+ 0x0A0A, // GREASE value
+ TLS_AES_128_GCM_SHA256,
+ TLS_CHACHA20_POLY1305_SHA256,
+ },
+ serverHasAESGCM: true,
+ expectedCipher: TLS_AES_128_GCM_SHA256,
+ },
+ }
+
+ for _, tc := range tests {
+ t.Run(tc.name, func(t *testing.T) {
+ hasAESGCMHardwareSupport = tc.serverHasAESGCM
+ pk, _ := ecdh.X25519().GenerateKey(rand.Reader)
+ hs := &serverHandshakeStateTLS13{
+ c: &Conn{
+ config: &Config{},
+ vers: VersionTLS13,
+ },
+ clientHello: &clientHelloMsg{
+ cipherSuites: tc.clientCiphers,
+ supportedVersions: []uint16{VersionTLS13},
+ compressionMethods: []uint8{compressionNone},
+ keyShares: []keyShare{{group: X25519, data: pk.PublicKey().Bytes()}},
+ },
+ }
+
+ err := hs.processClientHello()
+ if err != nil {
+ t.Errorf("pickCipherSuite failed: %s", err)
+ }
+
+ if tc.expectedCipher != hs.suite.id {
+ t.Errorf("unexpected cipher chosen: want %d, got %d", tc.expectedCipher, hs.suite.id)
+ }
+ })
+ }
+}
+
+// TestServerHandshakeContextCancellation tests that canceling
+// the context given to the server side conn.HandshakeContext
+// interrupts the in-progress handshake.
+func TestServerHandshakeContextCancellation(t *testing.T) {
+ c, s := localPipe(t)
+ ctx, cancel := context.WithCancel(context.Background())
+ unblockClient := make(chan struct{})
+ defer close(unblockClient)
+ go func() {
+ cancel()
+ <-unblockClient
+ _ = c.Close()
+ }()
+ conn := Server(s, testConfig)
+ // Initiates server side handshake, which will block until a client hello is read
+ // unless the cancellation works.
+ err := conn.HandshakeContext(ctx)
+ if err == nil {
+ t.Fatal("Server handshake did not error when the context was canceled")
+ }
+ if err != context.Canceled {
+ t.Errorf("Unexpected server handshake error: %v", err)
+ }
+ if runtime.GOARCH == "wasm" {
+ t.Skip("conn.Close does not error as expected when called multiple times on WASM")
+ }
+ err = conn.Close()
+ if err == nil {
+ t.Error("Server connection was not closed when the context was canceled")
+ }
+}
+
+// TestHandshakeContextHierarchy tests whether the contexts
+// available to GetClientCertificate and GetCertificate are
+// derived from the context provided to HandshakeContext, and
+// that those contexts are canceled after HandshakeContext has
+// returned.
+func TestHandshakeContextHierarchy(t *testing.T) {
+ c, s := localPipe(t)
+ clientErr := make(chan error, 1)
+ clientConfig := testConfig.Clone()
+ serverConfig := testConfig.Clone()
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+ key := struct{}{}
+ ctx = context.WithValue(ctx, key, true)
+ go func() {
+ defer close(clientErr)
+ defer c.Close()
+ var innerCtx context.Context
+ clientConfig.Certificates = nil
+ clientConfig.GetClientCertificate = func(certificateRequest *CertificateRequestInfo) (*Certificate, error) {
+ if val, ok := certificateRequest.Context().Value(key).(bool); !ok || !val {
+ t.Errorf("GetClientCertificate context was not child of HandshakeContext")
+ }
+ innerCtx = certificateRequest.Context()
+ return &Certificate{
+ Certificate: [][]byte{testRSACertificate},
+ PrivateKey: testRSAPrivateKey,
+ }, nil
+ }
+ cli := Client(c, clientConfig)
+ err := cli.HandshakeContext(ctx)
+ if err != nil {
+ clientErr <- err
+ return
+ }
+ select {
+ case <-innerCtx.Done():
+ default:
+ t.Errorf("GetClientCertificate context was not canceled after HandshakeContext returned.")
+ }
+ }()
+ var innerCtx context.Context
+ serverConfig.Certificates = nil
+ serverConfig.ClientAuth = RequestClientCert
+ serverConfig.GetCertificate = func(clientHello *ClientHelloInfo) (*Certificate, error) {
+ if val, ok := clientHello.Context().Value(key).(bool); !ok || !val {
+ t.Errorf("GetClientCertificate context was not child of HandshakeContext")
+ }
+ innerCtx = clientHello.Context()
+ return &Certificate{
+ Certificate: [][]byte{testRSACertificate},
+ PrivateKey: testRSAPrivateKey,
+ }, nil
+ }
+ conn := Server(s, serverConfig)
+ err := conn.HandshakeContext(ctx)
+ if err != nil {
+ t.Errorf("Unexpected server handshake error: %v", err)
+ }
+ select {
+ case <-innerCtx.Done():
+ default:
+ t.Errorf("GetCertificate context was not canceled after HandshakeContext returned.")
+ }
+ if err := <-clientErr; err != nil {
+ t.Errorf("Unexpected client error: %v", err)
+ }
+}
diff --git a/src/crypto/tls/handshake_server_tls13.go b/src/crypto/tls/handshake_server_tls13.go
new file mode 100644
index 0000000..07b1a38
--- /dev/null
+++ b/src/crypto/tls/handshake_server_tls13.go
@@ -0,0 +1,991 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+ "bytes"
+ "context"
+ "crypto"
+ "crypto/hmac"
+ "crypto/rsa"
+ "encoding/binary"
+ "errors"
+ "hash"
+ "io"
+ "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
+ ctx context.Context
+ clientHello *clientHelloMsg
+ hello *serverHelloMsg
+ sentDummyCCS bool
+ usingPSK bool
+ earlyData bool
+ suite *cipherSuiteTLS13
+ cert *Certificate
+ sigAlg SignatureScheme
+ earlySecret []byte
+ sharedKey []byte
+ handshakeSecret []byte
+ masterSecret []byte
+ trafficSecret []byte // client_application_traffic_secret_0
+ transcript hash.Hash
+ clientFinished []byte
+}
+
+func (hs *serverHandshakeStateTLS13) handshake() error {
+ c := hs.c
+
+ if needFIPS() {
+ return errors.New("tls: internal error: TLS 1.3 reached in FIPS mode")
+ }
+
+ // For an overview of the TLS 1.3 handshake, see RFC 8446, Section 2.
+ if err := hs.processClientHello(); err != nil {
+ return err
+ }
+ if err := hs.checkForResumption(); err != nil {
+ return err
+ }
+ if err := hs.pickCertificate(); err != nil {
+ return err
+ }
+ c.buffering = true
+ if err := hs.sendServerParameters(); err != nil {
+ return err
+ }
+ 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 := c.flush(); err != nil {
+ return err
+ }
+ if err := hs.readClientCertificate(); err != nil {
+ return err
+ }
+ if err := hs.readClientFinished(); err != nil {
+ return err
+ }
+
+ c.isHandshakeComplete.Store(true)
+
+ return nil
+}
+
+func (hs *serverHandshakeStateTLS13) processClientHello() error {
+ c := hs.c
+
+ hs.hello = new(serverHelloMsg)
+
+ // TLS 1.3 froze the ServerHello.legacy_version field, and uses
+ // supported_versions instead. See RFC 8446, sections 4.1.3 and 4.2.1.
+ hs.hello.vers = VersionTLS12
+ hs.hello.supportedVersion = c.vers
+
+ if len(hs.clientHello.supportedVersions) == 0 {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: client used the legacy version field to negotiate TLS 1.3")
+ }
+
+ // Abort if the client is doing a fallback and landing lower than what we
+ // support. See RFC 7507, which however does not specify the interaction
+ // with supported_versions. The only difference is that with
+ // supported_versions a client has a chance to attempt a [TLS 1.2, TLS 1.4]
+ // handshake in case TLS 1.3 is broken but 1.2 is not. Alas, in that case,
+ // it will have to drop the TLS_FALLBACK_SCSV protection if it falls back to
+ // TLS 1.2, because a TLS 1.3 server would abort here. The situation before
+ // supported_versions was not better because there was just no way to do a
+ // TLS 1.4 handshake without risking the server selecting TLS 1.3.
+ for _, id := range hs.clientHello.cipherSuites {
+ if id == TLS_FALLBACK_SCSV {
+ // Use c.vers instead of max(supported_versions) because an attacker
+ // could defeat this by adding an arbitrary high version otherwise.
+ if c.vers < c.config.maxSupportedVersion(roleServer) {
+ c.sendAlert(alertInappropriateFallback)
+ return errors.New("tls: client using inappropriate protocol fallback")
+ }
+ break
+ }
+ }
+
+ if len(hs.clientHello.compressionMethods) != 1 ||
+ hs.clientHello.compressionMethods[0] != compressionNone {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: TLS 1.3 client supports illegal compression methods")
+ }
+
+ hs.hello.random = make([]byte, 32)
+ if _, err := io.ReadFull(c.config.rand(), hs.hello.random); err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+
+ if len(hs.clientHello.secureRenegotiation) != 0 {
+ c.sendAlert(alertHandshakeFailure)
+ return errors.New("tls: initial handshake had non-empty renegotiation extension")
+ }
+
+ if hs.clientHello.earlyData && c.quic != nil {
+ if len(hs.clientHello.pskIdentities) == 0 {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: early_data without pre_shared_key")
+ }
+ } else if hs.clientHello.earlyData {
+ // See RFC 8446, Section 4.2.10 for the complicated behavior required
+ // here. The scenario is that a different server at our address offered
+ // to accept early data in the past, which we can't handle. For now, all
+ // 0-RTT enabled session tickets need to expire before a Go server can
+ // replace a server or join a pool. That's the same requirement that
+ // applies to mixing or replacing with any TLS 1.2 server.
+ c.sendAlert(alertUnsupportedExtension)
+ return errors.New("tls: client sent unexpected early data")
+ }
+
+ hs.hello.sessionId = hs.clientHello.sessionId
+ hs.hello.compressionMethod = compressionNone
+
+ preferenceList := defaultCipherSuitesTLS13
+ if !hasAESGCMHardwareSupport || !aesgcmPreferred(hs.clientHello.cipherSuites) {
+ preferenceList = defaultCipherSuitesTLS13NoAES
+ }
+ for _, suiteID := range preferenceList {
+ hs.suite = mutualCipherSuiteTLS13(hs.clientHello.cipherSuites, suiteID)
+ if hs.suite != nil {
+ break
+ }
+ }
+ if hs.suite == nil {
+ c.sendAlert(alertHandshakeFailure)
+ return errors.New("tls: no cipher suite supported by both client and server")
+ }
+ c.cipherSuite = hs.suite.id
+ hs.hello.cipherSuite = hs.suite.id
+ hs.transcript = hs.suite.hash.New()
+
+ // Pick the ECDHE group in server preference order, but give priority to
+ // groups with a key share, to avoid a HelloRetryRequest round-trip.
+ var selectedGroup CurveID
+ var clientKeyShare *keyShare
+GroupSelection:
+ for _, preferredGroup := range c.config.curvePreferences() {
+ for _, ks := range hs.clientHello.keyShares {
+ if ks.group == preferredGroup {
+ selectedGroup = ks.group
+ clientKeyShare = &ks
+ break GroupSelection
+ }
+ }
+ if selectedGroup != 0 {
+ continue
+ }
+ for _, group := range hs.clientHello.supportedCurves {
+ if group == preferredGroup {
+ selectedGroup = group
+ break
+ }
+ }
+ }
+ if selectedGroup == 0 {
+ c.sendAlert(alertHandshakeFailure)
+ return errors.New("tls: no ECDHE curve supported by both client and server")
+ }
+ if clientKeyShare == nil {
+ if err := hs.doHelloRetryRequest(selectedGroup); err != nil {
+ return err
+ }
+ clientKeyShare = &hs.clientHello.keyShares[0]
+ }
+
+ if _, ok := curveForCurveID(selectedGroup); !ok {
+ c.sendAlert(alertInternalError)
+ return errors.New("tls: CurvePreferences includes unsupported curve")
+ }
+ key, err := generateECDHEKey(c.config.rand(), selectedGroup)
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+ hs.hello.serverShare = keyShare{group: selectedGroup, data: key.PublicKey().Bytes()}
+ peerKey, err := key.Curve().NewPublicKey(clientKeyShare.data)
+ if err != nil {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: invalid client key share")
+ }
+ hs.sharedKey, err = key.ECDH(peerKey)
+ if err != nil {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: invalid client key share")
+ }
+
+ selectedProto, err := negotiateALPN(c.config.NextProtos, hs.clientHello.alpnProtocols, c.quic != nil)
+ if err != nil {
+ c.sendAlert(alertNoApplicationProtocol)
+ return err
+ }
+ c.clientProtocol = selectedProto
+
+ if c.quic != nil {
+ if hs.clientHello.quicTransportParameters == nil {
+ // RFC 9001 Section 8.2.
+ c.sendAlert(alertMissingExtension)
+ return errors.New("tls: client did not send a quic_transport_parameters extension")
+ }
+ c.quicSetTransportParameters(hs.clientHello.quicTransportParameters)
+ } else {
+ if hs.clientHello.quicTransportParameters != nil {
+ c.sendAlert(alertUnsupportedExtension)
+ return errors.New("tls: client sent an unexpected quic_transport_parameters extension")
+ }
+ }
+
+ c.serverName = hs.clientHello.serverName
+ return nil
+}
+
+func (hs *serverHandshakeStateTLS13) checkForResumption() error {
+ c := hs.c
+
+ if c.config.SessionTicketsDisabled {
+ return nil
+ }
+
+ modeOK := false
+ for _, mode := range hs.clientHello.pskModes {
+ if mode == pskModeDHE {
+ modeOK = true
+ break
+ }
+ }
+ if !modeOK {
+ return nil
+ }
+
+ if len(hs.clientHello.pskIdentities) != len(hs.clientHello.pskBinders) {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: invalid or missing PSK binders")
+ }
+ if len(hs.clientHello.pskIdentities) == 0 {
+ return nil
+ }
+
+ for i, identity := range hs.clientHello.pskIdentities {
+ if i >= maxClientPSKIdentities {
+ break
+ }
+
+ var sessionState *SessionState
+ if c.config.UnwrapSession != nil {
+ var err error
+ sessionState, err = c.config.UnwrapSession(identity.label, c.connectionStateLocked())
+ if err != nil {
+ return err
+ }
+ if sessionState == nil {
+ continue
+ }
+ } else {
+ plaintext := c.config.decryptTicket(identity.label, c.ticketKeys)
+ if plaintext == nil {
+ continue
+ }
+ var err error
+ sessionState, err = ParseSessionState(plaintext)
+ if err != nil {
+ continue
+ }
+ }
+
+ if sessionState.version != VersionTLS13 {
+ continue
+ }
+
+ createdAt := time.Unix(int64(sessionState.createdAt), 0)
+ if c.config.time().Sub(createdAt) > maxSessionTicketLifetime {
+ continue
+ }
+
+ 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.peerCertificates) != 0
+ needClientCerts := requiresClientCert(c.config.ClientAuth)
+ if needClientCerts && !sessionHasClientCerts {
+ continue
+ }
+ if sessionHasClientCerts && c.config.ClientAuth == NoClientCert {
+ continue
+ }
+ if sessionHasClientCerts && c.config.time().After(sessionState.peerCertificates[0].NotAfter) {
+ continue
+ }
+ if sessionHasClientCerts && c.config.ClientAuth >= VerifyClientCertIfGiven &&
+ len(sessionState.verifiedChains) == 0 {
+ continue
+ }
+
+ hs.earlySecret = hs.suite.extract(sessionState.secret, 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 errors.New("tls: internal error: failed to clone hash")
+ }
+ clientHelloBytes, err := hs.clientHello.marshalWithoutBinders()
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+ transcript.Write(clientHelloBytes)
+ pskBinder := hs.suite.finishedHash(binderKey, transcript)
+ if !hmac.Equal(hs.clientHello.pskBinders[i], pskBinder) {
+ c.sendAlert(alertDecryptError)
+ return errors.New("tls: invalid PSK binder")
+ }
+
+ if c.quic != nil && hs.clientHello.earlyData && i == 0 &&
+ sessionState.EarlyData && sessionState.cipherSuite == hs.suite.id &&
+ sessionState.alpnProtocol == c.clientProtocol {
+ hs.earlyData = true
+
+ transcript := hs.suite.hash.New()
+ if err := transcriptMsg(hs.clientHello, transcript); err != nil {
+ return err
+ }
+ earlyTrafficSecret := hs.suite.deriveSecret(hs.earlySecret, clientEarlyTrafficLabel, transcript)
+ c.quicSetReadSecret(QUICEncryptionLevelEarly, hs.suite.id, earlyTrafficSecret)
+ }
+
+ c.didResume = true
+ c.peerCertificates = sessionState.peerCertificates
+ c.ocspResponse = sessionState.ocspResponse
+ c.scts = sessionState.scts
+ c.verifiedChains = sessionState.verifiedChains
+
+ hs.hello.selectedIdentityPresent = true
+ hs.hello.selectedIdentity = uint16(i)
+ hs.usingPSK = true
+ return nil
+ }
+
+ return 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
+
+ // Only one of PSK and certificates are used at a time.
+ if hs.usingPSK {
+ return nil
+ }
+
+ // signature_algorithms is required in TLS 1.3. See RFC 8446, Section 4.2.3.
+ if len(hs.clientHello.supportedSignatureAlgorithms) == 0 {
+ return c.sendAlert(alertMissingExtension)
+ }
+
+ certificate, err := c.config.getCertificate(clientHelloInfo(hs.ctx, c, hs.clientHello))
+ if err != nil {
+ if err == errNoCertificates {
+ c.sendAlert(alertUnrecognizedName)
+ } else {
+ c.sendAlert(alertInternalError)
+ }
+ return err
+ }
+ hs.sigAlg, err = selectSignatureScheme(c.vers, certificate, hs.clientHello.supportedSignatureAlgorithms)
+ if err != nil {
+ // getCertificate returned a certificate that is unsupported or
+ // incompatible with the client's signature algorithms.
+ c.sendAlert(alertHandshakeFailure)
+ return err
+ }
+ hs.cert = certificate
+
+ return nil
+}
+
+// sendDummyChangeCipherSpec sends a ChangeCipherSpec record for compatibility
+// with middleboxes that didn't implement TLS correctly. See RFC 8446, Appendix D.4.
+func (hs *serverHandshakeStateTLS13) sendDummyChangeCipherSpec() error {
+ if hs.c.quic != nil {
+ return nil
+ }
+ if hs.sentDummyCCS {
+ return nil
+ }
+ hs.sentDummyCCS = true
+
+ return hs.c.writeChangeCipherRecord()
+}
+
+func (hs *serverHandshakeStateTLS13) doHelloRetryRequest(selectedGroup CurveID) error {
+ c := hs.c
+
+ // The first ClientHello gets double-hashed into the transcript upon a
+ // HelloRetryRequest. See RFC 8446, Section 4.4.1.
+ if err := transcriptMsg(hs.clientHello, hs.transcript); err != nil {
+ return err
+ }
+ chHash := hs.transcript.Sum(nil)
+ hs.transcript.Reset()
+ hs.transcript.Write([]byte{typeMessageHash, 0, 0, uint8(len(chHash))})
+ hs.transcript.Write(chHash)
+
+ helloRetryRequest := &serverHelloMsg{
+ vers: hs.hello.vers,
+ random: helloRetryRequestRandom,
+ sessionId: hs.hello.sessionId,
+ cipherSuite: hs.hello.cipherSuite,
+ compressionMethod: hs.hello.compressionMethod,
+ supportedVersion: hs.hello.supportedVersion,
+ selectedGroup: selectedGroup,
+ }
+
+ if _, err := hs.c.writeHandshakeRecord(helloRetryRequest, hs.transcript); err != nil {
+ return err
+ }
+
+ if err := hs.sendDummyChangeCipherSpec(); err != nil {
+ return err
+ }
+
+ // clientHelloMsg is not included in the transcript.
+ msg, err := c.readHandshake(nil)
+ if err != nil {
+ return err
+ }
+
+ clientHello, ok := msg.(*clientHelloMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(clientHello, msg)
+ }
+
+ if len(clientHello.keyShares) != 1 || clientHello.keyShares[0].group != selectedGroup {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: client sent invalid key share in second ClientHello")
+ }
+
+ if clientHello.earlyData {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: client indicated early data in second ClientHello")
+ }
+
+ if illegalClientHelloChange(clientHello, hs.clientHello) {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: client illegally modified second ClientHello")
+ }
+
+ hs.clientHello = clientHello
+ return nil
+}
+
+// illegalClientHelloChange reports whether the two ClientHello messages are
+// different, with the exception of the changes allowed before and after a
+// HelloRetryRequest. See RFC 8446, Section 4.1.2.
+func illegalClientHelloChange(ch, ch1 *clientHelloMsg) bool {
+ if len(ch.supportedVersions) != len(ch1.supportedVersions) ||
+ len(ch.cipherSuites) != len(ch1.cipherSuites) ||
+ len(ch.supportedCurves) != len(ch1.supportedCurves) ||
+ len(ch.supportedSignatureAlgorithms) != len(ch1.supportedSignatureAlgorithms) ||
+ len(ch.supportedSignatureAlgorithmsCert) != len(ch1.supportedSignatureAlgorithmsCert) ||
+ len(ch.alpnProtocols) != len(ch1.alpnProtocols) {
+ return true
+ }
+ for i := range ch.supportedVersions {
+ if ch.supportedVersions[i] != ch1.supportedVersions[i] {
+ return true
+ }
+ }
+ for i := range ch.cipherSuites {
+ if ch.cipherSuites[i] != ch1.cipherSuites[i] {
+ return true
+ }
+ }
+ for i := range ch.supportedCurves {
+ if ch.supportedCurves[i] != ch1.supportedCurves[i] {
+ return true
+ }
+ }
+ for i := range ch.supportedSignatureAlgorithms {
+ if ch.supportedSignatureAlgorithms[i] != ch1.supportedSignatureAlgorithms[i] {
+ return true
+ }
+ }
+ for i := range ch.supportedSignatureAlgorithmsCert {
+ if ch.supportedSignatureAlgorithmsCert[i] != ch1.supportedSignatureAlgorithmsCert[i] {
+ return true
+ }
+ }
+ for i := range ch.alpnProtocols {
+ if ch.alpnProtocols[i] != ch1.alpnProtocols[i] {
+ return true
+ }
+ }
+ return ch.vers != ch1.vers ||
+ !bytes.Equal(ch.random, ch1.random) ||
+ !bytes.Equal(ch.sessionId, ch1.sessionId) ||
+ !bytes.Equal(ch.compressionMethods, ch1.compressionMethods) ||
+ ch.serverName != ch1.serverName ||
+ ch.ocspStapling != ch1.ocspStapling ||
+ !bytes.Equal(ch.supportedPoints, ch1.supportedPoints) ||
+ ch.ticketSupported != ch1.ticketSupported ||
+ !bytes.Equal(ch.sessionTicket, ch1.sessionTicket) ||
+ ch.secureRenegotiationSupported != ch1.secureRenegotiationSupported ||
+ !bytes.Equal(ch.secureRenegotiation, ch1.secureRenegotiation) ||
+ ch.scts != ch1.scts ||
+ !bytes.Equal(ch.cookie, ch1.cookie) ||
+ !bytes.Equal(ch.pskModes, ch1.pskModes)
+}
+
+func (hs *serverHandshakeStateTLS13) sendServerParameters() error {
+ c := hs.c
+
+ if err := transcriptMsg(hs.clientHello, hs.transcript); err != nil {
+ return err
+ }
+ if _, err := hs.c.writeHandshakeRecord(hs.hello, hs.transcript); err != nil {
+ return err
+ }
+
+ if err := hs.sendDummyChangeCipherSpec(); err != nil {
+ 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, QUICEncryptionLevelHandshake, clientSecret)
+ serverSecret := hs.suite.deriveSecret(hs.handshakeSecret,
+ serverHandshakeTrafficLabel, hs.transcript)
+ c.out.setTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, serverSecret)
+
+ if c.quic != nil {
+ if c.hand.Len() != 0 {
+ c.sendAlert(alertUnexpectedMessage)
+ }
+ c.quicSetWriteSecret(QUICEncryptionLevelHandshake, hs.suite.id, serverSecret)
+ c.quicSetReadSecret(QUICEncryptionLevelHandshake, hs.suite.id, clientSecret)
+ }
+
+ err := c.config.writeKeyLog(keyLogLabelClientHandshake, hs.clientHello.random, clientSecret)
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+ err = c.config.writeKeyLog(keyLogLabelServerHandshake, hs.clientHello.random, serverSecret)
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+
+ encryptedExtensions := new(encryptedExtensionsMsg)
+ encryptedExtensions.alpnProtocol = c.clientProtocol
+
+ if c.quic != nil {
+ p, err := c.quicGetTransportParameters()
+ if err != nil {
+ return err
+ }
+ encryptedExtensions.quicTransportParameters = p
+ encryptedExtensions.earlyData = hs.earlyData
+ }
+
+ if _, err := hs.c.writeHandshakeRecord(encryptedExtensions, hs.transcript); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (hs *serverHandshakeStateTLS13) requestClientCert() bool {
+ return hs.c.config.ClientAuth >= RequestClientCert && !hs.usingPSK
+}
+
+func (hs *serverHandshakeStateTLS13) sendServerCertificate() error {
+ c := hs.c
+
+ // Only one of PSK and certificates are used at a time.
+ if hs.usingPSK {
+ return nil
+ }
+
+ if hs.requestClientCert() {
+ // Request a client certificate
+ certReq := new(certificateRequestMsgTLS13)
+ certReq.ocspStapling = true
+ certReq.scts = true
+ certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms()
+ if c.config.ClientCAs != nil {
+ certReq.certificateAuthorities = c.config.ClientCAs.Subjects()
+ }
+
+ if _, err := hs.c.writeHandshakeRecord(certReq, hs.transcript); err != nil {
+ return err
+ }
+ }
+
+ certMsg := new(certificateMsgTLS13)
+
+ certMsg.certificate = *hs.cert
+ certMsg.scts = hs.clientHello.scts && len(hs.cert.SignedCertificateTimestamps) > 0
+ certMsg.ocspStapling = hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0
+
+ if _, err := hs.c.writeHandshakeRecord(certMsg, hs.transcript); err != nil {
+ return err
+ }
+
+ certVerifyMsg := new(certificateVerifyMsg)
+ certVerifyMsg.hasSignatureAlgorithm = true
+ certVerifyMsg.signatureAlgorithm = hs.sigAlg
+
+ sigType, sigHash, err := typeAndHashFromSignatureScheme(hs.sigAlg)
+ if err != nil {
+ return c.sendAlert(alertInternalError)
+ }
+
+ signed := signedMessage(sigHash, serverSignatureContext, hs.transcript)
+ signOpts := crypto.SignerOpts(sigHash)
+ if sigType == signatureRSAPSS {
+ signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash}
+ }
+ sig, err := hs.cert.PrivateKey.(crypto.Signer).Sign(c.config.rand(), signed, signOpts)
+ if err != nil {
+ public := hs.cert.PrivateKey.(crypto.Signer).Public()
+ if rsaKey, ok := public.(*rsa.PublicKey); ok && sigType == signatureRSAPSS &&
+ rsaKey.N.BitLen()/8 < sigHash.Size()*2+2 { // key too small for RSA-PSS
+ c.sendAlert(alertHandshakeFailure)
+ } else {
+ c.sendAlert(alertInternalError)
+ }
+ return errors.New("tls: failed to sign handshake: " + err.Error())
+ }
+ certVerifyMsg.signature = sig
+
+ if _, err := hs.c.writeHandshakeRecord(certVerifyMsg, hs.transcript); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (hs *serverHandshakeStateTLS13) sendServerFinished() error {
+ c := hs.c
+
+ finished := &finishedMsg{
+ verifyData: hs.suite.finishedHash(c.out.trafficSecret, hs.transcript),
+ }
+
+ if _, err := hs.c.writeHandshakeRecord(finished, hs.transcript); err != nil {
+ return err
+ }
+
+ // Derive secrets that take context through the server Finished.
+
+ hs.masterSecret = hs.suite.extract(nil,
+ hs.suite.deriveSecret(hs.handshakeSecret, "derived", nil))
+
+ hs.trafficSecret = hs.suite.deriveSecret(hs.masterSecret,
+ clientApplicationTrafficLabel, hs.transcript)
+ serverSecret := hs.suite.deriveSecret(hs.masterSecret,
+ serverApplicationTrafficLabel, hs.transcript)
+ c.out.setTrafficSecret(hs.suite, QUICEncryptionLevelApplication, serverSecret)
+
+ if c.quic != nil {
+ if c.hand.Len() != 0 {
+ // TODO: Handle this in setTrafficSecret?
+ c.sendAlert(alertUnexpectedMessage)
+ }
+ c.quicSetWriteSecret(QUICEncryptionLevelApplication, hs.suite.id, serverSecret)
+ }
+
+ err := c.config.writeKeyLog(keyLogLabelClientTraffic, hs.clientHello.random, hs.trafficSecret)
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+ err = c.config.writeKeyLog(keyLogLabelServerTraffic, hs.clientHello.random, serverSecret)
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+
+ c.ekm = hs.suite.exportKeyingMaterial(hs.masterSecret, hs.transcript)
+
+ // If we did not request client certificates, at this point we can
+ // precompute the client finished and roll the transcript forward to send
+ // session tickets in our first flight.
+ if !hs.requestClientCert() {
+ if err := hs.sendSessionTickets(); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (hs *serverHandshakeStateTLS13) shouldSendSessionTickets() bool {
+ if hs.c.config.SessionTicketsDisabled {
+ return false
+ }
+
+ // QUIC tickets are sent by QUICConn.SendSessionTicket, not automatically.
+ if hs.c.quic != nil {
+ 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
+
+ hs.clientFinished = hs.suite.finishedHash(c.in.trafficSecret, hs.transcript)
+ finishedMsg := &finishedMsg{
+ verifyData: hs.clientFinished,
+ }
+ if err := transcriptMsg(finishedMsg, hs.transcript); err != nil {
+ return err
+ }
+
+ c.resumptionSecret = hs.suite.deriveSecret(hs.masterSecret,
+ resumptionLabel, hs.transcript)
+
+ if !hs.shouldSendSessionTickets() {
+ return nil
+ }
+ return c.sendSessionTicket(false)
+}
+
+func (c *Conn) sendSessionTicket(earlyData bool) error {
+ suite := cipherSuiteTLS13ByID(c.cipherSuite)
+ if suite == nil {
+ return errors.New("tls: internal error: unknown cipher suite")
+ }
+ // ticket_nonce, which must be unique per connection, is always left at
+ // zero because we only ever send one ticket per connection.
+ psk := suite.expandLabel(c.resumptionSecret, "resumption",
+ nil, suite.hash.Size())
+
+ m := new(newSessionTicketMsgTLS13)
+
+ state, err := c.sessionState()
+ if err != nil {
+ return err
+ }
+ state.secret = psk
+ state.EarlyData = earlyData
+ if c.config.WrapSession != nil {
+ m.label, err = c.config.WrapSession(c.connectionStateLocked(), state)
+ if err != nil {
+ return err
+ }
+ } else {
+ stateBytes, err := state.Bytes()
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+ m.label, err = c.config.encryptTicket(stateBytes, c.ticketKeys)
+ if err != nil {
+ return err
+ }
+ }
+ m.lifetime = uint32(maxSessionTicketLifetime / time.Second)
+
+ // ticket_age_add is a random 32-bit value. See RFC 8446, section 4.6.1
+ // The value is not stored anywhere; we never need to check the ticket age
+ // because 0-RTT is not supported.
+ ageAdd := make([]byte, 4)
+ _, err = c.config.rand().Read(ageAdd)
+ if err != nil {
+ return err
+ }
+ m.ageAdd = binary.LittleEndian.Uint32(ageAdd)
+
+ if earlyData {
+ // RFC 9001, Section 4.6.1
+ m.maxEarlyData = 0xffffffff
+ }
+
+ if _, err := c.writeHandshakeRecord(m, nil); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (hs *serverHandshakeStateTLS13) readClientCertificate() error {
+ c := hs.c
+
+ if !hs.requestClientCert() {
+ // Make sure the connection is still being verified whether or not
+ // the server requested a client certificate.
+ if c.config.VerifyConnection != nil {
+ if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
+ c.sendAlert(alertBadCertificate)
+ return err
+ }
+ }
+ return nil
+ }
+
+ // If we requested a client certificate, then the client must send a
+ // certificate message. If it's empty, no CertificateVerify is sent.
+
+ msg, err := c.readHandshake(hs.transcript)
+ if err != nil {
+ return err
+ }
+
+ certMsg, ok := msg.(*certificateMsgTLS13)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(certMsg, msg)
+ }
+
+ if err := c.processCertsFromClient(certMsg.certificate); err != nil {
+ return err
+ }
+
+ if c.config.VerifyConnection != nil {
+ if err := c.config.VerifyConnection(c.connectionStateLocked()); err != nil {
+ c.sendAlert(alertBadCertificate)
+ return err
+ }
+ }
+
+ if len(certMsg.certificate.Certificate) != 0 {
+ // certificateVerifyMsg is included in the transcript, but not until
+ // after we verify the handshake signature, since the state before
+ // this message was sent is used.
+ msg, err = c.readHandshake(nil)
+ if err != nil {
+ return err
+ }
+
+ certVerify, ok := msg.(*certificateVerifyMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(certVerify, msg)
+ }
+
+ // See RFC 8446, Section 4.4.3.
+ if !isSupportedSignatureAlgorithm(certVerify.signatureAlgorithm, supportedSignatureAlgorithms()) {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: client certificate used with invalid signature algorithm")
+ }
+ sigType, sigHash, err := typeAndHashFromSignatureScheme(certVerify.signatureAlgorithm)
+ if err != nil {
+ return c.sendAlert(alertInternalError)
+ }
+ if sigType == signaturePKCS1v15 || sigHash == crypto.SHA1 {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: client certificate used with invalid signature algorithm")
+ }
+ signed := signedMessage(sigHash, clientSignatureContext, hs.transcript)
+ if err := verifyHandshakeSignature(sigType, c.peerCertificates[0].PublicKey,
+ sigHash, signed, certVerify.signature); err != nil {
+ c.sendAlert(alertDecryptError)
+ return errors.New("tls: invalid signature by the client certificate: " + err.Error())
+ }
+
+ if err := transcriptMsg(certVerify, hs.transcript); err != nil {
+ return err
+ }
+ }
+
+ // If we waited until the client certificates to send session tickets, we
+ // are ready to do it now.
+ if err := hs.sendSessionTickets(); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (hs *serverHandshakeStateTLS13) readClientFinished() error {
+ c := hs.c
+
+ // finishedMsg is not included in the transcript.
+ msg, err := c.readHandshake(nil)
+ if err != nil {
+ return err
+ }
+
+ finished, ok := msg.(*finishedMsg)
+ if !ok {
+ c.sendAlert(alertUnexpectedMessage)
+ return unexpectedMessageError(finished, msg)
+ }
+
+ if !hmac.Equal(hs.clientFinished, finished.verifyData) {
+ c.sendAlert(alertDecryptError)
+ return errors.New("tls: invalid client finished hash")
+ }
+
+ c.in.setTrafficSecret(hs.suite, QUICEncryptionLevelApplication, hs.trafficSecret)
+
+ return nil
+}
diff --git a/src/crypto/tls/handshake_test.go b/src/crypto/tls/handshake_test.go
new file mode 100644
index 0000000..bacc8b7
--- /dev/null
+++ b/src/crypto/tls/handshake_test.go
@@ -0,0 +1,530 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+ "bufio"
+ "crypto/ed25519"
+ "crypto/x509"
+ "encoding/hex"
+ "errors"
+ "flag"
+ "fmt"
+ "io"
+ "net"
+ "os"
+ "os/exec"
+ "runtime"
+ "strconv"
+ "strings"
+ "sync"
+ "testing"
+ "time"
+)
+
+// TLS reference tests run a connection against a reference implementation
+// (OpenSSL) of TLS and record the bytes of the resulting connection. The Go
+// code, during a test, is configured with deterministic randomness and so the
+// reference test can be reproduced exactly in the future.
+//
+// In order to save everyone who wishes to run the tests from needing the
+// reference implementation installed, the reference connections are saved in
+// files in the testdata directory. Thus running the tests involves nothing
+// external, but creating and updating them requires the reference
+// implementation.
+//
+// Tests can be updated by running them with the -update flag. This will cause
+// the test files for failing tests to be regenerated. Since the reference
+// implementation will always generate fresh random numbers, large parts of the
+// reference connection will always change.
+
+var (
+ update = flag.Bool("update", false, "update golden files on failure")
+ fast = flag.Bool("fast", false, "impose a quick, possibly flaky timeout on recorded tests")
+ keyFile = flag.String("keylog", "", "destination file for KeyLogWriter")
+)
+
+func runTestAndUpdateIfNeeded(t *testing.T, name string, run func(t *testing.T, update bool), wait bool) {
+ success := t.Run(name, func(t *testing.T) {
+ if !*update && !wait {
+ t.Parallel()
+ }
+ run(t, false)
+ })
+
+ if !success && *update {
+ t.Run(name+"#update", func(t *testing.T) {
+ run(t, true)
+ })
+ }
+}
+
+// checkOpenSSLVersion ensures that the version of OpenSSL looks reasonable
+// before updating the test data.
+func checkOpenSSLVersion() error {
+ if !*update {
+ return nil
+ }
+
+ openssl := exec.Command("openssl", "version")
+ output, err := openssl.CombinedOutput()
+ if err != nil {
+ return err
+ }
+
+ version := string(output)
+ if strings.HasPrefix(version, "OpenSSL 1.1.1") {
+ return nil
+ }
+
+ println("***********************************************")
+ println("")
+ println("You need to build OpenSSL 1.1.1 from source in order")
+ println("to update the test data.")
+ println("")
+ println("Configure it with:")
+ println("./Configure enable-weak-ssl-ciphers no-shared")
+ println("and then add the apps/ directory at the front of your PATH.")
+ println("***********************************************")
+
+ return errors.New("version of OpenSSL does not appear to be suitable for updating test data")
+}
+
+// recordingConn is a net.Conn that records the traffic that passes through it.
+// WriteTo can be used to produce output that can be later be loaded with
+// ParseTestData.
+type recordingConn struct {
+ net.Conn
+ sync.Mutex
+ flows [][]byte
+ reading bool
+}
+
+func (r *recordingConn) Read(b []byte) (n int, err error) {
+ if n, err = r.Conn.Read(b); n == 0 {
+ return
+ }
+ b = b[:n]
+
+ r.Lock()
+ defer r.Unlock()
+
+ if l := len(r.flows); l == 0 || !r.reading {
+ buf := make([]byte, len(b))
+ copy(buf, b)
+ r.flows = append(r.flows, buf)
+ } else {
+ r.flows[l-1] = append(r.flows[l-1], b[:n]...)
+ }
+ r.reading = true
+ return
+}
+
+func (r *recordingConn) Write(b []byte) (n int, err error) {
+ if n, err = r.Conn.Write(b); n == 0 {
+ return
+ }
+ b = b[:n]
+
+ r.Lock()
+ defer r.Unlock()
+
+ if l := len(r.flows); l == 0 || r.reading {
+ buf := make([]byte, len(b))
+ copy(buf, b)
+ r.flows = append(r.flows, buf)
+ } else {
+ r.flows[l-1] = append(r.flows[l-1], b[:n]...)
+ }
+ r.reading = false
+ return
+}
+
+// WriteTo writes Go source code to w that contains the recorded traffic.
+func (r *recordingConn) WriteTo(w io.Writer) (int64, error) {
+ // TLS always starts with a client to server flow.
+ clientToServer := true
+ var written int64
+ for i, flow := range r.flows {
+ source, dest := "client", "server"
+ if !clientToServer {
+ source, dest = dest, source
+ }
+ n, err := fmt.Fprintf(w, ">>> Flow %d (%s to %s)\n", i+1, source, dest)
+ written += int64(n)
+ if err != nil {
+ return written, err
+ }
+ dumper := hex.Dumper(w)
+ n, err = dumper.Write(flow)
+ written += int64(n)
+ if err != nil {
+ return written, err
+ }
+ err = dumper.Close()
+ if err != nil {
+ return written, err
+ }
+ clientToServer = !clientToServer
+ }
+ return written, nil
+}
+
+func parseTestData(r io.Reader) (flows [][]byte, err error) {
+ var currentFlow []byte
+
+ scanner := bufio.NewScanner(r)
+ for scanner.Scan() {
+ line := scanner.Text()
+ // If the line starts with ">>> " then it marks the beginning
+ // of a new flow.
+ if strings.HasPrefix(line, ">>> ") {
+ if len(currentFlow) > 0 || len(flows) > 0 {
+ flows = append(flows, currentFlow)
+ currentFlow = nil
+ }
+ continue
+ }
+
+ // Otherwise the line is a line of hex dump that looks like:
+ // 00000170 fc f5 06 bf (...) |.....X{&?......!|
+ // (Some bytes have been omitted from the middle section.)
+ _, after, ok := strings.Cut(line, " ")
+ if !ok {
+ return nil, errors.New("invalid test data")
+ }
+ line = after
+
+ before, _, ok := strings.Cut(line, "|")
+ if !ok {
+ return nil, errors.New("invalid test data")
+ }
+ line = before
+
+ hexBytes := strings.Fields(line)
+ for _, hexByte := range hexBytes {
+ val, err := strconv.ParseUint(hexByte, 16, 8)
+ if err != nil {
+ return nil, errors.New("invalid hex byte in test data: " + err.Error())
+ }
+ currentFlow = append(currentFlow, byte(val))
+ }
+ }
+
+ if len(currentFlow) > 0 {
+ flows = append(flows, currentFlow)
+ }
+
+ return flows, nil
+}
+
+// tempFile creates a temp file containing contents and returns its path.
+func tempFile(contents string) string {
+ file, err := os.CreateTemp("", "go-tls-test")
+ if err != nil {
+ panic("failed to create temp file: " + err.Error())
+ }
+ path := file.Name()
+ file.WriteString(contents)
+ file.Close()
+ return path
+}
+
+// localListener is set up by TestMain and used by localPipe to create Conn
+// pairs like net.Pipe, but connected by an actual buffered TCP connection.
+var localListener struct {
+ mu sync.Mutex
+ addr net.Addr
+ ch chan net.Conn
+}
+
+const localFlakes = 0 // change to 1 or 2 to exercise localServer/localPipe handling of mismatches
+
+func localServer(l net.Listener) {
+ for n := 0; ; n++ {
+ c, err := l.Accept()
+ if err != nil {
+ return
+ }
+ if localFlakes == 1 && n%2 == 0 {
+ c.Close()
+ continue
+ }
+ localListener.ch <- c
+ }
+}
+
+var isConnRefused = func(err error) bool { return false }
+
+func localPipe(t testing.TB) (net.Conn, net.Conn) {
+ localListener.mu.Lock()
+ defer localListener.mu.Unlock()
+
+ addr := localListener.addr
+
+ var err error
+Dialing:
+ // We expect a rare mismatch, but probably not 5 in a row.
+ for i := 0; i < 5; i++ {
+ tooSlow := time.NewTimer(1 * time.Second)
+ defer tooSlow.Stop()
+ var c1 net.Conn
+ c1, err = net.Dial(addr.Network(), addr.String())
+ if err != nil {
+ if runtime.GOOS == "dragonfly" && (isConnRefused(err) || os.IsTimeout(err)) {
+ // golang.org/issue/29583: Dragonfly sometimes returns a spurious
+ // ECONNREFUSED or ETIMEDOUT.
+ <-tooSlow.C
+ continue
+ }
+ t.Fatalf("localPipe: %v", err)
+ }
+ if localFlakes == 2 && i == 0 {
+ c1.Close()
+ continue
+ }
+ for {
+ select {
+ case <-tooSlow.C:
+ t.Logf("localPipe: timeout waiting for %v", c1.LocalAddr())
+ c1.Close()
+ continue Dialing
+
+ case c2 := <-localListener.ch:
+ if c2.RemoteAddr().String() == c1.LocalAddr().String() {
+ return c1, c2
+ }
+ t.Logf("localPipe: unexpected connection: %v != %v", c2.RemoteAddr(), c1.LocalAddr())
+ c2.Close()
+ }
+ }
+ }
+
+ t.Fatalf("localPipe: failed to connect: %v", err)
+ panic("unreachable")
+}
+
+// zeroSource is an io.Reader that returns an unlimited number of zero bytes.
+type zeroSource struct{}
+
+func (zeroSource) Read(b []byte) (n int, err error) {
+ for i := range b {
+ b[i] = 0
+ }
+
+ return len(b), nil
+}
+
+func allCipherSuites() []uint16 {
+ ids := make([]uint16, len(cipherSuites))
+ for i, suite := range cipherSuites {
+ ids[i] = suite.id
+ }
+
+ return ids
+}
+
+var testConfig *Config
+
+func TestMain(m *testing.M) {
+ flag.Parse()
+ os.Exit(runMain(m))
+}
+
+func runMain(m *testing.M) int {
+ // Cipher suites preferences change based on the architecture. Force them to
+ // the version without AES acceleration for test consistency.
+ hasAESGCMHardwareSupport = false
+
+ // Set up localPipe.
+ l, err := net.Listen("tcp", "127.0.0.1:0")
+ if err != nil {
+ l, err = net.Listen("tcp6", "[::1]:0")
+ }
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Failed to open local listener: %v", err)
+ os.Exit(1)
+ }
+ localListener.ch = make(chan net.Conn)
+ localListener.addr = l.Addr()
+ defer l.Close()
+ go localServer(l)
+
+ if err := checkOpenSSLVersion(); err != nil {
+ fmt.Fprintf(os.Stderr, "Error: %v", err)
+ os.Exit(1)
+ }
+
+ testConfig = &Config{
+ Time: func() time.Time { return time.Unix(0, 0) },
+ Rand: zeroSource{},
+ Certificates: make([]Certificate, 2),
+ InsecureSkipVerify: true,
+ CipherSuites: allCipherSuites(),
+ MinVersion: VersionTLS10,
+ MaxVersion: VersionTLS13,
+ }
+ testConfig.Certificates[0].Certificate = [][]byte{testRSACertificate}
+ testConfig.Certificates[0].PrivateKey = testRSAPrivateKey
+ testConfig.Certificates[1].Certificate = [][]byte{testSNICertificate}
+ testConfig.Certificates[1].PrivateKey = testRSAPrivateKey
+ testConfig.BuildNameToCertificate()
+ if *keyFile != "" {
+ f, err := os.OpenFile(*keyFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
+ if err != nil {
+ panic("failed to open -keylog file: " + err.Error())
+ }
+ testConfig.KeyLogWriter = f
+ defer f.Close()
+ }
+
+ return m.Run()
+}
+
+func testHandshake(t *testing.T, clientConfig, serverConfig *Config) (serverState, clientState ConnectionState, err error) {
+ const sentinel = "SENTINEL\n"
+ c, s := localPipe(t)
+ errChan := make(chan error)
+ go func() {
+ cli := Client(c, clientConfig)
+ err := cli.Handshake()
+ if err != nil {
+ errChan <- fmt.Errorf("client: %v", err)
+ c.Close()
+ return
+ }
+ defer cli.Close()
+ clientState = cli.ConnectionState()
+ buf, err := io.ReadAll(cli)
+ if err != nil {
+ t.Errorf("failed to call cli.Read: %v", err)
+ }
+ if got := string(buf); got != sentinel {
+ t.Errorf("read %q from TLS connection, but expected %q", got, sentinel)
+ }
+ errChan <- nil
+ }()
+ server := Server(s, serverConfig)
+ err = server.Handshake()
+ if err == nil {
+ serverState = server.ConnectionState()
+ if _, err := io.WriteString(server, sentinel); 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()
+ <-errChan
+ }
+ return
+}
+
+func fromHex(s string) []byte {
+ b, _ := hex.DecodeString(s)
+ return b
+}
+
+var testRSACertificate = fromHex("3082024b308201b4a003020102020900e8f09d3fe25beaa6300d06092a864886f70d01010b0500301f310b3009060355040a1302476f3110300e06035504031307476f20526f6f74301e170d3136303130313030303030305a170d3235303130313030303030305a301a310b3009060355040a1302476f310b300906035504031302476f30819f300d06092a864886f70d010101050003818d0030818902818100db467d932e12270648bc062821ab7ec4b6a25dfe1e5245887a3647a5080d92425bc281c0be97799840fb4f6d14fd2b138bc2a52e67d8d4099ed62238b74a0b74732bc234f1d193e596d9747bf3589f6c613cc0b041d4d92b2b2423775b1c3bbd755dce2054cfa163871d1e24c4f31d1a508baab61443ed97a77562f414c852d70203010001a38193308190300e0603551d0f0101ff0404030205a0301d0603551d250416301406082b0601050507030106082b06010505070302300c0603551d130101ff0402300030190603551d0e041204109f91161f43433e49a6de6db680d79f60301b0603551d230414301280104813494d137e1631bba301d5acab6e7b30190603551d1104123010820e6578616d706c652e676f6c616e67300d06092a864886f70d01010b0500038181009d30cc402b5b50a061cbbae55358e1ed8328a9581aa938a495a1ac315a1a84663d43d32dd90bf297dfd320643892243a00bccf9c7db74020015faad3166109a276fd13c3cce10c5ceeb18782f16c04ed73bbb343778d0c1cf10fa1d8408361c94c722b9daedb4606064df4c1b33ec0d1bd42d4dbfe3d1360845c21d33be9fae7")
+
+var testRSACertificateIssuer = fromHex("3082021930820182a003020102020900ca5e4e811a965964300d06092a864886f70d01010b0500301f310b3009060355040a1302476f3110300e06035504031307476f20526f6f74301e170d3136303130313030303030305a170d3235303130313030303030305a301f310b3009060355040a1302476f3110300e06035504031307476f20526f6f7430819f300d06092a864886f70d010101050003818d0030818902818100d667b378bb22f34143b6cd2008236abefaf2852adf3ab05e01329e2c14834f5105df3f3073f99dab5442d45ee5f8f57b0111c8cb682fbb719a86944eebfffef3406206d898b8c1b1887797c9c5006547bb8f00e694b7a063f10839f269f2c34fff7a1f4b21fbcd6bfdfb13ac792d1d11f277b5c5b48600992203059f2a8f8cc50203010001a35d305b300e0603551d0f0101ff040403020204301d0603551d250416301406082b0601050507030106082b06010505070302300f0603551d130101ff040530030101ff30190603551d0e041204104813494d137e1631bba301d5acab6e7b300d06092a864886f70d01010b050003818100c1154b4bab5266221f293766ae4138899bd4c5e36b13cee670ceeaa4cbdf4f6679017e2fe649765af545749fe4249418a56bd38a04b81e261f5ce86b8d5c65413156a50d12449554748c59a30c515bc36a59d38bddf51173e899820b282e40aa78c806526fd184fb6b4cf186ec728edffa585440d2b3225325f7ab580e87dd76")
+
+// testRSAPSSCertificate has signatureAlgorithm rsassaPss, but subjectPublicKeyInfo
+// algorithm rsaEncryption, for use with the rsa_pss_rsae_* SignatureSchemes.
+// See also TestRSAPSSKeyError. testRSAPSSCertificate is self-signed.
+var testRSAPSSCertificate = fromHex("308202583082018da003020102021100f29926eb87ea8a0db9fcc247347c11b0304106092a864886f70d01010a3034a00f300d06096086480165030402010500a11c301a06092a864886f70d010108300d06096086480165030402010500a20302012030123110300e060355040a130741636d6520436f301e170d3137313132333136313631305a170d3138313132333136313631305a30123110300e060355040a130741636d6520436f30819f300d06092a864886f70d010101050003818d0030818902818100db467d932e12270648bc062821ab7ec4b6a25dfe1e5245887a3647a5080d92425bc281c0be97799840fb4f6d14fd2b138bc2a52e67d8d4099ed62238b74a0b74732bc234f1d193e596d9747bf3589f6c613cc0b041d4d92b2b2423775b1c3bbd755dce2054cfa163871d1e24c4f31d1a508baab61443ed97a77562f414c852d70203010001a3463044300e0603551d0f0101ff0404030205a030130603551d25040c300a06082b06010505070301300c0603551d130101ff04023000300f0603551d110408300687047f000001304106092a864886f70d01010a3034a00f300d06096086480165030402010500a11c301a06092a864886f70d010108300d06096086480165030402010500a20302012003818100cdac4ef2ce5f8d79881042707f7cbf1b5a8a00ef19154b40151771006cd41626e5496d56da0c1a139fd84695593cb67f87765e18aa03ea067522dd78d2a589b8c92364e12838ce346c6e067b51f1a7e6f4b37ffab13f1411896679d18e880e0ba09e302ac067efca460288e9538122692297ad8093d4f7dd701424d7700a46a1")
+
+var testECDSACertificate = fromHex("3082020030820162020900b8bf2d47a0d2ebf4300906072a8648ce3d04013045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c7464301e170d3132313132323135303633325a170d3232313132303135303633325a3045310b3009060355040613024155311330110603550408130a536f6d652d53746174653121301f060355040a1318496e7465726e6574205769646769747320507479204c746430819b301006072a8648ce3d020106052b81040023038186000400c4a1edbe98f90b4873367ec316561122f23d53c33b4d213dcd6b75e6f6b0dc9adf26c1bcb287f072327cb3642f1c90bcea6823107efee325c0483a69e0286dd33700ef0462dd0da09c706283d881d36431aa9e9731bd96b068c09b23de76643f1a5c7fe9120e5858b65f70dd9bd8ead5d7f5d5ccb9b69f30665b669a20e227e5bffe3b300906072a8648ce3d040103818c0030818802420188a24febe245c5487d1bacf5ed989dae4770c05e1bb62fbdf1b64db76140d311a2ceee0b7e927eff769dc33b7ea53fcefa10e259ec472d7cacda4e970e15a06fd00242014dfcbe67139c2d050ebd3fa38c25c13313830d9406bbd4377af6ec7ac9862eddd711697f857c56defb31782be4c7780daecbbe9e4e3624317b6a0f399512078f2a")
+
+var testEd25519Certificate = fromHex("3082012e3081e1a00302010202100f431c425793941de987e4f1ad15005d300506032b657030123110300e060355040a130741636d6520436f301e170d3139303531363231333830315a170d3230303531353231333830315a30123110300e060355040a130741636d6520436f302a300506032b65700321003fe2152ee6e3ef3f4e854a7577a3649eede0bf842ccc92268ffa6f3483aaec8fa34d304b300e0603551d0f0101ff0404030205a030130603551d25040c300a06082b06010505070301300c0603551d130101ff0402300030160603551d11040f300d820b6578616d706c652e636f6d300506032b65700341006344ed9cc4be5324539fd2108d9fe82108909539e50dc155ff2c16b71dfcab7d4dd4e09313d0a942e0b66bfe5d6748d79f50bc6ccd4b03837cf20858cdaccf0c")
+
+var testSNICertificate = fromHex("0441883421114c81480804c430820237308201a0a003020102020900e8f09d3fe25beaa6300d06092a864886f70d01010b0500301f310b3009060355040a1302476f3110300e06035504031307476f20526f6f74301e170d3136303130313030303030305a170d3235303130313030303030305a3023310b3009060355040a1302476f311430120603550403130b736e69746573742e636f6d30819f300d06092a864886f70d010101050003818d0030818902818100db467d932e12270648bc062821ab7ec4b6a25dfe1e5245887a3647a5080d92425bc281c0be97799840fb4f6d14fd2b138bc2a52e67d8d4099ed62238b74a0b74732bc234f1d193e596d9747bf3589f6c613cc0b041d4d92b2b2423775b1c3bbd755dce2054cfa163871d1e24c4f31d1a508baab61443ed97a77562f414c852d70203010001a3773075300e0603551d0f0101ff0404030205a0301d0603551d250416301406082b0601050507030106082b06010505070302300c0603551d130101ff0402300030190603551d0e041204109f91161f43433e49a6de6db680d79f60301b0603551d230414301280104813494d137e1631bba301d5acab6e7b300d06092a864886f70d01010b0500038181007beeecff0230dbb2e7a334af65430b7116e09f327c3bbf918107fc9c66cb497493207ae9b4dbb045cb63d605ec1b5dd485bb69124d68fa298dc776699b47632fd6d73cab57042acb26f083c4087459bc5a3bb3ca4d878d7fe31016b7bc9a627438666566e3389bfaeebe6becc9a0093ceed18d0f9ac79d56f3a73f18188988ed")
+
+var testP256Certificate = fromHex("308201693082010ea00302010202105012dc24e1124ade4f3e153326ff27bf300a06082a8648ce3d04030230123110300e060355040a130741636d6520436f301e170d3137303533313232343934375a170d3138303533313232343934375a30123110300e060355040a130741636d6520436f3059301306072a8648ce3d020106082a8648ce3d03010703420004c02c61c9b16283bbcc14956d886d79b358aa614596975f78cece787146abf74c2d5dc578c0992b4f3c631373479ebf3892efe53d21c4f4f1cc9a11c3536b7f75a3463044300e0603551d0f0101ff0404030205a030130603551d25040c300a06082b06010505070301300c0603551d130101ff04023000300f0603551d1104083006820474657374300a06082a8648ce3d0403020349003046022100963712d6226c7b2bef41512d47e1434131aaca3ba585d666c924df71ac0448b3022100f4d05c725064741aef125f243cdbccaa2a5d485927831f221c43023bd5ae471a")
+
+var testRSAPrivateKey, _ = x509.ParsePKCS1PrivateKey(fromHex("3082025b02010002818100db467d932e12270648bc062821ab7ec4b6a25dfe1e5245887a3647a5080d92425bc281c0be97799840fb4f6d14fd2b138bc2a52e67d8d4099ed62238b74a0b74732bc234f1d193e596d9747bf3589f6c613cc0b041d4d92b2b2423775b1c3bbd755dce2054cfa163871d1e24c4f31d1a508baab61443ed97a77562f414c852d702030100010281800b07fbcf48b50f1388db34b016298b8217f2092a7c9a04f77db6775a3d1279b62ee9951f7e371e9de33f015aea80660760b3951dc589a9f925ed7de13e8f520e1ccbc7498ce78e7fab6d59582c2386cc07ed688212a576ff37833bd5943483b5554d15a0b9b4010ed9bf09f207e7e9805f649240ed6c1256ed75ab7cd56d9671024100fded810da442775f5923debae4ac758390a032a16598d62f059bb2e781a9c2f41bfa015c209f966513fe3bf5a58717cbdb385100de914f88d649b7d15309fa49024100dd10978c623463a1802c52f012cfa72ff5d901f25a2292446552c2568b1840e49a312e127217c2186615aae4fb6602a4f6ebf3f3d160f3b3ad04c592f65ae41f02400c69062ca781841a09de41ed7a6d9f54adc5d693a2c6847949d9e1358555c9ac6a8d9e71653ac77beb2d3abaf7bb1183aa14278956575dbebf525d0482fd72d90240560fe1900ba36dae3022115fd952f2399fb28e2975a1c3e3d0b679660bdcb356cc189d611cfdd6d87cd5aea45aa30a2082e8b51e94c2f3dd5d5c6036a8a615ed0240143993d80ece56f877cb80048335701eb0e608cc0c1ca8c2227b52edf8f1ac99c562f2541b5ce81f0515af1c5b4770dba53383964b4b725ff46fdec3d08907df"))
+
+var testECDSAPrivateKey, _ = x509.ParseECPrivateKey(fromHex("3081dc0201010442019883e909ad0ac9ea3d33f9eae661f1785206970f8ca9a91672f1eedca7a8ef12bd6561bb246dda5df4b4d5e7e3a92649bc5d83a0bf92972e00e62067d0c7bd99d7a00706052b81040023a18189038186000400c4a1edbe98f90b4873367ec316561122f23d53c33b4d213dcd6b75e6f6b0dc9adf26c1bcb287f072327cb3642f1c90bcea6823107efee325c0483a69e0286dd33700ef0462dd0da09c706283d881d36431aa9e9731bd96b068c09b23de76643f1a5c7fe9120e5858b65f70dd9bd8ead5d7f5d5ccb9b69f30665b669a20e227e5bffe3b"))
+
+var testP256PrivateKey, _ = x509.ParseECPrivateKey(fromHex("30770201010420012f3b52bc54c36ba3577ad45034e2e8efe1e6999851284cb848725cfe029991a00a06082a8648ce3d030107a14403420004c02c61c9b16283bbcc14956d886d79b358aa614596975f78cece787146abf74c2d5dc578c0992b4f3c631373479ebf3892efe53d21c4f4f1cc9a11c3536b7f75"))
+
+var testEd25519PrivateKey = ed25519.PrivateKey(fromHex("3a884965e76b3f55e5faf9615458a92354894234de3ec9f684d46d55cebf3dc63fe2152ee6e3ef3f4e854a7577a3649eede0bf842ccc92268ffa6f3483aaec8f"))
+
+const clientCertificatePEM = `
+-----BEGIN CERTIFICATE-----
+MIIB7zCCAVigAwIBAgIQXBnBiWWDVW/cC8m5k5/pvDANBgkqhkiG9w0BAQsFADAS
+MRAwDgYDVQQKEwdBY21lIENvMB4XDTE2MDgxNzIxNTIzMVoXDTE3MDgxNzIxNTIz
+MVowEjEQMA4GA1UEChMHQWNtZSBDbzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC
+gYEAum+qhr3Pv5/y71yUYHhv6BPy0ZZvzdkybiI3zkH5yl0prOEn2mGi7oHLEMff
+NFiVhuk9GeZcJ3NgyI14AvQdpJgJoxlwaTwlYmYqqyIjxXuFOE8uCXMyp70+m63K
+hAfmDzr/d8WdQYUAirab7rCkPy1MTOZCPrtRyN1IVPQMjkcCAwEAAaNGMEQwDgYD
+VR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAw
+DwYDVR0RBAgwBocEfwAAATANBgkqhkiG9w0BAQsFAAOBgQBGq0Si+yhU+Fpn+GKU
+8ZqyGJ7ysd4dfm92lam6512oFmyc9wnTN+RLKzZ8Aa1B0jLYw9KT+RBrjpW5LBeK
+o0RIvFkTgxYEiKSBXCUNmAysEbEoVr4dzWFihAm/1oDGRY2CLLTYg5vbySK3KhIR
+e/oCO8HJ/+rJnahJ05XX1Q7lNQ==
+-----END CERTIFICATE-----`
+
+var clientKeyPEM = testingKey(`
+-----BEGIN RSA TESTING KEY-----
+MIICXQIBAAKBgQC6b6qGvc+/n/LvXJRgeG/oE/LRlm/N2TJuIjfOQfnKXSms4Sfa
+YaLugcsQx980WJWG6T0Z5lwnc2DIjXgC9B2kmAmjGXBpPCViZiqrIiPFe4U4Ty4J
+czKnvT6brcqEB+YPOv93xZ1BhQCKtpvusKQ/LUxM5kI+u1HI3UhU9AyORwIDAQAB
+AoGAEJZ03q4uuMb7b26WSQsOMeDsftdatT747LGgs3pNRkMJvTb/O7/qJjxoG+Mc
+qeSj0TAZXp+PXXc3ikCECAc+R8rVMfWdmp903XgO/qYtmZGCorxAHEmR80SrfMXv
+PJnznLQWc8U9nphQErR+tTESg7xWEzmFcPKwnZd1xg8ERYkCQQDTGtrFczlB2b/Z
+9TjNMqUlMnTLIk/a/rPE2fLLmAYhK5sHnJdvDURaH2mF4nso0EGtENnTsh6LATnY
+dkrxXGm9AkEA4hXHG2q3MnhgK1Z5hjv+Fnqd+8bcbII9WW4flFs15EKoMgS1w/PJ
+zbsySaSy5IVS8XeShmT9+3lrleed4sy+UwJBAJOOAbxhfXP5r4+5R6ql66jES75w
+jUCVJzJA5ORJrn8g64u2eGK28z/LFQbv9wXgCwfc72R468BdawFSLa/m2EECQGbZ
+rWiFla26IVXV0xcD98VWJsTBZMlgPnSOqoMdM1kSEd4fUmlAYI/dFzV1XYSkOmVr
+FhdZnklmpVDeu27P4c0CQQCuCOup0FlJSBpWY1TTfun/KMBkBatMz0VMA3d7FKIU
+csPezl677Yjo8u1r/KzeI6zLg87Z8E6r6ZWNc9wBSZK6
+-----END RSA TESTING KEY-----`)
+
+const clientECDSACertificatePEM = `
+-----BEGIN CERTIFICATE-----
+MIIB/DCCAV4CCQCaMIRsJjXZFzAJBgcqhkjOPQQBMEUxCzAJBgNVBAYTAkFVMRMw
+EQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0
+eSBMdGQwHhcNMTIxMTE0MTMyNTUzWhcNMjIxMTEyMTMyNTUzWjBBMQswCQYDVQQG
+EwJBVTEMMAoGA1UECBMDTlNXMRAwDgYDVQQHEwdQeXJtb250MRIwEAYDVQQDEwlK
+b2VsIFNpbmcwgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABACVjJF1FMBexFe01MNv
+ja5oHt1vzobhfm6ySD6B5U7ixohLZNz1MLvT/2XMW/TdtWo+PtAd3kfDdq0Z9kUs
+jLzYHQFMH3CQRnZIi4+DzEpcj0B22uCJ7B0rxE4wdihBsmKo+1vx+U56jb0JuK7q
+ixgnTy5w/hOWusPTQBbNZU6sER7m8TAJBgcqhkjOPQQBA4GMADCBiAJCAOAUxGBg
+C3JosDJdYUoCdFzCgbkWqD8pyDbHgf9stlvZcPE4O1BIKJTLCRpS8V3ujfK58PDa
+2RU6+b0DeoeiIzXsAkIBo9SKeDUcSpoj0gq+KxAxnZxfvuiRs9oa9V2jI/Umi0Vw
+jWVim34BmT0Y9hCaOGGbLlfk+syxis7iI6CH8OFnUes=
+-----END CERTIFICATE-----`
+
+var clientECDSAKeyPEM = testingKey(`
+-----BEGIN EC PARAMETERS-----
+BgUrgQQAIw==
+-----END EC PARAMETERS-----
+-----BEGIN EC TESTING KEY-----
+MIHcAgEBBEIBkJN9X4IqZIguiEVKMqeBUP5xtRsEv4HJEtOpOGLELwO53SD78Ew8
+k+wLWoqizS3NpQyMtrU8JFdWfj+C57UNkOugBwYFK4EEACOhgYkDgYYABACVjJF1
+FMBexFe01MNvja5oHt1vzobhfm6ySD6B5U7ixohLZNz1MLvT/2XMW/TdtWo+PtAd
+3kfDdq0Z9kUsjLzYHQFMH3CQRnZIi4+DzEpcj0B22uCJ7B0rxE4wdihBsmKo+1vx
++U56jb0JuK7qixgnTy5w/hOWusPTQBbNZU6sER7m8Q==
+-----END EC TESTING KEY-----`)
+
+const clientEd25519CertificatePEM = `
+-----BEGIN CERTIFICATE-----
+MIIBLjCB4aADAgECAhAX0YGTviqMISAQJRXoNCNPMAUGAytlcDASMRAwDgYDVQQK
+EwdBY21lIENvMB4XDTE5MDUxNjIxNTQyNloXDTIwMDUxNTIxNTQyNlowEjEQMA4G
+A1UEChMHQWNtZSBDbzAqMAUGAytlcAMhAAvgtWC14nkwPb7jHuBQsQTIbcd4bGkv
+xRStmmNveRKRo00wSzAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUH
+AwIwDAYDVR0TAQH/BAIwADAWBgNVHREEDzANggtleGFtcGxlLmNvbTAFBgMrZXAD
+QQD8GRcqlKUx+inILn9boF2KTjRAOdazENwZ/qAicbP1j6FYDc308YUkv+Y9FN/f
+7Q7hF9gRomDQijcjKsJGqjoI
+-----END CERTIFICATE-----`
+
+var clientEd25519KeyPEM = testingKey(`
+-----BEGIN TESTING KEY-----
+MC4CAQAwBQYDK2VwBCIEINifzf07d9qx3d44e0FSbV4mC/xQxT644RRbpgNpin7I
+-----END TESTING KEY-----`)
diff --git a/src/crypto/tls/handshake_unix_test.go b/src/crypto/tls/handshake_unix_test.go
new file mode 100644
index 0000000..86a48f2
--- /dev/null
+++ b/src/crypto/tls/handshake_unix_test.go
@@ -0,0 +1,18 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build unix
+
+package tls
+
+import (
+ "errors"
+ "syscall"
+)
+
+func init() {
+ isConnRefused = func(err error) bool {
+ return errors.Is(err, syscall.ECONNREFUSED)
+ }
+}
diff --git a/src/crypto/tls/key_agreement.go b/src/crypto/tls/key_agreement.go
new file mode 100644
index 0000000..2c8c5b8
--- /dev/null
+++ b/src/crypto/tls/key_agreement.go
@@ -0,0 +1,366 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+ "crypto"
+ "crypto/ecdh"
+ "crypto/md5"
+ "crypto/rsa"
+ "crypto/sha1"
+ "crypto/x509"
+ "errors"
+ "fmt"
+ "io"
+)
+
+// a keyAgreement implements the client and server side of a TLS key agreement
+// protocol by generating and processing key exchange messages.
+type keyAgreement interface {
+ // On the server side, the first two methods are called in order.
+
+ // In the case that the key agreement protocol doesn't use a
+ // ServerKeyExchange message, generateServerKeyExchange can return nil,
+ // nil.
+ generateServerKeyExchange(*Config, *Certificate, *clientHelloMsg, *serverHelloMsg) (*serverKeyExchangeMsg, error)
+ processClientKeyExchange(*Config, *Certificate, *clientKeyExchangeMsg, uint16) ([]byte, error)
+
+ // On the client side, the next two methods are called in order.
+
+ // This method may not be called if the server doesn't send a
+ // ServerKeyExchange message.
+ processServerKeyExchange(*Config, *clientHelloMsg, *serverHelloMsg, *x509.Certificate, *serverKeyExchangeMsg) error
+ generateClientKeyExchange(*Config, *clientHelloMsg, *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error)
+}
+
+var errClientKeyExchange = errors.New("tls: invalid ClientKeyExchange message")
+var errServerKeyExchange = errors.New("tls: invalid ServerKeyExchange message")
+
+// rsaKeyAgreement implements the standard TLS key agreement where the client
+// encrypts the pre-master secret to the server's public key.
+type rsaKeyAgreement struct{}
+
+func (ka rsaKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
+ return nil, nil
+}
+
+func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
+ if len(ckx.ciphertext) < 2 {
+ return nil, errClientKeyExchange
+ }
+ ciphertextLen := int(ckx.ciphertext[0])<<8 | int(ckx.ciphertext[1])
+ if ciphertextLen != len(ckx.ciphertext)-2 {
+ return nil, errClientKeyExchange
+ }
+ ciphertext := ckx.ciphertext[2:]
+
+ priv, ok := cert.PrivateKey.(crypto.Decrypter)
+ if !ok {
+ return nil, errors.New("tls: certificate private key does not implement crypto.Decrypter")
+ }
+ // Perform constant time RSA PKCS #1 v1.5 decryption
+ preMasterSecret, err := priv.Decrypt(config.rand(), ciphertext, &rsa.PKCS1v15DecryptOptions{SessionKeyLen: 48})
+ if err != nil {
+ return nil, err
+ }
+ // We don't check the version number in the premaster secret. For one,
+ // by checking it, we would leak information about the validity of the
+ // encrypted pre-master secret. Secondly, it provides only a small
+ // benefit against a downgrade attack and some implementations send the
+ // wrong version anyway. See the discussion at the end of section
+ // 7.4.7.1 of RFC 4346.
+ return preMasterSecret, nil
+}
+
+func (ka rsaKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
+ return errors.New("tls: unexpected ServerKeyExchange")
+}
+
+func (ka rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
+ preMasterSecret := make([]byte, 48)
+ preMasterSecret[0] = byte(clientHello.vers >> 8)
+ preMasterSecret[1] = byte(clientHello.vers)
+ _, err := io.ReadFull(config.rand(), preMasterSecret[2:])
+ if err != nil {
+ return nil, nil, err
+ }
+
+ rsaKey, ok := cert.PublicKey.(*rsa.PublicKey)
+ if !ok {
+ return nil, nil, errors.New("tls: server certificate contains incorrect key type for selected ciphersuite")
+ }
+ encrypted, err := rsa.EncryptPKCS1v15(config.rand(), rsaKey, preMasterSecret)
+ if err != nil {
+ return nil, nil, err
+ }
+ ckx := new(clientKeyExchangeMsg)
+ ckx.ciphertext = make([]byte, len(encrypted)+2)
+ ckx.ciphertext[0] = byte(len(encrypted) >> 8)
+ ckx.ciphertext[1] = byte(len(encrypted))
+ copy(ckx.ciphertext[2:], encrypted)
+ return preMasterSecret, ckx, nil
+}
+
+// sha1Hash calculates a SHA1 hash over the given byte slices.
+func sha1Hash(slices [][]byte) []byte {
+ hsha1 := sha1.New()
+ for _, slice := range slices {
+ hsha1.Write(slice)
+ }
+ return hsha1.Sum(nil)
+}
+
+// md5SHA1Hash implements TLS 1.0's hybrid hash function which consists of the
+// concatenation of an MD5 and SHA1 hash.
+func md5SHA1Hash(slices [][]byte) []byte {
+ md5sha1 := make([]byte, md5.Size+sha1.Size)
+ hmd5 := md5.New()
+ for _, slice := range slices {
+ hmd5.Write(slice)
+ }
+ copy(md5sha1, hmd5.Sum(nil))
+ copy(md5sha1[md5.Size:], sha1Hash(slices))
+ return md5sha1
+}
+
+// hashForServerKeyExchange hashes the given slices and returns their digest
+// using the given hash function (for >= TLS 1.2) or using a default based on
+// the sigType (for earlier TLS versions). For Ed25519 signatures, which don't
+// do pre-hashing, it returns the concatenation of the slices.
+func hashForServerKeyExchange(sigType uint8, hashFunc crypto.Hash, version uint16, slices ...[]byte) []byte {
+ if sigType == signatureEd25519 {
+ var signed []byte
+ for _, slice := range slices {
+ signed = append(signed, slice...)
+ }
+ return signed
+ }
+ if version >= VersionTLS12 {
+ h := hashFunc.New()
+ for _, slice := range slices {
+ h.Write(slice)
+ }
+ digest := h.Sum(nil)
+ return digest
+ }
+ if sigType == signatureECDSA {
+ return sha1Hash(slices)
+ }
+ return md5SHA1Hash(slices)
+}
+
+// ecdheKeyAgreement implements a TLS key agreement where the server
+// generates an ephemeral EC public/private key pair and signs it. The
+// pre-master secret is then calculated using ECDH. The signature may
+// be ECDSA, Ed25519 or RSA.
+type ecdheKeyAgreement struct {
+ version uint16
+ isRSA bool
+ key *ecdh.PrivateKey
+
+ // ckx and preMasterSecret are generated in processServerKeyExchange
+ // and returned in generateClientKeyExchange.
+ ckx *clientKeyExchangeMsg
+ preMasterSecret []byte
+}
+
+func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) {
+ var curveID CurveID
+ for _, c := range clientHello.supportedCurves {
+ if config.supportsCurve(c) {
+ curveID = c
+ break
+ }
+ }
+
+ if curveID == 0 {
+ return nil, errors.New("tls: no supported elliptic curves offered")
+ }
+ if _, ok := curveForCurveID(curveID); !ok {
+ return nil, errors.New("tls: CurvePreferences includes unsupported curve")
+ }
+
+ key, err := generateECDHEKey(config.rand(), curveID)
+ if err != nil {
+ return nil, err
+ }
+ ka.key = key
+
+ // See RFC 4492, Section 5.4.
+ ecdhePublic := key.PublicKey().Bytes()
+ serverECDHEParams := make([]byte, 1+2+1+len(ecdhePublic))
+ serverECDHEParams[0] = 3 // named curve
+ serverECDHEParams[1] = byte(curveID >> 8)
+ serverECDHEParams[2] = byte(curveID)
+ serverECDHEParams[3] = byte(len(ecdhePublic))
+ copy(serverECDHEParams[4:], ecdhePublic)
+
+ priv, ok := cert.PrivateKey.(crypto.Signer)
+ if !ok {
+ return nil, fmt.Errorf("tls: certificate private key of type %T does not implement crypto.Signer", cert.PrivateKey)
+ }
+
+ var signatureAlgorithm SignatureScheme
+ var sigType uint8
+ var sigHash crypto.Hash
+ if ka.version >= VersionTLS12 {
+ signatureAlgorithm, err = selectSignatureScheme(ka.version, cert, clientHello.supportedSignatureAlgorithms)
+ if err != nil {
+ return nil, err
+ }
+ sigType, sigHash, err = typeAndHashFromSignatureScheme(signatureAlgorithm)
+ if err != nil {
+ return nil, err
+ }
+ } else {
+ sigType, sigHash, err = legacyTypeAndHashFromPublicKey(priv.Public())
+ if err != nil {
+ return nil, err
+ }
+ }
+ if (sigType == signaturePKCS1v15 || sigType == signatureRSAPSS) != ka.isRSA {
+ return nil, errors.New("tls: certificate cannot be used with the selected cipher suite")
+ }
+
+ signed := hashForServerKeyExchange(sigType, sigHash, ka.version, clientHello.random, hello.random, serverECDHEParams)
+
+ signOpts := crypto.SignerOpts(sigHash)
+ if sigType == signatureRSAPSS {
+ signOpts = &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash, Hash: sigHash}
+ }
+ sig, err := priv.Sign(config.rand(), signed, signOpts)
+ if err != nil {
+ return nil, errors.New("tls: failed to sign ECDHE parameters: " + err.Error())
+ }
+
+ skx := new(serverKeyExchangeMsg)
+ sigAndHashLen := 0
+ if ka.version >= VersionTLS12 {
+ sigAndHashLen = 2
+ }
+ skx.key = make([]byte, len(serverECDHEParams)+sigAndHashLen+2+len(sig))
+ copy(skx.key, serverECDHEParams)
+ k := skx.key[len(serverECDHEParams):]
+ if ka.version >= VersionTLS12 {
+ k[0] = byte(signatureAlgorithm >> 8)
+ k[1] = byte(signatureAlgorithm)
+ k = k[2:]
+ }
+ k[0] = byte(len(sig) >> 8)
+ k[1] = byte(len(sig))
+ copy(k[2:], sig)
+
+ return skx, nil
+}
+
+func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) {
+ if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 {
+ return nil, errClientKeyExchange
+ }
+
+ peerKey, err := ka.key.Curve().NewPublicKey(ckx.ciphertext[1:])
+ if err != nil {
+ return nil, errClientKeyExchange
+ }
+ preMasterSecret, err := ka.key.ECDH(peerKey)
+ if err != nil {
+ return nil, errClientKeyExchange
+ }
+
+ return preMasterSecret, nil
+}
+
+func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error {
+ if len(skx.key) < 4 {
+ return errServerKeyExchange
+ }
+ if skx.key[0] != 3 { // named curve
+ return errors.New("tls: server selected unsupported curve")
+ }
+ curveID := CurveID(skx.key[1])<<8 | CurveID(skx.key[2])
+
+ publicLen := int(skx.key[3])
+ if publicLen+4 > len(skx.key) {
+ return errServerKeyExchange
+ }
+ serverECDHEParams := skx.key[:4+publicLen]
+ publicKey := serverECDHEParams[4:]
+
+ sig := skx.key[4+publicLen:]
+ if len(sig) < 2 {
+ return errServerKeyExchange
+ }
+
+ if _, ok := curveForCurveID(curveID); !ok {
+ return errors.New("tls: server selected unsupported curve")
+ }
+
+ key, err := generateECDHEKey(config.rand(), curveID)
+ if err != nil {
+ return err
+ }
+ ka.key = key
+
+ peerKey, err := key.Curve().NewPublicKey(publicKey)
+ if err != nil {
+ return errServerKeyExchange
+ }
+ ka.preMasterSecret, err = key.ECDH(peerKey)
+ if err != nil {
+ return errServerKeyExchange
+ }
+
+ ourPublicKey := key.PublicKey().Bytes()
+ ka.ckx = new(clientKeyExchangeMsg)
+ ka.ckx.ciphertext = make([]byte, 1+len(ourPublicKey))
+ ka.ckx.ciphertext[0] = byte(len(ourPublicKey))
+ copy(ka.ckx.ciphertext[1:], ourPublicKey)
+
+ var sigType uint8
+ var sigHash crypto.Hash
+ if ka.version >= VersionTLS12 {
+ signatureAlgorithm := SignatureScheme(sig[0])<<8 | SignatureScheme(sig[1])
+ sig = sig[2:]
+ if len(sig) < 2 {
+ return errServerKeyExchange
+ }
+
+ if !isSupportedSignatureAlgorithm(signatureAlgorithm, clientHello.supportedSignatureAlgorithms) {
+ return errors.New("tls: certificate used with invalid signature algorithm")
+ }
+ sigType, sigHash, err = typeAndHashFromSignatureScheme(signatureAlgorithm)
+ if err != nil {
+ return err
+ }
+ } else {
+ sigType, sigHash, err = legacyTypeAndHashFromPublicKey(cert.PublicKey)
+ if err != nil {
+ return err
+ }
+ }
+ if (sigType == signaturePKCS1v15 || sigType == signatureRSAPSS) != ka.isRSA {
+ return errServerKeyExchange
+ }
+
+ sigLen := int(sig[0])<<8 | int(sig[1])
+ if sigLen+2 != len(sig) {
+ return errServerKeyExchange
+ }
+ sig = sig[2:]
+
+ signed := hashForServerKeyExchange(sigType, sigHash, ka.version, clientHello.random, serverHello.random, serverECDHEParams)
+ if err := verifyHandshakeSignature(sigType, cert.PublicKey, sigHash, signed, sig); err != nil {
+ return errors.New("tls: invalid signature by the server certificate: " + err.Error())
+ }
+ return nil
+}
+
+func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) {
+ if ka.ckx == nil {
+ return nil, nil, errors.New("tls: missing ServerKeyExchange message")
+ }
+
+ return ka.preMasterSecret, ka.ckx, nil
+}
diff --git a/src/crypto/tls/key_schedule.go b/src/crypto/tls/key_schedule.go
new file mode 100644
index 0000000..d7f082c
--- /dev/null
+++ b/src/crypto/tls/key_schedule.go
@@ -0,0 +1,159 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+ "crypto/ecdh"
+ "crypto/hmac"
+ "errors"
+ "fmt"
+ "hash"
+ "io"
+
+ "golang.org/x/crypto/cryptobyte"
+ "golang.org/x/crypto/hkdf"
+)
+
+// This file contains the functions necessary to compute the TLS 1.3 key
+// schedule. See RFC 8446, Section 7.
+
+const (
+ resumptionBinderLabel = "res binder"
+ clientEarlyTrafficLabel = "c e traffic"
+ clientHandshakeTrafficLabel = "c hs traffic"
+ serverHandshakeTrafficLabel = "s hs traffic"
+ clientApplicationTrafficLabel = "c ap traffic"
+ serverApplicationTrafficLabel = "s ap traffic"
+ exporterLabel = "exp master"
+ resumptionLabel = "res master"
+ trafficUpdateLabel = "traffic upd"
+)
+
+// expandLabel implements HKDF-Expand-Label from RFC 8446, Section 7.1.
+func (c *cipherSuiteTLS13) expandLabel(secret []byte, label string, context []byte, length int) []byte {
+ var hkdfLabel cryptobyte.Builder
+ hkdfLabel.AddUint16(uint16(length))
+ hkdfLabel.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes([]byte("tls13 "))
+ b.AddBytes([]byte(label))
+ })
+ hkdfLabel.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(context)
+ })
+ hkdfLabelBytes, err := hkdfLabel.Bytes()
+ if err != nil {
+ // Rather than calling BytesOrPanic, we explicitly handle this error, in
+ // order to provide a reasonable error message. It should be basically
+ // impossible for this to panic, and routing errors back through the
+ // tree rooted in this function is quite painful. The labels are fixed
+ // size, and the context is either a fixed-length computed hash, or
+ // parsed from a field which has the same length limitation. As such, an
+ // error here is likely to only be caused during development.
+ //
+ // NOTE: another reasonable approach here might be to return a
+ // randomized slice if we encounter an error, which would break the
+ // connection, but avoid panicking. This would perhaps be safer but
+ // significantly more confusing to users.
+ panic(fmt.Errorf("failed to construct HKDF label: %s", err))
+ }
+ out := make([]byte, length)
+ n, err := hkdf.Expand(c.hash.New, secret, hkdfLabelBytes).Read(out)
+ if err != nil || n != length {
+ panic("tls: HKDF-Expand-Label invocation failed unexpectedly")
+ }
+ return out
+}
+
+// deriveSecret implements Derive-Secret from RFC 8446, Section 7.1.
+func (c *cipherSuiteTLS13) deriveSecret(secret []byte, label string, transcript hash.Hash) []byte {
+ if transcript == nil {
+ transcript = c.hash.New()
+ }
+ return c.expandLabel(secret, label, transcript.Sum(nil), c.hash.Size())
+}
+
+// extract implements HKDF-Extract with the cipher suite hash.
+func (c *cipherSuiteTLS13) extract(newSecret, currentSecret []byte) []byte {
+ if newSecret == nil {
+ newSecret = make([]byte, c.hash.Size())
+ }
+ return hkdf.Extract(c.hash.New, newSecret, currentSecret)
+}
+
+// nextTrafficSecret generates the next traffic secret, given the current one,
+// according to RFC 8446, Section 7.2.
+func (c *cipherSuiteTLS13) nextTrafficSecret(trafficSecret []byte) []byte {
+ return c.expandLabel(trafficSecret, trafficUpdateLabel, nil, c.hash.Size())
+}
+
+// trafficKey generates traffic keys according to RFC 8446, Section 7.3.
+func (c *cipherSuiteTLS13) trafficKey(trafficSecret []byte) (key, iv []byte) {
+ key = c.expandLabel(trafficSecret, "key", nil, c.keyLen)
+ iv = c.expandLabel(trafficSecret, "iv", nil, aeadNonceLength)
+ return
+}
+
+// finishedHash generates the Finished verify_data or PskBinderEntry according
+// to RFC 8446, Section 4.4.4. See sections 4.4 and 4.2.11.2 for the baseKey
+// selection.
+func (c *cipherSuiteTLS13) finishedHash(baseKey []byte, transcript hash.Hash) []byte {
+ finishedKey := c.expandLabel(baseKey, "finished", nil, c.hash.Size())
+ verifyData := hmac.New(c.hash.New, finishedKey)
+ verifyData.Write(transcript.Sum(nil))
+ return verifyData.Sum(nil)
+}
+
+// exportKeyingMaterial implements RFC5705 exporters for TLS 1.3 according to
+// RFC 8446, Section 7.5.
+func (c *cipherSuiteTLS13) exportKeyingMaterial(masterSecret []byte, transcript hash.Hash) func(string, []byte, int) ([]byte, error) {
+ expMasterSecret := c.deriveSecret(masterSecret, exporterLabel, transcript)
+ return func(label string, context []byte, length int) ([]byte, error) {
+ secret := c.deriveSecret(expMasterSecret, label, nil)
+ h := c.hash.New()
+ h.Write(context)
+ return c.expandLabel(secret, "exporter", h.Sum(nil), length), nil
+ }
+}
+
+// generateECDHEKey returns a PrivateKey that implements Diffie-Hellman
+// according to RFC 8446, Section 4.2.8.2.
+func generateECDHEKey(rand io.Reader, curveID CurveID) (*ecdh.PrivateKey, error) {
+ curve, ok := curveForCurveID(curveID)
+ if !ok {
+ return nil, errors.New("tls: internal error: unsupported curve")
+ }
+
+ return curve.GenerateKey(rand)
+}
+
+func curveForCurveID(id CurveID) (ecdh.Curve, bool) {
+ switch id {
+ case X25519:
+ return ecdh.X25519(), true
+ case CurveP256:
+ return ecdh.P256(), true
+ case CurveP384:
+ return ecdh.P384(), true
+ case CurveP521:
+ return ecdh.P521(), true
+ default:
+ return nil, false
+ }
+}
+
+func curveIDForCurve(curve ecdh.Curve) (CurveID, bool) {
+ switch curve {
+ case ecdh.X25519():
+ return X25519, true
+ case ecdh.P256():
+ return CurveP256, true
+ case ecdh.P384():
+ return CurveP384, true
+ case ecdh.P521():
+ return CurveP521, true
+ default:
+ return 0, false
+ }
+}
diff --git a/src/crypto/tls/key_schedule_test.go b/src/crypto/tls/key_schedule_test.go
new file mode 100644
index 0000000..79ff6a6
--- /dev/null
+++ b/src/crypto/tls/key_schedule_test.go
@@ -0,0 +1,175 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+ "bytes"
+ "encoding/hex"
+ "hash"
+ "strings"
+ "testing"
+ "unicode"
+)
+
+// This file contains tests derived from draft-ietf-tls-tls13-vectors-07.
+
+func parseVector(v string) []byte {
+ v = strings.Map(func(c rune) rune {
+ if unicode.IsSpace(c) {
+ return -1
+ }
+ return c
+ }, v)
+ parts := strings.Split(v, ":")
+ v = parts[len(parts)-1]
+ res, err := hex.DecodeString(v)
+ if err != nil {
+ panic(err)
+ }
+ return res
+}
+
+func TestDeriveSecret(t *testing.T) {
+ chTranscript := cipherSuitesTLS13[0].hash.New()
+ chTranscript.Write(parseVector(`
+ payload (512 octets): 01 00 01 fc 03 03 1b c3 ce b6 bb e3 9c ff
+ 93 83 55 b5 a5 0a db 6d b2 1b 7a 6a f6 49 d7 b4 bc 41 9d 78 76
+ 48 7d 95 00 00 06 13 01 13 03 13 02 01 00 01 cd 00 00 00 0b 00
+ 09 00 00 06 73 65 72 76 65 72 ff 01 00 01 00 00 0a 00 14 00 12
+ 00 1d 00 17 00 18 00 19 01 00 01 01 01 02 01 03 01 04 00 33 00
+ 26 00 24 00 1d 00 20 e4 ff b6 8a c0 5f 8d 96 c9 9d a2 66 98 34
+ 6c 6b e1 64 82 ba dd da fe 05 1a 66 b4 f1 8d 66 8f 0b 00 2a 00
+ 00 00 2b 00 03 02 03 04 00 0d 00 20 00 1e 04 03 05 03 06 03 02
+ 03 08 04 08 05 08 06 04 01 05 01 06 01 02 01 04 02 05 02 06 02
+ 02 02 00 2d 00 02 01 01 00 1c 00 02 40 01 00 15 00 57 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ 00 29 00 dd 00 b8 00 b2 2c 03 5d 82 93 59 ee 5f f7 af 4e c9 00
+ 00 00 00 26 2a 64 94 dc 48 6d 2c 8a 34 cb 33 fa 90 bf 1b 00 70
+ ad 3c 49 88 83 c9 36 7c 09 a2 be 78 5a bc 55 cd 22 60 97 a3 a9
+ 82 11 72 83 f8 2a 03 a1 43 ef d3 ff 5d d3 6d 64 e8 61 be 7f d6
+ 1d 28 27 db 27 9c ce 14 50 77 d4 54 a3 66 4d 4e 6d a4 d2 9e e0
+ 37 25 a6 a4 da fc d0 fc 67 d2 ae a7 05 29 51 3e 3d a2 67 7f a5
+ 90 6c 5b 3f 7d 8f 92 f2 28 bd a4 0d da 72 14 70 f9 fb f2 97 b5
+ ae a6 17 64 6f ac 5c 03 27 2e 97 07 27 c6 21 a7 91 41 ef 5f 7d
+ e6 50 5e 5b fb c3 88 e9 33 43 69 40 93 93 4a e4 d3 57 fa d6 aa
+ cb 00 21 20 3a dd 4f b2 d8 fd f8 22 a0 ca 3c f7 67 8e f5 e8 8d
+ ae 99 01 41 c5 92 4d 57 bb 6f a3 1b 9e 5f 9d`))
+
+ type args struct {
+ secret []byte
+ label string
+ transcript hash.Hash
+ }
+ tests := []struct {
+ name string
+ args args
+ want []byte
+ }{
+ {
+ `derive secret for handshake "tls13 derived"`,
+ args{
+ parseVector(`PRK (32 octets): 33 ad 0a 1c 60 7e c0 3b 09 e6 cd 98 93 68 0c e2
+ 10 ad f3 00 aa 1f 26 60 e1 b2 2e 10 f1 70 f9 2a`),
+ "derived",
+ nil,
+ },
+ parseVector(`expanded (32 octets): 6f 26 15 a1 08 c7 02 c5 67 8f 54 fc 9d ba
+ b6 97 16 c0 76 18 9c 48 25 0c eb ea c3 57 6c 36 11 ba`),
+ },
+ {
+ `derive secret "tls13 c e traffic"`,
+ args{
+ parseVector(`PRK (32 octets): 9b 21 88 e9 b2 fc 6d 64 d7 1d c3 29 90 0e 20 bb
+ 41 91 50 00 f6 78 aa 83 9c bb 79 7c b7 d8 33 2c`),
+ "c e traffic",
+ chTranscript,
+ },
+ parseVector(`expanded (32 octets): 3f bb e6 a6 0d eb 66 c3 0a 32 79 5a ba 0e
+ ff 7e aa 10 10 55 86 e7 be 5c 09 67 8d 63 b6 ca ab 62`),
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ c := cipherSuitesTLS13[0]
+ if got := c.deriveSecret(tt.args.secret, tt.args.label, tt.args.transcript); !bytes.Equal(got, tt.want) {
+ t.Errorf("cipherSuiteTLS13.deriveSecret() = % x, want % x", got, tt.want)
+ }
+ })
+ }
+}
+
+func TestTrafficKey(t *testing.T) {
+ trafficSecret := parseVector(
+ `PRK (32 octets): b6 7b 7d 69 0c c1 6c 4e 75 e5 42 13 cb 2d 37 b4
+ e9 c9 12 bc de d9 10 5d 42 be fd 59 d3 91 ad 38`)
+ wantKey := parseVector(
+ `key expanded (16 octets): 3f ce 51 60 09 c2 17 27 d0 f2 e4 e8 6e
+ e4 03 bc`)
+ wantIV := parseVector(
+ `iv expanded (12 octets): 5d 31 3e b2 67 12 76 ee 13 00 0b 30`)
+
+ c := cipherSuitesTLS13[0]
+ gotKey, gotIV := c.trafficKey(trafficSecret)
+ if !bytes.Equal(gotKey, wantKey) {
+ t.Errorf("cipherSuiteTLS13.trafficKey() gotKey = % x, want % x", gotKey, wantKey)
+ }
+ if !bytes.Equal(gotIV, wantIV) {
+ t.Errorf("cipherSuiteTLS13.trafficKey() gotIV = % x, want % x", gotIV, wantIV)
+ }
+}
+
+func TestExtract(t *testing.T) {
+ type args struct {
+ newSecret []byte
+ currentSecret []byte
+ }
+ tests := []struct {
+ name string
+ args args
+ want []byte
+ }{
+ {
+ `extract secret "early"`,
+ args{
+ nil,
+ nil,
+ },
+ parseVector(`secret (32 octets): 33 ad 0a 1c 60 7e c0 3b 09 e6 cd 98 93 68 0c
+ e2 10 ad f3 00 aa 1f 26 60 e1 b2 2e 10 f1 70 f9 2a`),
+ },
+ {
+ `extract secret "master"`,
+ args{
+ nil,
+ parseVector(`salt (32 octets): 43 de 77 e0 c7 77 13 85 9a 94 4d b9 db 25 90 b5
+ 31 90 a6 5b 3e e2 e4 f1 2d d7 a0 bb 7c e2 54 b4`),
+ },
+ parseVector(`secret (32 octets): 18 df 06 84 3d 13 a0 8b f2 a4 49 84 4c 5f 8a
+ 47 80 01 bc 4d 4c 62 79 84 d5 a4 1d a8 d0 40 29 19`),
+ },
+ {
+ `extract secret "handshake"`,
+ args{
+ parseVector(`IKM (32 octets): 8b d4 05 4f b5 5b 9d 63 fd fb ac f9 f0 4b 9f 0d
+ 35 e6 d6 3f 53 75 63 ef d4 62 72 90 0f 89 49 2d`),
+ parseVector(`salt (32 octets): 6f 26 15 a1 08 c7 02 c5 67 8f 54 fc 9d ba b6 97
+ 16 c0 76 18 9c 48 25 0c eb ea c3 57 6c 36 11 ba`),
+ },
+ parseVector(`secret (32 octets): 1d c8 26 e9 36 06 aa 6f dc 0a ad c1 2f 74 1b
+ 01 04 6a a6 b9 9f 69 1e d2 21 a9 f0 ca 04 3f be ac`),
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ c := cipherSuitesTLS13[0]
+ if got := c.extract(tt.args.newSecret, tt.args.currentSecret); !bytes.Equal(got, tt.want) {
+ t.Errorf("cipherSuiteTLS13.extract() = % x, want % x", got, tt.want)
+ }
+ })
+ }
+}
diff --git a/src/crypto/tls/link_test.go b/src/crypto/tls/link_test.go
new file mode 100644
index 0000000..454d370
--- /dev/null
+++ b/src/crypto/tls/link_test.go
@@ -0,0 +1,107 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+ "bytes"
+ "internal/testenv"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "testing"
+)
+
+// Tests that the linker is able to remove references to the Client or Server if unused.
+func TestLinkerGC(t *testing.T) {
+ if testing.Short() {
+ t.Skip("skipping in short mode")
+ }
+ t.Parallel()
+ goBin := testenv.GoToolPath(t)
+ testenv.MustHaveGoBuild(t)
+
+ tests := []struct {
+ name string
+ program string
+ want []string
+ bad []string
+ }{
+ {
+ name: "empty_import",
+ program: `package main
+import _ "crypto/tls"
+func main() {}
+`,
+ bad: []string{
+ "tls.(*Conn)",
+ "type:crypto/tls.clientHandshakeState",
+ "type:crypto/tls.serverHandshakeState",
+ },
+ },
+ {
+ name: "client_and_server",
+ program: `package main
+import "crypto/tls"
+func main() {
+ tls.Dial("", "", nil)
+ tls.Server(nil, nil)
+}
+`,
+ want: []string{
+ "crypto/tls.(*Conn).clientHandshake",
+ "crypto/tls.(*Conn).serverHandshake",
+ },
+ },
+ {
+ name: "only_client",
+ program: `package main
+import "crypto/tls"
+func main() { tls.Dial("", "", nil) }
+`,
+ want: []string{
+ "crypto/tls.(*Conn).clientHandshake",
+ },
+ bad: []string{
+ "crypto/tls.(*Conn).serverHandshake",
+ },
+ },
+ // TODO: add only_server like func main() { tls.Server(nil, nil) }
+ // That currently brings in the client via Conn.handleRenegotiation.
+
+ }
+ tmpDir := t.TempDir()
+ goFile := filepath.Join(tmpDir, "x.go")
+ exeFile := filepath.Join(tmpDir, "x.exe")
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ if err := os.WriteFile(goFile, []byte(tt.program), 0644); err != nil {
+ t.Fatal(err)
+ }
+ os.Remove(exeFile)
+ cmd := exec.Command(goBin, "build", "-o", "x.exe", "x.go")
+ cmd.Dir = tmpDir
+ if out, err := cmd.CombinedOutput(); err != nil {
+ t.Fatalf("compile: %v, %s", err, out)
+ }
+
+ cmd = exec.Command(goBin, "tool", "nm", "x.exe")
+ cmd.Dir = tmpDir
+ nm, err := cmd.CombinedOutput()
+ if err != nil {
+ t.Fatalf("nm: %v, %s", err, nm)
+ }
+ for _, sym := range tt.want {
+ if !bytes.Contains(nm, []byte(sym)) {
+ t.Errorf("expected symbol %q not found", sym)
+ }
+ }
+ for _, sym := range tt.bad {
+ if bytes.Contains(nm, []byte(sym)) {
+ t.Errorf("unexpected symbol %q found", sym)
+ }
+ }
+ })
+ }
+}
diff --git a/src/crypto/tls/notboring.go b/src/crypto/tls/notboring.go
new file mode 100644
index 0000000..7d85b39
--- /dev/null
+++ b/src/crypto/tls/notboring.go
@@ -0,0 +1,20 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !boringcrypto
+
+package tls
+
+func needFIPS() bool { return false }
+
+func supportedSignatureAlgorithms() []SignatureScheme {
+ return defaultSupportedSignatureAlgorithms
+}
+
+func fipsMinVersion(c *Config) uint16 { panic("fipsMinVersion") }
+func fipsMaxVersion(c *Config) uint16 { panic("fipsMaxVersion") }
+func fipsCurvePreferences(c *Config) []CurveID { panic("fipsCurvePreferences") }
+func fipsCipherSuites(c *Config) []uint16 { panic("fipsCipherSuites") }
+
+var fipsSupportedSignatureAlgorithms []SignatureScheme
diff --git a/src/crypto/tls/prf.go b/src/crypto/tls/prf.go
new file mode 100644
index 0000000..20bac96
--- /dev/null
+++ b/src/crypto/tls/prf.go
@@ -0,0 +1,292 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+ "crypto"
+ "crypto/hmac"
+ "crypto/md5"
+ "crypto/sha1"
+ "crypto/sha256"
+ "crypto/sha512"
+ "errors"
+ "fmt"
+ "hash"
+)
+
+// Split a premaster secret in two as specified in RFC 4346, Section 5.
+func splitPreMasterSecret(secret []byte) (s1, s2 []byte) {
+ s1 = secret[0 : (len(secret)+1)/2]
+ s2 = secret[len(secret)/2:]
+ return
+}
+
+// pHash implements the P_hash function, as defined in RFC 4346, Section 5.
+func pHash(result, secret, seed []byte, hash func() hash.Hash) {
+ h := hmac.New(hash, secret)
+ h.Write(seed)
+ a := h.Sum(nil)
+
+ j := 0
+ for j < len(result) {
+ h.Reset()
+ h.Write(a)
+ h.Write(seed)
+ b := h.Sum(nil)
+ copy(result[j:], b)
+ j += len(b)
+
+ h.Reset()
+ h.Write(a)
+ a = h.Sum(nil)
+ }
+}
+
+// prf10 implements the TLS 1.0 pseudo-random function, as defined in RFC 2246, Section 5.
+func prf10(result, secret, label, seed []byte) {
+ hashSHA1 := sha1.New
+ hashMD5 := md5.New
+
+ labelAndSeed := make([]byte, len(label)+len(seed))
+ copy(labelAndSeed, label)
+ copy(labelAndSeed[len(label):], seed)
+
+ s1, s2 := splitPreMasterSecret(secret)
+ pHash(result, s1, labelAndSeed, hashMD5)
+ result2 := make([]byte, len(result))
+ pHash(result2, s2, labelAndSeed, hashSHA1)
+
+ for i, b := range result2 {
+ result[i] ^= b
+ }
+}
+
+// prf12 implements the TLS 1.2 pseudo-random function, as defined in RFC 5246, Section 5.
+func prf12(hashFunc func() hash.Hash) func(result, secret, label, seed []byte) {
+ return func(result, secret, label, seed []byte) {
+ labelAndSeed := make([]byte, len(label)+len(seed))
+ copy(labelAndSeed, label)
+ copy(labelAndSeed[len(label):], seed)
+
+ pHash(result, secret, labelAndSeed, hashFunc)
+ }
+}
+
+const (
+ masterSecretLength = 48 // Length of a master secret in TLS 1.1.
+ finishedVerifyLength = 12 // Length of verify_data in a Finished message.
+)
+
+var masterSecretLabel = []byte("master secret")
+var extendedMasterSecretLabel = []byte("extended master secret")
+var keyExpansionLabel = []byte("key expansion")
+var clientFinishedLabel = []byte("client finished")
+var serverFinishedLabel = []byte("server finished")
+
+func prfAndHashForVersion(version uint16, suite *cipherSuite) (func(result, secret, label, seed []byte), crypto.Hash) {
+ switch version {
+ case VersionTLS10, VersionTLS11:
+ return prf10, crypto.Hash(0)
+ case VersionTLS12:
+ if suite.flags&suiteSHA384 != 0 {
+ return prf12(sha512.New384), crypto.SHA384
+ }
+ return prf12(sha256.New), crypto.SHA256
+ default:
+ panic("unknown version")
+ }
+}
+
+func prfForVersion(version uint16, suite *cipherSuite) func(result, secret, label, seed []byte) {
+ prf, _ := prfAndHashForVersion(version, suite)
+ return prf
+}
+
+// masterFromPreMasterSecret generates the master secret from the pre-master
+// secret. See RFC 5246, Section 8.1.
+func masterFromPreMasterSecret(version uint16, suite *cipherSuite, preMasterSecret, clientRandom, serverRandom []byte) []byte {
+ seed := make([]byte, 0, len(clientRandom)+len(serverRandom))
+ seed = append(seed, clientRandom...)
+ seed = append(seed, serverRandom...)
+
+ masterSecret := make([]byte, masterSecretLength)
+ prfForVersion(version, suite)(masterSecret, preMasterSecret, masterSecretLabel, seed)
+ return masterSecret
+}
+
+// extMasterFromPreMasterSecret generates the extended master secret from the
+// pre-master secret. See RFC 7627.
+func extMasterFromPreMasterSecret(version uint16, suite *cipherSuite, preMasterSecret, transcript []byte) []byte {
+ masterSecret := make([]byte, masterSecretLength)
+ prfForVersion(version, suite)(masterSecret, preMasterSecret, extendedMasterSecretLabel, transcript)
+ return masterSecret
+}
+
+// keysFromMasterSecret generates the connection keys from the master
+// secret, given the lengths of the MAC key, cipher key and IV, as defined in
+// RFC 2246, Section 6.3.
+func keysFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int) (clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV []byte) {
+ seed := make([]byte, 0, len(serverRandom)+len(clientRandom))
+ seed = append(seed, serverRandom...)
+ seed = append(seed, clientRandom...)
+
+ n := 2*macLen + 2*keyLen + 2*ivLen
+ keyMaterial := make([]byte, n)
+ prfForVersion(version, suite)(keyMaterial, masterSecret, keyExpansionLabel, seed)
+ clientMAC = keyMaterial[:macLen]
+ keyMaterial = keyMaterial[macLen:]
+ serverMAC = keyMaterial[:macLen]
+ keyMaterial = keyMaterial[macLen:]
+ clientKey = keyMaterial[:keyLen]
+ keyMaterial = keyMaterial[keyLen:]
+ serverKey = keyMaterial[:keyLen]
+ keyMaterial = keyMaterial[keyLen:]
+ clientIV = keyMaterial[:ivLen]
+ keyMaterial = keyMaterial[ivLen:]
+ serverIV = keyMaterial[:ivLen]
+ return
+}
+
+func newFinishedHash(version uint16, cipherSuite *cipherSuite) finishedHash {
+ var buffer []byte
+ if version >= VersionTLS12 {
+ buffer = []byte{}
+ }
+
+ prf, hash := prfAndHashForVersion(version, cipherSuite)
+ if hash != 0 {
+ return finishedHash{hash.New(), hash.New(), nil, nil, buffer, version, prf}
+ }
+
+ return finishedHash{sha1.New(), sha1.New(), md5.New(), md5.New(), buffer, version, prf}
+}
+
+// A finishedHash calculates the hash of a set of handshake messages suitable
+// for including in a Finished message.
+type finishedHash struct {
+ client hash.Hash
+ server hash.Hash
+
+ // Prior to TLS 1.2, an additional MD5 hash is required.
+ clientMD5 hash.Hash
+ serverMD5 hash.Hash
+
+ // In TLS 1.2, a full buffer is sadly required.
+ buffer []byte
+
+ version uint16
+ prf func(result, secret, label, seed []byte)
+}
+
+func (h *finishedHash) Write(msg []byte) (n int, err error) {
+ h.client.Write(msg)
+ h.server.Write(msg)
+
+ if h.version < VersionTLS12 {
+ h.clientMD5.Write(msg)
+ h.serverMD5.Write(msg)
+ }
+
+ if h.buffer != nil {
+ h.buffer = append(h.buffer, msg...)
+ }
+
+ return len(msg), nil
+}
+
+func (h finishedHash) Sum() []byte {
+ if h.version >= VersionTLS12 {
+ return h.client.Sum(nil)
+ }
+
+ out := make([]byte, 0, md5.Size+sha1.Size)
+ out = h.clientMD5.Sum(out)
+ return h.client.Sum(out)
+}
+
+// clientSum returns the contents of the verify_data member of a client's
+// Finished message.
+func (h finishedHash) clientSum(masterSecret []byte) []byte {
+ out := make([]byte, finishedVerifyLength)
+ h.prf(out, masterSecret, clientFinishedLabel, h.Sum())
+ return out
+}
+
+// serverSum returns the contents of the verify_data member of a server's
+// Finished message.
+func (h finishedHash) serverSum(masterSecret []byte) []byte {
+ out := make([]byte, finishedVerifyLength)
+ h.prf(out, masterSecret, serverFinishedLabel, h.Sum())
+ return out
+}
+
+// hashForClientCertificate returns the handshake messages so far, pre-hashed if
+// necessary, suitable for signing by a TLS client certificate.
+func (h finishedHash) hashForClientCertificate(sigType uint8, hashAlg crypto.Hash) []byte {
+ if (h.version >= VersionTLS12 || sigType == signatureEd25519) && h.buffer == nil {
+ panic("tls: handshake hash for a client certificate requested after discarding the handshake buffer")
+ }
+
+ if sigType == signatureEd25519 {
+ return h.buffer
+ }
+
+ if h.version >= VersionTLS12 {
+ hash := hashAlg.New()
+ hash.Write(h.buffer)
+ return hash.Sum(nil)
+ }
+
+ if sigType == signatureECDSA {
+ return h.server.Sum(nil)
+ }
+
+ return h.Sum()
+}
+
+// discardHandshakeBuffer is called when there is no more need to
+// buffer the entirety of the handshake messages.
+func (h *finishedHash) discardHandshakeBuffer() {
+ h.buffer = nil
+}
+
+// noExportedKeyingMaterial is used as a value of
+// ConnectionState.ekm when renegotiation is enabled and thus
+// we wish to fail all key-material export requests.
+func noExportedKeyingMaterial(label string, context []byte, length int) ([]byte, error) {
+ return nil, errors.New("crypto/tls: ExportKeyingMaterial is unavailable when renegotiation is enabled")
+}
+
+// ekmFromMasterSecret generates exported keying material as defined in RFC 5705.
+func ekmFromMasterSecret(version uint16, suite *cipherSuite, masterSecret, clientRandom, serverRandom []byte) func(string, []byte, int) ([]byte, error) {
+ return func(label string, context []byte, length int) ([]byte, error) {
+ switch label {
+ case "client finished", "server finished", "master secret", "key expansion":
+ // These values are reserved and may not be used.
+ return nil, fmt.Errorf("crypto/tls: reserved ExportKeyingMaterial label: %s", label)
+ }
+
+ seedLen := len(serverRandom) + len(clientRandom)
+ if context != nil {
+ seedLen += 2 + len(context)
+ }
+ seed := make([]byte, 0, seedLen)
+
+ seed = append(seed, clientRandom...)
+ seed = append(seed, serverRandom...)
+
+ if context != nil {
+ if len(context) >= 1<<16 {
+ return nil, fmt.Errorf("crypto/tls: ExportKeyingMaterial context too long")
+ }
+ seed = append(seed, byte(len(context)>>8), byte(len(context)))
+ seed = append(seed, context...)
+ }
+
+ keyMaterial := make([]byte, length)
+ prfForVersion(version, suite)(keyMaterial, masterSecret, []byte(label), seed)
+ return keyMaterial, nil
+ }
+}
diff --git a/src/crypto/tls/prf_test.go b/src/crypto/tls/prf_test.go
new file mode 100644
index 0000000..8233985
--- /dev/null
+++ b/src/crypto/tls/prf_test.go
@@ -0,0 +1,140 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+ "encoding/hex"
+ "testing"
+)
+
+type testSplitPreMasterSecretTest struct {
+ in, out1, out2 string
+}
+
+var testSplitPreMasterSecretTests = []testSplitPreMasterSecretTest{
+ {"", "", ""},
+ {"00", "00", "00"},
+ {"0011", "00", "11"},
+ {"001122", "0011", "1122"},
+ {"00112233", "0011", "2233"},
+}
+
+func TestSplitPreMasterSecret(t *testing.T) {
+ for i, test := range testSplitPreMasterSecretTests {
+ in, _ := hex.DecodeString(test.in)
+ out1, out2 := splitPreMasterSecret(in)
+ s1 := hex.EncodeToString(out1)
+ s2 := hex.EncodeToString(out2)
+ if s1 != test.out1 || s2 != test.out2 {
+ t.Errorf("#%d: got: (%s, %s) want: (%s, %s)", i, s1, s2, test.out1, test.out2)
+ }
+ }
+}
+
+type testKeysFromTest struct {
+ version uint16
+ suite *cipherSuite
+ preMasterSecret string
+ clientRandom, serverRandom string
+ masterSecret string
+ clientMAC, serverMAC string
+ clientKey, serverKey string
+ macLen, keyLen int
+ contextKeyingMaterial, noContextKeyingMaterial string
+}
+
+func TestKeysFromPreMasterSecret(t *testing.T) {
+ for i, test := range testKeysFromTests {
+ in, _ := hex.DecodeString(test.preMasterSecret)
+ clientRandom, _ := hex.DecodeString(test.clientRandom)
+ serverRandom, _ := hex.DecodeString(test.serverRandom)
+
+ masterSecret := masterFromPreMasterSecret(test.version, test.suite, in, clientRandom, serverRandom)
+ if s := hex.EncodeToString(masterSecret); s != test.masterSecret {
+ t.Errorf("#%d: bad master secret %s, want %s", i, s, test.masterSecret)
+ continue
+ }
+
+ clientMAC, serverMAC, clientKey, serverKey, _, _ := keysFromMasterSecret(test.version, test.suite, masterSecret, clientRandom, serverRandom, test.macLen, test.keyLen, 0)
+ clientMACString := hex.EncodeToString(clientMAC)
+ serverMACString := hex.EncodeToString(serverMAC)
+ clientKeyString := hex.EncodeToString(clientKey)
+ serverKeyString := hex.EncodeToString(serverKey)
+ if clientMACString != test.clientMAC ||
+ serverMACString != test.serverMAC ||
+ clientKeyString != test.clientKey ||
+ serverKeyString != test.serverKey {
+ t.Errorf("#%d: got: (%s, %s, %s, %s) want: (%s, %s, %s, %s)", i, clientMACString, serverMACString, clientKeyString, serverKeyString, test.clientMAC, test.serverMAC, test.clientKey, test.serverKey)
+ }
+
+ ekm := ekmFromMasterSecret(test.version, test.suite, masterSecret, clientRandom, serverRandom)
+ contextKeyingMaterial, err := ekm("label", []byte("context"), 32)
+ if err != nil {
+ t.Fatalf("ekmFromMasterSecret failed: %v", err)
+ }
+
+ noContextKeyingMaterial, err := ekm("label", nil, 32)
+ if err != nil {
+ t.Fatalf("ekmFromMasterSecret failed: %v", err)
+ }
+
+ if hex.EncodeToString(contextKeyingMaterial) != test.contextKeyingMaterial ||
+ hex.EncodeToString(noContextKeyingMaterial) != test.noContextKeyingMaterial {
+ t.Errorf("#%d: got keying material: (%s, %s) want: (%s, %s)", i, contextKeyingMaterial, noContextKeyingMaterial, test.contextKeyingMaterial, test.noContextKeyingMaterial)
+ }
+ }
+}
+
+// These test vectors were generated from GnuTLS using `gnutls-cli --insecure -d 9 `
+var testKeysFromTests = []testKeysFromTest{
+ {
+ VersionTLS10,
+ cipherSuiteByID(TLS_RSA_WITH_RC4_128_SHA),
+ "0302cac83ad4b1db3b9ab49ad05957de2a504a634a386fc600889321e1a971f57479466830ac3e6f468e87f5385fa0c5",
+ "4ae66303755184a3917fcb44880605fcc53baa01912b22ed94473fc69cebd558",
+ "4ae663020ec16e6bb5130be918cfcafd4d765979a3136a5d50c593446e4e44db",
+ "3d851bab6e5556e959a16bc36d66cfae32f672bfa9ecdef6096cbb1b23472df1da63dbbd9827606413221d149ed08ceb",
+ "805aaa19b3d2c0a0759a4b6c9959890e08480119",
+ "2d22f9fe519c075c16448305ceee209fc24ad109",
+ "d50b5771244f850cd8117a9ccafe2cf1",
+ "e076e33206b30507a85c32855acd0919",
+ 20,
+ 16,
+ "4d1bb6fc278c37d27aa6e2a13c2e079095d143272c2aa939da33d88c1c0cec22",
+ "93fba89599b6321ae538e27c6548ceb8b46821864318f5190d64a375e5d69d41",
+ },
+ {
+ VersionTLS10,
+ cipherSuiteByID(TLS_RSA_WITH_RC4_128_SHA),
+ "03023f7527316bc12cbcd69e4b9e8275d62c028f27e65c745cfcddc7ce01bd3570a111378b63848127f1c36e5f9e4890",
+ "4ae66364b5ea56b20ce4e25555aed2d7e67f42788dd03f3fee4adae0459ab106",
+ "4ae66363ab815cbf6a248b87d6b556184e945e9b97fbdf247858b0bdafacfa1c",
+ "7d64be7c80c59b740200b4b9c26d0baaa1c5ae56705acbcf2307fe62beb4728c19392c83f20483801cce022c77645460",
+ "97742ed60a0554ca13f04f97ee193177b971e3b0",
+ "37068751700400e03a8477a5c7eec0813ab9e0dc",
+ "207cddbc600d2a200abac6502053ee5c",
+ "df3f94f6e1eacc753b815fe16055cd43",
+ 20,
+ 16,
+ "2c9f8961a72b97cbe76553b5f954caf8294fc6360ef995ac1256fe9516d0ce7f",
+ "274f19c10291d188857ad8878e2119f5aa437d4da556601cf1337aff23154016",
+ },
+ {
+ VersionTLS10,
+ cipherSuiteByID(TLS_RSA_WITH_RC4_128_SHA),
+ "832d515f1d61eebb2be56ba0ef79879efb9b527504abb386fb4310ed5d0e3b1f220d3bb6b455033a2773e6d8bdf951d278a187482b400d45deb88a5d5a6bb7d6a7a1decc04eb9ef0642876cd4a82d374d3b6ff35f0351dc5d411104de431375355addc39bfb1f6329fb163b0bc298d658338930d07d313cd980a7e3d9196cac1",
+ "4ae663b2ee389c0de147c509d8f18f5052afc4aaf9699efe8cb05ece883d3a5e",
+ "4ae664d503fd4cff50cfc1fb8fc606580f87b0fcdac9554ba0e01d785bdf278e",
+ "1aff2e7a2c4279d0126f57a65a77a8d9d0087cf2733366699bec27eb53d5740705a8574bb1acc2abbe90e44f0dd28d6c",
+ "3c7647c93c1379a31a609542aa44e7f117a70085",
+ "0d73102994be74a575a3ead8532590ca32a526d4",
+ "ac7581b0b6c10d85bbd905ffbf36c65e",
+ "ff07edde49682b45466bd2e39464b306",
+ 20,
+ 16,
+ "678b0d43f607de35241dc7e9d1a7388a52c35033a1a0336d4d740060a6638fe2",
+ "f3b4ac743f015ef21d79978297a53da3e579ee047133f38c234d829c0f907dab",
+ },
+}
diff --git a/src/crypto/tls/quic.go b/src/crypto/tls/quic.go
new file mode 100644
index 0000000..ba5c2af
--- /dev/null
+++ b/src/crypto/tls/quic.go
@@ -0,0 +1,421 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+ "context"
+ "errors"
+ "fmt"
+)
+
+// QUICEncryptionLevel represents a QUIC encryption level used to transmit
+// handshake messages.
+type QUICEncryptionLevel int
+
+const (
+ QUICEncryptionLevelInitial = QUICEncryptionLevel(iota)
+ QUICEncryptionLevelEarly
+ QUICEncryptionLevelHandshake
+ QUICEncryptionLevelApplication
+)
+
+func (l QUICEncryptionLevel) String() string {
+ switch l {
+ case QUICEncryptionLevelInitial:
+ return "Initial"
+ case QUICEncryptionLevelEarly:
+ return "Early"
+ case QUICEncryptionLevelHandshake:
+ return "Handshake"
+ case QUICEncryptionLevelApplication:
+ return "Application"
+ default:
+ return fmt.Sprintf("QUICEncryptionLevel(%v)", int(l))
+ }
+}
+
+// A QUICConn represents a connection which uses a QUIC implementation as the underlying
+// transport as described in RFC 9001.
+//
+// Methods of QUICConn are not safe for concurrent use.
+type QUICConn struct {
+ conn *Conn
+
+ sessionTicketSent bool
+}
+
+// A QUICConfig configures a QUICConn.
+type QUICConfig struct {
+ TLSConfig *Config
+}
+
+// A QUICEventKind is a type of operation on a QUIC connection.
+type QUICEventKind int
+
+const (
+ // QUICNoEvent indicates that there are no events available.
+ QUICNoEvent QUICEventKind = iota
+
+ // QUICSetReadSecret and QUICSetWriteSecret provide the read and write
+ // secrets for a given encryption level.
+ // QUICEvent.Level, QUICEvent.Data, and QUICEvent.Suite are set.
+ //
+ // Secrets for the Initial encryption level are derived from the initial
+ // destination connection ID, and are not provided by the QUICConn.
+ QUICSetReadSecret
+ QUICSetWriteSecret
+
+ // QUICWriteData provides data to send to the peer in CRYPTO frames.
+ // QUICEvent.Data is set.
+ QUICWriteData
+
+ // QUICTransportParameters provides the peer's QUIC transport parameters.
+ // QUICEvent.Data is set.
+ QUICTransportParameters
+
+ // QUICTransportParametersRequired indicates that the caller must provide
+ // QUIC transport parameters to send to the peer. The caller should set
+ // the transport parameters with QUICConn.SetTransportParameters and call
+ // QUICConn.NextEvent again.
+ //
+ // If transport parameters are set before calling QUICConn.Start, the
+ // connection will never generate a QUICTransportParametersRequired event.
+ QUICTransportParametersRequired
+
+ // QUICRejectedEarlyData indicates that the server rejected 0-RTT data even
+ // if we offered it. It's returned before QUICEncryptionLevelApplication
+ // keys are returned.
+ QUICRejectedEarlyData
+
+ // QUICHandshakeDone indicates that the TLS handshake has completed.
+ QUICHandshakeDone
+)
+
+// A QUICEvent is an event occurring on a QUIC connection.
+//
+// The type of event is specified by the Kind field.
+// The contents of the other fields are kind-specific.
+type QUICEvent struct {
+ Kind QUICEventKind
+
+ // Set for QUICSetReadSecret, QUICSetWriteSecret, and QUICWriteData.
+ Level QUICEncryptionLevel
+
+ // Set for QUICTransportParameters, QUICSetReadSecret, QUICSetWriteSecret, and QUICWriteData.
+ // The contents are owned by crypto/tls, and are valid until the next NextEvent call.
+ Data []byte
+
+ // Set for QUICSetReadSecret and QUICSetWriteSecret.
+ Suite uint16
+}
+
+type quicState struct {
+ events []QUICEvent
+ nextEvent int
+
+ // eventArr is a statically allocated event array, large enough to handle
+ // the usual maximum number of events resulting from a single call: transport
+ // parameters, Initial data, Early read secret, Handshake write and read
+ // secrets, Handshake data, Application write secret, Application data.
+ eventArr [8]QUICEvent
+
+ started bool
+ signalc chan struct{} // handshake data is available to be read
+ blockedc chan struct{} // handshake is waiting for data, closed when done
+ cancelc <-chan struct{} // handshake has been canceled
+ cancel context.CancelFunc
+
+ // readbuf is shared between HandleData and the handshake goroutine.
+ // HandshakeCryptoData passes ownership to the handshake goroutine by
+ // reading from signalc, and reclaims ownership by reading from blockedc.
+ readbuf []byte
+
+ transportParams []byte // to send to the peer
+}
+
+// QUICClient returns a new TLS client side connection using QUICTransport as the
+// underlying transport. The config cannot be nil.
+//
+// The config's MinVersion must be at least TLS 1.3.
+func QUICClient(config *QUICConfig) *QUICConn {
+ return newQUICConn(Client(nil, config.TLSConfig))
+}
+
+// QUICServer returns a new TLS server side connection using QUICTransport as the
+// underlying transport. The config cannot be nil.
+//
+// The config's MinVersion must be at least TLS 1.3.
+func QUICServer(config *QUICConfig) *QUICConn {
+ return newQUICConn(Server(nil, config.TLSConfig))
+}
+
+func newQUICConn(conn *Conn) *QUICConn {
+ conn.quic = &quicState{
+ signalc: make(chan struct{}),
+ blockedc: make(chan struct{}),
+ }
+ conn.quic.events = conn.quic.eventArr[:0]
+ return &QUICConn{
+ conn: conn,
+ }
+}
+
+// Start starts the client or server handshake protocol.
+// It may produce connection events, which may be read with NextEvent.
+//
+// Start must be called at most once.
+func (q *QUICConn) Start(ctx context.Context) error {
+ if q.conn.quic.started {
+ return quicError(errors.New("tls: Start called more than once"))
+ }
+ q.conn.quic.started = true
+ if q.conn.config.MinVersion < VersionTLS13 {
+ return quicError(errors.New("tls: Config MinVersion must be at least TLS 1.13"))
+ }
+ go q.conn.HandshakeContext(ctx)
+ if _, ok := <-q.conn.quic.blockedc; !ok {
+ return q.conn.handshakeErr
+ }
+ return nil
+}
+
+// NextEvent returns the next event occurring on the connection.
+// It returns an event with a Kind of QUICNoEvent when no events are available.
+func (q *QUICConn) NextEvent() QUICEvent {
+ qs := q.conn.quic
+ if last := qs.nextEvent - 1; last >= 0 && len(qs.events[last].Data) > 0 {
+ // Write over some of the previous event's data,
+ // to catch callers erroniously retaining it.
+ qs.events[last].Data[0] = 0
+ }
+ if qs.nextEvent >= len(qs.events) {
+ qs.events = qs.events[:0]
+ qs.nextEvent = 0
+ return QUICEvent{Kind: QUICNoEvent}
+ }
+ e := qs.events[qs.nextEvent]
+ qs.events[qs.nextEvent] = QUICEvent{} // zero out references to data
+ qs.nextEvent++
+ return e
+}
+
+// Close closes the connection and stops any in-progress handshake.
+func (q *QUICConn) Close() error {
+ if q.conn.quic.cancel == nil {
+ return nil // never started
+ }
+ q.conn.quic.cancel()
+ for range q.conn.quic.blockedc {
+ // Wait for the handshake goroutine to return.
+ }
+ return q.conn.handshakeErr
+}
+
+// HandleData handles handshake bytes received from the peer.
+// It may produce connection events, which may be read with NextEvent.
+func (q *QUICConn) HandleData(level QUICEncryptionLevel, data []byte) error {
+ c := q.conn
+ if c.in.level != level {
+ return quicError(c.in.setErrorLocked(errors.New("tls: handshake data received at wrong level")))
+ }
+ c.quic.readbuf = data
+ <-c.quic.signalc
+ _, ok := <-c.quic.blockedc
+ if ok {
+ // The handshake goroutine is waiting for more data.
+ return nil
+ }
+ // The handshake goroutine has exited.
+ c.handshakeMutex.Lock()
+ defer c.handshakeMutex.Unlock()
+ c.hand.Write(c.quic.readbuf)
+ c.quic.readbuf = nil
+ for q.conn.hand.Len() >= 4 && q.conn.handshakeErr == nil {
+ b := q.conn.hand.Bytes()
+ n := int(b[1])<<16 | int(b[2])<<8 | int(b[3])
+ if n > maxHandshake {
+ q.conn.handshakeErr = fmt.Errorf("tls: handshake message of length %d bytes exceeds maximum of %d bytes", n, maxHandshake)
+ break
+ }
+ if len(b) < 4+n {
+ return nil
+ }
+ if err := q.conn.handlePostHandshakeMessage(); err != nil {
+ q.conn.handshakeErr = err
+ }
+ }
+ if q.conn.handshakeErr != nil {
+ return quicError(q.conn.handshakeErr)
+ }
+ return nil
+}
+
+type QUICSessionTicketOptions struct {
+ // EarlyData specifies whether the ticket may be used for 0-RTT.
+ EarlyData bool
+}
+
+// SendSessionTicket sends a session ticket to the client.
+// It produces connection events, which may be read with NextEvent.
+// Currently, it can only be called once.
+func (q *QUICConn) SendSessionTicket(opts QUICSessionTicketOptions) error {
+ c := q.conn
+ if !c.isHandshakeComplete.Load() {
+ return quicError(errors.New("tls: SendSessionTicket called before handshake completed"))
+ }
+ if c.isClient {
+ return quicError(errors.New("tls: SendSessionTicket called on the client"))
+ }
+ if q.sessionTicketSent {
+ return quicError(errors.New("tls: SendSessionTicket called multiple times"))
+ }
+ q.sessionTicketSent = true
+ return quicError(c.sendSessionTicket(opts.EarlyData))
+}
+
+// ConnectionState returns basic TLS details about the connection.
+func (q *QUICConn) ConnectionState() ConnectionState {
+ return q.conn.ConnectionState()
+}
+
+// SetTransportParameters sets the transport parameters to send to the peer.
+//
+// Server connections may delay setting the transport parameters until after
+// receiving the client's transport parameters. See QUICTransportParametersRequired.
+func (q *QUICConn) SetTransportParameters(params []byte) {
+ if params == nil {
+ params = []byte{}
+ }
+ q.conn.quic.transportParams = params
+ if q.conn.quic.started {
+ <-q.conn.quic.signalc
+ <-q.conn.quic.blockedc
+ }
+}
+
+// quicError ensures err is an AlertError.
+// If err is not already, quicError wraps it with alertInternalError.
+func quicError(err error) error {
+ if err == nil {
+ return nil
+ }
+ var ae AlertError
+ if errors.As(err, &ae) {
+ return err
+ }
+ var a alert
+ if !errors.As(err, &a) {
+ a = alertInternalError
+ }
+ // Return an error wrapping the original error and an AlertError.
+ // Truncate the text of the alert to 0 characters.
+ return fmt.Errorf("%w%.0w", err, AlertError(a))
+}
+
+func (c *Conn) quicReadHandshakeBytes(n int) error {
+ for c.hand.Len() < n {
+ if err := c.quicWaitForSignal(); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (c *Conn) quicSetReadSecret(level QUICEncryptionLevel, suite uint16, secret []byte) {
+ c.quic.events = append(c.quic.events, QUICEvent{
+ Kind: QUICSetReadSecret,
+ Level: level,
+ Suite: suite,
+ Data: secret,
+ })
+}
+
+func (c *Conn) quicSetWriteSecret(level QUICEncryptionLevel, suite uint16, secret []byte) {
+ c.quic.events = append(c.quic.events, QUICEvent{
+ Kind: QUICSetWriteSecret,
+ Level: level,
+ Suite: suite,
+ Data: secret,
+ })
+}
+
+func (c *Conn) quicWriteCryptoData(level QUICEncryptionLevel, data []byte) {
+ var last *QUICEvent
+ if len(c.quic.events) > 0 {
+ last = &c.quic.events[len(c.quic.events)-1]
+ }
+ if last == nil || last.Kind != QUICWriteData || last.Level != level {
+ c.quic.events = append(c.quic.events, QUICEvent{
+ Kind: QUICWriteData,
+ Level: level,
+ })
+ last = &c.quic.events[len(c.quic.events)-1]
+ }
+ last.Data = append(last.Data, data...)
+}
+
+func (c *Conn) quicSetTransportParameters(params []byte) {
+ c.quic.events = append(c.quic.events, QUICEvent{
+ Kind: QUICTransportParameters,
+ Data: params,
+ })
+}
+
+func (c *Conn) quicGetTransportParameters() ([]byte, error) {
+ if c.quic.transportParams == nil {
+ c.quic.events = append(c.quic.events, QUICEvent{
+ Kind: QUICTransportParametersRequired,
+ })
+ }
+ for c.quic.transportParams == nil {
+ if err := c.quicWaitForSignal(); err != nil {
+ return nil, err
+ }
+ }
+ return c.quic.transportParams, nil
+}
+
+func (c *Conn) quicHandshakeComplete() {
+ c.quic.events = append(c.quic.events, QUICEvent{
+ Kind: QUICHandshakeDone,
+ })
+}
+
+func (c *Conn) quicRejectedEarlyData() {
+ c.quic.events = append(c.quic.events, QUICEvent{
+ Kind: QUICRejectedEarlyData,
+ })
+}
+
+// quicWaitForSignal notifies the QUICConn that handshake progress is blocked,
+// and waits for a signal that the handshake should proceed.
+//
+// The handshake may become blocked waiting for handshake bytes
+// or for the user to provide transport parameters.
+func (c *Conn) quicWaitForSignal() error {
+ // Drop the handshake mutex while blocked to allow the user
+ // to call ConnectionState before the handshake completes.
+ c.handshakeMutex.Unlock()
+ defer c.handshakeMutex.Lock()
+ // Send on blockedc to notify the QUICConn that the handshake is blocked.
+ // Exported methods of QUICConn wait for the handshake to become blocked
+ // before returning to the user.
+ select {
+ case c.quic.blockedc <- struct{}{}:
+ case <-c.quic.cancelc:
+ return c.sendAlertLocked(alertCloseNotify)
+ }
+ // The QUICConn reads from signalc to notify us that the handshake may
+ // be able to proceed. (The QUICConn reads, because we close signalc to
+ // indicate that the handshake has completed.)
+ select {
+ case c.quic.signalc <- struct{}{}:
+ c.hand.Write(c.quic.readbuf)
+ c.quic.readbuf = nil
+ case <-c.quic.cancelc:
+ return c.sendAlertLocked(alertCloseNotify)
+ }
+ return nil
+}
diff --git a/src/crypto/tls/quic_test.go b/src/crypto/tls/quic_test.go
new file mode 100644
index 0000000..323906a
--- /dev/null
+++ b/src/crypto/tls/quic_test.go
@@ -0,0 +1,489 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+ "context"
+ "errors"
+ "reflect"
+ "testing"
+)
+
+type testQUICConn struct {
+ t *testing.T
+ conn *QUICConn
+ readSecret map[QUICEncryptionLevel]suiteSecret
+ writeSecret map[QUICEncryptionLevel]suiteSecret
+ gotParams []byte
+ complete bool
+}
+
+func newTestQUICClient(t *testing.T, config *Config) *testQUICConn {
+ q := &testQUICConn{t: t}
+ q.conn = QUICClient(&QUICConfig{
+ TLSConfig: config,
+ })
+ t.Cleanup(func() {
+ q.conn.Close()
+ })
+ return q
+}
+
+func newTestQUICServer(t *testing.T, config *Config) *testQUICConn {
+ q := &testQUICConn{t: t}
+ q.conn = QUICServer(&QUICConfig{
+ TLSConfig: config,
+ })
+ t.Cleanup(func() {
+ q.conn.Close()
+ })
+ return q
+}
+
+type suiteSecret struct {
+ suite uint16
+ secret []byte
+}
+
+func (q *testQUICConn) setReadSecret(level QUICEncryptionLevel, suite uint16, secret []byte) {
+ if _, ok := q.writeSecret[level]; !ok {
+ q.t.Errorf("SetReadSecret for level %v called before SetWriteSecret", level)
+ }
+ if level == QUICEncryptionLevelApplication && !q.complete {
+ q.t.Errorf("SetReadSecret for level %v called before HandshakeComplete", level)
+ }
+ if _, ok := q.readSecret[level]; ok {
+ q.t.Errorf("SetReadSecret for level %v called twice", level)
+ }
+ if q.readSecret == nil {
+ q.readSecret = map[QUICEncryptionLevel]suiteSecret{}
+ }
+ switch level {
+ case QUICEncryptionLevelHandshake, QUICEncryptionLevelApplication:
+ q.readSecret[level] = suiteSecret{suite, secret}
+ default:
+ q.t.Errorf("SetReadSecret for unexpected level %v", level)
+ }
+}
+
+func (q *testQUICConn) setWriteSecret(level QUICEncryptionLevel, suite uint16, secret []byte) {
+ if _, ok := q.writeSecret[level]; ok {
+ q.t.Errorf("SetWriteSecret for level %v called twice", level)
+ }
+ if q.writeSecret == nil {
+ q.writeSecret = map[QUICEncryptionLevel]suiteSecret{}
+ }
+ switch level {
+ case QUICEncryptionLevelHandshake, QUICEncryptionLevelApplication:
+ q.writeSecret[level] = suiteSecret{suite, secret}
+ default:
+ q.t.Errorf("SetWriteSecret for unexpected level %v", level)
+ }
+}
+
+var errTransportParametersRequired = errors.New("transport parameters required")
+
+func runTestQUICConnection(ctx context.Context, cli, srv *testQUICConn, onEvent func(e QUICEvent, src, dst *testQUICConn) bool) error {
+ a, b := cli, srv
+ for _, c := range []*testQUICConn{a, b} {
+ if !c.conn.conn.quic.started {
+ if err := c.conn.Start(ctx); err != nil {
+ return err
+ }
+ }
+ }
+ idleCount := 0
+ for {
+ e := a.conn.NextEvent()
+ if onEvent != nil && onEvent(e, a, b) {
+ continue
+ }
+ switch e.Kind {
+ case QUICNoEvent:
+ idleCount++
+ if idleCount == 2 {
+ if !a.complete || !b.complete {
+ return errors.New("handshake incomplete")
+ }
+ return nil
+ }
+ a, b = b, a
+ case QUICSetReadSecret:
+ a.setReadSecret(e.Level, e.Suite, e.Data)
+ case QUICSetWriteSecret:
+ a.setWriteSecret(e.Level, e.Suite, e.Data)
+ case QUICWriteData:
+ if err := b.conn.HandleData(e.Level, e.Data); err != nil {
+ return err
+ }
+ case QUICTransportParameters:
+ a.gotParams = e.Data
+ if a.gotParams == nil {
+ a.gotParams = []byte{}
+ }
+ case QUICTransportParametersRequired:
+ return errTransportParametersRequired
+ case QUICHandshakeDone:
+ a.complete = true
+ if a == srv {
+ opts := QUICSessionTicketOptions{}
+ if err := srv.conn.SendSessionTicket(opts); err != nil {
+ return err
+ }
+ }
+ }
+ if e.Kind != QUICNoEvent {
+ idleCount = 0
+ }
+ }
+}
+
+func TestQUICConnection(t *testing.T) {
+ config := testConfig.Clone()
+ config.MinVersion = VersionTLS13
+
+ cli := newTestQUICClient(t, config)
+ cli.conn.SetTransportParameters(nil)
+
+ srv := newTestQUICServer(t, config)
+ srv.conn.SetTransportParameters(nil)
+
+ if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != nil {
+ t.Fatalf("error during connection handshake: %v", err)
+ }
+
+ if _, ok := cli.readSecret[QUICEncryptionLevelHandshake]; !ok {
+ t.Errorf("client has no Handshake secret")
+ }
+ if _, ok := cli.readSecret[QUICEncryptionLevelApplication]; !ok {
+ t.Errorf("client has no Application secret")
+ }
+ if _, ok := srv.readSecret[QUICEncryptionLevelHandshake]; !ok {
+ t.Errorf("server has no Handshake secret")
+ }
+ if _, ok := srv.readSecret[QUICEncryptionLevelApplication]; !ok {
+ t.Errorf("server has no Application secret")
+ }
+ for _, level := range []QUICEncryptionLevel{QUICEncryptionLevelHandshake, QUICEncryptionLevelApplication} {
+ if _, ok := cli.readSecret[level]; !ok {
+ t.Errorf("client has no %v read secret", level)
+ }
+ if _, ok := srv.readSecret[level]; !ok {
+ t.Errorf("server has no %v read secret", level)
+ }
+ if !reflect.DeepEqual(cli.readSecret[level], srv.writeSecret[level]) {
+ t.Errorf("client read secret does not match server write secret for level %v", level)
+ }
+ if !reflect.DeepEqual(cli.writeSecret[level], srv.readSecret[level]) {
+ t.Errorf("client write secret does not match server read secret for level %v", level)
+ }
+ }
+}
+
+func TestQUICSessionResumption(t *testing.T) {
+ clientConfig := testConfig.Clone()
+ clientConfig.MinVersion = VersionTLS13
+ clientConfig.ClientSessionCache = NewLRUClientSessionCache(1)
+ clientConfig.ServerName = "example.go.dev"
+
+ serverConfig := testConfig.Clone()
+ serverConfig.MinVersion = VersionTLS13
+
+ cli := newTestQUICClient(t, clientConfig)
+ cli.conn.SetTransportParameters(nil)
+ srv := newTestQUICServer(t, serverConfig)
+ srv.conn.SetTransportParameters(nil)
+ if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != nil {
+ t.Fatalf("error during first connection handshake: %v", err)
+ }
+ if cli.conn.ConnectionState().DidResume {
+ t.Errorf("first connection unexpectedly used session resumption")
+ }
+
+ cli2 := newTestQUICClient(t, clientConfig)
+ cli2.conn.SetTransportParameters(nil)
+ srv2 := newTestQUICServer(t, serverConfig)
+ srv2.conn.SetTransportParameters(nil)
+ if err := runTestQUICConnection(context.Background(), cli2, srv2, nil); err != nil {
+ t.Fatalf("error during second connection handshake: %v", err)
+ }
+ if !cli2.conn.ConnectionState().DidResume {
+ t.Errorf("second connection did not use session resumption")
+ }
+}
+
+func TestQUICFragmentaryData(t *testing.T) {
+ clientConfig := testConfig.Clone()
+ clientConfig.MinVersion = VersionTLS13
+ clientConfig.ClientSessionCache = NewLRUClientSessionCache(1)
+ clientConfig.ServerName = "example.go.dev"
+
+ serverConfig := testConfig.Clone()
+ serverConfig.MinVersion = VersionTLS13
+
+ cli := newTestQUICClient(t, clientConfig)
+ cli.conn.SetTransportParameters(nil)
+ srv := newTestQUICServer(t, serverConfig)
+ srv.conn.SetTransportParameters(nil)
+ onEvent := func(e QUICEvent, src, dst *testQUICConn) bool {
+ if e.Kind == QUICWriteData {
+ // Provide the data one byte at a time.
+ for i := range e.Data {
+ if err := dst.conn.HandleData(e.Level, e.Data[i:i+1]); err != nil {
+ t.Errorf("HandleData: %v", err)
+ break
+ }
+ }
+ return true
+ }
+ return false
+ }
+ if err := runTestQUICConnection(context.Background(), cli, srv, onEvent); err != nil {
+ t.Fatalf("error during first connection handshake: %v", err)
+ }
+}
+
+func TestQUICPostHandshakeClientAuthentication(t *testing.T) {
+ // RFC 9001, Section 4.4.
+ config := testConfig.Clone()
+ config.MinVersion = VersionTLS13
+ cli := newTestQUICClient(t, config)
+ cli.conn.SetTransportParameters(nil)
+ srv := newTestQUICServer(t, config)
+ srv.conn.SetTransportParameters(nil)
+ if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != nil {
+ t.Fatalf("error during connection handshake: %v", err)
+ }
+
+ certReq := new(certificateRequestMsgTLS13)
+ certReq.ocspStapling = true
+ certReq.scts = true
+ certReq.supportedSignatureAlgorithms = supportedSignatureAlgorithms()
+ certReqBytes, err := certReq.marshal()
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err := cli.conn.HandleData(QUICEncryptionLevelApplication, append([]byte{
+ byte(typeCertificateRequest),
+ byte(0), byte(0), byte(len(certReqBytes)),
+ }, certReqBytes...)); err == nil {
+ t.Fatalf("post-handshake authentication request: got no error, want one")
+ }
+}
+
+func TestQUICPostHandshakeKeyUpdate(t *testing.T) {
+ // RFC 9001, Section 6.
+ config := testConfig.Clone()
+ config.MinVersion = VersionTLS13
+ cli := newTestQUICClient(t, config)
+ cli.conn.SetTransportParameters(nil)
+ srv := newTestQUICServer(t, config)
+ srv.conn.SetTransportParameters(nil)
+ if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != nil {
+ t.Fatalf("error during connection handshake: %v", err)
+ }
+
+ keyUpdate := new(keyUpdateMsg)
+ keyUpdateBytes, err := keyUpdate.marshal()
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err := cli.conn.HandleData(QUICEncryptionLevelApplication, append([]byte{
+ byte(typeKeyUpdate),
+ byte(0), byte(0), byte(len(keyUpdateBytes)),
+ }, keyUpdateBytes...)); !errors.Is(err, alertUnexpectedMessage) {
+ t.Fatalf("key update request: got error %v, want alertUnexpectedMessage", err)
+ }
+}
+
+func TestQUICPostHandshakeMessageTooLarge(t *testing.T) {
+ config := testConfig.Clone()
+ config.MinVersion = VersionTLS13
+ cli := newTestQUICClient(t, config)
+ cli.conn.SetTransportParameters(nil)
+ srv := newTestQUICServer(t, config)
+ srv.conn.SetTransportParameters(nil)
+ if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != nil {
+ t.Fatalf("error during connection handshake: %v", err)
+ }
+
+ size := maxHandshake + 1
+ if err := cli.conn.HandleData(QUICEncryptionLevelApplication, []byte{
+ byte(typeNewSessionTicket),
+ byte(size >> 16),
+ byte(size >> 8),
+ byte(size),
+ }); err == nil {
+ t.Fatalf("%v-byte post-handshake message: got no error, want one", size)
+ }
+}
+
+func TestQUICHandshakeError(t *testing.T) {
+ clientConfig := testConfig.Clone()
+ clientConfig.MinVersion = VersionTLS13
+ clientConfig.InsecureSkipVerify = false
+ clientConfig.ServerName = "name"
+
+ serverConfig := testConfig.Clone()
+ serverConfig.MinVersion = VersionTLS13
+
+ cli := newTestQUICClient(t, clientConfig)
+ cli.conn.SetTransportParameters(nil)
+ srv := newTestQUICServer(t, serverConfig)
+ srv.conn.SetTransportParameters(nil)
+ err := runTestQUICConnection(context.Background(), cli, srv, nil)
+ if !errors.Is(err, AlertError(alertBadCertificate)) {
+ t.Errorf("connection handshake terminated with error %q, want alertBadCertificate", err)
+ }
+ var e *CertificateVerificationError
+ if !errors.As(err, &e) {
+ t.Errorf("connection handshake terminated with error %q, want CertificateVerificationError", err)
+ }
+}
+
+// Test that QUICConn.ConnectionState can be used during the handshake,
+// and that it reports the application protocol as soon as it has been
+// negotiated.
+func TestQUICConnectionState(t *testing.T) {
+ config := testConfig.Clone()
+ config.MinVersion = VersionTLS13
+ config.NextProtos = []string{"h3"}
+ cli := newTestQUICClient(t, config)
+ cli.conn.SetTransportParameters(nil)
+ srv := newTestQUICServer(t, config)
+ srv.conn.SetTransportParameters(nil)
+ onEvent := func(e QUICEvent, src, dst *testQUICConn) bool {
+ cliCS := cli.conn.ConnectionState()
+ if _, ok := cli.readSecret[QUICEncryptionLevelApplication]; ok {
+ if want, got := cliCS.NegotiatedProtocol, "h3"; want != got {
+ t.Errorf("cli.ConnectionState().NegotiatedProtocol = %q, want %q", want, got)
+ }
+ }
+ srvCS := srv.conn.ConnectionState()
+ if _, ok := srv.readSecret[QUICEncryptionLevelHandshake]; ok {
+ if want, got := srvCS.NegotiatedProtocol, "h3"; want != got {
+ t.Errorf("srv.ConnectionState().NegotiatedProtocol = %q, want %q", want, got)
+ }
+ }
+ return false
+ }
+ if err := runTestQUICConnection(context.Background(), cli, srv, onEvent); err != nil {
+ t.Fatalf("error during connection handshake: %v", err)
+ }
+}
+
+func TestQUICStartContextPropagation(t *testing.T) {
+ const key = "key"
+ const value = "value"
+ ctx := context.WithValue(context.Background(), key, value)
+ config := testConfig.Clone()
+ config.MinVersion = VersionTLS13
+ calls := 0
+ config.GetConfigForClient = func(info *ClientHelloInfo) (*Config, error) {
+ calls++
+ got, _ := info.Context().Value(key).(string)
+ if got != value {
+ t.Errorf("GetConfigForClient context key %q has value %q, want %q", key, got, value)
+ }
+ return nil, nil
+ }
+ cli := newTestQUICClient(t, config)
+ cli.conn.SetTransportParameters(nil)
+ srv := newTestQUICServer(t, config)
+ srv.conn.SetTransportParameters(nil)
+ if err := runTestQUICConnection(ctx, cli, srv, nil); err != nil {
+ t.Fatalf("error during connection handshake: %v", err)
+ }
+ if calls != 1 {
+ t.Errorf("GetConfigForClient called %v times, want 1", calls)
+ }
+}
+
+func TestQUICDelayedTransportParameters(t *testing.T) {
+ clientConfig := testConfig.Clone()
+ clientConfig.MinVersion = VersionTLS13
+ clientConfig.ClientSessionCache = NewLRUClientSessionCache(1)
+ clientConfig.ServerName = "example.go.dev"
+
+ serverConfig := testConfig.Clone()
+ serverConfig.MinVersion = VersionTLS13
+
+ cliParams := "client params"
+ srvParams := "server params"
+
+ cli := newTestQUICClient(t, clientConfig)
+ srv := newTestQUICServer(t, serverConfig)
+ if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != errTransportParametersRequired {
+ t.Fatalf("handshake with no client parameters: %v; want errTransportParametersRequired", err)
+ }
+ cli.conn.SetTransportParameters([]byte(cliParams))
+ if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != errTransportParametersRequired {
+ t.Fatalf("handshake with no server parameters: %v; want errTransportParametersRequired", err)
+ }
+ srv.conn.SetTransportParameters([]byte(srvParams))
+ if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != nil {
+ t.Fatalf("error during connection handshake: %v", err)
+ }
+
+ if got, want := string(cli.gotParams), srvParams; got != want {
+ t.Errorf("client got transport params: %q, want %q", got, want)
+ }
+ if got, want := string(srv.gotParams), cliParams; got != want {
+ t.Errorf("server got transport params: %q, want %q", got, want)
+ }
+}
+
+func TestQUICEmptyTransportParameters(t *testing.T) {
+ config := testConfig.Clone()
+ config.MinVersion = VersionTLS13
+
+ cli := newTestQUICClient(t, config)
+ cli.conn.SetTransportParameters(nil)
+ srv := newTestQUICServer(t, config)
+ srv.conn.SetTransportParameters(nil)
+ if err := runTestQUICConnection(context.Background(), cli, srv, nil); err != nil {
+ t.Fatalf("error during connection handshake: %v", err)
+ }
+
+ if cli.gotParams == nil {
+ t.Errorf("client did not get transport params")
+ }
+ if srv.gotParams == nil {
+ t.Errorf("server did not get transport params")
+ }
+ if len(cli.gotParams) != 0 {
+ t.Errorf("client got transport params: %v, want empty", cli.gotParams)
+ }
+ if len(srv.gotParams) != 0 {
+ t.Errorf("server got transport params: %v, want empty", srv.gotParams)
+ }
+}
+
+func TestQUICCanceledWaitingForData(t *testing.T) {
+ config := testConfig.Clone()
+ config.MinVersion = VersionTLS13
+ cli := newTestQUICClient(t, config)
+ cli.conn.SetTransportParameters(nil)
+ cli.conn.Start(context.Background())
+ for cli.conn.NextEvent().Kind != QUICNoEvent {
+ }
+ err := cli.conn.Close()
+ if !errors.Is(err, alertCloseNotify) {
+ t.Errorf("conn.Close() = %v, want alertCloseNotify", err)
+ }
+}
+
+func TestQUICCanceledWaitingForTransportParams(t *testing.T) {
+ config := testConfig.Clone()
+ config.MinVersion = VersionTLS13
+ cli := newTestQUICClient(t, config)
+ cli.conn.Start(context.Background())
+ for cli.conn.NextEvent().Kind != QUICTransportParametersRequired {
+ }
+ err := cli.conn.Close()
+ if !errors.Is(err, alertCloseNotify) {
+ t.Errorf("conn.Close() = %v, want alertCloseNotify", err)
+ }
+}
diff --git a/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-ECDSA b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-ECDSA
new file mode 100644
index 0000000..e018e87
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-ECDSA
@@ -0,0 +1,135 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 01 00 5d 02 00 00 59 03 01 8d 16 c0 c7 69 |....]...Y......i|
+00000010 4a 19 df eb e0 a2 f1 43 43 d6 4a ac 8c cd ee 58 |J......CC.J....X|
+00000020 2e f9 f2 7d d2 61 df 54 0c e8 4e 20 2e 1c 65 31 |...}.a.T..N ..e1|
+00000030 60 6d 7f f9 10 9b fd d1 31 fa 0c 45 01 ca 06 e3 |`m......1..E....|
+00000040 30 9a ab b4 b7 96 b3 99 de 8c 10 84 c0 09 00 00 |0...............|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 01 02 0e 0b 00 02 0a 00 02 07 00 02 |................|
+00000070 04 30 82 02 00 30 82 01 62 02 09 00 b8 bf 2d 47 |.0...0..b.....-G|
+00000080 a0 d2 eb f4 30 09 06 07 2a 86 48 ce 3d 04 01 30 |....0...*.H.=..0|
+00000090 45 31 0b 30 09 06 03 55 04 06 13 02 41 55 31 13 |E1.0...U....AU1.|
+000000a0 30 11 06 03 55 04 08 13 0a 53 6f 6d 65 2d 53 74 |0...U....Some-St|
+000000b0 61 74 65 31 21 30 1f 06 03 55 04 0a 13 18 49 6e |ate1!0...U....In|
+000000c0 74 65 72 6e 65 74 20 57 69 64 67 69 74 73 20 50 |ternet Widgits P|
+000000d0 74 79 20 4c 74 64 30 1e 17 0d 31 32 31 31 32 32 |ty Ltd0...121122|
+000000e0 31 35 30 36 33 32 5a 17 0d 32 32 31 31 32 30 31 |150632Z..2211201|
+000000f0 35 30 36 33 32 5a 30 45 31 0b 30 09 06 03 55 04 |50632Z0E1.0...U.|
+00000100 06 13 02 41 55 31 13 30 11 06 03 55 04 08 13 0a |...AU1.0...U....|
+00000110 53 6f 6d 65 2d 53 74 61 74 65 31 21 30 1f 06 03 |Some-State1!0...|
+00000120 55 04 0a 13 18 49 6e 74 65 72 6e 65 74 20 57 69 |U....Internet Wi|
+00000130 64 67 69 74 73 20 50 74 79 20 4c 74 64 30 81 9b |dgits Pty Ltd0..|
+00000140 30 10 06 07 2a 86 48 ce 3d 02 01 06 05 2b 81 04 |0...*.H.=....+..|
+00000150 00 23 03 81 86 00 04 00 c4 a1 ed be 98 f9 0b 48 |.#.............H|
+00000160 73 36 7e c3 16 56 11 22 f2 3d 53 c3 3b 4d 21 3d |s6~..V.".=S.;M!=|
+00000170 cd 6b 75 e6 f6 b0 dc 9a df 26 c1 bc b2 87 f0 72 |.ku......&.....r|
+00000180 32 7c b3 64 2f 1c 90 bc ea 68 23 10 7e fe e3 25 |2|.d/....h#.~..%|
+00000190 c0 48 3a 69 e0 28 6d d3 37 00 ef 04 62 dd 0d a0 |.H:i.(m.7...b...|
+000001a0 9c 70 62 83 d8 81 d3 64 31 aa 9e 97 31 bd 96 b0 |.pb....d1...1...|
+000001b0 68 c0 9b 23 de 76 64 3f 1a 5c 7f e9 12 0e 58 58 |h..#.vd?.\....XX|
+000001c0 b6 5f 70 dd 9b d8 ea d5 d7 f5 d5 cc b9 b6 9f 30 |._p............0|
+000001d0 66 5b 66 9a 20 e2 27 e5 bf fe 3b 30 09 06 07 2a |f[f. .'...;0...*|
+000001e0 86 48 ce 3d 04 01 03 81 8c 00 30 81 88 02 42 01 |.H.=......0...B.|
+000001f0 88 a2 4f eb e2 45 c5 48 7d 1b ac f5 ed 98 9d ae |..O..E.H}.......|
+00000200 47 70 c0 5e 1b b6 2f bd f1 b6 4d b7 61 40 d3 11 |Gp.^../...M.a@..|
+00000210 a2 ce ee 0b 7e 92 7e ff 76 9d c3 3b 7e a5 3f ce |....~.~.v..;~.?.|
+00000220 fa 10 e2 59 ec 47 2d 7c ac da 4e 97 0e 15 a0 6f |...Y.G-|..N....o|
+00000230 d0 02 42 01 4d fc be 67 13 9c 2d 05 0e bd 3f a3 |..B.M..g..-...?.|
+00000240 8c 25 c1 33 13 83 0d 94 06 bb d4 37 7a f6 ec 7a |.%.3.......7z..z|
+00000250 c9 86 2e dd d7 11 69 7f 85 7c 56 de fb 31 78 2b |......i..|V..1x+|
+00000260 e4 c7 78 0d ae cb be 9e 4e 36 24 31 7b 6a 0f 39 |..x.....N6$1{j.9|
+00000270 95 12 07 8f 2a 16 03 01 00 b5 0c 00 00 b1 03 00 |....*...........|
+00000280 1d 20 2a 39 4c 47 2f 16 34 c1 2b 55 8b 1f 26 bb |. *9LG/.4.+U..&.|
+00000290 f7 27 e1 e1 6c 62 e3 76 16 ed ff 23 bf 07 09 3c |.'..lb.v...#...<|
+000002a0 24 1c 00 8b 30 81 88 02 42 01 34 ea 39 ef 28 c1 |$...0...B.4.9.(.|
+000002b0 f9 00 fc a9 37 0e a8 ce 4e 17 0e 8d c3 3d 27 9b |....7...N....='.|
+000002c0 87 ce b2 d1 31 e3 82 9b 7b e6 40 19 c9 da ba 7f |....1...{.@.....|
+000002d0 03 f9 57 01 c9 f0 28 66 64 1a f6 f7 6a 67 09 b4 |..W...(fd...jg..|
+000002e0 b9 c7 ef 1f 37 fd 7c 04 ba 4e ef 02 42 00 e1 15 |....7.|..N..B...|
+000002f0 c9 22 ae 13 8d bc 24 26 ce 62 09 9e c4 95 80 65 |."....$&.b.....e|
+00000300 b3 dc a4 df 98 c8 cd 95 8c 55 c7 af 27 b1 31 2c |.........U..'.1,|
+00000310 df 62 72 47 b4 e8 df 76 43 16 60 7f 42 60 b0 eb |.brG...vC.`.B`..|
+00000320 b8 f7 75 75 ef d6 7e aa d9 c5 9c 9d f0 0d d8 16 |..uu..~.........|
+00000330 03 01 00 0a 0d 00 00 06 03 01 02 40 00 00 16 03 |...........@....|
+00000340 01 00 04 0e 00 00 00 |.......|
+>>> Flow 3 (client to server)
+00000000 16 03 01 02 0a 0b 00 02 06 00 02 03 00 02 00 30 |...............0|
+00000010 82 01 fc 30 82 01 5e 02 09 00 9a 30 84 6c 26 35 |...0..^....0.l&5|
+00000020 d9 17 30 09 06 07 2a 86 48 ce 3d 04 01 30 45 31 |..0...*.H.=..0E1|
+00000030 0b 30 09 06 03 55 04 06 13 02 41 55 31 13 30 11 |.0...U....AU1.0.|
+00000040 06 03 55 04 08 13 0a 53 6f 6d 65 2d 53 74 61 74 |..U....Some-Stat|
+00000050 65 31 21 30 1f 06 03 55 04 0a 13 18 49 6e 74 65 |e1!0...U....Inte|
+00000060 72 6e 65 74 20 57 69 64 67 69 74 73 20 50 74 79 |rnet Widgits Pty|
+00000070 20 4c 74 64 30 1e 17 0d 31 32 31 31 31 34 31 33 | Ltd0...12111413|
+00000080 32 35 35 33 5a 17 0d 32 32 31 31 31 32 31 33 32 |2553Z..221112132|
+00000090 35 35 33 5a 30 41 31 0b 30 09 06 03 55 04 06 13 |553Z0A1.0...U...|
+000000a0 02 41 55 31 0c 30 0a 06 03 55 04 08 13 03 4e 53 |.AU1.0...U....NS|
+000000b0 57 31 10 30 0e 06 03 55 04 07 13 07 50 79 72 6d |W1.0...U....Pyrm|
+000000c0 6f 6e 74 31 12 30 10 06 03 55 04 03 13 09 4a 6f |ont1.0...U....Jo|
+000000d0 65 6c 20 53 69 6e 67 30 81 9b 30 10 06 07 2a 86 |el Sing0..0...*.|
+000000e0 48 ce 3d 02 01 06 05 2b 81 04 00 23 03 81 86 00 |H.=....+...#....|
+000000f0 04 00 95 8c 91 75 14 c0 5e c4 57 b4 d4 c3 6f 8d |.....u..^.W...o.|
+00000100 ae 68 1e dd 6f ce 86 e1 7e 6e b2 48 3e 81 e5 4e |.h..o...~n.H>..N|
+00000110 e2 c6 88 4b 64 dc f5 30 bb d3 ff 65 cc 5b f4 dd |...Kd..0...e.[..|
+00000120 b5 6a 3e 3e d0 1d de 47 c3 76 ad 19 f6 45 2c 8c |.j>>...G.v...E,.|
+00000130 bc d8 1d 01 4c 1f 70 90 46 76 48 8b 8f 83 cc 4a |....L.p.FvH....J|
+00000140 5c 8f 40 76 da e0 89 ec 1d 2b c4 4e 30 76 28 41 |\.@v.....+.N0v(A|
+00000150 b2 62 a8 fb 5b f1 f9 4e 7a 8d bd 09 b8 ae ea 8b |.b..[..Nz.......|
+00000160 18 27 4f 2e 70 fe 13 96 ba c3 d3 40 16 cd 65 4e |.'O.p......@..eN|
+00000170 ac 11 1e e6 f1 30 09 06 07 2a 86 48 ce 3d 04 01 |.....0...*.H.=..|
+00000180 03 81 8c 00 30 81 88 02 42 00 e0 14 c4 60 60 0b |....0...B....``.|
+00000190 72 68 b0 32 5d 61 4a 02 74 5c c2 81 b9 16 a8 3f |rh.2]aJ.t\.....?|
+000001a0 29 c8 36 c7 81 ff 6c b6 5b d9 70 f1 38 3b 50 48 |).6...l.[.p.8;PH|
+000001b0 28 94 cb 09 1a 52 f1 5d ee 8d f2 b9 f0 f0 da d9 |(....R.]........|
+000001c0 15 3a f9 bd 03 7a 87 a2 23 35 ec 02 42 01 a3 d4 |.:...z..#5..B...|
+000001d0 8a 78 35 1c 4a 9a 23 d2 0a be 2b 10 31 9d 9c 5f |.x5.J.#...+.1.._|
+000001e0 be e8 91 b3 da 1a f5 5d a3 23 f5 26 8b 45 70 8d |.......].#.&.Ep.|
+000001f0 65 62 9b 7e 01 99 3d 18 f6 10 9a 38 61 9b 2e 57 |eb.~..=....8a..W|
+00000200 e4 fa cc b1 8a ce e2 23 a0 87 f0 e1 67 51 eb 16 |.......#....gQ..|
+00000210 03 01 00 25 10 00 00 21 20 2f e5 7d a3 47 cd 62 |...%...! /.}.G.b|
+00000220 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 cf |C.(.._.).0......|
+00000230 c2 ed 90 99 5f 58 cb 3b 74 16 03 01 00 91 0f 00 |...._X.;t.......|
+00000240 00 8d 00 8b 30 81 88 02 42 01 9a ce de b0 79 2f |....0...B.....y/|
+00000250 8b f3 6a ab 71 75 38 58 6a 85 d5 eb 60 ee de d0 |..j.qu8Xj...`...|
+00000260 c8 61 46 fc 41 2a d7 dd b5 db cd d8 74 4e a2 62 |.aF.A*......tN.b|
+00000270 c8 a5 1c f6 62 7a 04 ea 0b 70 39 cd 68 75 d2 b6 |....bz...p9.hu..|
+00000280 cc f9 71 ee f2 cc 9a a2 12 78 bc 02 42 01 4d 03 |..q......x..B.M.|
+00000290 1a 75 bb 13 64 ab 08 c5 fb f3 ff 18 74 c5 25 dd |.u..d.......t.%.|
+000002a0 27 99 5b ad 76 7a a7 e2 4d a7 1d d7 ba 6e e4 e7 |'.[.vz..M....n..|
+000002b0 32 00 70 4a 35 6c c4 bb 03 5b 83 d5 e5 fc 53 e4 |2.pJ5l...[....S.|
+000002c0 7e 1b f3 e7 18 79 b3 d4 76 ac 0f 74 6e 8f f7 14 |~....y..v..tn...|
+000002d0 03 01 00 01 01 16 03 01 00 30 1a 3f 4b ba 4c e4 |.........0.?K.L.|
+000002e0 6d 21 25 4d 90 2b 94 01 2b 82 f6 0a 0f a9 f9 95 |m!%M.+..+.......|
+000002f0 03 1f 13 ee cf 27 d2 84 8a 59 cd ca 8d a8 c1 07 |.....'...Y......|
+00000300 3f f6 c3 2b d5 91 21 2a 84 23 |?..+..!*.#|
+>>> Flow 4 (server to client)
+00000000 14 03 01 00 01 01 16 03 01 00 30 ac 6a 3b cf 6b |..........0.j;.k|
+00000010 fc d7 25 1d ee d1 c0 61 65 73 be df 21 65 07 b8 |..%....aes..!e..|
+00000020 9d 88 13 b9 b2 23 9c 90 a5 b4 71 31 75 b9 2e 97 |.....#....q1u...|
+00000030 73 a1 c0 85 cc 6c f5 ac 49 2e 5f |s....l..I._|
+>>> Flow 5 (client to server)
+00000000 17 03 01 00 20 46 71 8d 32 ba c1 05 5c 59 bc 82 |.... Fq.2...\Y..|
+00000010 e1 bc 6f eb de 23 26 8d 9c b2 b4 e8 c8 69 f3 46 |..o..#&......i.F|
+00000020 0b 07 61 69 ae 17 03 01 00 20 e5 a5 ea 4c 59 7d |..ai..... ...LY}|
+00000030 74 cd b8 0a 66 b6 ec 95 b0 8a 86 3a 9c e3 f5 11 |t...f......:....|
+00000040 5b 05 62 9a ce 2e 87 8e 41 f4 15 03 01 00 20 be |[.b.....A..... .|
+00000050 0a 29 47 93 e8 ef ad d4 5d f9 e1 a4 46 1a 51 98 |.)G.....]...F.Q.|
+00000060 f0 8c be 3b fc cc a0 ed 7c 18 ac bf 94 35 93 |...;....|....5.|
diff --git a/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-RSA b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-RSA
new file mode 100644
index 0000000..364d33d
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-RSA
@@ -0,0 +1,139 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 01 00 5d 02 00 00 59 03 01 a1 07 34 d5 08 |....]...Y....4..|
+00000010 09 17 79 08 6e 26 2b b3 2f e5 35 08 54 b4 5b 0e |..y.n&+./.5.T.[.|
+00000020 c8 58 57 2b 5a 75 8d e8 d2 9e 35 20 ae bf 94 16 |.XW+Zu....5 ....|
+00000030 e5 a9 f6 05 18 1f 7f a4 1e e9 cd 4a c0 7d a6 4d |...........J.}.M|
+00000040 75 4f 06 de e0 6c 79 b3 39 5c a7 ed c0 13 00 00 |uO...ly.9\......|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 01 02 59 0b 00 02 55 00 02 52 00 02 |......Y...U..R..|
+00000070 4f 30 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 |O0..K0..........|
+00000080 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 |....?.[..0...*.H|
+00000090 86 f7 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 |........0.1.0...|
+000000a0 55 04 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 |U....Go1.0...U..|
+000000b0 13 07 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 |..Go Root0...160|
+000000c0 31 30 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 |101000000Z..2501|
+000000d0 30 31 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 |01000000Z0.1.0..|
+000000e0 03 55 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 |.U....Go1.0...U.|
+000000f0 03 13 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 |...Go0..0...*.H.|
+00000100 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 |...........0....|
+00000110 81 00 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab |...F}...'.H..(!.|
+00000120 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d |~...]..RE.z6G...|
+00000130 92 42 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd |.B[.....y.@.Om..|
+00000140 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a |+.....g....."8.J|
+00000150 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 |.ts+.4......t{.X|
+00000160 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c |.la<..A..++$#w[.|
+00000170 3b bd 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 |;.u]. T..c...$..|
+00000180 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 |..P....C...ub...|
+00000190 52 d7 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 |R.........0..0..|
+000001a0 03 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 |.U...........0..|
+000001b0 03 55 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 |.U.%..0...+.....|
+000001c0 03 01 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 |....+.......0...|
+000001d0 55 1d 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d |U.......0.0...U.|
+000001e0 0e 04 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d |.........CC>I..m|
+000001f0 b6 80 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 |....`0...U.#..0.|
+00000200 80 10 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab |..H.IM.~.1......|
+00000210 6e 7b 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 |n{0...U....0...e|
+00000220 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 |xample.golang0..|
+00000230 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 |.*.H............|
+00000240 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed |.0.@+[P.a...SX..|
+00000250 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 |.(.X..8....1Z..f|
+00000260 3d 43 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a |=C.-...... d8.$:|
+00000270 00 bc cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 |....}.@ ._...a..|
+00000280 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed |v......\.....l..|
+00000290 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 |s..Cw.......@.a.|
+000002a0 4c 72 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 |Lr+...F..M...>..|
+000002b0 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 |.B...=.`.\!.;...|
+000002c0 16 03 01 00 aa 0c 00 00 a6 03 00 1d 20 6d 79 f8 |............ my.|
+000002d0 b3 f9 f8 39 10 ea 9a f0 d7 40 a7 94 b4 5b 87 fc |...9.....@...[..|
+000002e0 63 e1 7f 82 f8 cd e9 02 f7 0c 83 e0 48 00 80 cc |c...........H...|
+000002f0 23 b7 af c6 3b 6a ed cd 07 be 81 cd 81 f9 85 f1 |#...;j..........|
+00000300 a2 32 82 3b 1c 02 3e 02 20 da 71 e0 3a cc 4b 49 |.2.;..>. .q.:.KI|
+00000310 09 36 af 1e 9e b5 14 6e 4c d1 4d df 87 38 92 52 |.6.....nL.M..8.R|
+00000320 47 0c e7 e8 2b 2e 65 38 e3 c4 d7 24 db bb fb 2c |G...+.e8...$...,|
+00000330 04 2c 9e e5 a7 9d 4b 03 b8 cb 71 c6 62 e0 42 f7 |.,....K...q.b.B.|
+00000340 d7 1e 62 7e 21 e0 4d 37 e2 67 46 fa 82 df 49 62 |..b~!.M7.gF...Ib|
+00000350 33 fe e1 44 fd 62 31 46 b7 66 27 ce 85 99 00 b2 |3..D.b1F.f'.....|
+00000360 2c 94 1b c1 66 7b 95 a9 2c d2 33 5c 57 50 f1 16 |,...f{..,.3\WP..|
+00000370 03 01 00 0a 0d 00 00 06 03 01 02 40 00 00 16 03 |...........@....|
+00000380 01 00 04 0e 00 00 00 |.......|
+>>> Flow 3 (client to server)
+00000000 16 03 01 02 0a 0b 00 02 06 00 02 03 00 02 00 30 |...............0|
+00000010 82 01 fc 30 82 01 5e 02 09 00 9a 30 84 6c 26 35 |...0..^....0.l&5|
+00000020 d9 17 30 09 06 07 2a 86 48 ce 3d 04 01 30 45 31 |..0...*.H.=..0E1|
+00000030 0b 30 09 06 03 55 04 06 13 02 41 55 31 13 30 11 |.0...U....AU1.0.|
+00000040 06 03 55 04 08 13 0a 53 6f 6d 65 2d 53 74 61 74 |..U....Some-Stat|
+00000050 65 31 21 30 1f 06 03 55 04 0a 13 18 49 6e 74 65 |e1!0...U....Inte|
+00000060 72 6e 65 74 20 57 69 64 67 69 74 73 20 50 74 79 |rnet Widgits Pty|
+00000070 20 4c 74 64 30 1e 17 0d 31 32 31 31 31 34 31 33 | Ltd0...12111413|
+00000080 32 35 35 33 5a 17 0d 32 32 31 31 31 32 31 33 32 |2553Z..221112132|
+00000090 35 35 33 5a 30 41 31 0b 30 09 06 03 55 04 06 13 |553Z0A1.0...U...|
+000000a0 02 41 55 31 0c 30 0a 06 03 55 04 08 13 03 4e 53 |.AU1.0...U....NS|
+000000b0 57 31 10 30 0e 06 03 55 04 07 13 07 50 79 72 6d |W1.0...U....Pyrm|
+000000c0 6f 6e 74 31 12 30 10 06 03 55 04 03 13 09 4a 6f |ont1.0...U....Jo|
+000000d0 65 6c 20 53 69 6e 67 30 81 9b 30 10 06 07 2a 86 |el Sing0..0...*.|
+000000e0 48 ce 3d 02 01 06 05 2b 81 04 00 23 03 81 86 00 |H.=....+...#....|
+000000f0 04 00 95 8c 91 75 14 c0 5e c4 57 b4 d4 c3 6f 8d |.....u..^.W...o.|
+00000100 ae 68 1e dd 6f ce 86 e1 7e 6e b2 48 3e 81 e5 4e |.h..o...~n.H>..N|
+00000110 e2 c6 88 4b 64 dc f5 30 bb d3 ff 65 cc 5b f4 dd |...Kd..0...e.[..|
+00000120 b5 6a 3e 3e d0 1d de 47 c3 76 ad 19 f6 45 2c 8c |.j>>...G.v...E,.|
+00000130 bc d8 1d 01 4c 1f 70 90 46 76 48 8b 8f 83 cc 4a |....L.p.FvH....J|
+00000140 5c 8f 40 76 da e0 89 ec 1d 2b c4 4e 30 76 28 41 |\.@v.....+.N0v(A|
+00000150 b2 62 a8 fb 5b f1 f9 4e 7a 8d bd 09 b8 ae ea 8b |.b..[..Nz.......|
+00000160 18 27 4f 2e 70 fe 13 96 ba c3 d3 40 16 cd 65 4e |.'O.p......@..eN|
+00000170 ac 11 1e e6 f1 30 09 06 07 2a 86 48 ce 3d 04 01 |.....0...*.H.=..|
+00000180 03 81 8c 00 30 81 88 02 42 00 e0 14 c4 60 60 0b |....0...B....``.|
+00000190 72 68 b0 32 5d 61 4a 02 74 5c c2 81 b9 16 a8 3f |rh.2]aJ.t\.....?|
+000001a0 29 c8 36 c7 81 ff 6c b6 5b d9 70 f1 38 3b 50 48 |).6...l.[.p.8;PH|
+000001b0 28 94 cb 09 1a 52 f1 5d ee 8d f2 b9 f0 f0 da d9 |(....R.]........|
+000001c0 15 3a f9 bd 03 7a 87 a2 23 35 ec 02 42 01 a3 d4 |.:...z..#5..B...|
+000001d0 8a 78 35 1c 4a 9a 23 d2 0a be 2b 10 31 9d 9c 5f |.x5.J.#...+.1.._|
+000001e0 be e8 91 b3 da 1a f5 5d a3 23 f5 26 8b 45 70 8d |.......].#.&.Ep.|
+000001f0 65 62 9b 7e 01 99 3d 18 f6 10 9a 38 61 9b 2e 57 |eb.~..=....8a..W|
+00000200 e4 fa cc b1 8a ce e2 23 a0 87 f0 e1 67 51 eb 16 |.......#....gQ..|
+00000210 03 01 00 25 10 00 00 21 20 2f e5 7d a3 47 cd 62 |...%...! /.}.G.b|
+00000220 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 cf |C.(.._.).0......|
+00000230 c2 ed 90 99 5f 58 cb 3b 74 16 03 01 00 91 0f 00 |...._X.;t.......|
+00000240 00 8d 00 8b 30 81 88 02 42 00 f7 1a 73 32 b1 a7 |....0...B...s2..|
+00000250 04 a2 26 85 14 53 5a 70 76 c4 44 4c 0d f8 5a a6 |..&..SZpv.DL..Z.|
+00000260 bc 64 44 88 3f 01 80 a4 0d 17 ce 30 ca 92 4c 29 |.dD.?......0..L)|
+00000270 b2 f3 a4 65 1e 28 55 bc b8 47 64 39 b7 49 20 05 |...e.(U..Gd9.I .|
+00000280 9d a4 84 6b 1b 8b df eb b6 f6 b9 02 42 01 68 c8 |...k........B.h.|
+00000290 fd 3c ad 36 ad 15 28 4f f2 ac b3 7f 63 28 30 5c |.<.6..(O....c(0\|
+000002a0 68 59 f5 84 b2 cf 23 d6 dd 3b f5 7b 2b 1a ac 32 |hY....#..;.{+..2|
+000002b0 20 da 76 af 63 2a 68 6e 18 cd 07 82 41 6f 50 91 | .v.c*hn....AoP.|
+000002c0 d0 51 3b 9b ab 71 84 d4 be 15 dd 4b 8c 57 b7 14 |.Q;..q.....K.W..|
+000002d0 03 01 00 01 01 16 03 01 00 30 e3 e6 b9 cb 0b 0f |.........0......|
+000002e0 71 55 4e 15 53 85 5c 2a 55 ac 83 cc e9 71 69 eb |qUN.S.\*U....qi.|
+000002f0 dd 64 cb 2f 9f 74 b4 e6 80 52 9e a0 08 e3 7e 14 |.d./.t...R....~.|
+00000300 2c 5e 15 e4 81 38 11 aa fb ab |,^...8....|
+>>> Flow 4 (server to client)
+00000000 14 03 01 00 01 01 16 03 01 00 30 bb 2d 20 48 7a |..........0.- Hz|
+00000010 53 bf 3a ee c3 91 ec 1b be cf 4a 18 57 5a c4 a7 |S.:.......J.WZ..|
+00000020 57 d7 51 fa 4a 69 8a bf cd ff 2e 64 e7 76 a7 49 |W.Q.Ji.....d.v.I|
+00000030 1e 19 34 8d 4f c3 40 14 5d 68 8c |..4.O.@.]h.|
+>>> Flow 5 (client to server)
+00000000 17 03 01 00 20 c6 82 9a ee a3 de fe 3f cd 56 92 |.... .......?.V.|
+00000010 20 b3 27 ae 5d db 4c 6c a3 a9 01 ba ce 98 c5 d7 | .'.].Ll........|
+00000020 af be 49 92 50 17 03 01 00 20 35 a5 2d 8e 5a 4f |..I.P.... 5.-.ZO|
+00000030 0d a8 ea 08 f8 dd 6c 01 04 d9 a7 2b 71 b1 c9 84 |......l....+q...|
+00000040 9d de d3 ce 69 4c 7a 3e 3c 7b 15 03 01 00 20 5c |....iLz><{.... \|
+00000050 00 f6 57 56 dc f9 fc 36 15 85 71 01 7b 18 ae 11 |..WV...6..q.{...|
+00000060 51 0b f7 a3 e4 f8 d9 d8 ae 1d 0b 68 0f 4c 87 |Q..........h.L.|
diff --git a/src/crypto/tls/testdata/Client-TLSv10-ClientCert-Ed25519 b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-Ed25519
new file mode 100644
index 0000000..a14cef1
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-Ed25519
@@ -0,0 +1,110 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fa 01 00 00 f6 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a8 |.............2..|
+00000050 cc a9 c0 2f c0 2b c0 30 c0 2c c0 27 c0 13 c0 23 |.../.+.0.,.'...#|
+00000060 c0 09 c0 14 c0 0a 00 9c 00 9d 00 3c 00 2f 00 35 |...........<./.5|
+00000070 c0 12 00 0a 00 05 c0 11 c0 07 13 01 13 03 13 02 |................|
+00000080 01 00 00 7b 00 05 00 05 01 00 00 00 00 00 0a 00 |...{............|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 08 05 08 06 04 01 04 |................|
+000000b0 03 05 01 05 03 06 01 06 03 02 01 02 03 08 07 ff |................|
+000000c0 01 00 01 00 00 12 00 00 00 2b 00 09 08 03 04 03 |.........+......|
+000000d0 03 03 02 03 01 00 33 00 26 00 24 00 1d 00 20 2f |......3.&.$... /|
+000000e0 e5 7d a3 47 cd 62 43 15 28 da ac 5f bb 29 07 30 |.}.G.bC.(.._.).0|
+000000f0 ff f6 84 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 |.........._X.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 01 00 59 02 00 00 55 03 01 55 df 11 fe c6 |....Y...U..U....|
+00000010 aa d4 85 4b 87 c2 35 4c ac a9 c3 15 a3 7f 6d 7e |...K..5L......m~|
+00000020 15 d1 47 b2 d2 09 16 4d 08 1b dd 20 49 d9 51 42 |..G....M... I.QB|
+00000030 97 cf 36 b3 74 3e 05 0a e5 c9 97 ef 01 9c 24 34 |..6.t>........$4|
+00000040 31 17 e1 8a 6a ce 37 60 02 47 46 7f c0 13 00 00 |1...j.7`.GF.....|
+00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................|
+00000060 01 02 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 |..Y...U..R..O0..|
+00000070 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d |K0..............|
+00000080 3f e2 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 |?.[..0...*.H....|
+00000090 01 0b 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 |....0.1.0...U...|
+000000a0 02 47 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f |.Go1.0...U....Go|
+000000b0 20 52 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 | Root0...1601010|
+000000c0 30 30 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 |00000Z..25010100|
+000000d0 30 30 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a |0000Z0.1.0...U..|
+000000e0 13 02 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 |..Go1.0...U....G|
+000000f0 6f 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 |o0..0...*.H.....|
+00000100 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 |.......0.......F|
+00000110 7d 93 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 |}...'.H..(!.~...|
+00000120 5d fe 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 |]..RE.z6G....B[.|
+00000130 81 c0 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 |....y.@.Om..+...|
+00000140 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b |..g....."8.J.ts+|
+00000150 c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c |.4......t{.X.la<|
+00000160 c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d |..A..++$#w[.;.u]|
+00000170 ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b |. T..c...$....P.|
+00000180 aa b6 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 |...C...ub...R...|
+00000190 01 00 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f |......0..0...U..|
+000001a0 01 01 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 |.........0...U.%|
+000001b0 04 16 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 |..0...+.........|
+000001c0 2b 06 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 |+.......0...U...|
+000001d0 01 ff 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 |....0.0...U.....|
+000001e0 10 9f 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f |.....CC>I..m....|
+000001f0 60 30 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 |`0...U.#..0...H.|
+00000200 49 4d 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 |IM.~.1......n{0.|
+00000210 06 03 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 |..U....0...examp|
+00000220 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 |le.golang0...*.H|
+00000230 86 f7 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 |.............0.@|
+00000240 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 |+[P.a...SX...(.X|
+00000250 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d |..8....1Z..f=C.-|
+00000260 d9 0b f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c |...... d8.$:....|
+00000270 7d b7 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 |}.@ ._...a..v...|
+00000280 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 |...\.....l..s..C|
+00000290 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d |w.......@.a.Lr+.|
+000002a0 ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db |..F..M...>...B..|
+000002b0 fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 01 00 |.=.`.\!.;.......|
+000002c0 aa 0c 00 00 a6 03 00 1d 20 17 27 58 d2 5f 59 a3 |........ .'X._Y.|
+000002d0 62 62 d4 97 4a 49 c4 ff ec dc f7 d3 c9 ea f3 00 |bb..JI..........|
+000002e0 61 1b d3 73 38 9e af 7d 17 00 80 59 7a 4e 55 97 |a..s8..}...YzNU.|
+000002f0 5a 81 0e 2e 85 0b c2 61 f0 79 72 0e d1 d5 3b bf |Z......a.yr...;.|
+00000300 6a 77 03 0a 9a 51 42 f5 98 2f 09 d5 7b 17 76 b8 |jw...QB../..{.v.|
+00000310 2c a7 95 ee 61 65 d7 37 b3 1b 16 3c 48 7e 9d ed |,...ae.7...<H~..|
+00000320 87 25 b0 77 d9 93 44 28 9f 2a f1 2f 35 23 0d e5 |.%.w..D(.*./5#..|
+00000330 7b 08 e0 b0 42 9b d5 0d e7 ca 73 49 b0 09 03 e2 |{...B.....sI....|
+00000340 bf 25 92 be bf d5 ac 84 38 1e a4 39 66 3b 18 71 |.%......8..9f;.q|
+00000350 31 df 4b 42 9b bf 38 c1 72 81 5c d6 4c 67 b1 58 |1.KB..8.r.\.Lg.X|
+00000360 24 84 71 73 0b 5d 21 9d e2 e6 89 16 03 01 00 0a |$.qs.]!.........|
+00000370 0d 00 00 06 03 01 02 40 00 00 16 03 01 00 04 0e |.......@........|
+00000380 00 00 00 |...|
+>>> Flow 3 (client to server)
+00000000 16 03 01 01 3c 0b 00 01 38 00 01 35 00 01 32 30 |....<...8..5..20|
+00000010 82 01 2e 30 81 e1 a0 03 02 01 02 02 10 17 d1 81 |...0............|
+00000020 93 be 2a 8c 21 20 10 25 15 e8 34 23 4f 30 05 06 |..*.! .%..4#O0..|
+00000030 03 2b 65 70 30 12 31 10 30 0e 06 03 55 04 0a 13 |.+ep0.1.0...U...|
+00000040 07 41 63 6d 65 20 43 6f 30 1e 17 0d 31 39 30 35 |.Acme Co0...1905|
+00000050 31 36 32 31 35 34 32 36 5a 17 0d 32 30 30 35 31 |16215426Z..20051|
+00000060 35 32 31 35 34 32 36 5a 30 12 31 10 30 0e 06 03 |5215426Z0.1.0...|
+00000070 55 04 0a 13 07 41 63 6d 65 20 43 6f 30 2a 30 05 |U....Acme Co0*0.|
+00000080 06 03 2b 65 70 03 21 00 0b e0 b5 60 b5 e2 79 30 |..+ep.!....`..y0|
+00000090 3d be e3 1e e0 50 b1 04 c8 6d c7 78 6c 69 2f c5 |=....P...m.xli/.|
+000000a0 14 ad 9a 63 6f 79 12 91 a3 4d 30 4b 30 0e 06 03 |...coy...M0K0...|
+000000b0 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 13 06 03 |U...........0...|
+000000c0 55 1d 25 04 0c 30 0a 06 08 2b 06 01 05 05 07 03 |U.%..0...+......|
+000000d0 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 |.0...U.......0.0|
+000000e0 16 06 03 55 1d 11 04 0f 30 0d 82 0b 65 78 61 6d |...U....0...exam|
+000000f0 70 6c 65 2e 63 6f 6d 30 05 06 03 2b 65 70 03 41 |ple.com0...+ep.A|
+00000100 00 fc 19 17 2a 94 a5 31 fa 29 c8 2e 7f 5b a0 5d |....*..1.)...[.]|
+00000110 8a 4e 34 40 39 d6 b3 10 dc 19 fe a0 22 71 b3 f5 |.N4@9......."q..|
+00000120 8f a1 58 0d cd f4 f1 85 24 bf e6 3d 14 df df ed |..X.....$..=....|
+00000130 0e e1 17 d8 11 a2 60 d0 8a 37 23 2a c2 46 aa 3a |......`..7#*.F.:|
+00000140 08 16 03 01 00 25 10 00 00 21 20 2f e5 7d a3 47 |.....%...! /.}.G|
+00000150 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af |.bC.(.._.).0....|
+00000160 c4 cf c2 ed 90 99 5f 58 cb 3b 74 16 03 01 00 46 |......_X.;t....F|
+00000170 0f 00 00 42 00 40 14 6a d7 c1 9c 3d 81 fa e9 da |...B.@.j...=....|
+00000180 96 5c 3a 09 e2 fc 36 e2 30 39 e4 6e 0d ac aa 54 |.\:...6.09.n...T|
+00000190 24 4d 8c f0 35 14 b0 0b e9 5b 57 52 31 02 9f 6c |$M..5....[WR1..l|
+000001a0 6f 6c d7 e9 b5 7f cb 30 fe b9 ba b9 7a 46 67 e3 |ol.....0....zFg.|
+000001b0 a7 50 ca ce e4 04 14 03 01 00 01 01 16 03 01 00 |.P..............|
+000001c0 30 8d 0a ca d1 5e 2c 7e 92 d0 69 f4 d9 e8 5d 0a |0....^,~..i...].|
+000001d0 11 72 67 20 3e 80 64 29 e5 79 f5 33 ad 06 78 07 |.rg >.d).y.3..x.|
+000001e0 4c 03 fc 2e 16 35 70 b1 72 e7 35 a9 cc 49 b8 29 |L....5p.r.5..I.)|
+000001f0 30 |0|
+>>> Flow 4 (server to client)
+00000000 15 03 01 00 02 02 50 |......P|
diff --git a/src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-ECDSA b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-ECDSA
new file mode 100644
index 0000000..d150bab
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-ECDSA
@@ -0,0 +1,134 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 01 00 5d 02 00 00 59 03 01 53 6b 9f 42 b4 |....]...Y..Sk.B.|
+00000010 38 d0 d3 ef 17 52 44 10 a5 70 61 35 8c ae a9 52 |8....RD..pa5...R|
+00000020 6c d6 e2 c3 bd c4 3c b9 3c 09 83 20 aa 22 81 b5 |l.....<.<.. ."..|
+00000030 02 b5 aa e6 24 88 e6 75 70 1c 32 9a 3b 2c 2f 05 |....$..up.2.;,/.|
+00000040 e0 eb 59 65 4c 9e 45 82 fd d7 37 5e c0 09 00 00 |..YeL.E...7^....|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 01 02 0e 0b 00 02 0a 00 02 07 00 02 |................|
+00000070 04 30 82 02 00 30 82 01 62 02 09 00 b8 bf 2d 47 |.0...0..b.....-G|
+00000080 a0 d2 eb f4 30 09 06 07 2a 86 48 ce 3d 04 01 30 |....0...*.H.=..0|
+00000090 45 31 0b 30 09 06 03 55 04 06 13 02 41 55 31 13 |E1.0...U....AU1.|
+000000a0 30 11 06 03 55 04 08 13 0a 53 6f 6d 65 2d 53 74 |0...U....Some-St|
+000000b0 61 74 65 31 21 30 1f 06 03 55 04 0a 13 18 49 6e |ate1!0...U....In|
+000000c0 74 65 72 6e 65 74 20 57 69 64 67 69 74 73 20 50 |ternet Widgits P|
+000000d0 74 79 20 4c 74 64 30 1e 17 0d 31 32 31 31 32 32 |ty Ltd0...121122|
+000000e0 31 35 30 36 33 32 5a 17 0d 32 32 31 31 32 30 31 |150632Z..2211201|
+000000f0 35 30 36 33 32 5a 30 45 31 0b 30 09 06 03 55 04 |50632Z0E1.0...U.|
+00000100 06 13 02 41 55 31 13 30 11 06 03 55 04 08 13 0a |...AU1.0...U....|
+00000110 53 6f 6d 65 2d 53 74 61 74 65 31 21 30 1f 06 03 |Some-State1!0...|
+00000120 55 04 0a 13 18 49 6e 74 65 72 6e 65 74 20 57 69 |U....Internet Wi|
+00000130 64 67 69 74 73 20 50 74 79 20 4c 74 64 30 81 9b |dgits Pty Ltd0..|
+00000140 30 10 06 07 2a 86 48 ce 3d 02 01 06 05 2b 81 04 |0...*.H.=....+..|
+00000150 00 23 03 81 86 00 04 00 c4 a1 ed be 98 f9 0b 48 |.#.............H|
+00000160 73 36 7e c3 16 56 11 22 f2 3d 53 c3 3b 4d 21 3d |s6~..V.".=S.;M!=|
+00000170 cd 6b 75 e6 f6 b0 dc 9a df 26 c1 bc b2 87 f0 72 |.ku......&.....r|
+00000180 32 7c b3 64 2f 1c 90 bc ea 68 23 10 7e fe e3 25 |2|.d/....h#.~..%|
+00000190 c0 48 3a 69 e0 28 6d d3 37 00 ef 04 62 dd 0d a0 |.H:i.(m.7...b...|
+000001a0 9c 70 62 83 d8 81 d3 64 31 aa 9e 97 31 bd 96 b0 |.pb....d1...1...|
+000001b0 68 c0 9b 23 de 76 64 3f 1a 5c 7f e9 12 0e 58 58 |h..#.vd?.\....XX|
+000001c0 b6 5f 70 dd 9b d8 ea d5 d7 f5 d5 cc b9 b6 9f 30 |._p............0|
+000001d0 66 5b 66 9a 20 e2 27 e5 bf fe 3b 30 09 06 07 2a |f[f. .'...;0...*|
+000001e0 86 48 ce 3d 04 01 03 81 8c 00 30 81 88 02 42 01 |.H.=......0...B.|
+000001f0 88 a2 4f eb e2 45 c5 48 7d 1b ac f5 ed 98 9d ae |..O..E.H}.......|
+00000200 47 70 c0 5e 1b b6 2f bd f1 b6 4d b7 61 40 d3 11 |Gp.^../...M.a@..|
+00000210 a2 ce ee 0b 7e 92 7e ff 76 9d c3 3b 7e a5 3f ce |....~.~.v..;~.?.|
+00000220 fa 10 e2 59 ec 47 2d 7c ac da 4e 97 0e 15 a0 6f |...Y.G-|..N....o|
+00000230 d0 02 42 01 4d fc be 67 13 9c 2d 05 0e bd 3f a3 |..B.M..g..-...?.|
+00000240 8c 25 c1 33 13 83 0d 94 06 bb d4 37 7a f6 ec 7a |.%.3.......7z..z|
+00000250 c9 86 2e dd d7 11 69 7f 85 7c 56 de fb 31 78 2b |......i..|V..1x+|
+00000260 e4 c7 78 0d ae cb be 9e 4e 36 24 31 7b 6a 0f 39 |..x.....N6$1{j.9|
+00000270 95 12 07 8f 2a 16 03 01 00 b5 0c 00 00 b1 03 00 |....*...........|
+00000280 1d 20 fc 74 81 8e 09 19 14 86 d3 4d 8d cf 7d 00 |. .t.......M..}.|
+00000290 c1 83 83 b5 9a 32 f1 38 01 ae a9 9b a1 d9 26 54 |.....2.8......&T|
+000002a0 a4 08 00 8b 30 81 88 02 42 00 a1 56 29 a7 ba 25 |....0...B..V)..%|
+000002b0 bb 6a 12 51 77 c1 28 35 1e 4b 3e a8 01 63 e6 f6 |.j.Qw.(5.K>..c..|
+000002c0 f3 99 05 7b 0f 1f 21 dd 9e de c9 c1 08 c6 bc 23 |...{..!........#|
+000002d0 71 87 1e a1 30 07 0c 5d f6 9f bf 45 7d 60 3c c2 |q...0..]...E}`<.|
+000002e0 48 65 3d 3f a3 b4 67 89 90 1d 12 02 42 00 93 43 |He=?..g.....B..C|
+000002f0 12 c1 46 b5 6d 2e cc 60 50 11 95 86 bd 36 53 fc |..F.m..`P....6S.|
+00000300 92 01 6a 11 92 97 69 c2 cf c9 b0 a0 4a 42 0b d2 |..j...i.....JB..|
+00000310 c4 0c 84 e5 9e f6 2c a3 91 70 45 25 1f 78 17 b0 |......,..pE%.x..|
+00000320 1f 0e f7 a2 d5 4d 1c 77 ec f9 04 ca ab 68 26 16 |.....M.w.....h&.|
+00000330 03 01 00 0a 0d 00 00 06 03 01 02 40 00 00 16 03 |...........@....|
+00000340 01 00 04 0e 00 00 00 |.......|
+>>> Flow 3 (client to server)
+00000000 16 03 01 01 fd 0b 00 01 f9 00 01 f6 00 01 f3 30 |...............0|
+00000010 82 01 ef 30 82 01 58 a0 03 02 01 02 02 10 5c 19 |...0..X.......\.|
+00000020 c1 89 65 83 55 6f dc 0b c9 b9 93 9f e9 bc 30 0d |..e.Uo........0.|
+00000030 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 12 31 |..*.H........0.1|
+00000040 10 30 0e 06 03 55 04 0a 13 07 41 63 6d 65 20 43 |.0...U....Acme C|
+00000050 6f 30 1e 17 0d 31 36 30 38 31 37 32 31 35 32 33 |o0...16081721523|
+00000060 31 5a 17 0d 31 37 30 38 31 37 32 31 35 32 33 31 |1Z..170817215231|
+00000070 5a 30 12 31 10 30 0e 06 03 55 04 0a 13 07 41 63 |Z0.1.0...U....Ac|
+00000080 6d 65 20 43 6f 30 81 9f 30 0d 06 09 2a 86 48 86 |me Co0..0...*.H.|
+00000090 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 |...........0....|
+000000a0 81 00 ba 6f aa 86 bd cf bf 9f f2 ef 5c 94 60 78 |...o........\.`x|
+000000b0 6f e8 13 f2 d1 96 6f cd d9 32 6e 22 37 ce 41 f9 |o.....o..2n"7.A.|
+000000c0 ca 5d 29 ac e1 27 da 61 a2 ee 81 cb 10 c7 df 34 |.])..'.a.......4|
+000000d0 58 95 86 e9 3d 19 e6 5c 27 73 60 c8 8d 78 02 f4 |X...=..\'s`..x..|
+000000e0 1d a4 98 09 a3 19 70 69 3c 25 62 66 2a ab 22 23 |......pi<%bf*."#|
+000000f0 c5 7b 85 38 4f 2e 09 73 32 a7 bd 3e 9b ad ca 84 |.{.8O..s2..>....|
+00000100 07 e6 0f 3a ff 77 c5 9d 41 85 00 8a b6 9b ee b0 |...:.w..A.......|
+00000110 a4 3f 2d 4c 4c e6 42 3e bb 51 c8 dd 48 54 f4 0c |.?-LL.B>.Q..HT..|
+00000120 8e 47 02 03 01 00 01 a3 46 30 44 30 0e 06 03 55 |.G......F0D0...U|
+00000130 1d 0f 01 01 ff 04 04 03 02 05 a0 30 13 06 03 55 |...........0...U|
+00000140 1d 25 04 0c 30 0a 06 08 2b 06 01 05 05 07 03 01 |.%..0...+.......|
+00000150 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 0f |0...U.......0.0.|
+00000160 06 03 55 1d 11 04 08 30 06 87 04 7f 00 00 01 30 |..U....0.......0|
+00000170 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 |...*.H..........|
+00000180 81 00 46 ab 44 a2 fb 28 54 f8 5a 67 f8 62 94 f1 |..F.D..(T.Zg.b..|
+00000190 9a b2 18 9e f2 b1 de 1d 7e 6f 76 95 a9 ba e7 5d |........~ov....]|
+000001a0 a8 16 6c 9c f7 09 d3 37 e4 4b 2b 36 7c 01 ad 41 |..l....7.K+6|..A|
+000001b0 d2 32 d8 c3 d2 93 f9 10 6b 8e 95 b9 2c 17 8a a3 |.2......k...,...|
+000001c0 44 48 bc 59 13 83 16 04 88 a4 81 5c 25 0d 98 0c |DH.Y.......\%...|
+000001d0 ac 11 b1 28 56 be 1d cd 61 62 84 09 bf d6 80 c6 |...(V...ab......|
+000001e0 45 8d 82 2c b4 d8 83 9b db c9 22 b7 2a 12 11 7b |E..,......".*..{|
+000001f0 fa 02 3b c1 c9 ff ea c9 9d a8 49 d3 95 d7 d5 0e |..;.......I.....|
+00000200 e5 35 16 03 01 00 25 10 00 00 21 20 2f e5 7d a3 |.5....%...! /.}.|
+00000210 47 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 |G.bC.(.._.).0...|
+00000220 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 16 03 01 00 |......._X.;t....|
+00000230 86 0f 00 00 82 00 80 3b af ba ad 44 f1 06 e4 79 |.......;...D...y|
+00000240 d7 fa 41 42 2a 7e 45 3d fc 9d f7 5d a9 13 b9 35 |..AB*~E=...]...5|
+00000250 49 ea 28 6a 03 48 0b 14 c9 43 69 16 32 b7 6b b5 |I.(j.H...Ci.2.k.|
+00000260 a7 11 44 15 26 61 04 ea f8 1e a0 32 3d 6b 26 be |..D.&a.....2=k&.|
+00000270 37 44 34 0e 06 62 ee cf b9 41 4c 84 ba 3f aa 5f |7D4..b...AL..?._|
+00000280 d7 ea 31 c8 77 07 13 38 66 ba ec b4 b0 6c 44 ee |..1.w..8f....lD.|
+00000290 8e d4 49 1d 9e 7b 2d b2 48 23 a0 06 04 22 9b 3a |..I..{-.H#...".:|
+000002a0 3f 71 13 13 ce 67 3f e8 84 0f a4 8d ff 2c de f5 |?q...g?......,..|
+000002b0 ce 8d 15 8d 64 bc 5e 14 03 01 00 01 01 16 03 01 |....d.^.........|
+000002c0 00 30 f6 42 8a 63 15 7b 24 63 62 dc f7 6a ab 38 |.0.B.c.{$cb..j.8|
+000002d0 33 32 6d c6 44 5e 10 8a 7a f8 f0 77 e7 5c 2a 6e |32m.D^..z..w.\*n|
+000002e0 8f 18 72 c6 e2 42 66 c0 f7 7a 45 fb 68 01 30 8a |..r..Bf..zE.h.0.|
+000002f0 59 1a |Y.|
+>>> Flow 4 (server to client)
+00000000 14 03 01 00 01 01 16 03 01 00 30 1f a1 61 8d 3e |..........0..a.>|
+00000010 6e 5d 29 bd d0 14 80 ec 55 fc 7d b2 02 bd 6d c5 |n]).....U.}...m.|
+00000020 93 50 67 30 4f ce d5 8a 8b 80 3c 9a a6 0f ac be |.Pg0O.....<.....|
+00000030 dd b0 1b 22 0d 89 dc cd 73 ba 99 |..."....s..|
+>>> Flow 5 (client to server)
+00000000 17 03 01 00 20 23 4b ba 47 65 fb 41 fb ad c6 06 |.... #K.Ge.A....|
+00000010 c2 c7 ed 6e b4 d0 42 48 6b 68 60 69 7c f0 91 85 |...n..BHkh`i|...|
+00000020 f3 a2 ea b1 5b 17 03 01 00 20 d2 fa 3c a5 d2 ea |....[.... ..<...|
+00000030 b8 81 7a fb 31 95 bc e5 e3 4d 1a 15 e7 e3 96 8e |..z.1....M......|
+00000040 bc 77 26 b1 5c b5 61 14 99 7c 15 03 01 00 20 b2 |.w&.\.a..|.... .|
+00000050 0c 6a 3d 02 6b 32 2f 43 9e 5e ac f1 c3 97 e2 27 |.j=.k2/C.^.....'|
+00000060 c1 a1 b9 b6 b7 11 36 17 27 0a 7a 8d 53 18 d6 |......6.'.z.S..|
diff --git a/src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-RSA b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-RSA
new file mode 100644
index 0000000..b3157bb
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-RSA
@@ -0,0 +1,138 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 01 00 5d 02 00 00 59 03 01 a1 43 a5 02 b9 |....]...Y...C...|
+00000010 48 81 74 51 b7 89 df 36 43 1c a3 5e f3 11 7e 81 |H.tQ...6C..^..~.|
+00000020 2d 43 b5 86 e8 4a f4 fe 5e 5e 92 20 10 31 08 7a |-C...J..^^. .1.z|
+00000030 cc 0e 5a 90 0e 07 aa 2f c7 17 b8 c9 d5 93 36 e3 |..Z..../......6.|
+00000040 ca 34 ed a2 e2 3d 6c 0c fd 56 d9 64 c0 13 00 00 |.4...=l..V.d....|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 01 02 59 0b 00 02 55 00 02 52 00 02 |......Y...U..R..|
+00000070 4f 30 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 |O0..K0..........|
+00000080 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 |....?.[..0...*.H|
+00000090 86 f7 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 |........0.1.0...|
+000000a0 55 04 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 |U....Go1.0...U..|
+000000b0 13 07 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 |..Go Root0...160|
+000000c0 31 30 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 |101000000Z..2501|
+000000d0 30 31 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 |01000000Z0.1.0..|
+000000e0 03 55 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 |.U....Go1.0...U.|
+000000f0 03 13 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 |...Go0..0...*.H.|
+00000100 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 |...........0....|
+00000110 81 00 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab |...F}...'.H..(!.|
+00000120 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d |~...]..RE.z6G...|
+00000130 92 42 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd |.B[.....y.@.Om..|
+00000140 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a |+.....g....."8.J|
+00000150 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 |.ts+.4......t{.X|
+00000160 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c |.la<..A..++$#w[.|
+00000170 3b bd 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 |;.u]. T..c...$..|
+00000180 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 |..P....C...ub...|
+00000190 52 d7 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 |R.........0..0..|
+000001a0 03 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 |.U...........0..|
+000001b0 03 55 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 |.U.%..0...+.....|
+000001c0 03 01 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 |....+.......0...|
+000001d0 55 1d 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d |U.......0.0...U.|
+000001e0 0e 04 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d |.........CC>I..m|
+000001f0 b6 80 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 |....`0...U.#..0.|
+00000200 80 10 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab |..H.IM.~.1......|
+00000210 6e 7b 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 |n{0...U....0...e|
+00000220 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 |xample.golang0..|
+00000230 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 |.*.H............|
+00000240 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed |.0.@+[P.a...SX..|
+00000250 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 |.(.X..8....1Z..f|
+00000260 3d 43 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a |=C.-...... d8.$:|
+00000270 00 bc cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 |....}.@ ._...a..|
+00000280 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed |v......\.....l..|
+00000290 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 |s..Cw.......@.a.|
+000002a0 4c 72 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 |Lr+...F..M...>..|
+000002b0 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 |.B...=.`.\!.;...|
+000002c0 16 03 01 00 aa 0c 00 00 a6 03 00 1d 20 62 23 e4 |............ b#.|
+000002d0 5c 02 03 2d 62 41 93 e8 99 9d 01 cb 55 2c 7d 8d |\..-bA......U,}.|
+000002e0 fd db d6 ac c6 99 d0 78 0f 27 27 37 70 00 80 6a |.......x.''7p..j|
+000002f0 58 5e 29 6b 93 82 42 fa a2 b7 5c 06 d8 ac ae 85 |X^)k..B...\.....|
+00000300 48 37 98 35 cf 31 09 8e d6 a3 37 26 d1 e5 b3 3b |H7.5.1....7&...;|
+00000310 98 53 dc b5 d2 9d 73 80 89 04 35 20 e6 e7 ac 48 |.S....s...5 ...H|
+00000320 88 6f 42 ac 1b 46 d3 78 6a f0 5d a0 68 e1 83 db |.oB..F.xj.].h...|
+00000330 8a f3 bc f0 d2 35 b7 ae 8d 38 75 9f d6 76 01 ce |.....5...8u..v..|
+00000340 d7 a9 0f 69 11 09 75 4a 20 b4 3b ec 14 fd 2b 7b |...i..uJ .;...+{|
+00000350 e1 cf 12 89 d2 a2 94 3d 76 d5 b8 65 b4 17 24 43 |.......=v..e..$C|
+00000360 96 68 c4 c9 cc a2 08 e7 ca bc 2d 14 90 fa 53 16 |.h........-...S.|
+00000370 03 01 00 0a 0d 00 00 06 03 01 02 40 00 00 16 03 |...........@....|
+00000380 01 00 04 0e 00 00 00 |.......|
+>>> Flow 3 (client to server)
+00000000 16 03 01 01 fd 0b 00 01 f9 00 01 f6 00 01 f3 30 |...............0|
+00000010 82 01 ef 30 82 01 58 a0 03 02 01 02 02 10 5c 19 |...0..X.......\.|
+00000020 c1 89 65 83 55 6f dc 0b c9 b9 93 9f e9 bc 30 0d |..e.Uo........0.|
+00000030 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 12 31 |..*.H........0.1|
+00000040 10 30 0e 06 03 55 04 0a 13 07 41 63 6d 65 20 43 |.0...U....Acme C|
+00000050 6f 30 1e 17 0d 31 36 30 38 31 37 32 31 35 32 33 |o0...16081721523|
+00000060 31 5a 17 0d 31 37 30 38 31 37 32 31 35 32 33 31 |1Z..170817215231|
+00000070 5a 30 12 31 10 30 0e 06 03 55 04 0a 13 07 41 63 |Z0.1.0...U....Ac|
+00000080 6d 65 20 43 6f 30 81 9f 30 0d 06 09 2a 86 48 86 |me Co0..0...*.H.|
+00000090 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 |...........0....|
+000000a0 81 00 ba 6f aa 86 bd cf bf 9f f2 ef 5c 94 60 78 |...o........\.`x|
+000000b0 6f e8 13 f2 d1 96 6f cd d9 32 6e 22 37 ce 41 f9 |o.....o..2n"7.A.|
+000000c0 ca 5d 29 ac e1 27 da 61 a2 ee 81 cb 10 c7 df 34 |.])..'.a.......4|
+000000d0 58 95 86 e9 3d 19 e6 5c 27 73 60 c8 8d 78 02 f4 |X...=..\'s`..x..|
+000000e0 1d a4 98 09 a3 19 70 69 3c 25 62 66 2a ab 22 23 |......pi<%bf*."#|
+000000f0 c5 7b 85 38 4f 2e 09 73 32 a7 bd 3e 9b ad ca 84 |.{.8O..s2..>....|
+00000100 07 e6 0f 3a ff 77 c5 9d 41 85 00 8a b6 9b ee b0 |...:.w..A.......|
+00000110 a4 3f 2d 4c 4c e6 42 3e bb 51 c8 dd 48 54 f4 0c |.?-LL.B>.Q..HT..|
+00000120 8e 47 02 03 01 00 01 a3 46 30 44 30 0e 06 03 55 |.G......F0D0...U|
+00000130 1d 0f 01 01 ff 04 04 03 02 05 a0 30 13 06 03 55 |...........0...U|
+00000140 1d 25 04 0c 30 0a 06 08 2b 06 01 05 05 07 03 01 |.%..0...+.......|
+00000150 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 0f |0...U.......0.0.|
+00000160 06 03 55 1d 11 04 08 30 06 87 04 7f 00 00 01 30 |..U....0.......0|
+00000170 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 |...*.H..........|
+00000180 81 00 46 ab 44 a2 fb 28 54 f8 5a 67 f8 62 94 f1 |..F.D..(T.Zg.b..|
+00000190 9a b2 18 9e f2 b1 de 1d 7e 6f 76 95 a9 ba e7 5d |........~ov....]|
+000001a0 a8 16 6c 9c f7 09 d3 37 e4 4b 2b 36 7c 01 ad 41 |..l....7.K+6|..A|
+000001b0 d2 32 d8 c3 d2 93 f9 10 6b 8e 95 b9 2c 17 8a a3 |.2......k...,...|
+000001c0 44 48 bc 59 13 83 16 04 88 a4 81 5c 25 0d 98 0c |DH.Y.......\%...|
+000001d0 ac 11 b1 28 56 be 1d cd 61 62 84 09 bf d6 80 c6 |...(V...ab......|
+000001e0 45 8d 82 2c b4 d8 83 9b db c9 22 b7 2a 12 11 7b |E..,......".*..{|
+000001f0 fa 02 3b c1 c9 ff ea c9 9d a8 49 d3 95 d7 d5 0e |..;.......I.....|
+00000200 e5 35 16 03 01 00 25 10 00 00 21 20 2f e5 7d a3 |.5....%...! /.}.|
+00000210 47 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 |G.bC.(.._.).0...|
+00000220 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 16 03 01 00 |......._X.;t....|
+00000230 86 0f 00 00 82 00 80 3d 7f 32 50 ff aa 3d ff 0f |.......=.2P..=..|
+00000240 f8 68 64 fb 2d 34 b8 5b 5e 4b 49 04 b8 eb f7 07 |.hd.-4.[^KI.....|
+00000250 b7 bf 55 17 e5 11 66 87 23 16 3e ba 87 2f 58 23 |..U...f.#.>../X#|
+00000260 28 d4 df 15 75 eb 7b f6 38 94 a8 73 8a d2 1f 51 |(...u.{.8..s...Q|
+00000270 0f b5 90 16 0f db f9 23 a0 bc a5 96 48 ac a6 fa |.......#....H...|
+00000280 fd e7 b4 94 5e c6 d4 a6 69 61 97 1a c3 ed 1e 5a |....^...ia.....Z|
+00000290 db d9 c5 8f 58 97 6c 2a 88 f8 fb 52 14 10 a6 5a |....X.l*...R...Z|
+000002a0 62 7a f8 37 40 e7 fd 27 c6 27 32 12 10 75 83 e3 |bz.7@..'.'2..u..|
+000002b0 66 c1 77 78 90 38 5d 14 03 01 00 01 01 16 03 01 |f.wx.8].........|
+000002c0 00 30 47 b5 75 6f 94 df 88 65 2d fc 45 33 29 d0 |.0G.uo...e-.E3).|
+000002d0 be 8d c0 72 59 be 7e 57 aa d8 42 d5 61 95 24 53 |...rY.~W..B.a.$S|
+000002e0 19 94 06 5b 48 34 22 44 6e 6e bf 2a 3d 0d 83 f6 |...[H4"Dnn.*=...|
+000002f0 a7 3b |.;|
+>>> Flow 4 (server to client)
+00000000 14 03 01 00 01 01 16 03 01 00 30 c1 88 7e 9e de |..........0..~..|
+00000010 d3 2d 1d 27 bf d5 49 c5 a7 67 cc 0b fc ca a6 9b |.-.'..I..g......|
+00000020 1b c7 96 59 ff 4f b9 7d a0 7a 5e ed eb 77 04 5f |...Y.O.}.z^..w._|
+00000030 ba b6 ea 33 80 b0 28 ef 96 ba 6a |...3..(...j|
+>>> Flow 5 (client to server)
+00000000 17 03 01 00 20 55 4a e0 a0 68 5f 32 17 9a a3 fd |.... UJ..h_2....|
+00000010 01 e9 2c fa 19 12 56 6f c6 d7 a7 8d b7 8b 74 8a |..,...Vo......t.|
+00000020 3a ae 72 9f 1e 17 03 01 00 20 b2 07 ca 31 62 b7 |:.r...... ...1b.|
+00000030 cb 46 d4 33 61 6c 81 11 d8 8b f3 cf 6a ac a8 c7 |.F.3al......j...|
+00000040 06 9c dc d9 49 ad 39 2a 6a ea 15 03 01 00 20 ee |....I.9*j..... .|
+00000050 53 44 2e a0 bc 8d 74 8c 12 6b 3d a8 3e a5 98 00 |SD....t..k=.>...|
+00000060 03 e8 bb 34 f5 a9 29 81 0a 6f e6 d3 0e ad 9d |...4..)..o.....|
diff --git a/src/crypto/tls/testdata/Client-TLSv10-ECDHE-ECDSA-AES b/src/crypto/tls/testdata/Client-TLSv10-ECDHE-ECDSA-AES
new file mode 100644
index 0000000..d146d79
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv10-ECDHE-ECDSA-AES
@@ -0,0 +1,92 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 01 00 5d 02 00 00 59 03 01 1c a5 a3 a1 49 |....]...Y......I|
+00000010 4e 93 54 cf 5a a2 8b 57 e7 f9 7b ce 53 48 fb 5b |N.T.Z..W..{.SH.[|
+00000020 82 51 d6 0d aa c7 8b 40 44 5f 18 20 e3 b4 ca 5c |.Q.....@D_. ...\|
+00000030 fd 20 e3 ae d2 a4 df e6 af db 4f 8b e9 95 41 1e |. ........O...A.|
+00000040 8f 6f 1e 0a 33 e4 0b 0b 1b aa 54 a7 c0 09 00 00 |.o..3.....T.....|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 01 02 0e 0b 00 02 0a 00 02 07 00 02 |................|
+00000070 04 30 82 02 00 30 82 01 62 02 09 00 b8 bf 2d 47 |.0...0..b.....-G|
+00000080 a0 d2 eb f4 30 09 06 07 2a 86 48 ce 3d 04 01 30 |....0...*.H.=..0|
+00000090 45 31 0b 30 09 06 03 55 04 06 13 02 41 55 31 13 |E1.0...U....AU1.|
+000000a0 30 11 06 03 55 04 08 13 0a 53 6f 6d 65 2d 53 74 |0...U....Some-St|
+000000b0 61 74 65 31 21 30 1f 06 03 55 04 0a 13 18 49 6e |ate1!0...U....In|
+000000c0 74 65 72 6e 65 74 20 57 69 64 67 69 74 73 20 50 |ternet Widgits P|
+000000d0 74 79 20 4c 74 64 30 1e 17 0d 31 32 31 31 32 32 |ty Ltd0...121122|
+000000e0 31 35 30 36 33 32 5a 17 0d 32 32 31 31 32 30 31 |150632Z..2211201|
+000000f0 35 30 36 33 32 5a 30 45 31 0b 30 09 06 03 55 04 |50632Z0E1.0...U.|
+00000100 06 13 02 41 55 31 13 30 11 06 03 55 04 08 13 0a |...AU1.0...U....|
+00000110 53 6f 6d 65 2d 53 74 61 74 65 31 21 30 1f 06 03 |Some-State1!0...|
+00000120 55 04 0a 13 18 49 6e 74 65 72 6e 65 74 20 57 69 |U....Internet Wi|
+00000130 64 67 69 74 73 20 50 74 79 20 4c 74 64 30 81 9b |dgits Pty Ltd0..|
+00000140 30 10 06 07 2a 86 48 ce 3d 02 01 06 05 2b 81 04 |0...*.H.=....+..|
+00000150 00 23 03 81 86 00 04 00 c4 a1 ed be 98 f9 0b 48 |.#.............H|
+00000160 73 36 7e c3 16 56 11 22 f2 3d 53 c3 3b 4d 21 3d |s6~..V.".=S.;M!=|
+00000170 cd 6b 75 e6 f6 b0 dc 9a df 26 c1 bc b2 87 f0 72 |.ku......&.....r|
+00000180 32 7c b3 64 2f 1c 90 bc ea 68 23 10 7e fe e3 25 |2|.d/....h#.~..%|
+00000190 c0 48 3a 69 e0 28 6d d3 37 00 ef 04 62 dd 0d a0 |.H:i.(m.7...b...|
+000001a0 9c 70 62 83 d8 81 d3 64 31 aa 9e 97 31 bd 96 b0 |.pb....d1...1...|
+000001b0 68 c0 9b 23 de 76 64 3f 1a 5c 7f e9 12 0e 58 58 |h..#.vd?.\....XX|
+000001c0 b6 5f 70 dd 9b d8 ea d5 d7 f5 d5 cc b9 b6 9f 30 |._p............0|
+000001d0 66 5b 66 9a 20 e2 27 e5 bf fe 3b 30 09 06 07 2a |f[f. .'...;0...*|
+000001e0 86 48 ce 3d 04 01 03 81 8c 00 30 81 88 02 42 01 |.H.=......0...B.|
+000001f0 88 a2 4f eb e2 45 c5 48 7d 1b ac f5 ed 98 9d ae |..O..E.H}.......|
+00000200 47 70 c0 5e 1b b6 2f bd f1 b6 4d b7 61 40 d3 11 |Gp.^../...M.a@..|
+00000210 a2 ce ee 0b 7e 92 7e ff 76 9d c3 3b 7e a5 3f ce |....~.~.v..;~.?.|
+00000220 fa 10 e2 59 ec 47 2d 7c ac da 4e 97 0e 15 a0 6f |...Y.G-|..N....o|
+00000230 d0 02 42 01 4d fc be 67 13 9c 2d 05 0e bd 3f a3 |..B.M..g..-...?.|
+00000240 8c 25 c1 33 13 83 0d 94 06 bb d4 37 7a f6 ec 7a |.%.3.......7z..z|
+00000250 c9 86 2e dd d7 11 69 7f 85 7c 56 de fb 31 78 2b |......i..|V..1x+|
+00000260 e4 c7 78 0d ae cb be 9e 4e 36 24 31 7b 6a 0f 39 |..x.....N6$1{j.9|
+00000270 95 12 07 8f 2a 16 03 01 00 b5 0c 00 00 b1 03 00 |....*...........|
+00000280 1d 20 d8 71 32 54 18 4e 03 b2 c7 dd 0d 04 2f c5 |. .q2T.N....../.|
+00000290 c4 da f0 c8 72 b5 c0 b8 c1 a9 f7 e3 8d 1f 0d 3b |....r..........;|
+000002a0 2a 08 00 8b 30 81 88 02 42 01 b6 59 64 4b 72 d6 |*...0...B..YdKr.|
+000002b0 ef 9e 3e 18 1d d4 da 89 e1 59 91 96 47 55 09 cd |..>......Y..GU..|
+000002c0 ee a1 e9 0c db c9 6c bc 09 82 e1 4e 03 e7 c9 c5 |......l....N....|
+000002d0 78 bd 2f 28 dc fc 6a 8c ed e7 43 74 4e e0 06 f6 |x./(..j...CtN...|
+000002e0 ee 85 f5 0f f9 c4 92 96 7d 69 4e 02 42 01 3f cc |........}iN.B.?.|
+000002f0 89 ce 81 42 00 4f 89 28 3d 6d 6a 70 5a 6c d9 87 |...B.O.(=mjpZl..|
+00000300 a3 80 36 7f fa c1 a1 50 57 4b 93 bf a3 16 01 f5 |..6....PWK......|
+00000310 d4 07 4d fd 33 4a 2f 50 36 83 82 40 ef 8d aa 10 |..M.3J/P6..@....|
+00000320 6d d0 e0 24 bd d6 33 d0 96 87 ce 43 28 44 86 16 |m..$..3....C(D..|
+00000330 03 01 00 04 0e 00 00 00 |........|
+>>> Flow 3 (client to server)
+00000000 16 03 01 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.|
+00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....|
+00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 01 00 01 01 |....._X.;t......|
+00000030 16 03 01 00 30 56 e4 5e 74 7d 22 11 ce 6a 97 42 |....0V.^t}"..j.B|
+00000040 9f 6f 71 26 d4 a3 0f e4 03 1d 96 e1 ed a5 bd e4 |.oq&............|
+00000050 a5 96 7c b0 49 d4 bf fe b2 3e d4 ed b0 52 f0 1b |..|.I....>...R..|
+00000060 72 f4 45 ab a3 |r.E..|
+>>> Flow 4 (server to client)
+00000000 14 03 01 00 01 01 16 03 01 00 30 85 b6 39 e7 4e |..........0..9.N|
+00000010 2d d9 aa 9c a7 a7 e9 13 a7 05 cb a4 c0 11 62 67 |-.............bg|
+00000020 34 6f b1 33 05 1e d0 a6 d1 20 f3 cc 47 7d ea 63 |4o.3..... ..G}.c|
+00000030 99 dc 34 46 8e 47 eb 5f 2c 1b b5 |..4F.G._,..|
+>>> Flow 5 (client to server)
+00000000 17 03 01 00 20 35 6d 66 48 4a a0 ee 5a b7 2a 15 |.... 5mfHJ..Z.*.|
+00000010 c8 0c f7 86 16 f1 6a 96 51 28 9b 81 14 fd ac 92 |......j.Q(......|
+00000020 7b d0 9d be 24 17 03 01 00 20 08 f2 38 45 8e a3 |{...$.... ..8E..|
+00000030 89 50 5d 7f c8 5e 4f 71 7e 23 17 da 9b 99 a9 9d |.P]..^Oq~#......|
+00000040 ed 51 8b 1a c8 67 fe 6c c8 2a 15 03 01 00 20 e1 |.Q...g.l.*.... .|
+00000050 ef 54 d4 d3 e3 1e 5a db c0 e9 92 8c 27 e5 86 dd |.T....Z.....'...|
+00000060 29 78 cc 90 6b a7 9c 7b b4 9b 1b 5d 1a 65 18 |)x..k..{...].e.|
diff --git a/src/crypto/tls/testdata/Client-TLSv10-ECDHE-RSA-AES b/src/crypto/tls/testdata/Client-TLSv10-ECDHE-RSA-AES
new file mode 100644
index 0000000..e66b88a
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv10-ECDHE-RSA-AES
@@ -0,0 +1,96 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 01 00 5d 02 00 00 59 03 01 4c dc 79 d9 cc |....]...Y..L.y..|
+00000010 4d 3e e9 7d b2 7c 46 0d 2d 2f ff 27 47 b1 e3 52 |M>.}.|F.-/.'G..R|
+00000020 b1 b4 34 80 6e 60 d5 b6 2d ab bd 20 d4 59 df e1 |..4.n`..-.. .Y..|
+00000030 99 75 36 f3 ac 26 40 99 74 f3 78 43 20 e0 da 18 |.u6..&@.t.xC ...|
+00000040 ae 5c bb bc b5 cc 3f c5 32 7e 3c ba c0 13 00 00 |.\....?.2~<.....|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 01 02 59 0b 00 02 55 00 02 52 00 02 |......Y...U..R..|
+00000070 4f 30 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 |O0..K0..........|
+00000080 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 |....?.[..0...*.H|
+00000090 86 f7 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 |........0.1.0...|
+000000a0 55 04 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 |U....Go1.0...U..|
+000000b0 13 07 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 |..Go Root0...160|
+000000c0 31 30 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 |101000000Z..2501|
+000000d0 30 31 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 |01000000Z0.1.0..|
+000000e0 03 55 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 |.U....Go1.0...U.|
+000000f0 03 13 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 |...Go0..0...*.H.|
+00000100 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 |...........0....|
+00000110 81 00 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab |...F}...'.H..(!.|
+00000120 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d |~...]..RE.z6G...|
+00000130 92 42 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd |.B[.....y.@.Om..|
+00000140 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a |+.....g....."8.J|
+00000150 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 |.ts+.4......t{.X|
+00000160 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c |.la<..A..++$#w[.|
+00000170 3b bd 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 |;.u]. T..c...$..|
+00000180 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 |..P....C...ub...|
+00000190 52 d7 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 |R.........0..0..|
+000001a0 03 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 |.U...........0..|
+000001b0 03 55 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 |.U.%..0...+.....|
+000001c0 03 01 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 |....+.......0...|
+000001d0 55 1d 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d |U.......0.0...U.|
+000001e0 0e 04 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d |.........CC>I..m|
+000001f0 b6 80 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 |....`0...U.#..0.|
+00000200 80 10 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab |..H.IM.~.1......|
+00000210 6e 7b 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 |n{0...U....0...e|
+00000220 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 |xample.golang0..|
+00000230 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 |.*.H............|
+00000240 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed |.0.@+[P.a...SX..|
+00000250 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 |.(.X..8....1Z..f|
+00000260 3d 43 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a |=C.-...... d8.$:|
+00000270 00 bc cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 |....}.@ ._...a..|
+00000280 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed |v......\.....l..|
+00000290 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 |s..Cw.......@.a.|
+000002a0 4c 72 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 |Lr+...F..M...>..|
+000002b0 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 |.B...=.`.\!.;...|
+000002c0 16 03 01 00 aa 0c 00 00 a6 03 00 1d 20 ee 7b 17 |............ .{.|
+000002d0 15 a8 03 82 b4 bc ec 9a 6f 77 a8 29 29 2f ed 2e |........ow.))/..|
+000002e0 65 91 4f 38 b4 e3 a8 f6 48 be c9 c4 26 00 80 ae |e.O8....H...&...|
+000002f0 ef 11 b3 78 c2 8b 4d 86 38 c6 4e 86 1c 26 57 24 |...x..M.8.N..&W$|
+00000300 cf 21 12 b1 74 13 eb 12 c4 90 5a a2 eb 2c 9b 97 |.!..t.....Z..,..|
+00000310 23 f6 8f 4f 25 b8 70 fe b1 dc 95 b5 0c 8f 0b 0d |#..O%.p.........|
+00000320 d9 23 40 a9 48 c3 52 08 0f 4b d4 7d 9f f3 e3 4e |.#@.H.R..K.}...N|
+00000330 8e 14 98 7c ac e9 ee a3 53 0c 25 bf 8e 06 a5 cb |...|....S.%.....|
+00000340 6e 96 76 37 be 8a c8 2e c3 72 cc 8d 12 78 bc 20 |n.v7.....r...x. |
+00000350 8c 53 0e e7 72 59 4d 46 34 72 27 37 6d 2c 88 d6 |.S..rYMF4r'7m,..|
+00000360 cd 0f ab 6d e1 2d a0 3c df 04 35 d9 d2 2d f5 16 |...m.-.<..5..-..|
+00000370 03 01 00 04 0e 00 00 00 |........|
+>>> Flow 3 (client to server)
+00000000 16 03 01 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.|
+00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....|
+00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 01 00 01 01 |....._X.;t......|
+00000030 16 03 01 00 30 af af 7d 17 17 49 08 86 ba 49 c7 |....0..}..I...I.|
+00000040 01 e9 f2 85 f4 70 2d 37 38 b3 38 4d c3 23 0f f5 |.....p-78.8M.#..|
+00000050 fe f3 22 58 6a ec cd ee 17 92 d0 fe aa d8 68 ff |.."Xj.........h.|
+00000060 1d b1 7a 5b 6a |..z[j|
+>>> Flow 4 (server to client)
+00000000 14 03 01 00 01 01 16 03 01 00 30 30 b9 1b da 00 |..........00....|
+00000010 85 eb 23 f3 69 6a 96 34 f1 03 b8 51 c4 0c 09 a7 |..#.ij.4...Q....|
+00000020 62 4c 14 c6 fb ee b0 2b f0 fc e6 9b b6 97 47 83 |bL.....+......G.|
+00000030 20 3d fe c4 42 43 6f c1 2f 09 6a | =..BCo./.j|
+>>> Flow 5 (client to server)
+00000000 17 03 01 00 20 42 e3 37 32 c0 b5 bb fb 9b 26 9e |.... B.72.....&.|
+00000010 1b b1 28 ee c7 44 c3 7c c8 51 88 3a e9 5a c7 2f |..(..D.|.Q.:.Z./|
+00000020 b6 0d 73 ee 3e 17 03 01 00 20 20 33 1e 5f 0f 81 |..s.>.... 3._..|
+00000030 aa 06 15 f1 e6 24 f3 12 07 ad 78 a6 0f 18 ad 33 |.....$....x....3|
+00000040 67 d4 1c ec 28 15 65 de e2 6e 15 03 01 00 20 b0 |g...(.e..n.... .|
+00000050 93 62 04 fe 6e 3f 41 a5 c8 e8 6c 9d a7 96 59 ba |.b..n?A...l...Y.|
+00000060 aa 81 c8 ff ef 66 91 89 5f 9c ba d1 aa e7 ef |.....f.._......|
diff --git a/src/crypto/tls/testdata/Client-TLSv10-Ed25519 b/src/crypto/tls/testdata/Client-TLSv10-Ed25519
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv10-Ed25519
diff --git a/src/crypto/tls/testdata/Client-TLSv10-ExportKeyingMaterial b/src/crypto/tls/testdata/Client-TLSv10-ExportKeyingMaterial
new file mode 100644
index 0000000..8225f78
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv10-ExportKeyingMaterial
@@ -0,0 +1,96 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 01 00 5d 02 00 00 59 03 01 b7 20 c3 67 7b |....]...Y... .g{|
+00000010 94 6e d7 da ea e0 77 4e 05 ad e0 9b a2 97 59 e3 |.n....wN......Y.|
+00000020 de 61 a2 49 d0 2f 27 7d fc 7c 4e 20 9a 18 52 f9 |.a.I./'}.|N ..R.|
+00000030 bf ec 13 7d 28 1a 44 14 ea 77 25 7a 30 81 36 1e |...}(.D..w%z0.6.|
+00000040 18 b3 23 37 79 dc 10 e8 f2 18 90 c7 c0 13 00 00 |..#7y...........|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 01 02 59 0b 00 02 55 00 02 52 00 02 |......Y...U..R..|
+00000070 4f 30 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 |O0..K0..........|
+00000080 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 |....?.[..0...*.H|
+00000090 86 f7 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 |........0.1.0...|
+000000a0 55 04 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 |U....Go1.0...U..|
+000000b0 13 07 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 |..Go Root0...160|
+000000c0 31 30 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 |101000000Z..2501|
+000000d0 30 31 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 |01000000Z0.1.0..|
+000000e0 03 55 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 |.U....Go1.0...U.|
+000000f0 03 13 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 |...Go0..0...*.H.|
+00000100 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 |...........0....|
+00000110 81 00 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab |...F}...'.H..(!.|
+00000120 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d |~...]..RE.z6G...|
+00000130 92 42 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd |.B[.....y.@.Om..|
+00000140 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a |+.....g....."8.J|
+00000150 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 |.ts+.4......t{.X|
+00000160 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c |.la<..A..++$#w[.|
+00000170 3b bd 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 |;.u]. T..c...$..|
+00000180 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 |..P....C...ub...|
+00000190 52 d7 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 |R.........0..0..|
+000001a0 03 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 |.U...........0..|
+000001b0 03 55 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 |.U.%..0...+.....|
+000001c0 03 01 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 |....+.......0...|
+000001d0 55 1d 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d |U.......0.0...U.|
+000001e0 0e 04 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d |.........CC>I..m|
+000001f0 b6 80 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 |....`0...U.#..0.|
+00000200 80 10 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab |..H.IM.~.1......|
+00000210 6e 7b 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 |n{0...U....0...e|
+00000220 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 |xample.golang0..|
+00000230 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 |.*.H............|
+00000240 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed |.0.@+[P.a...SX..|
+00000250 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 |.(.X..8....1Z..f|
+00000260 3d 43 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a |=C.-...... d8.$:|
+00000270 00 bc cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 |....}.@ ._...a..|
+00000280 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed |v......\.....l..|
+00000290 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 |s..Cw.......@.a.|
+000002a0 4c 72 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 |Lr+...F..M...>..|
+000002b0 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 |.B...=.`.\!.;...|
+000002c0 16 03 01 00 aa 0c 00 00 a6 03 00 1d 20 99 c4 bc |............ ...|
+000002d0 cb 82 39 73 e7 54 86 b6 36 ae 7a 82 4e 4a fc 6a |..9s.T..6.z.NJ.j|
+000002e0 19 ed 81 7b 53 03 2f 90 92 de 2a 84 65 00 80 01 |...{S./...*.e...|
+000002f0 4d 05 a7 5b ac 30 c4 47 68 1b 27 ce f9 9b bd 31 |M..[.0.Gh.'....1|
+00000300 08 90 21 16 c9 20 3c 72 da e4 8b ce 6b d5 d6 47 |..!.. <r....k..G|
+00000310 6d 8f 11 f1 36 7e 25 b0 5f 21 59 0c 1d 3b ec ae |m...6~%._!Y..;..|
+00000320 30 46 c4 4d 27 c5 31 cf b3 b2 44 88 2f 6f 89 1d |0F.M'.1...D./o..|
+00000330 09 44 1b 5e da 54 6c 3f ab cf 3b 72 e8 46 63 2e |.D.^.Tl?..;r.Fc.|
+00000340 2a 8f d6 a2 d8 83 75 17 08 0e 50 95 18 77 cb c1 |*.....u...P..w..|
+00000350 62 d3 2c b8 6c 26 ec 36 bb 48 54 72 b9 2f de 65 |b.,.l&.6.HTr./.e|
+00000360 e7 c9 c1 49 d7 5c 1f 41 bc f0 1e 14 a1 40 1b 16 |...I.\.A.....@..|
+00000370 03 01 00 04 0e 00 00 00 |........|
+>>> Flow 3 (client to server)
+00000000 16 03 01 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.|
+00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....|
+00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 01 00 01 01 |....._X.;t......|
+00000030 16 03 01 00 30 43 fc 64 73 ed 5b eb ac 0e 09 cf |....0C.ds.[.....|
+00000040 ae 3e 3c 8c 0a ab b5 a9 c0 32 ed 8d ea 71 ed 87 |.><......2...q..|
+00000050 e5 ee d7 0c 9d a4 09 c6 9b 1d b2 86 2f a3 2e 77 |............/..w|
+00000060 aa b2 5c 6f b0 |..\o.|
+>>> Flow 4 (server to client)
+00000000 14 03 01 00 01 01 16 03 01 00 30 c5 aa 36 4d 9a |..........0..6M.|
+00000010 7a e6 ea 66 2e 63 2d 69 9b b4 91 fa fc f1 f7 a5 |z..f.c-i........|
+00000020 19 17 eb da d6 95 d9 95 42 09 4c 54 30 60 c9 00 |........B.LT0`..|
+00000030 d4 a1 9e 25 dd 62 f0 33 29 43 9c |...%.b.3)C.|
+>>> Flow 5 (client to server)
+00000000 17 03 01 00 20 44 84 33 58 99 c7 71 39 e6 fa 89 |.... D.3X..q9...|
+00000010 f9 a2 bd 15 9a 41 2f e7 27 1a 33 e9 89 ce 24 4c |.....A/.'.3...$L|
+00000020 db cf c6 11 15 17 03 01 00 20 e5 5a 7b 6b ea 19 |......... .Z{k..|
+00000030 f1 55 77 54 b6 a0 c0 c6 02 d6 ce 49 b6 93 91 d3 |.UwT.......I....|
+00000040 7f 8a 93 d1 73 8d d6 f6 56 b6 15 03 01 00 20 71 |....s...V..... q|
+00000050 26 23 0c 06 c6 08 13 2d f3 b2 c0 91 f3 11 c4 23 |&#.....-.......#|
+00000060 c3 57 79 eb ff 8b e1 81 12 fb 13 02 26 b1 5b |.Wy.........&.[|
diff --git a/src/crypto/tls/testdata/Client-TLSv10-RSA-RC4 b/src/crypto/tls/testdata/Client-TLSv10-RSA-RC4
new file mode 100644
index 0000000..219462a
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv10-RSA-RC4
@@ -0,0 +1,86 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 01 00 55 02 00 00 51 03 01 73 52 96 88 0a |....U...Q..sR...|
+00000010 35 f9 ca 22 44 32 ec 69 08 b1 4d b3 6b 70 18 92 |5.."D2.i..M.kp..|
+00000020 af 91 bf 82 00 be 1d bf b4 2f 00 20 f3 e2 c8 e0 |........./. ....|
+00000030 5f 1a 7f 0c 69 f4 6b 74 44 39 b1 2a b9 33 8f 32 |_...i.ktD9.*.3.2|
+00000040 50 37 63 15 69 bc 45 d3 db a7 28 09 00 05 00 00 |P7c.i.E...(.....|
+00000050 09 ff 01 00 01 00 00 17 00 00 16 03 01 02 59 0b |..............Y.|
+00000060 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..|
+00000070 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.|
+00000080 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........|
+00000090 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1|
+000000a0 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo|
+000000b0 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000|
+000000c0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000|
+000000d0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go|
+000000e0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..|
+000000f0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........|
+00000100 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...|
+00000110 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R|
+00000120 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....|
+00000130 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.|
+00000140 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..|
+00000150 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.|
+00000160 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.|
+00000170 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C|
+00000180 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......|
+00000190 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......|
+000001a0 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.|
+000001b0 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...|
+000001c0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......|
+000001d0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........|
+000001e0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..|
+000001f0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~|
+00000200 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.|
+00000210 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g|
+00000220 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....|
+00000230 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.|
+00000240 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.|
+00000250 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....|
+00000260 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ |
+00000270 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\|
+00000280 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...|
+00000290 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.|
+000002a0 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`|
+000002b0 84 5c 21 d3 3b e9 fa e7 16 03 01 00 04 0e 00 00 |.\!.;...........|
+000002c0 00 |.|
+>>> Flow 3 (client to server)
+00000000 16 03 01 00 86 10 00 00 82 00 80 b9 65 8d bf a7 |............e...|
+00000010 c8 4b 79 ce 6f cb 8b 13 1c ac b9 7d 66 5e e9 ba |.Ky.o......}f^..|
+00000020 1d 71 4e a9 e9 34 ae f6 64 65 90 3b d8 16 52 a2 |.qN..4..de.;..R.|
+00000030 6f f4 cb 8a 13 74 a2 ee b7 27 69 b4 41 c0 90 68 |o....t...'i.A..h|
+00000040 bc 02 69 e1 c6 48 4f 39 36 30 25 ca 4c 17 ce 83 |..i..HO960%.L...|
+00000050 9e 08 56 e3 05 49 93 9e 2e c4 fb e6 c8 01 f1 0f |..V..I..........|
+00000060 c5 70 0f 08 83 48 e9 48 ef 6e 50 8b 05 7e e5 84 |.p...H.H.nP..~..|
+00000070 25 fa 55 c7 ae 31 02 27 00 ef 3f 98 86 20 12 89 |%.U..1.'..?.. ..|
+00000080 91 59 28 b4 f7 d7 af d2 69 61 35 14 03 01 00 01 |.Y(.....ia5.....|
+00000090 01 16 03 01 00 24 bd d6 29 83 bf 42 06 cf 06 86 |.....$..)..B....|
+000000a0 09 8a 2f 4c 72 d3 98 45 6b 24 2f 58 da 45 a3 9d |../Lr..Ek$/X.E..|
+000000b0 86 7b e0 5e 8f 52 6c ee 97 1a |.{.^.Rl...|
+>>> Flow 4 (server to client)
+00000000 14 03 01 00 01 01 16 03 01 00 24 b2 c6 b8 54 c9 |..........$...T.|
+00000010 8b 16 cb d4 40 54 08 a4 39 f9 88 37 2e d7 e2 f4 |....@T..9..7....|
+00000020 17 26 ec 00 0b d3 36 42 2f 7b 6d 3f 10 e0 6d |.&....6B/{m?..m|
+>>> Flow 5 (client to server)
+00000000 17 03 01 00 1a 75 40 46 0c 9d 5a 40 b9 b8 7c fa |.....u@F..Z@..|.|
+00000010 a3 bf ff 37 2b 30 72 cc a6 5c 8d c9 8a d6 64 15 |...7+0r..\....d.|
+00000020 03 01 00 16 f4 f1 6d 64 0a 21 35 dc c9 de b5 c4 |......md.!5.....|
+00000030 d7 2c 0a 6e 2a e5 90 21 20 cf |.,.n*..! .|
diff --git a/src/crypto/tls/testdata/Client-TLSv11-ECDHE-ECDSA-AES b/src/crypto/tls/testdata/Client-TLSv11-ECDHE-ECDSA-AES
new file mode 100644
index 0000000..cc9dd82
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv11-ECDHE-ECDSA-AES
@@ -0,0 +1,94 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 02 00 5d 02 00 00 59 03 02 7f 08 c0 d7 77 |....]...Y......w|
+00000010 20 72 4a f2 a2 2c 41 99 b0 3e 9f c8 9d ff 9b b5 | rJ..,A..>......|
+00000020 ea 99 73 91 7b 81 51 e2 1a 7e 9b 20 5d 47 a5 63 |..s.{.Q..~. ]G.c|
+00000030 86 cb fe bf 40 8e f9 f8 1c cf 4b cf 8b f2 af 56 |....@.....K....V|
+00000040 94 a3 71 ad 53 ab 30 71 2a 07 f3 a0 c0 09 00 00 |..q.S.0q*.......|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 02 02 0e 0b 00 02 0a 00 02 07 00 02 |................|
+00000070 04 30 82 02 00 30 82 01 62 02 09 00 b8 bf 2d 47 |.0...0..b.....-G|
+00000080 a0 d2 eb f4 30 09 06 07 2a 86 48 ce 3d 04 01 30 |....0...*.H.=..0|
+00000090 45 31 0b 30 09 06 03 55 04 06 13 02 41 55 31 13 |E1.0...U....AU1.|
+000000a0 30 11 06 03 55 04 08 13 0a 53 6f 6d 65 2d 53 74 |0...U....Some-St|
+000000b0 61 74 65 31 21 30 1f 06 03 55 04 0a 13 18 49 6e |ate1!0...U....In|
+000000c0 74 65 72 6e 65 74 20 57 69 64 67 69 74 73 20 50 |ternet Widgits P|
+000000d0 74 79 20 4c 74 64 30 1e 17 0d 31 32 31 31 32 32 |ty Ltd0...121122|
+000000e0 31 35 30 36 33 32 5a 17 0d 32 32 31 31 32 30 31 |150632Z..2211201|
+000000f0 35 30 36 33 32 5a 30 45 31 0b 30 09 06 03 55 04 |50632Z0E1.0...U.|
+00000100 06 13 02 41 55 31 13 30 11 06 03 55 04 08 13 0a |...AU1.0...U....|
+00000110 53 6f 6d 65 2d 53 74 61 74 65 31 21 30 1f 06 03 |Some-State1!0...|
+00000120 55 04 0a 13 18 49 6e 74 65 72 6e 65 74 20 57 69 |U....Internet Wi|
+00000130 64 67 69 74 73 20 50 74 79 20 4c 74 64 30 81 9b |dgits Pty Ltd0..|
+00000140 30 10 06 07 2a 86 48 ce 3d 02 01 06 05 2b 81 04 |0...*.H.=....+..|
+00000150 00 23 03 81 86 00 04 00 c4 a1 ed be 98 f9 0b 48 |.#.............H|
+00000160 73 36 7e c3 16 56 11 22 f2 3d 53 c3 3b 4d 21 3d |s6~..V.".=S.;M!=|
+00000170 cd 6b 75 e6 f6 b0 dc 9a df 26 c1 bc b2 87 f0 72 |.ku......&.....r|
+00000180 32 7c b3 64 2f 1c 90 bc ea 68 23 10 7e fe e3 25 |2|.d/....h#.~..%|
+00000190 c0 48 3a 69 e0 28 6d d3 37 00 ef 04 62 dd 0d a0 |.H:i.(m.7...b...|
+000001a0 9c 70 62 83 d8 81 d3 64 31 aa 9e 97 31 bd 96 b0 |.pb....d1...1...|
+000001b0 68 c0 9b 23 de 76 64 3f 1a 5c 7f e9 12 0e 58 58 |h..#.vd?.\....XX|
+000001c0 b6 5f 70 dd 9b d8 ea d5 d7 f5 d5 cc b9 b6 9f 30 |._p............0|
+000001d0 66 5b 66 9a 20 e2 27 e5 bf fe 3b 30 09 06 07 2a |f[f. .'...;0...*|
+000001e0 86 48 ce 3d 04 01 03 81 8c 00 30 81 88 02 42 01 |.H.=......0...B.|
+000001f0 88 a2 4f eb e2 45 c5 48 7d 1b ac f5 ed 98 9d ae |..O..E.H}.......|
+00000200 47 70 c0 5e 1b b6 2f bd f1 b6 4d b7 61 40 d3 11 |Gp.^../...M.a@..|
+00000210 a2 ce ee 0b 7e 92 7e ff 76 9d c3 3b 7e a5 3f ce |....~.~.v..;~.?.|
+00000220 fa 10 e2 59 ec 47 2d 7c ac da 4e 97 0e 15 a0 6f |...Y.G-|..N....o|
+00000230 d0 02 42 01 4d fc be 67 13 9c 2d 05 0e bd 3f a3 |..B.M..g..-...?.|
+00000240 8c 25 c1 33 13 83 0d 94 06 bb d4 37 7a f6 ec 7a |.%.3.......7z..z|
+00000250 c9 86 2e dd d7 11 69 7f 85 7c 56 de fb 31 78 2b |......i..|V..1x+|
+00000260 e4 c7 78 0d ae cb be 9e 4e 36 24 31 7b 6a 0f 39 |..x.....N6$1{j.9|
+00000270 95 12 07 8f 2a 16 03 02 00 b5 0c 00 00 b1 03 00 |....*...........|
+00000280 1d 20 23 be e0 2b 65 34 a4 91 3c 4e 3c 84 51 98 |. #..+e4..<N<.Q.|
+00000290 07 07 26 42 48 eb ff fd dc d3 e7 dd 1c 2d d0 aa |..&BH........-..|
+000002a0 98 18 00 8b 30 81 88 02 42 01 34 ed 12 83 dd a8 |....0...B.4.....|
+000002b0 dc 4c 6a bd 2c e0 fe ce af 92 b7 86 96 b3 19 92 |.Lj.,...........|
+000002c0 cc 28 56 12 bb 74 b5 9a 3a 07 0a b0 ef f1 3b 42 |.(V..t..:.....;B|
+000002d0 b2 c4 4a 44 d5 4b f2 5b 5a eb 43 21 23 4c 39 da |..JD.K.[Z.C!#L9.|
+000002e0 99 3f c0 0f 23 b3 4f 58 43 0a c7 02 42 01 2b a8 |.?..#.OXC...B.+.|
+000002f0 96 0f 04 3e c0 55 db eb 73 4d 7e 75 4b 73 fa 4d |...>.U..sM~uKs.M|
+00000300 62 de 29 b8 0e 59 68 0a 14 a5 75 31 4f 9d db 64 |b.)..Yh...u1O..d|
+00000310 d0 b4 f4 78 ae 30 99 2f fb 33 ea 1a 21 46 33 57 |...x.0./.3..!F3W|
+00000320 59 00 5d 84 4b b3 fe a1 60 3d ae 71 af b9 ea 16 |Y.].K...`=.q....|
+00000330 03 02 00 04 0e 00 00 00 |........|
+>>> Flow 3 (client to server)
+00000000 16 03 02 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.|
+00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....|
+00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 02 00 01 01 |....._X.;t......|
+00000030 16 03 02 00 40 00 00 00 00 00 00 00 00 00 00 00 |....@...........|
+00000040 00 00 00 00 00 ef 00 72 e6 a4 f6 8b 7f 98 ef e0 |.......r........|
+00000050 15 01 2c fc 31 7a e7 ba fa 07 ec 0e c1 4b 69 39 |..,.1z.......Ki9|
+00000060 89 97 fa a8 8b bf 3b 7f 1a 00 32 26 72 64 19 1c |......;...2&rd..|
+00000070 0c 2f 4b ba 78 |./K.x|
+>>> Flow 4 (server to client)
+00000000 14 03 02 00 01 01 16 03 02 00 40 d7 89 58 0a f0 |..........@..X..|
+00000010 bd c1 a0 bb b5 f0 b4 1a 0b 08 25 e8 5a 73 04 04 |..........%.Zs..|
+00000020 01 99 65 e1 9c 80 24 e5 80 a8 a8 a1 29 bd af 99 |..e...$.....)...|
+00000030 06 4d 9a 48 59 95 0a 0e bc 72 7d 90 cb 62 5a 2d |.M.HY....r}..bZ-|
+00000040 7b 19 53 83 10 47 55 8b c3 e0 84 |{.S..GU....|
+>>> Flow 5 (client to server)
+00000000 17 03 02 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
+00000010 00 00 00 00 00 5d d8 f2 5e 83 a1 39 cb 57 a9 7f |.....]..^..9.W..|
+00000020 93 35 72 a3 ce 15 f6 4c 5c 06 8f d1 f5 77 7c ca |.5r....L\....w|.|
+00000030 a9 59 5f e9 ce 15 03 02 00 30 00 00 00 00 00 00 |.Y_......0......|
+00000040 00 00 00 00 00 00 00 00 00 00 2b 0a 90 aa 87 8f |..........+.....|
+00000050 ff 26 85 22 26 26 bd 0e a3 40 88 e1 72 21 76 69 |.&."&&...@..r!vi|
+00000060 4c 69 22 2c 6c 72 a3 64 6e 61 |Li",lr.dna|
diff --git a/src/crypto/tls/testdata/Client-TLSv11-ECDHE-RSA-AES b/src/crypto/tls/testdata/Client-TLSv11-ECDHE-RSA-AES
new file mode 100644
index 0000000..5bde683
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv11-ECDHE-RSA-AES
@@ -0,0 +1,98 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 02 00 5d 02 00 00 59 03 02 a4 97 26 eb 45 |....]...Y....&.E|
+00000010 35 28 1a 9a 6b 3e b3 e6 c0 9f 4a c7 6f 57 70 9a |5(..k>....J.oWp.|
+00000020 fe 3a 1a a5 c3 05 d3 50 45 43 ee 20 3e 34 5b ef |.:.....PEC. >4[.|
+00000030 64 f3 f8 40 e4 69 7d 3a 46 db 4e 83 6c ff 68 2a |d..@.i}:F.N.l.h*|
+00000040 f9 f4 45 5e 7c 25 5f a0 d5 89 7e 83 c0 13 00 00 |..E^|%_...~.....|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 02 02 59 0b 00 02 55 00 02 52 00 02 |......Y...U..R..|
+00000070 4f 30 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 |O0..K0..........|
+00000080 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 |....?.[..0...*.H|
+00000090 86 f7 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 |........0.1.0...|
+000000a0 55 04 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 |U....Go1.0...U..|
+000000b0 13 07 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 |..Go Root0...160|
+000000c0 31 30 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 |101000000Z..2501|
+000000d0 30 31 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 |01000000Z0.1.0..|
+000000e0 03 55 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 |.U....Go1.0...U.|
+000000f0 03 13 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 |...Go0..0...*.H.|
+00000100 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 |...........0....|
+00000110 81 00 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab |...F}...'.H..(!.|
+00000120 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d |~...]..RE.z6G...|
+00000130 92 42 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd |.B[.....y.@.Om..|
+00000140 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a |+.....g....."8.J|
+00000150 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 |.ts+.4......t{.X|
+00000160 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c |.la<..A..++$#w[.|
+00000170 3b bd 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 |;.u]. T..c...$..|
+00000180 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 |..P....C...ub...|
+00000190 52 d7 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 |R.........0..0..|
+000001a0 03 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 |.U...........0..|
+000001b0 03 55 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 |.U.%..0...+.....|
+000001c0 03 01 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 |....+.......0...|
+000001d0 55 1d 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d |U.......0.0...U.|
+000001e0 0e 04 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d |.........CC>I..m|
+000001f0 b6 80 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 |....`0...U.#..0.|
+00000200 80 10 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab |..H.IM.~.1......|
+00000210 6e 7b 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 |n{0...U....0...e|
+00000220 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 |xample.golang0..|
+00000230 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 |.*.H............|
+00000240 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed |.0.@+[P.a...SX..|
+00000250 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 |.(.X..8....1Z..f|
+00000260 3d 43 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a |=C.-...... d8.$:|
+00000270 00 bc cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 |....}.@ ._...a..|
+00000280 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed |v......\.....l..|
+00000290 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 |s..Cw.......@.a.|
+000002a0 4c 72 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 |Lr+...F..M...>..|
+000002b0 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 |.B...=.`.\!.;...|
+000002c0 16 03 02 00 aa 0c 00 00 a6 03 00 1d 20 46 15 e3 |............ F..|
+000002d0 8f f8 ab 26 88 9c 0f 28 30 d6 58 96 77 55 77 62 |...&...(0.X.wUwb|
+000002e0 26 a1 64 98 df b3 cc 15 48 fc 90 2b 30 00 80 7d |&.d.....H..+0..}|
+000002f0 e3 98 42 4a 27 c1 08 29 93 22 0e 7e 53 4e b7 03 |..BJ'..).".~SN..|
+00000300 ca c1 67 34 0e 8d c0 94 cb dd 38 34 f4 d8 0e 10 |..g4......84....|
+00000310 68 bb e7 01 3e 4b 22 27 bb 43 e2 cf da e2 6c 49 |h...>K"'.C....lI|
+00000320 d7 31 2f 31 04 b2 7a 8f 86 35 5e f8 16 3f 80 b7 |.1/1..z..5^..?..|
+00000330 1e 06 e1 3e 57 89 24 d7 25 65 8b 13 84 27 b6 eb |...>W.$.%e...'..|
+00000340 e9 64 bd 69 22 17 bc 53 57 2c 78 b3 1d 01 97 65 |.d.i"..SW,x....e|
+00000350 d9 0e b7 a7 bf d3 86 d3 a4 24 07 0f 16 0f fb 3a |.........$.....:|
+00000360 e8 35 ce 80 79 93 2f 26 75 36 fa ad 99 d3 88 16 |.5..y./&u6......|
+00000370 03 02 00 04 0e 00 00 00 |........|
+>>> Flow 3 (client to server)
+00000000 16 03 02 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.|
+00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....|
+00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 02 00 01 01 |....._X.;t......|
+00000030 16 03 02 00 40 00 00 00 00 00 00 00 00 00 00 00 |....@...........|
+00000040 00 00 00 00 00 89 35 3f 26 26 9c d0 87 70 65 56 |......5?&&...peV|
+00000050 b4 32 f9 9e 3f 1f 20 6f 8d 71 eb 6c 45 15 a0 f4 |.2..?. o.q.lE...|
+00000060 ff 02 60 8c 01 1a b7 2b 0d 1e 56 e7 be 06 ac 16 |..`....+..V.....|
+00000070 74 73 be 0a 95 |ts...|
+>>> Flow 4 (server to client)
+00000000 14 03 02 00 01 01 16 03 02 00 40 04 35 19 05 8e |..........@.5...|
+00000010 c6 68 3e 37 75 5f 5d bb 41 58 8b a7 b3 cf 97 28 |.h>7u_].AX.....(|
+00000020 60 ad b7 be db b1 31 b9 9c f5 d2 57 49 17 7c f6 |`.....1....WI.|.|
+00000030 de 60 24 87 cb c5 51 2d 7a 8d f1 4b e5 7f 2d c7 |.`$...Q-z..K..-.|
+00000040 7f f4 e1 94 d9 6f 5c 2a 68 f0 24 |.....o\*h.$|
+>>> Flow 5 (client to server)
+00000000 17 03 02 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
+00000010 00 00 00 00 00 a2 ba 70 25 b0 a9 b0 ea 87 7e 6b |.......p%.....~k|
+00000020 ef 89 e3 10 f4 98 da 12 cf bc 20 f6 18 76 c7 ad |.......... ..v..|
+00000030 b7 12 1e 7b 12 15 03 02 00 30 00 00 00 00 00 00 |...{.....0......|
+00000040 00 00 00 00 00 00 00 00 00 00 91 33 9b b8 76 89 |...........3..v.|
+00000050 39 ef 4b 3f d1 09 40 e4 68 6f 30 35 d9 a9 82 c1 |9.K?..@.ho05....|
+00000060 9d c6 c2 a5 dc cb 1d 43 83 0a |.......C..|
diff --git a/src/crypto/tls/testdata/Client-TLSv11-Ed25519 b/src/crypto/tls/testdata/Client-TLSv11-Ed25519
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv11-Ed25519
diff --git a/src/crypto/tls/testdata/Client-TLSv11-RSA-RC4 b/src/crypto/tls/testdata/Client-TLSv11-RSA-RC4
new file mode 100644
index 0000000..addd480
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv11-RSA-RC4
@@ -0,0 +1,86 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 02 00 55 02 00 00 51 03 02 66 66 1b 2f 55 |....U...Q..ff./U|
+00000010 a4 db ad db 42 88 e0 12 12 36 60 41 32 ca 27 0f |....B....6`A2.'.|
+00000020 36 22 d1 0b 4e 0e ba df 44 71 9f 20 7a fa f5 a7 |6"..N...Dq. z...|
+00000030 ba ca 0a 9a be c5 b7 a8 98 a7 d9 0f d8 24 d4 cf |.............$..|
+00000040 ab f5 13 84 03 45 57 ab 89 6d 43 42 00 05 00 00 |.....EW..mCB....|
+00000050 09 ff 01 00 01 00 00 17 00 00 16 03 02 02 59 0b |..............Y.|
+00000060 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..|
+00000070 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.|
+00000080 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........|
+00000090 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1|
+000000a0 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo|
+000000b0 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000|
+000000c0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000|
+000000d0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go|
+000000e0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..|
+000000f0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........|
+00000100 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...|
+00000110 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R|
+00000120 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....|
+00000130 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.|
+00000140 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..|
+00000150 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.|
+00000160 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.|
+00000170 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C|
+00000180 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......|
+00000190 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......|
+000001a0 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.|
+000001b0 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...|
+000001c0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......|
+000001d0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........|
+000001e0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..|
+000001f0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~|
+00000200 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.|
+00000210 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g|
+00000220 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....|
+00000230 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.|
+00000240 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.|
+00000250 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....|
+00000260 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ |
+00000270 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\|
+00000280 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...|
+00000290 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.|
+000002a0 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`|
+000002b0 84 5c 21 d3 3b e9 fa e7 16 03 02 00 04 0e 00 00 |.\!.;...........|
+000002c0 00 |.|
+>>> Flow 3 (client to server)
+00000000 16 03 02 00 86 10 00 00 82 00 80 b9 65 8d bf a7 |............e...|
+00000010 c8 4b 79 ce 6f cb 8b 13 1c ac b9 7d 66 5e e9 ba |.Ky.o......}f^..|
+00000020 1d 71 4e a9 e9 34 ae f6 64 65 90 3b d8 16 52 a2 |.qN..4..de.;..R.|
+00000030 6f f4 cb 8a 13 74 a2 ee b7 27 69 b4 41 c0 90 68 |o....t...'i.A..h|
+00000040 bc 02 69 e1 c6 48 4f 39 36 30 25 ca 4c 17 ce 83 |..i..HO960%.L...|
+00000050 9e 08 56 e3 05 49 93 9e 2e c4 fb e6 c8 01 f1 0f |..V..I..........|
+00000060 c5 70 0f 08 83 48 e9 48 ef 6e 50 8b 05 7e e5 84 |.p...H.H.nP..~..|
+00000070 25 fa 55 c7 ae 31 02 27 00 ef 3f 98 86 20 12 89 |%.U..1.'..?.. ..|
+00000080 91 59 28 b4 f7 d7 af d2 69 61 35 14 03 02 00 01 |.Y(.....ia5.....|
+00000090 01 16 03 02 00 24 a9 03 2f 22 ef b7 e8 78 38 a9 |.....$../"...x8.|
+000000a0 12 07 27 e3 bf 3b a9 50 5a 83 9c 6b 83 06 07 4d |..'..;.PZ..k...M|
+000000b0 38 33 12 dc 21 aa 95 3c f0 cc |83..!..<..|
+>>> Flow 4 (server to client)
+00000000 14 03 02 00 01 01 16 03 02 00 24 df db 82 41 b6 |..........$...A.|
+00000010 3f 2d d5 0f d1 7e ca 3c 73 e0 31 58 ae f5 08 fd |?-...~.<s.1X....|
+00000020 08 ef 3b cc 45 7b 21 74 ac c9 fc 07 22 6a 5e |..;.E{!t...."j^|
+>>> Flow 5 (client to server)
+00000000 17 03 02 00 1a b6 12 91 b4 74 7f 92 b5 fd 7e 8c |.........t....~.|
+00000010 15 1d 51 f9 e1 a3 d6 74 6e b2 07 c2 f0 a8 11 15 |..Q....tn.......|
+00000020 03 02 00 16 ca 4b cb cf 88 2d 48 a7 27 29 19 ef |.....K...-H.')..|
+00000030 eb 4e 58 ac 57 e2 ed af e2 a0 |.NX.W.....|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-AES128-GCM-SHA256 b/src/crypto/tls/testdata/Client-TLSv12-AES128-GCM-SHA256
new file mode 100644
index 0000000..22cff45
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-AES128-GCM-SHA256
@@ -0,0 +1,88 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 55 02 00 00 51 03 03 9f d7 f5 00 f6 |....U...Q.......|
+00000010 a1 c5 37 e8 2b 2e 66 42 54 c6 67 29 b6 ad bb 5f |..7.+.fBT.g)..._|
+00000020 23 b7 bb 56 2e 8a 15 a9 7a ce a2 20 47 be 36 13 |#..V....z.. G.6.|
+00000030 31 d7 51 a6 ec d1 67 e7 e3 8c fb e2 f5 d2 61 e6 |1.Q...g.......a.|
+00000040 4e 11 0c 03 b0 5e b1 ae e7 8c 61 c8 00 9c 00 00 |N....^....a.....|
+00000050 09 ff 01 00 01 00 00 17 00 00 16 03 03 02 59 0b |..............Y.|
+00000060 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..|
+00000070 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.|
+00000080 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........|
+00000090 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1|
+000000a0 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo|
+000000b0 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000|
+000000c0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000|
+000000d0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go|
+000000e0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..|
+000000f0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........|
+00000100 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...|
+00000110 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R|
+00000120 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....|
+00000130 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.|
+00000140 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..|
+00000150 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.|
+00000160 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.|
+00000170 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C|
+00000180 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......|
+00000190 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......|
+000001a0 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.|
+000001b0 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...|
+000001c0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......|
+000001d0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........|
+000001e0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..|
+000001f0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~|
+00000200 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.|
+00000210 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g|
+00000220 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....|
+00000230 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.|
+00000240 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.|
+00000250 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....|
+00000260 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ |
+00000270 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\|
+00000280 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...|
+00000290 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.|
+000002a0 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`|
+000002b0 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e 00 00 |.\!.;...........|
+000002c0 00 |.|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 86 10 00 00 82 00 80 b9 65 8d bf a7 |............e...|
+00000010 c8 4b 79 ce 6f cb 8b 13 1c ac b9 7d 66 5e e9 ba |.Ky.o......}f^..|
+00000020 1d 71 4e a9 e9 34 ae f6 64 65 90 3b d8 16 52 a2 |.qN..4..de.;..R.|
+00000030 6f f4 cb 8a 13 74 a2 ee b7 27 69 b4 41 c0 90 68 |o....t...'i.A..h|
+00000040 bc 02 69 e1 c6 48 4f 39 36 30 25 ca 4c 17 ce 83 |..i..HO960%.L...|
+00000050 9e 08 56 e3 05 49 93 9e 2e c4 fb e6 c8 01 f1 0f |..V..I..........|
+00000060 c5 70 0f 08 83 48 e9 48 ef 6e 50 8b 05 7e e5 84 |.p...H.H.nP..~..|
+00000070 25 fa 55 c7 ae 31 02 27 00 ef 3f 98 86 20 12 89 |%.U..1.'..?.. ..|
+00000080 91 59 28 b4 f7 d7 af d2 69 61 35 14 03 03 00 01 |.Y(.....ia5.....|
+00000090 01 16 03 03 00 28 00 00 00 00 00 00 00 00 10 d7 |.....(..........|
+000000a0 17 1b 75 0d 79 ed 8d bc fb 1c c4 d6 35 44 f0 ed |..u.y.......5D..|
+000000b0 ed 03 24 02 df 44 9b 70 df 4b 51 19 e6 72 |..$..D.p.KQ..r|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 28 68 9f 7c f3 ac |..........(h.|..|
+00000010 31 93 86 d0 b7 0a 68 55 7a 93 00 4e c3 d6 dc 60 |1.....hUz..N...`|
+00000020 d1 c5 4a 04 53 da 27 ed c1 0e 14 41 a5 27 f1 d5 |..J.S.'....A.'..|
+00000030 2e 4a 43 |.JC|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 e7 e6 3e |...............>|
+00000010 e9 04 96 38 0c d4 e1 46 c6 d2 2a 1b b0 b3 11 9b |...8...F..*.....|
+00000020 6d f4 81 15 03 03 00 1a 00 00 00 00 00 00 00 02 |m...............|
+00000030 a3 60 58 f2 f6 60 95 f3 c4 e1 95 23 22 52 55 63 |.`X..`.....#"RUc|
+00000040 b9 75 |.u|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-AES128-SHA256 b/src/crypto/tls/testdata/Client-TLSv12-AES128-SHA256
new file mode 100644
index 0000000..ee6ab62
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-AES128-SHA256
@@ -0,0 +1,97 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 55 02 00 00 51 03 03 b3 4d 83 66 45 |....U...Q...M.fE|
+00000010 e7 32 1f e5 99 ea a0 90 c7 12 91 2b 25 82 ba ca |.2.........+%...|
+00000020 01 c1 a9 22 1f 1d 06 62 e1 37 6a 20 a4 87 9b c0 |..."...b.7j ....|
+00000030 7f 86 ff c1 0f 49 56 fe c4 49 f7 fb e5 97 23 dc |.....IV..I....#.|
+00000040 fc 51 80 75 f7 03 52 5e 86 80 97 0f 00 3c 00 00 |.Q.u..R^.....<..|
+00000050 09 ff 01 00 01 00 00 17 00 00 16 03 03 02 59 0b |..............Y.|
+00000060 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..|
+00000070 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.|
+00000080 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........|
+00000090 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1|
+000000a0 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo|
+000000b0 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000|
+000000c0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000|
+000000d0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go|
+000000e0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..|
+000000f0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........|
+00000100 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...|
+00000110 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R|
+00000120 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....|
+00000130 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.|
+00000140 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..|
+00000150 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.|
+00000160 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.|
+00000170 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C|
+00000180 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......|
+00000190 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......|
+000001a0 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.|
+000001b0 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...|
+000001c0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......|
+000001d0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........|
+000001e0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..|
+000001f0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~|
+00000200 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.|
+00000210 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g|
+00000220 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....|
+00000230 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.|
+00000240 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.|
+00000250 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....|
+00000260 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ |
+00000270 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\|
+00000280 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...|
+00000290 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.|
+000002a0 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`|
+000002b0 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e 00 00 |.\!.;...........|
+000002c0 00 |.|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 86 10 00 00 82 00 80 b9 65 8d bf a7 |............e...|
+00000010 c8 4b 79 ce 6f cb 8b 13 1c ac b9 7d 66 5e e9 ba |.Ky.o......}f^..|
+00000020 1d 71 4e a9 e9 34 ae f6 64 65 90 3b d8 16 52 a2 |.qN..4..de.;..R.|
+00000030 6f f4 cb 8a 13 74 a2 ee b7 27 69 b4 41 c0 90 68 |o....t...'i.A..h|
+00000040 bc 02 69 e1 c6 48 4f 39 36 30 25 ca 4c 17 ce 83 |..i..HO960%.L...|
+00000050 9e 08 56 e3 05 49 93 9e 2e c4 fb e6 c8 01 f1 0f |..V..I..........|
+00000060 c5 70 0f 08 83 48 e9 48 ef 6e 50 8b 05 7e e5 84 |.p...H.H.nP..~..|
+00000070 25 fa 55 c7 ae 31 02 27 00 ef 3f 98 86 20 12 89 |%.U..1.'..?.. ..|
+00000080 91 59 28 b4 f7 d7 af d2 69 61 35 14 03 03 00 01 |.Y(.....ia5.....|
+00000090 01 16 03 03 00 50 00 00 00 00 00 00 00 00 00 00 |.....P..........|
+000000a0 00 00 00 00 00 00 ad 28 77 9e 77 a8 54 2d df fe |.......(w.w.T-..|
+000000b0 b3 d1 3a 88 49 e8 ee 86 a1 46 d8 46 26 98 88 f3 |..:.I....F.F&...|
+000000c0 eb e1 bd 26 38 26 78 53 90 47 bf 76 4b 29 a6 db |...&8&xS.G.vK)..|
+000000d0 e5 c5 5d aa e7 cc d1 ad ee 3f 27 72 a3 a7 06 8b |..]......?'r....|
+000000e0 1a da 35 1a 57 4a |..5.WJ|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 50 b6 40 f7 ea 59 |..........P.@..Y|
+00000010 29 60 1f b0 00 78 db 1b 29 4e 4f 7d 02 12 a9 f9 |)`...x..)NO}....|
+00000020 98 fb 89 9e 08 8d 55 91 f3 d1 b3 58 73 ba 58 12 |......U....Xs.X.|
+00000030 2e b3 3a da 3a 96 76 63 5c 89 7b d5 64 9a 41 3f |..:.:.vc\.{.d.A?|
+00000040 f9 55 4c 19 d7 08 a1 b2 c4 cc f0 6a e3 7d ab 6b |.UL........j.}.k|
+00000050 26 cf 80 10 a9 c6 1a d6 2d 0e 77 |&.......-.w|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 40 00 00 00 00 00 00 00 00 00 00 00 |....@...........|
+00000010 00 00 00 00 00 04 1d bb 53 4a 08 73 26 c2 33 d5 |........SJ.s&.3.|
+00000020 95 2c cf aa 74 1b 58 27 11 99 f9 67 e7 93 56 72 |.,..t.X'...g..Vr|
+00000030 a5 0b 96 9e ea 32 b2 c8 c3 2e 47 b4 91 81 47 86 |.....2....G...G.|
+00000040 f2 31 fd 7a f8 15 03 03 00 40 00 00 00 00 00 00 |.1.z.....@......|
+00000050 00 00 00 00 00 00 00 00 00 00 55 3a e3 6d aa 75 |..........U:.m.u|
+00000060 31 f5 92 6c ae f8 8d fc f4 6e 20 de a6 66 7c 97 |1..l.....n ..f|.|
+00000070 51 e5 c7 8b 4a 1d 0e e8 38 f5 9f 0a 6b b6 63 c1 |Q...J...8...k.c.|
+00000080 85 97 c6 3c d2 79 b5 a3 42 1d |...<.y..B.|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-AES256-GCM-SHA384 b/src/crypto/tls/testdata/Client-TLSv12-AES256-GCM-SHA384
new file mode 100644
index 0000000..0166f1a
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-AES256-GCM-SHA384
@@ -0,0 +1,88 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 55 02 00 00 51 03 03 38 33 33 fb 62 |....U...Q..833.b|
+00000010 ff ce 69 f1 cd 8c fe 50 05 bd 1e ce f9 ad a5 e6 |..i....P........|
+00000020 ee d7 71 82 97 25 04 2a cd aa c5 20 13 68 7a d0 |..q..%.*... .hz.|
+00000030 0f cc 61 05 63 31 cc 47 24 1c 52 81 8d cc d3 d1 |..a.c1.G$.R.....|
+00000040 d1 53 97 70 e9 f1 98 3b 00 2d df ab 00 9d 00 00 |.S.p...;.-......|
+00000050 09 ff 01 00 01 00 00 17 00 00 16 03 03 02 59 0b |..............Y.|
+00000060 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..|
+00000070 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.|
+00000080 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........|
+00000090 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1|
+000000a0 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo|
+000000b0 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000|
+000000c0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000|
+000000d0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go|
+000000e0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..|
+000000f0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........|
+00000100 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...|
+00000110 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R|
+00000120 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....|
+00000130 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.|
+00000140 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..|
+00000150 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.|
+00000160 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.|
+00000170 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C|
+00000180 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......|
+00000190 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......|
+000001a0 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.|
+000001b0 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...|
+000001c0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......|
+000001d0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........|
+000001e0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..|
+000001f0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~|
+00000200 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.|
+00000210 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g|
+00000220 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....|
+00000230 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.|
+00000240 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.|
+00000250 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....|
+00000260 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ |
+00000270 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\|
+00000280 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...|
+00000290 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.|
+000002a0 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`|
+000002b0 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e 00 00 |.\!.;...........|
+000002c0 00 |.|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 86 10 00 00 82 00 80 b9 65 8d bf a7 |............e...|
+00000010 c8 4b 79 ce 6f cb 8b 13 1c ac b9 7d 66 5e e9 ba |.Ky.o......}f^..|
+00000020 1d 71 4e a9 e9 34 ae f6 64 65 90 3b d8 16 52 a2 |.qN..4..de.;..R.|
+00000030 6f f4 cb 8a 13 74 a2 ee b7 27 69 b4 41 c0 90 68 |o....t...'i.A..h|
+00000040 bc 02 69 e1 c6 48 4f 39 36 30 25 ca 4c 17 ce 83 |..i..HO960%.L...|
+00000050 9e 08 56 e3 05 49 93 9e 2e c4 fb e6 c8 01 f1 0f |..V..I..........|
+00000060 c5 70 0f 08 83 48 e9 48 ef 6e 50 8b 05 7e e5 84 |.p...H.H.nP..~..|
+00000070 25 fa 55 c7 ae 31 02 27 00 ef 3f 98 86 20 12 89 |%.U..1.'..?.. ..|
+00000080 91 59 28 b4 f7 d7 af d2 69 61 35 14 03 03 00 01 |.Y(.....ia5.....|
+00000090 01 16 03 03 00 28 00 00 00 00 00 00 00 00 2b 4c |.....(........+L|
+000000a0 62 77 65 ac 19 53 aa 52 8e 3d 92 5b e1 45 c6 90 |bwe..S.R.=.[.E..|
+000000b0 bf 01 bb e3 9c d2 6a ed bf e6 8c 53 3d 58 |......j....S=X|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 28 77 7f 9b a4 ea |..........(w....|
+00000010 30 03 8f fd 22 37 60 78 db b1 1a 37 bc 2d 50 ad |0..."7`x...7.-P.|
+00000020 40 b4 a6 8f f8 0c e8 ab 24 54 82 12 75 be 0b 8c |@.......$T..u...|
+00000030 9f 35 e2 |.5.|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 01 66 69 |..............fi|
+00000010 ac a4 9d 4f d2 59 01 4e d6 04 98 e5 c8 83 b3 cb |...O.Y.N........|
+00000020 36 4d cf 15 03 03 00 1a 00 00 00 00 00 00 00 02 |6M..............|
+00000030 17 80 89 ac 0b d6 00 8c 1d ae b2 c2 46 42 69 82 |............FBi.|
+00000040 da ac |..|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ALPN b/src/crypto/tls/testdata/Client-TLSv12-ALPN
new file mode 100644
index 0000000..4ae1fe9
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ALPN
@@ -0,0 +1,93 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 01 12 01 00 01 0e 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 93 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 10 00 10 00 0e 06 70 |...............p|
+000000d0 72 6f 74 6f 32 06 70 72 6f 74 6f 31 00 12 00 00 |roto2.proto1....|
+000000e0 00 2b 00 09 08 03 04 03 03 03 02 03 01 00 33 00 |.+............3.|
+000000f0 26 00 24 00 1d 00 20 2f e5 7d a3 47 cd 62 43 15 |&.$... /.}.G.bC.|
+00000100 28 da ac 5f bb 29 07 30 ff f6 84 af c4 cf c2 ed |(.._.).0........|
+00000110 90 99 5f 58 cb 3b 74 |.._X.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 6a 02 00 00 66 03 03 a8 8a 7d 2c f6 |....j...f....},.|
+00000010 d0 44 0a 7b 16 26 e5 aa 6e 4b 78 7c ff 7f 07 86 |.D.{.&..nKx|....|
+00000020 48 cc 3a dd 73 95 94 d2 75 d8 87 20 6d 0b 3a a3 |H.:.s...u.. m.:.|
+00000030 71 b9 50 4e c7 ad 33 04 8a 9c d8 71 48 93 ec ae |q.PN..3....qH...|
+00000040 db ad 5f 79 d5 7c 65 33 37 06 73 0e cc a8 00 00 |.._y.|e37.s.....|
+00000050 1e ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 10 |................|
+00000060 00 09 00 07 06 70 72 6f 74 6f 31 00 17 00 00 16 |.....proto1.....|
+00000070 03 03 02 59 0b 00 02 55 00 02 52 00 02 4f 30 82 |...Y...U..R..O0.|
+00000080 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 |.K0.............|
+00000090 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d |.?.[..0...*.H...|
+000000a0 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 55 04 0a |.....0.1.0...U..|
+000000b0 13 02 47 6f 31 10 30 0e 06 03 55 04 03 13 07 47 |..Go1.0...U....G|
+000000c0 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 |o Root0...160101|
+000000d0 30 30 30 30 30 30 5a 17 0d 32 35 30 31 30 31 30 |000000Z..2501010|
+000000e0 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 |00000Z0.1.0...U.|
+000000f0 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 03 13 02 |...Go1.0...U....|
+00000100 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 |Go0..0...*.H....|
+00000110 01 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 db |........0.......|
+00000120 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 |F}...'.H..(!.~..|
+00000130 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b |.]..RE.z6G....B[|
+00000140 c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b |.....y.@.Om..+..|
+00000150 c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 |...g....."8.J.ts|
+00000160 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 |+.4......t{.X.la|
+00000170 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 |<..A..++$#w[.;.u|
+00000180 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 |]. T..c...$....P|
+00000190 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 |....C...ub...R..|
+000001a0 03 01 00 01 a3 81 93 30 81 90 30 0e 06 03 55 1d |.......0..0...U.|
+000001b0 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d |..........0...U.|
+000001c0 25 04 16 30 14 06 08 2b 06 01 05 05 07 03 01 06 |%..0...+........|
+000001d0 08 2b 06 01 05 05 07 03 02 30 0c 06 03 55 1d 13 |.+.......0...U..|
+000001e0 01 01 ff 04 02 30 00 30 19 06 03 55 1d 0e 04 12 |.....0.0...U....|
+000001f0 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 |......CC>I..m...|
+00000200 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 80 10 48 |.`0...U.#..0...H|
+00000210 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 |.IM.~.1......n{0|
+00000220 19 06 03 55 1d 11 04 12 30 10 82 0e 65 78 61 6d |...U....0...exam|
+00000230 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 |ple.golang0...*.|
+00000240 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc |H.............0.|
+00000250 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 |@+[P.a...SX...(.|
+00000260 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 |X..8....1Z..f=C.|
+00000270 2d d9 0b f2 97 df d3 20 64 38 92 24 3a 00 bc cf |-...... d8.$:...|
+00000280 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 |.}.@ ._...a..v..|
+00000290 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 |....\.....l..s..|
+000002a0 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b |Cw.......@.a.Lr+|
+000002b0 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 |...F..M...>...B.|
+000002c0 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 |..=.`.\!.;......|
+000002d0 00 ac 0c 00 00 a8 03 00 1d 20 fe 7c 30 da b3 7e |......... .|0..~|
+000002e0 b9 f5 74 9f c2 5a 3b 2e a4 c4 fe 98 50 1d 14 ea |..t..Z;.....P...|
+000002f0 31 f0 ff d9 90 88 42 77 f6 18 08 04 00 80 70 97 |1.....Bw......p.|
+00000300 1d e4 fb 40 de b5 9a cc 6a 63 63 86 b4 91 55 c4 |...@....jcc...U.|
+00000310 ad b7 2f a2 8f 4f 28 22 86 df ec 2f 7c d2 83 b7 |../..O(".../|...|
+00000320 28 9c 22 e7 73 74 51 f0 1e 20 50 d5 f1 3c 15 65 |(.".stQ.. P..<.e|
+00000330 d9 cb 7f 4e 82 11 41 f8 c6 2a 23 ed b5 b4 cf 2d |...N..A..*#....-|
+00000340 02 e2 8e 8b e8 88 bb 8c 63 1e 9c 37 44 c3 89 cf |........c..7D...|
+00000350 ea 68 4b 81 73 0e 57 82 c9 dc ab f3 0c 63 ce f6 |.hK.s.W......c..|
+00000360 c3 3a a3 da df be a7 10 4a 27 e1 bd b3 88 47 a2 |.:......J'....G.|
+00000370 0d 02 03 17 3c 6c 7f 6e 04 26 75 1c a0 3e 16 03 |....<l.n.&u..>..|
+00000380 03 00 04 0e 00 00 00 |.......|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.|
+00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....|
+00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 03 00 01 01 |....._X.;t......|
+00000030 16 03 03 00 20 a0 68 d5 5a 22 13 42 16 b2 13 f4 |.... .h.Z".B....|
+00000040 99 a1 5c f7 38 22 a1 8b e0 6b c2 7e f9 e5 a0 ef |..\.8"...k.~....|
+00000050 79 ce 5a 74 d1 |y.Zt.|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 20 dd a3 ff 04 65 |.......... ....e|
+00000010 4b 49 77 b6 88 ab f3 31 07 3d 2e 30 ec b3 e1 1f |KIw....1.=.0....|
+00000020 18 0f ef a9 2d 32 1f e6 b9 71 3f |....-2...q?|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 16 54 7a 06 57 6b 66 e0 93 f8 f5 7a |.....Tz.Wkf....z|
+00000010 ab 1a d1 f4 53 91 47 e8 5c 11 15 15 03 03 00 12 |....S.G.\.......|
+00000020 42 b6 c5 6f 63 b6 72 8b 85 c3 ba c5 e3 38 8f e2 |B..oc.r......8..|
+00000030 42 dd |B.|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ALPN-NoMatch b/src/crypto/tls/testdata/Client-TLSv12-ALPN-NoMatch
new file mode 100644
index 0000000..62e7d11
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ALPN-NoMatch
@@ -0,0 +1,91 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 9c 01 00 00 98 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 00 00 28 c0 2f |.............(./|
+00000030 c0 2b c0 30 c0 2c c0 27 c0 13 c0 23 c0 09 c0 14 |.+.0.,.'...#....|
+00000040 c0 0a 00 9c 00 9d 00 3c 00 2f 00 35 c0 12 00 0a |.......<./.5....|
+00000050 00 05 c0 11 c0 07 01 00 00 47 33 74 00 00 00 05 |.........G3t....|
+00000060 00 05 01 00 00 00 00 00 0a 00 08 00 06 00 17 00 |................|
+00000070 18 00 19 00 0b 00 02 01 00 00 0d 00 0e 00 0c 04 |................|
+00000080 01 04 03 05 01 05 03 02 01 02 03 ff 01 00 01 00 |................|
+00000090 00 10 00 09 00 07 06 70 72 6f 74 6f 33 00 12 00 |.......proto3...|
+000000a0 00 |.|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 59 02 00 00 55 03 03 36 0e 9f 51 42 |....Y...U..6..QB|
+00000010 82 65 fa b5 17 7a 86 d6 40 33 a9 67 d3 3d aa 2f |.e...z..@3.g.=./|
+00000020 89 a0 39 82 af 16 30 8e 64 80 d4 20 23 a6 d0 12 |..9...0.d.. #...|
+00000030 ff 8c fc b4 b5 47 ec 10 fe ba 73 fb 0f ab e8 1c |.....G....s.....|
+00000040 15 c1 fb 11 c1 b2 e1 8a f7 5d 5b ad c0 2f 00 00 |.........][../..|
+00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................|
+00000060 03 02 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 |..Y...U..R..O0..|
+00000070 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d |K0..............|
+00000080 3f e2 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 |?.[..0...*.H....|
+00000090 01 0b 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 |....0.1.0...U...|
+000000a0 02 47 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f |.Go1.0...U....Go|
+000000b0 20 52 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 | Root0...1601010|
+000000c0 30 30 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 |00000Z..25010100|
+000000d0 30 30 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a |0000Z0.1.0...U..|
+000000e0 13 02 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 |..Go1.0...U....G|
+000000f0 6f 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 |o0..0...*.H.....|
+00000100 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 |.......0.......F|
+00000110 7d 93 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 |}...'.H..(!.~...|
+00000120 5d fe 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 |]..RE.z6G....B[.|
+00000130 81 c0 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 |....y.@.Om..+...|
+00000140 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b |..g....."8.J.ts+|
+00000150 c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c |.4......t{.X.la<|
+00000160 c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d |..A..++$#w[.;.u]|
+00000170 ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b |. T..c...$....P.|
+00000180 aa b6 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 |...C...ub...R...|
+00000190 01 00 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f |......0..0...U..|
+000001a0 01 01 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 |.........0...U.%|
+000001b0 04 16 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 |..0...+.........|
+000001c0 2b 06 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 |+.......0...U...|
+000001d0 01 ff 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 |....0.0...U.....|
+000001e0 10 9f 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f |.....CC>I..m....|
+000001f0 60 30 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 |`0...U.#..0...H.|
+00000200 49 4d 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 |IM.~.1......n{0.|
+00000210 06 03 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 |..U....0...examp|
+00000220 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 |le.golang0...*.H|
+00000230 86 f7 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 |.............0.@|
+00000240 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 |+[P.a...SX...(.X|
+00000250 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d |..8....1Z..f=C.-|
+00000260 d9 0b f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c |...... d8.$:....|
+00000270 7d b7 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 |}.@ ._...a..v...|
+00000280 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 |...\.....l..s..C|
+00000290 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d |w.......@.a.Lr+.|
+000002a0 ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db |..F..M...>...B..|
+000002b0 fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 |.=.`.\!.;.......|
+000002c0 cd 0c 00 00 c9 03 00 17 41 04 11 b4 a9 10 7e 5c |........A.....~\|
+000002d0 41 5e 39 12 15 a3 ed 5b 3e 5d 68 c8 ad 48 39 ef |A^9....[>]h..H9.|
+000002e0 09 8b b1 a7 bf db 5f 54 49 cd d5 de 4d b3 47 4c |......_TI...M.GL|
+000002f0 18 02 84 7c ec 75 4e d0 3e 8a d1 6c 80 83 98 64 |...|.uN.>..l...d|
+00000300 4a 81 bc 8f 84 c7 e5 b4 2d fa 04 01 00 80 72 ee |J.......-.....r.|
+00000310 41 38 f2 b8 a1 56 81 d8 04 78 75 05 f4 78 5f f2 |A8...V...xu..x_.|
+00000320 2b 5d a2 46 23 9d 48 c8 63 a9 1d de a8 78 6e 99 |+].F#.H.c....xn.|
+00000330 cd 59 6b 19 20 f5 b1 11 e1 f8 1c 5b 40 c3 b8 cd |.Yk. ......[@...|
+00000340 66 a3 98 37 c5 c2 5c b7 d6 cc 61 b4 5e 97 fa dd |f..7..\...a.^...|
+00000350 b7 85 5d b6 34 8c 39 4a 60 5a 03 20 47 7f e3 65 |..].4.9J`Z. G..e|
+00000360 01 18 00 2c c3 eb be d4 aa 58 57 a9 5e 69 fb 3c |...,.....XW.^i.<|
+00000370 fa c6 28 1a 5c f7 00 d5 21 e5 c1 30 db 84 38 c3 |..(.\...!..0..8.|
+00000380 08 aa 08 5f c9 fd a0 b7 8e d0 66 77 bf 13 16 03 |..._......fw....|
+00000390 03 00 04 0e 00 00 00 |.......|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 46 10 00 00 42 41 04 1e 18 37 ef 0d |....F...BA...7..|
+00000010 19 51 88 35 75 71 b5 e5 54 5b 12 2e 8f 09 67 fd |.Q.5uq..T[....g.|
+00000020 a7 24 20 3e b2 56 1c ce 97 28 5e f8 2b 2d 4f 9e |.$ >.V...(^.+-O.|
+00000030 f1 07 9f 6c 4b 5b 83 56 e2 32 42 e9 58 b6 d7 49 |...lK[.V.2B.X..I|
+00000040 a6 b5 68 1a 41 03 56 6b dc 5a 89 14 03 03 00 01 |..h.A.Vk.Z......|
+00000050 01 16 03 03 00 28 00 00 00 00 00 00 00 00 4f 7e |.....(........O~|
+00000060 9a 3a cc 74 a4 91 77 01 0b 0e 28 0a c5 bd 55 b7 |.:.t..w...(...U.|
+00000070 9a 4c 40 4e e9 c9 46 d5 5f c5 e1 77 c3 f2 |.L@N..F._..w..|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 28 62 4b 13 ef 22 |..........(bK.."|
+00000010 f9 a8 8d ec 42 3a 36 80 5d a8 5b e9 60 d1 ba 65 |....B:6.].[.`..e|
+00000020 2b d8 37 64 e5 12 b2 ef 84 75 87 0c 0f 3d 35 6e |+.7d.....u...=5n|
+00000030 59 7c 51 |Y|Q|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 5f cd 4d |............._.M|
+00000010 7b a7 c0 f9 6c 1f 80 93 cf 55 3b 12 c7 21 12 86 |{...l....U;..!..|
+00000020 f6 b1 52 15 03 03 00 1a 00 00 00 00 00 00 00 02 |..R.............|
+00000030 fd 31 a4 4b d1 e9 f0 e0 18 b5 96 28 f7 b4 0c 29 |.1.K.......(...)|
+00000040 8c 0c |..|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-ECDSA b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-ECDSA
new file mode 100644
index 0000000..4b40e44
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-ECDSA
@@ -0,0 +1,140 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 5d 02 00 00 59 03 03 7c 3c 83 43 cf |....]...Y..|<.C.|
+00000010 60 91 0b 04 73 55 30 be 25 6b 41 c9 4c 67 5b 91 |`...sU0.%kA.Lg[.|
+00000020 af 04 b5 34 c7 61 c7 d3 62 2e ca 20 88 47 3a 15 |...4.a..b.. .G:.|
+00000030 b4 8d 3f eb a6 b3 fd ae a4 e9 d9 db 5b 59 3b 1c |..?.........[Y;.|
+00000040 e6 47 e3 98 74 da 32 04 32 b0 57 81 c0 09 00 00 |.G..t.2.2.W.....|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 03 02 0e 0b 00 02 0a 00 02 07 00 02 |................|
+00000070 04 30 82 02 00 30 82 01 62 02 09 00 b8 bf 2d 47 |.0...0..b.....-G|
+00000080 a0 d2 eb f4 30 09 06 07 2a 86 48 ce 3d 04 01 30 |....0...*.H.=..0|
+00000090 45 31 0b 30 09 06 03 55 04 06 13 02 41 55 31 13 |E1.0...U....AU1.|
+000000a0 30 11 06 03 55 04 08 13 0a 53 6f 6d 65 2d 53 74 |0...U....Some-St|
+000000b0 61 74 65 31 21 30 1f 06 03 55 04 0a 13 18 49 6e |ate1!0...U....In|
+000000c0 74 65 72 6e 65 74 20 57 69 64 67 69 74 73 20 50 |ternet Widgits P|
+000000d0 74 79 20 4c 74 64 30 1e 17 0d 31 32 31 31 32 32 |ty Ltd0...121122|
+000000e0 31 35 30 36 33 32 5a 17 0d 32 32 31 31 32 30 31 |150632Z..2211201|
+000000f0 35 30 36 33 32 5a 30 45 31 0b 30 09 06 03 55 04 |50632Z0E1.0...U.|
+00000100 06 13 02 41 55 31 13 30 11 06 03 55 04 08 13 0a |...AU1.0...U....|
+00000110 53 6f 6d 65 2d 53 74 61 74 65 31 21 30 1f 06 03 |Some-State1!0...|
+00000120 55 04 0a 13 18 49 6e 74 65 72 6e 65 74 20 57 69 |U....Internet Wi|
+00000130 64 67 69 74 73 20 50 74 79 20 4c 74 64 30 81 9b |dgits Pty Ltd0..|
+00000140 30 10 06 07 2a 86 48 ce 3d 02 01 06 05 2b 81 04 |0...*.H.=....+..|
+00000150 00 23 03 81 86 00 04 00 c4 a1 ed be 98 f9 0b 48 |.#.............H|
+00000160 73 36 7e c3 16 56 11 22 f2 3d 53 c3 3b 4d 21 3d |s6~..V.".=S.;M!=|
+00000170 cd 6b 75 e6 f6 b0 dc 9a df 26 c1 bc b2 87 f0 72 |.ku......&.....r|
+00000180 32 7c b3 64 2f 1c 90 bc ea 68 23 10 7e fe e3 25 |2|.d/....h#.~..%|
+00000190 c0 48 3a 69 e0 28 6d d3 37 00 ef 04 62 dd 0d a0 |.H:i.(m.7...b...|
+000001a0 9c 70 62 83 d8 81 d3 64 31 aa 9e 97 31 bd 96 b0 |.pb....d1...1...|
+000001b0 68 c0 9b 23 de 76 64 3f 1a 5c 7f e9 12 0e 58 58 |h..#.vd?.\....XX|
+000001c0 b6 5f 70 dd 9b d8 ea d5 d7 f5 d5 cc b9 b6 9f 30 |._p............0|
+000001d0 66 5b 66 9a 20 e2 27 e5 bf fe 3b 30 09 06 07 2a |f[f. .'...;0...*|
+000001e0 86 48 ce 3d 04 01 03 81 8c 00 30 81 88 02 42 01 |.H.=......0...B.|
+000001f0 88 a2 4f eb e2 45 c5 48 7d 1b ac f5 ed 98 9d ae |..O..E.H}.......|
+00000200 47 70 c0 5e 1b b6 2f bd f1 b6 4d b7 61 40 d3 11 |Gp.^../...M.a@..|
+00000210 a2 ce ee 0b 7e 92 7e ff 76 9d c3 3b 7e a5 3f ce |....~.~.v..;~.?.|
+00000220 fa 10 e2 59 ec 47 2d 7c ac da 4e 97 0e 15 a0 6f |...Y.G-|..N....o|
+00000230 d0 02 42 01 4d fc be 67 13 9c 2d 05 0e bd 3f a3 |..B.M..g..-...?.|
+00000240 8c 25 c1 33 13 83 0d 94 06 bb d4 37 7a f6 ec 7a |.%.3.......7z..z|
+00000250 c9 86 2e dd d7 11 69 7f 85 7c 56 de fb 31 78 2b |......i..|V..1x+|
+00000260 e4 c7 78 0d ae cb be 9e 4e 36 24 31 7b 6a 0f 39 |..x.....N6$1{j.9|
+00000270 95 12 07 8f 2a 16 03 03 00 b6 0c 00 00 b2 03 00 |....*...........|
+00000280 1d 20 b5 f3 76 c4 a9 33 34 2a 38 16 b1 38 f5 a1 |. ..v..34*8..8..|
+00000290 dc f7 60 67 32 cf 6b aa 82 0c b5 db 31 c4 b4 36 |..`g2.k.....1..6|
+000002a0 3e 16 04 03 00 8a 30 81 87 02 41 34 fc 19 0c 94 |>.....0...A4....|
+000002b0 d7 c3 9d ed ae 75 7a 20 b5 b0 93 69 85 8e 4b 20 |.....uz ...i..K |
+000002c0 27 03 83 12 12 8d d5 e4 cc 06 95 a7 dc 7c b2 dc |'............|..|
+000002d0 71 6e 8c 18 89 4b fe 14 41 59 f7 af c8 1f d4 b8 |qn...K..AY......|
+000002e0 7b c4 1f cb 75 53 04 29 87 df 92 37 02 42 01 e7 |{...uS.)...7.B..|
+000002f0 c3 86 70 fa 8e 5e 21 16 52 0e 87 65 4a 69 aa ae |..p..^!.R..eJi..|
+00000300 4c 4f 1e b5 91 17 24 b9 7d 18 7e 0f d0 db a5 33 |LO....$.}.~....3|
+00000310 19 7d 98 7b 5e 15 23 d2 8c 52 8d 17 56 08 60 d6 |.}.{^.#..R..V.`.|
+00000320 7c 2c 19 11 e1 d7 37 a7 b0 68 7b df 8c ae 3d 3e ||,....7..h{...=>|
+00000330 16 03 03 00 3a 0d 00 00 36 03 01 02 40 00 2e 04 |....:...6...@...|
+00000340 03 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b 08 |................|
+00000350 04 08 05 08 06 04 01 05 01 06 01 03 03 02 03 03 |................|
+00000360 01 02 01 03 02 02 02 04 02 05 02 06 02 00 00 16 |................|
+00000370 03 03 00 04 0e 00 00 00 |........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 02 0a 0b 00 02 06 00 02 03 00 02 00 30 |...............0|
+00000010 82 01 fc 30 82 01 5e 02 09 00 9a 30 84 6c 26 35 |...0..^....0.l&5|
+00000020 d9 17 30 09 06 07 2a 86 48 ce 3d 04 01 30 45 31 |..0...*.H.=..0E1|
+00000030 0b 30 09 06 03 55 04 06 13 02 41 55 31 13 30 11 |.0...U....AU1.0.|
+00000040 06 03 55 04 08 13 0a 53 6f 6d 65 2d 53 74 61 74 |..U....Some-Stat|
+00000050 65 31 21 30 1f 06 03 55 04 0a 13 18 49 6e 74 65 |e1!0...U....Inte|
+00000060 72 6e 65 74 20 57 69 64 67 69 74 73 20 50 74 79 |rnet Widgits Pty|
+00000070 20 4c 74 64 30 1e 17 0d 31 32 31 31 31 34 31 33 | Ltd0...12111413|
+00000080 32 35 35 33 5a 17 0d 32 32 31 31 31 32 31 33 32 |2553Z..221112132|
+00000090 35 35 33 5a 30 41 31 0b 30 09 06 03 55 04 06 13 |553Z0A1.0...U...|
+000000a0 02 41 55 31 0c 30 0a 06 03 55 04 08 13 03 4e 53 |.AU1.0...U....NS|
+000000b0 57 31 10 30 0e 06 03 55 04 07 13 07 50 79 72 6d |W1.0...U....Pyrm|
+000000c0 6f 6e 74 31 12 30 10 06 03 55 04 03 13 09 4a 6f |ont1.0...U....Jo|
+000000d0 65 6c 20 53 69 6e 67 30 81 9b 30 10 06 07 2a 86 |el Sing0..0...*.|
+000000e0 48 ce 3d 02 01 06 05 2b 81 04 00 23 03 81 86 00 |H.=....+...#....|
+000000f0 04 00 95 8c 91 75 14 c0 5e c4 57 b4 d4 c3 6f 8d |.....u..^.W...o.|
+00000100 ae 68 1e dd 6f ce 86 e1 7e 6e b2 48 3e 81 e5 4e |.h..o...~n.H>..N|
+00000110 e2 c6 88 4b 64 dc f5 30 bb d3 ff 65 cc 5b f4 dd |...Kd..0...e.[..|
+00000120 b5 6a 3e 3e d0 1d de 47 c3 76 ad 19 f6 45 2c 8c |.j>>...G.v...E,.|
+00000130 bc d8 1d 01 4c 1f 70 90 46 76 48 8b 8f 83 cc 4a |....L.p.FvH....J|
+00000140 5c 8f 40 76 da e0 89 ec 1d 2b c4 4e 30 76 28 41 |\.@v.....+.N0v(A|
+00000150 b2 62 a8 fb 5b f1 f9 4e 7a 8d bd 09 b8 ae ea 8b |.b..[..Nz.......|
+00000160 18 27 4f 2e 70 fe 13 96 ba c3 d3 40 16 cd 65 4e |.'O.p......@..eN|
+00000170 ac 11 1e e6 f1 30 09 06 07 2a 86 48 ce 3d 04 01 |.....0...*.H.=..|
+00000180 03 81 8c 00 30 81 88 02 42 00 e0 14 c4 60 60 0b |....0...B....``.|
+00000190 72 68 b0 32 5d 61 4a 02 74 5c c2 81 b9 16 a8 3f |rh.2]aJ.t\.....?|
+000001a0 29 c8 36 c7 81 ff 6c b6 5b d9 70 f1 38 3b 50 48 |).6...l.[.p.8;PH|
+000001b0 28 94 cb 09 1a 52 f1 5d ee 8d f2 b9 f0 f0 da d9 |(....R.]........|
+000001c0 15 3a f9 bd 03 7a 87 a2 23 35 ec 02 42 01 a3 d4 |.:...z..#5..B...|
+000001d0 8a 78 35 1c 4a 9a 23 d2 0a be 2b 10 31 9d 9c 5f |.x5.J.#...+.1.._|
+000001e0 be e8 91 b3 da 1a f5 5d a3 23 f5 26 8b 45 70 8d |.......].#.&.Ep.|
+000001f0 65 62 9b 7e 01 99 3d 18 f6 10 9a 38 61 9b 2e 57 |eb.~..=....8a..W|
+00000200 e4 fa cc b1 8a ce e2 23 a0 87 f0 e1 67 51 eb 16 |.......#....gQ..|
+00000210 03 03 00 25 10 00 00 21 20 2f e5 7d a3 47 cd 62 |...%...! /.}.G.b|
+00000220 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 cf |C.(.._.).0......|
+00000230 c2 ed 90 99 5f 58 cb 3b 74 16 03 03 00 92 0f 00 |...._X.;t.......|
+00000240 00 8e 04 03 00 8a 30 81 87 02 42 00 92 a9 5e 4b |......0...B...^K|
+00000250 9d ee cc 03 2e 34 e8 5b bd 7b 11 5a 25 00 80 a6 |.....4.[.{.Z%...|
+00000260 83 44 79 07 06 0d ba 0f 76 4d e9 40 50 52 9a c3 |.Dy.....vM.@PR..|
+00000270 24 43 e4 2a 2c 29 d8 da 78 af a4 ad b1 db 0f e6 |$C.*,)..x.......|
+00000280 29 a8 be ec d5 c9 79 4e dc e6 6b 39 77 02 41 45 |).....yN..k9w.AE|
+00000290 be 07 99 32 88 da 0b 8c 33 48 91 78 2e 23 03 9a |...2....3H.x.#..|
+000002a0 6a 92 b3 4c 82 c0 fd cf 0f 08 b5 19 f6 6d 21 95 |j..L.........m!.|
+000002b0 32 7a bc 6f 4b a8 01 b2 e2 a3 48 6c d0 ec 77 1c |2z.oK.....Hl..w.|
+000002c0 30 83 f4 6c 12 a7 50 ea de a3 6e 47 59 cc 0d 35 |0..l..P...nGY..5|
+000002d0 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....|
+000002e0 00 00 00 00 00 00 00 00 00 00 00 65 d3 93 a7 5f |...........e..._|
+000002f0 ff 8c 1e 8f e5 9b 61 fe df ac b6 9d e3 68 31 f8 |......a......h1.|
+00000300 2b d0 70 32 2a 07 13 fe 34 5d a2 ab 35 f1 4c 81 |+.p2*...4]..5.L.|
+00000310 28 34 50 0d 21 bc 4a a9 2d 90 c4 |(4P.!.J.-..|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 40 49 93 f4 1d 25 |..........@I...%|
+00000010 62 e3 5d 46 a2 ae 3d d2 4c 35 a9 06 f0 e1 ca d7 |b.]F..=.L5......|
+00000020 43 c1 96 27 96 ce d1 f6 d5 07 cc ec 6a 4a 96 c6 |C..'........jJ..|
+00000030 1f 89 14 ff 15 6f 79 bc 90 3e fd 63 ed 21 69 95 |.....oy..>.c.!i.|
+00000040 91 a1 08 4a 7e e6 f0 5d e6 ae b6 |...J~..]...|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
+00000010 00 00 00 00 00 88 36 f6 a8 b4 e5 b6 58 ec 9b 08 |......6.....X...|
+00000020 6f bf 5a 7c f1 b5 81 b2 6b 93 f2 35 40 34 89 61 |o.Z|....k..5@4.a|
+00000030 a9 ef 6d fe 2c 15 03 03 00 30 00 00 00 00 00 00 |..m.,....0......|
+00000040 00 00 00 00 00 00 00 00 00 00 97 6d 99 d3 e5 8b |...........m....|
+00000050 54 93 b6 fd 3f ec 6e 03 03 4e 04 39 35 2c bb 10 |T...?.n..N.95,..|
+00000060 02 d0 8d 48 4e 56 1a e5 98 97 |...HNV....|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-RSA b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-RSA
new file mode 100644
index 0000000..b7323e5
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-RSA
@@ -0,0 +1,140 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 5d 02 00 00 59 03 03 75 bb 71 f8 35 |....]...Y..u.q.5|
+00000010 6c a2 b1 c8 b1 a1 dc 40 01 bc e7 0c 8c 22 90 2c |l......@.....".,|
+00000020 aa 34 d3 d2 c8 b1 96 3b bf 4a bf 20 b3 2a f7 96 |.4.....;.J. .*..|
+00000030 9d 79 53 4b 64 b2 80 4d 0e ab f8 3d cd 82 2d 78 |.ySKd..M...=..-x|
+00000040 47 8e cd 9b 14 8c 1e 6d 0e 52 7b db c0 2f 00 00 |G......m.R{../..|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 03 02 59 0b 00 02 55 00 02 52 00 02 |......Y...U..R..|
+00000070 4f 30 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 |O0..K0..........|
+00000080 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 |....?.[..0...*.H|
+00000090 86 f7 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 |........0.1.0...|
+000000a0 55 04 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 |U....Go1.0...U..|
+000000b0 13 07 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 |..Go Root0...160|
+000000c0 31 30 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 |101000000Z..2501|
+000000d0 30 31 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 |01000000Z0.1.0..|
+000000e0 03 55 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 |.U....Go1.0...U.|
+000000f0 03 13 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 |...Go0..0...*.H.|
+00000100 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 |...........0....|
+00000110 81 00 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab |...F}...'.H..(!.|
+00000120 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d |~...]..RE.z6G...|
+00000130 92 42 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd |.B[.....y.@.Om..|
+00000140 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a |+.....g....."8.J|
+00000150 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 |.ts+.4......t{.X|
+00000160 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c |.la<..A..++$#w[.|
+00000170 3b bd 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 |;.u]. T..c...$..|
+00000180 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 |..P....C...ub...|
+00000190 52 d7 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 |R.........0..0..|
+000001a0 03 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 |.U...........0..|
+000001b0 03 55 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 |.U.%..0...+.....|
+000001c0 03 01 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 |....+.......0...|
+000001d0 55 1d 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d |U.......0.0...U.|
+000001e0 0e 04 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d |.........CC>I..m|
+000001f0 b6 80 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 |....`0...U.#..0.|
+00000200 80 10 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab |..H.IM.~.1......|
+00000210 6e 7b 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 |n{0...U....0...e|
+00000220 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 |xample.golang0..|
+00000230 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 |.*.H............|
+00000240 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed |.0.@+[P.a...SX..|
+00000250 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 |.(.X..8....1Z..f|
+00000260 3d 43 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a |=C.-...... d8.$:|
+00000270 00 bc cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 |....}.@ ._...a..|
+00000280 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed |v......\.....l..|
+00000290 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 |s..Cw.......@.a.|
+000002a0 4c 72 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 |Lr+...F..M...>..|
+000002b0 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 |.B...=.`.\!.;...|
+000002c0 16 03 03 00 ac 0c 00 00 a8 03 00 1d 20 f1 7e d0 |............ .~.|
+000002d0 74 5c 5a ab 67 9d 3e ad b5 4a 07 22 4a b7 3c e5 |t\Z.g.>..J."J.<.|
+000002e0 dd 4a 1f ba 33 b5 73 91 87 2a ef 5d 2b 08 04 00 |.J..3.s..*.]+...|
+000002f0 80 d7 78 82 c0 ee 54 02 e8 69 66 94 4b 92 74 0b |..x...T..if.K.t.|
+00000300 be 72 05 ef 78 e2 60 c0 72 3a 09 42 4b d3 0d a0 |.r..x.`.r:.BK...|
+00000310 8b 50 b2 48 33 e4 d2 9f 64 4b 81 8c 5a c4 ad 8d |.P.H3...dK..Z...|
+00000320 52 7c c4 79 10 1c df a8 80 bc 91 bc a7 5e b9 87 |R|.y.........^..|
+00000330 8c 68 63 41 dc 95 b0 b7 65 c4 e8 54 39 ce 2b f8 |.hcA....e..T9.+.|
+00000340 36 76 7f d1 1f ec 84 2b 08 63 10 d0 3c c0 4a 61 |6v.....+.c..<.Ja|
+00000350 5f 74 6a e2 94 93 82 e9 4f 81 bf 93 65 e8 09 06 |_tj.....O...e...|
+00000360 b6 61 14 ed 1a e0 52 f7 4f 08 2d 93 1e 1a 83 e2 |.a....R.O.-.....|
+00000370 17 16 03 03 00 3a 0d 00 00 36 03 01 02 40 00 2e |.....:...6...@..|
+00000380 04 03 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b |................|
+00000390 08 04 08 05 08 06 04 01 05 01 06 01 03 03 02 03 |................|
+000003a0 03 01 02 01 03 02 02 02 04 02 05 02 06 02 00 00 |................|
+000003b0 16 03 03 00 04 0e 00 00 00 |.........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 02 0a 0b 00 02 06 00 02 03 00 02 00 30 |...............0|
+00000010 82 01 fc 30 82 01 5e 02 09 00 9a 30 84 6c 26 35 |...0..^....0.l&5|
+00000020 d9 17 30 09 06 07 2a 86 48 ce 3d 04 01 30 45 31 |..0...*.H.=..0E1|
+00000030 0b 30 09 06 03 55 04 06 13 02 41 55 31 13 30 11 |.0...U....AU1.0.|
+00000040 06 03 55 04 08 13 0a 53 6f 6d 65 2d 53 74 61 74 |..U....Some-Stat|
+00000050 65 31 21 30 1f 06 03 55 04 0a 13 18 49 6e 74 65 |e1!0...U....Inte|
+00000060 72 6e 65 74 20 57 69 64 67 69 74 73 20 50 74 79 |rnet Widgits Pty|
+00000070 20 4c 74 64 30 1e 17 0d 31 32 31 31 31 34 31 33 | Ltd0...12111413|
+00000080 32 35 35 33 5a 17 0d 32 32 31 31 31 32 31 33 32 |2553Z..221112132|
+00000090 35 35 33 5a 30 41 31 0b 30 09 06 03 55 04 06 13 |553Z0A1.0...U...|
+000000a0 02 41 55 31 0c 30 0a 06 03 55 04 08 13 03 4e 53 |.AU1.0...U....NS|
+000000b0 57 31 10 30 0e 06 03 55 04 07 13 07 50 79 72 6d |W1.0...U....Pyrm|
+000000c0 6f 6e 74 31 12 30 10 06 03 55 04 03 13 09 4a 6f |ont1.0...U....Jo|
+000000d0 65 6c 20 53 69 6e 67 30 81 9b 30 10 06 07 2a 86 |el Sing0..0...*.|
+000000e0 48 ce 3d 02 01 06 05 2b 81 04 00 23 03 81 86 00 |H.=....+...#....|
+000000f0 04 00 95 8c 91 75 14 c0 5e c4 57 b4 d4 c3 6f 8d |.....u..^.W...o.|
+00000100 ae 68 1e dd 6f ce 86 e1 7e 6e b2 48 3e 81 e5 4e |.h..o...~n.H>..N|
+00000110 e2 c6 88 4b 64 dc f5 30 bb d3 ff 65 cc 5b f4 dd |...Kd..0...e.[..|
+00000120 b5 6a 3e 3e d0 1d de 47 c3 76 ad 19 f6 45 2c 8c |.j>>...G.v...E,.|
+00000130 bc d8 1d 01 4c 1f 70 90 46 76 48 8b 8f 83 cc 4a |....L.p.FvH....J|
+00000140 5c 8f 40 76 da e0 89 ec 1d 2b c4 4e 30 76 28 41 |\.@v.....+.N0v(A|
+00000150 b2 62 a8 fb 5b f1 f9 4e 7a 8d bd 09 b8 ae ea 8b |.b..[..Nz.......|
+00000160 18 27 4f 2e 70 fe 13 96 ba c3 d3 40 16 cd 65 4e |.'O.p......@..eN|
+00000170 ac 11 1e e6 f1 30 09 06 07 2a 86 48 ce 3d 04 01 |.....0...*.H.=..|
+00000180 03 81 8c 00 30 81 88 02 42 00 e0 14 c4 60 60 0b |....0...B....``.|
+00000190 72 68 b0 32 5d 61 4a 02 74 5c c2 81 b9 16 a8 3f |rh.2]aJ.t\.....?|
+000001a0 29 c8 36 c7 81 ff 6c b6 5b d9 70 f1 38 3b 50 48 |).6...l.[.p.8;PH|
+000001b0 28 94 cb 09 1a 52 f1 5d ee 8d f2 b9 f0 f0 da d9 |(....R.]........|
+000001c0 15 3a f9 bd 03 7a 87 a2 23 35 ec 02 42 01 a3 d4 |.:...z..#5..B...|
+000001d0 8a 78 35 1c 4a 9a 23 d2 0a be 2b 10 31 9d 9c 5f |.x5.J.#...+.1.._|
+000001e0 be e8 91 b3 da 1a f5 5d a3 23 f5 26 8b 45 70 8d |.......].#.&.Ep.|
+000001f0 65 62 9b 7e 01 99 3d 18 f6 10 9a 38 61 9b 2e 57 |eb.~..=....8a..W|
+00000200 e4 fa cc b1 8a ce e2 23 a0 87 f0 e1 67 51 eb 16 |.......#....gQ..|
+00000210 03 03 00 25 10 00 00 21 20 2f e5 7d a3 47 cd 62 |...%...! /.}.G.b|
+00000220 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 cf |C.(.._.).0......|
+00000230 c2 ed 90 99 5f 58 cb 3b 74 16 03 03 00 93 0f 00 |...._X.;t.......|
+00000240 00 8f 04 03 00 8b 30 81 88 02 42 01 8a 49 56 8a |......0...B..IV.|
+00000250 3d 09 db 5b ae 29 2f 93 04 b1 7a 80 95 5c 30 4b |=..[.)/...z..\0K|
+00000260 9a 90 5a 64 3d 12 72 03 7a 8f 4d 40 a8 b0 fd d3 |..Zd=.r.z.M@....|
+00000270 2d e5 3f a4 ce 97 34 e6 e4 23 4f 0b 00 7c 89 8e |-.?...4..#O..|..|
+00000280 f2 37 14 a8 50 d3 d6 ec 99 f2 ff c6 8e 02 42 01 |.7..P.........B.|
+00000290 75 ba 90 7c 16 88 9f 93 73 2a ec e8 e0 53 82 6c |u..|....s*...S.l|
+000002a0 85 a9 1f 42 7e a2 db 55 e9 cd a7 b0 b2 c6 a2 38 |...B~..U.......8|
+000002b0 14 75 ea 91 2f 10 c7 0a f4 98 14 c7 a4 71 72 af |.u../........qr.|
+000002c0 d1 b3 2b 86 a7 25 97 5f de 5a c3 79 fe 44 42 b1 |..+..%._.Z.y.DB.|
+000002d0 dd 14 03 03 00 01 01 16 03 03 00 28 00 00 00 00 |...........(....|
+000002e0 00 00 00 00 a8 a3 81 5b 57 fb 9e 15 5a aa 77 1c |.......[W...Z.w.|
+000002f0 39 cb 84 05 dc 58 2e 65 3c 25 b2 46 9a b3 17 a4 |9....X.e<%.F....|
+00000300 2f 6c ae fb |/l..|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 28 fd 91 33 fe 0c |..........(..3..|
+00000010 f3 cf d7 9d b0 d1 e7 63 ea 06 f7 93 d3 f5 cd 33 |.......c.......3|
+00000020 32 ac 94 78 8e 15 ac 57 c9 b4 44 36 97 96 8d f1 |2..x...W..D6....|
+00000030 c3 20 0d |. .|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 99 85 0f |................|
+00000010 d6 6c 5e b9 55 12 d5 b5 93 a8 b8 85 cb 0b 8f cd |.l^.U...........|
+00000020 f5 fc a1 15 03 03 00 1a 00 00 00 00 00 00 00 02 |................|
+00000030 e3 c0 5e 6a 72 6c 2d 5a 4c 94 0d 1e 77 85 ef 4a |..^jrl-ZL...w..J|
+00000040 90 a5 |..|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-Ed25519 b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-Ed25519
new file mode 100644
index 0000000..c683f6d
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-Ed25519
@@ -0,0 +1,120 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 5d 02 00 00 59 03 03 6c b5 d2 af 6d |....]...Y..l...m|
+00000010 6d 09 3b 84 5c 76 fc 25 81 84 b9 07 01 e9 54 cc |m.;.\v.%......T.|
+00000020 4f 3f ab da ef 02 e7 59 8a e6 10 20 f9 72 db 0c |O?.....Y... .r..|
+00000030 a4 c6 29 f6 ce 25 04 5d af 3c 0f fa 97 28 ee 43 |..)..%.].<...(.C|
+00000040 b1 e5 5f 0a 42 36 2b 63 06 7d d0 de cc a8 00 00 |.._.B6+c.}......|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 03 02 59 0b 00 02 55 00 02 52 00 02 |......Y...U..R..|
+00000070 4f 30 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 |O0..K0..........|
+00000080 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 |....?.[..0...*.H|
+00000090 86 f7 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 |........0.1.0...|
+000000a0 55 04 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 |U....Go1.0...U..|
+000000b0 13 07 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 |..Go Root0...160|
+000000c0 31 30 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 |101000000Z..2501|
+000000d0 30 31 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 |01000000Z0.1.0..|
+000000e0 03 55 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 |.U....Go1.0...U.|
+000000f0 03 13 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 |...Go0..0...*.H.|
+00000100 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 |...........0....|
+00000110 81 00 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab |...F}...'.H..(!.|
+00000120 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d |~...]..RE.z6G...|
+00000130 92 42 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd |.B[.....y.@.Om..|
+00000140 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a |+.....g....."8.J|
+00000150 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 |.ts+.4......t{.X|
+00000160 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c |.la<..A..++$#w[.|
+00000170 3b bd 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 |;.u]. T..c...$..|
+00000180 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 |..P....C...ub...|
+00000190 52 d7 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 |R.........0..0..|
+000001a0 03 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 |.U...........0..|
+000001b0 03 55 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 |.U.%..0...+.....|
+000001c0 03 01 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 |....+.......0...|
+000001d0 55 1d 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d |U.......0.0...U.|
+000001e0 0e 04 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d |.........CC>I..m|
+000001f0 b6 80 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 |....`0...U.#..0.|
+00000200 80 10 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab |..H.IM.~.1......|
+00000210 6e 7b 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 |n{0...U....0...e|
+00000220 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 |xample.golang0..|
+00000230 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 |.*.H............|
+00000240 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed |.0.@+[P.a...SX..|
+00000250 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 |.(.X..8....1Z..f|
+00000260 3d 43 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a |=C.-...... d8.$:|
+00000270 00 bc cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 |....}.@ ._...a..|
+00000280 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed |v......\.....l..|
+00000290 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 |s..Cw.......@.a.|
+000002a0 4c 72 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 |Lr+...F..M...>..|
+000002b0 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 |.B...=.`.\!.;...|
+000002c0 16 03 03 00 ac 0c 00 00 a8 03 00 1d 20 05 e2 67 |............ ..g|
+000002d0 4b 7b e7 b3 0f 62 ff 90 4d 73 b1 c6 b7 ef 9c 33 |K{...b..Ms.....3|
+000002e0 30 83 7d 09 66 b6 d8 10 51 c6 95 b3 64 08 04 00 |0.}.f...Q...d...|
+000002f0 80 71 0d e7 a9 1b d7 2e 08 90 5b aa 30 cf c1 e0 |.q........[.0...|
+00000300 26 df 57 2d b2 95 4a 69 51 e4 b1 26 ad 91 1a 3e |&.W-..JiQ..&...>|
+00000310 38 9f 4e 9e e3 72 7a a7 a8 57 79 3d e5 94 ab c2 |8.N..rz..Wy=....|
+00000320 e3 0f e9 07 aa 31 c9 d6 d8 3d 9c 00 2e c3 8b 3f |.....1...=.....?|
+00000330 23 5a a9 af f0 6b f0 8f 55 b5 5d b3 67 7a cf b5 |#Z...k..U.].gz..|
+00000340 b4 c7 52 29 e9 3a 05 d2 cd d9 a9 99 13 49 15 8a |..R).:.......I..|
+00000350 85 92 60 9a ed 72 c7 75 34 0f b5 26 70 ba 67 0b |..`..r.u4..&p.g.|
+00000360 6e fb 52 97 01 bd 32 59 5b 56 bc e5 d9 68 cd 88 |n.R...2Y[V...h..|
+00000370 7c 16 03 03 00 3a 0d 00 00 36 03 01 02 40 00 2e ||....:...6...@..|
+00000380 04 03 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b |................|
+00000390 08 04 08 05 08 06 04 01 05 01 06 01 03 03 02 03 |................|
+000003a0 03 01 02 01 03 02 02 02 04 02 05 02 06 02 00 00 |................|
+000003b0 16 03 03 00 04 0e 00 00 00 |.........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 01 3c 0b 00 01 38 00 01 35 00 01 32 30 |....<...8..5..20|
+00000010 82 01 2e 30 81 e1 a0 03 02 01 02 02 10 17 d1 81 |...0............|
+00000020 93 be 2a 8c 21 20 10 25 15 e8 34 23 4f 30 05 06 |..*.! .%..4#O0..|
+00000030 03 2b 65 70 30 12 31 10 30 0e 06 03 55 04 0a 13 |.+ep0.1.0...U...|
+00000040 07 41 63 6d 65 20 43 6f 30 1e 17 0d 31 39 30 35 |.Acme Co0...1905|
+00000050 31 36 32 31 35 34 32 36 5a 17 0d 32 30 30 35 31 |16215426Z..20051|
+00000060 35 32 31 35 34 32 36 5a 30 12 31 10 30 0e 06 03 |5215426Z0.1.0...|
+00000070 55 04 0a 13 07 41 63 6d 65 20 43 6f 30 2a 30 05 |U....Acme Co0*0.|
+00000080 06 03 2b 65 70 03 21 00 0b e0 b5 60 b5 e2 79 30 |..+ep.!....`..y0|
+00000090 3d be e3 1e e0 50 b1 04 c8 6d c7 78 6c 69 2f c5 |=....P...m.xli/.|
+000000a0 14 ad 9a 63 6f 79 12 91 a3 4d 30 4b 30 0e 06 03 |...coy...M0K0...|
+000000b0 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 13 06 03 |U...........0...|
+000000c0 55 1d 25 04 0c 30 0a 06 08 2b 06 01 05 05 07 03 |U.%..0...+......|
+000000d0 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 |.0...U.......0.0|
+000000e0 16 06 03 55 1d 11 04 0f 30 0d 82 0b 65 78 61 6d |...U....0...exam|
+000000f0 70 6c 65 2e 63 6f 6d 30 05 06 03 2b 65 70 03 41 |ple.com0...+ep.A|
+00000100 00 fc 19 17 2a 94 a5 31 fa 29 c8 2e 7f 5b a0 5d |....*..1.)...[.]|
+00000110 8a 4e 34 40 39 d6 b3 10 dc 19 fe a0 22 71 b3 f5 |.N4@9......."q..|
+00000120 8f a1 58 0d cd f4 f1 85 24 bf e6 3d 14 df df ed |..X.....$..=....|
+00000130 0e e1 17 d8 11 a2 60 d0 8a 37 23 2a c2 46 aa 3a |......`..7#*.F.:|
+00000140 08 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 47 |.....%...! /.}.G|
+00000150 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af |.bC.(.._.).0....|
+00000160 c4 cf c2 ed 90 99 5f 58 cb 3b 74 16 03 03 00 48 |......_X.;t....H|
+00000170 0f 00 00 44 08 07 00 40 2f cb 89 2f a3 4e ee bb |...D...@/../.N..|
+00000180 1a b0 77 a1 9f e3 0e 21 60 58 8d 62 86 2c 23 74 |..w....!`X.b.,#t|
+00000190 bd b9 2c 48 7f d3 fa 98 85 01 3a 49 7c a3 f6 c9 |..,H......:I|...|
+000001a0 b7 89 83 39 03 21 ed 6b 4a 31 76 b1 20 49 10 1c |...9.!.kJ1v. I..|
+000001b0 55 ee bc 1c fb c3 ad 0c 14 03 03 00 01 01 16 03 |U...............|
+000001c0 03 00 20 7d f4 a6 96 ba b1 c3 87 f7 1b 61 ca 88 |.. }.........a..|
+000001d0 b2 7b 18 f6 92 27 e3 47 fb 46 7b aa 5f ed a1 4c |.{...'.G.F{._..L|
+000001e0 00 64 d7 |.d.|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 20 97 ae 75 77 58 |.......... ..uwX|
+00000010 02 f2 b3 fe ef cf 61 fe e8 d9 b3 49 02 49 64 c2 |......a....I.Id.|
+00000020 4b 94 fe 05 8d c1 46 ef 5b 53 8c |K.....F.[S.|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 16 16 ea 3f e3 7d 1f 53 af a2 74 82 |.......?.}.S..t.|
+00000010 6e 8a 01 6a ea 75 8b a8 4e 76 74 15 03 03 00 12 |n..j.u..Nvt.....|
+00000020 e3 d8 78 82 9f db 28 60 01 c6 03 f0 e7 86 52 ba |..x...(`......R.|
+00000030 2c 45 |,E|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-AES256-GCM-SHA384 b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-AES256-GCM-SHA384
new file mode 100644
index 0000000..9631c0c
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-AES256-GCM-SHA384
@@ -0,0 +1,138 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 5d 02 00 00 59 03 03 b7 f3 10 78 e0 |....]...Y.....x.|
+00000010 58 51 c7 7c 5c 88 27 e1 ce e4 df 24 45 36 7c fe |XQ.|\.'....$E6|.|
+00000020 9b 5c a1 89 0a 6e af 2a 73 b9 93 20 40 64 4c 4d |.\...n.*s.. @dLM|
+00000030 9d 10 58 ef 28 30 5d 81 2b 91 3b 5d 2b 67 b4 61 |..X.(0].+.;]+g.a|
+00000040 ef 24 f1 23 e2 32 46 4c 3e 96 7a a2 c0 30 00 00 |.$.#.2FL>.z..0..|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 03 02 59 0b 00 02 55 00 02 52 00 02 |......Y...U..R..|
+00000070 4f 30 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 |O0..K0..........|
+00000080 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 |....?.[..0...*.H|
+00000090 86 f7 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 |........0.1.0...|
+000000a0 55 04 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 |U....Go1.0...U..|
+000000b0 13 07 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 |..Go Root0...160|
+000000c0 31 30 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 |101000000Z..2501|
+000000d0 30 31 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 |01000000Z0.1.0..|
+000000e0 03 55 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 |.U....Go1.0...U.|
+000000f0 03 13 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 |...Go0..0...*.H.|
+00000100 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 |...........0....|
+00000110 81 00 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab |...F}...'.H..(!.|
+00000120 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d |~...]..RE.z6G...|
+00000130 92 42 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd |.B[.....y.@.Om..|
+00000140 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a |+.....g....."8.J|
+00000150 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 |.ts+.4......t{.X|
+00000160 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c |.la<..A..++$#w[.|
+00000170 3b bd 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 |;.u]. T..c...$..|
+00000180 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 |..P....C...ub...|
+00000190 52 d7 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 |R.........0..0..|
+000001a0 03 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 |.U...........0..|
+000001b0 03 55 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 |.U.%..0...+.....|
+000001c0 03 01 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 |....+.......0...|
+000001d0 55 1d 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d |U.......0.0...U.|
+000001e0 0e 04 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d |.........CC>I..m|
+000001f0 b6 80 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 |....`0...U.#..0.|
+00000200 80 10 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab |..H.IM.~.1......|
+00000210 6e 7b 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 |n{0...U....0...e|
+00000220 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 |xample.golang0..|
+00000230 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 |.*.H............|
+00000240 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed |.0.@+[P.a...SX..|
+00000250 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 |.(.X..8....1Z..f|
+00000260 3d 43 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a |=C.-...... d8.$:|
+00000270 00 bc cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 |....}.@ ._...a..|
+00000280 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed |v......\.....l..|
+00000290 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 |s..Cw.......@.a.|
+000002a0 4c 72 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 |Lr+...F..M...>..|
+000002b0 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 |.B...=.`.\!.;...|
+000002c0 16 03 03 00 ac 0c 00 00 a8 03 00 1d 20 e4 a0 4d |............ ..M|
+000002d0 a8 b2 65 c0 a7 f8 46 a3 79 1c c6 32 7d 1e c4 7b |..e...F.y..2}..{|
+000002e0 09 4a cd 92 5d a6 64 20 b7 c2 0e 5e 50 08 04 00 |.J..].d ...^P...|
+000002f0 80 32 80 e3 3b 30 c3 d9 67 9a ef ea 95 f1 c3 50 |.2..;0..g......P|
+00000300 cb 98 82 3e 92 fd 4c 1b 76 53 4e 31 41 f4 30 9a |...>..L.vSN1A.0.|
+00000310 0a c0 8b 50 5c d6 5c ce 9f ee d9 c6 02 79 48 58 |...P\.\......yHX|
+00000320 97 04 9f 7f 86 f2 7b 61 87 f8 5a d1 92 c3 57 d4 |......{a..Z...W.|
+00000330 c8 86 a2 be 75 3c 13 75 71 13 e2 20 e7 03 b6 6e |....u<.uq.. ...n|
+00000340 97 d5 32 f5 af ce d5 4f e6 7d a6 b3 36 11 f5 ae |..2....O.}..6...|
+00000350 4a 0a fb 43 fa 2c c5 29 e6 fa 59 5f 20 e4 41 f1 |J..C.,.)..Y_ .A.|
+00000360 3b be e1 1e 80 92 74 1c 8e fe 3a f8 c3 ef ed 93 |;.....t...:.....|
+00000370 02 16 03 03 00 3a 0d 00 00 36 03 01 02 40 00 2e |.....:...6...@..|
+00000380 04 03 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b |................|
+00000390 08 04 08 05 08 06 04 01 05 01 06 01 03 03 02 03 |................|
+000003a0 03 01 02 01 03 02 02 02 04 02 05 02 06 02 00 00 |................|
+000003b0 16 03 03 00 04 0e 00 00 00 |.........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 01 fd 0b 00 01 f9 00 01 f6 00 01 f3 30 |...............0|
+00000010 82 01 ef 30 82 01 58 a0 03 02 01 02 02 10 5c 19 |...0..X.......\.|
+00000020 c1 89 65 83 55 6f dc 0b c9 b9 93 9f e9 bc 30 0d |..e.Uo........0.|
+00000030 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 12 31 |..*.H........0.1|
+00000040 10 30 0e 06 03 55 04 0a 13 07 41 63 6d 65 20 43 |.0...U....Acme C|
+00000050 6f 30 1e 17 0d 31 36 30 38 31 37 32 31 35 32 33 |o0...16081721523|
+00000060 31 5a 17 0d 31 37 30 38 31 37 32 31 35 32 33 31 |1Z..170817215231|
+00000070 5a 30 12 31 10 30 0e 06 03 55 04 0a 13 07 41 63 |Z0.1.0...U....Ac|
+00000080 6d 65 20 43 6f 30 81 9f 30 0d 06 09 2a 86 48 86 |me Co0..0...*.H.|
+00000090 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 |...........0....|
+000000a0 81 00 ba 6f aa 86 bd cf bf 9f f2 ef 5c 94 60 78 |...o........\.`x|
+000000b0 6f e8 13 f2 d1 96 6f cd d9 32 6e 22 37 ce 41 f9 |o.....o..2n"7.A.|
+000000c0 ca 5d 29 ac e1 27 da 61 a2 ee 81 cb 10 c7 df 34 |.])..'.a.......4|
+000000d0 58 95 86 e9 3d 19 e6 5c 27 73 60 c8 8d 78 02 f4 |X...=..\'s`..x..|
+000000e0 1d a4 98 09 a3 19 70 69 3c 25 62 66 2a ab 22 23 |......pi<%bf*."#|
+000000f0 c5 7b 85 38 4f 2e 09 73 32 a7 bd 3e 9b ad ca 84 |.{.8O..s2..>....|
+00000100 07 e6 0f 3a ff 77 c5 9d 41 85 00 8a b6 9b ee b0 |...:.w..A.......|
+00000110 a4 3f 2d 4c 4c e6 42 3e bb 51 c8 dd 48 54 f4 0c |.?-LL.B>.Q..HT..|
+00000120 8e 47 02 03 01 00 01 a3 46 30 44 30 0e 06 03 55 |.G......F0D0...U|
+00000130 1d 0f 01 01 ff 04 04 03 02 05 a0 30 13 06 03 55 |...........0...U|
+00000140 1d 25 04 0c 30 0a 06 08 2b 06 01 05 05 07 03 01 |.%..0...+.......|
+00000150 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 0f |0...U.......0.0.|
+00000160 06 03 55 1d 11 04 08 30 06 87 04 7f 00 00 01 30 |..U....0.......0|
+00000170 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 |...*.H..........|
+00000180 81 00 46 ab 44 a2 fb 28 54 f8 5a 67 f8 62 94 f1 |..F.D..(T.Zg.b..|
+00000190 9a b2 18 9e f2 b1 de 1d 7e 6f 76 95 a9 ba e7 5d |........~ov....]|
+000001a0 a8 16 6c 9c f7 09 d3 37 e4 4b 2b 36 7c 01 ad 41 |..l....7.K+6|..A|
+000001b0 d2 32 d8 c3 d2 93 f9 10 6b 8e 95 b9 2c 17 8a a3 |.2......k...,...|
+000001c0 44 48 bc 59 13 83 16 04 88 a4 81 5c 25 0d 98 0c |DH.Y.......\%...|
+000001d0 ac 11 b1 28 56 be 1d cd 61 62 84 09 bf d6 80 c6 |...(V...ab......|
+000001e0 45 8d 82 2c b4 d8 83 9b db c9 22 b7 2a 12 11 7b |E..,......".*..{|
+000001f0 fa 02 3b c1 c9 ff ea c9 9d a8 49 d3 95 d7 d5 0e |..;.......I.....|
+00000200 e5 35 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 |.5....%...! /.}.|
+00000210 47 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 |G.bC.(.._.).0...|
+00000220 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 16 03 03 00 |......._X.;t....|
+00000230 88 0f 00 00 84 08 04 00 80 57 04 14 cf f4 73 9e |.........W....s.|
+00000240 5d 94 16 54 3a 06 6b 37 03 b2 15 52 f1 27 86 2e |]..T:.k7...R.'..|
+00000250 66 e3 0b 4c da f9 71 1b 6a 5b 65 d8 7c 43 80 6a |f..L..q.j[e.|C.j|
+00000260 d1 5c 5c 3b ff 44 dc c7 a9 74 01 51 76 69 79 24 |.\\;.D...t.Qviy$|
+00000270 c5 91 79 65 73 7e b7 1b 15 80 34 b4 31 89 c4 e9 |..yes~....4.1...|
+00000280 f8 e3 18 fd 68 65 b9 65 d7 31 cc d0 8d 00 4e 55 |....he.e.1....NU|
+00000290 3f dc 17 58 b3 b8 aa 98 4e 73 c5 05 bb 54 81 e3 |?..X....Ns...T..|
+000002a0 42 5d b3 1b 6e b0 f8 a0 2c 00 52 e0 e1 16 18 d3 |B]..n...,.R.....|
+000002b0 d1 df 2b b9 15 20 69 d6 1a 14 03 03 00 01 01 16 |..+.. i.........|
+000002c0 03 03 00 28 00 00 00 00 00 00 00 00 b7 cd 13 34 |...(...........4|
+000002d0 56 65 49 f9 1c 23 7f 7d 45 18 91 0f 23 27 c8 78 |VeI..#.}E...#'.x|
+000002e0 cb 34 f8 7c 90 58 5f 29 ff ac f8 1c |.4.|.X_)....|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 28 c0 cc d9 54 39 |..........(...T9|
+00000010 73 0a 5f d9 33 a2 00 cc 18 f6 73 c9 b1 c6 35 b7 |s._.3.....s...5.|
+00000020 49 85 5c 0d 46 21 84 4e 3d b8 ca b8 66 04 e7 96 |I.\.F!.N=...f...|
+00000030 e6 55 26 |.U&|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 61 6d a3 |.............am.|
+00000010 bd c6 12 0d b3 42 56 a3 e3 c9 e6 4d 38 bf 1d 4c |.....BV....M8..L|
+00000020 59 82 c8 15 03 03 00 1a 00 00 00 00 00 00 00 02 |Y...............|
+00000030 ea 55 21 35 64 fd c6 7c 0e f3 2d 67 d6 53 03 20 |.U!5d..|..-g.S. |
+00000040 64 06 |d.|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-ECDSA b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-ECDSA
new file mode 100644
index 0000000..ccb5998
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-ECDSA
@@ -0,0 +1,139 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 5d 02 00 00 59 03 03 62 ba 01 96 bd |....]...Y..b....|
+00000010 12 c5 9d 43 86 5e fe 8d 9e 77 a2 17 dc f3 a2 d6 |...C.^...w......|
+00000020 ca 8f d4 49 ff 9b cb a5 bc 86 29 20 58 57 f3 d7 |...I......) XW..|
+00000030 5e d8 b9 d7 95 54 f9 50 5c b6 78 44 29 bb 83 21 |^....T.P\.xD)..!|
+00000040 77 b2 95 23 5d 4f bb 6a 15 60 e6 86 c0 09 00 00 |w..#]O.j.`......|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 03 02 0e 0b 00 02 0a 00 02 07 00 02 |................|
+00000070 04 30 82 02 00 30 82 01 62 02 09 00 b8 bf 2d 47 |.0...0..b.....-G|
+00000080 a0 d2 eb f4 30 09 06 07 2a 86 48 ce 3d 04 01 30 |....0...*.H.=..0|
+00000090 45 31 0b 30 09 06 03 55 04 06 13 02 41 55 31 13 |E1.0...U....AU1.|
+000000a0 30 11 06 03 55 04 08 13 0a 53 6f 6d 65 2d 53 74 |0...U....Some-St|
+000000b0 61 74 65 31 21 30 1f 06 03 55 04 0a 13 18 49 6e |ate1!0...U....In|
+000000c0 74 65 72 6e 65 74 20 57 69 64 67 69 74 73 20 50 |ternet Widgits P|
+000000d0 74 79 20 4c 74 64 30 1e 17 0d 31 32 31 31 32 32 |ty Ltd0...121122|
+000000e0 31 35 30 36 33 32 5a 17 0d 32 32 31 31 32 30 31 |150632Z..2211201|
+000000f0 35 30 36 33 32 5a 30 45 31 0b 30 09 06 03 55 04 |50632Z0E1.0...U.|
+00000100 06 13 02 41 55 31 13 30 11 06 03 55 04 08 13 0a |...AU1.0...U....|
+00000110 53 6f 6d 65 2d 53 74 61 74 65 31 21 30 1f 06 03 |Some-State1!0...|
+00000120 55 04 0a 13 18 49 6e 74 65 72 6e 65 74 20 57 69 |U....Internet Wi|
+00000130 64 67 69 74 73 20 50 74 79 20 4c 74 64 30 81 9b |dgits Pty Ltd0..|
+00000140 30 10 06 07 2a 86 48 ce 3d 02 01 06 05 2b 81 04 |0...*.H.=....+..|
+00000150 00 23 03 81 86 00 04 00 c4 a1 ed be 98 f9 0b 48 |.#.............H|
+00000160 73 36 7e c3 16 56 11 22 f2 3d 53 c3 3b 4d 21 3d |s6~..V.".=S.;M!=|
+00000170 cd 6b 75 e6 f6 b0 dc 9a df 26 c1 bc b2 87 f0 72 |.ku......&.....r|
+00000180 32 7c b3 64 2f 1c 90 bc ea 68 23 10 7e fe e3 25 |2|.d/....h#.~..%|
+00000190 c0 48 3a 69 e0 28 6d d3 37 00 ef 04 62 dd 0d a0 |.H:i.(m.7...b...|
+000001a0 9c 70 62 83 d8 81 d3 64 31 aa 9e 97 31 bd 96 b0 |.pb....d1...1...|
+000001b0 68 c0 9b 23 de 76 64 3f 1a 5c 7f e9 12 0e 58 58 |h..#.vd?.\....XX|
+000001c0 b6 5f 70 dd 9b d8 ea d5 d7 f5 d5 cc b9 b6 9f 30 |._p............0|
+000001d0 66 5b 66 9a 20 e2 27 e5 bf fe 3b 30 09 06 07 2a |f[f. .'...;0...*|
+000001e0 86 48 ce 3d 04 01 03 81 8c 00 30 81 88 02 42 01 |.H.=......0...B.|
+000001f0 88 a2 4f eb e2 45 c5 48 7d 1b ac f5 ed 98 9d ae |..O..E.H}.......|
+00000200 47 70 c0 5e 1b b6 2f bd f1 b6 4d b7 61 40 d3 11 |Gp.^../...M.a@..|
+00000210 a2 ce ee 0b 7e 92 7e ff 76 9d c3 3b 7e a5 3f ce |....~.~.v..;~.?.|
+00000220 fa 10 e2 59 ec 47 2d 7c ac da 4e 97 0e 15 a0 6f |...Y.G-|..N....o|
+00000230 d0 02 42 01 4d fc be 67 13 9c 2d 05 0e bd 3f a3 |..B.M..g..-...?.|
+00000240 8c 25 c1 33 13 83 0d 94 06 bb d4 37 7a f6 ec 7a |.%.3.......7z..z|
+00000250 c9 86 2e dd d7 11 69 7f 85 7c 56 de fb 31 78 2b |......i..|V..1x+|
+00000260 e4 c7 78 0d ae cb be 9e 4e 36 24 31 7b 6a 0f 39 |..x.....N6$1{j.9|
+00000270 95 12 07 8f 2a 16 03 03 00 b7 0c 00 00 b3 03 00 |....*...........|
+00000280 1d 20 e7 43 a8 15 b3 d3 ea fd b4 dd 02 83 09 c8 |. .C............|
+00000290 76 8f 9b 0e d8 f1 9c e7 99 d5 80 0e fb b8 a1 5c |v..............\|
+000002a0 f2 1e 04 03 00 8b 30 81 88 02 42 01 22 7d 76 28 |......0...B."}v(|
+000002b0 67 0b 8c 78 65 0b d8 11 3e 29 70 02 49 d1 d7 c4 |g..xe...>)p.I...|
+000002c0 50 7b fb 07 2e 8d 91 f6 c4 f8 56 be 75 c6 61 05 |P{........V.u.a.|
+000002d0 43 42 2f f9 46 25 09 a6 a8 29 1d 95 6a 5c 65 fd |CB/.F%...)..j\e.|
+000002e0 07 c1 88 1b f3 fd 52 7a e4 17 01 fe ad 02 42 01 |......Rz......B.|
+000002f0 4f 77 cd d5 34 45 7d 3f 8f 70 ad 80 70 b9 77 9a |Ow..4E}?.p..p.w.|
+00000300 08 c6 96 1c 95 14 76 17 90 05 fd 9a 38 be aa ff |......v.....8...|
+00000310 64 76 35 ae 91 85 14 e5 e8 37 f7 0a b1 50 16 69 |dv5......7...P.i|
+00000320 ab 80 14 77 ee c0 56 77 e5 17 ea d4 57 3c 04 23 |...w..Vw....W<.#|
+00000330 d7 16 03 03 00 3a 0d 00 00 36 03 01 02 40 00 2e |.....:...6...@..|
+00000340 04 03 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b |................|
+00000350 08 04 08 05 08 06 04 01 05 01 06 01 03 03 02 03 |................|
+00000360 03 01 02 01 03 02 02 02 04 02 05 02 06 02 00 00 |................|
+00000370 16 03 03 00 04 0e 00 00 00 |.........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 01 fd 0b 00 01 f9 00 01 f6 00 01 f3 30 |...............0|
+00000010 82 01 ef 30 82 01 58 a0 03 02 01 02 02 10 5c 19 |...0..X.......\.|
+00000020 c1 89 65 83 55 6f dc 0b c9 b9 93 9f e9 bc 30 0d |..e.Uo........0.|
+00000030 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 12 31 |..*.H........0.1|
+00000040 10 30 0e 06 03 55 04 0a 13 07 41 63 6d 65 20 43 |.0...U....Acme C|
+00000050 6f 30 1e 17 0d 31 36 30 38 31 37 32 31 35 32 33 |o0...16081721523|
+00000060 31 5a 17 0d 31 37 30 38 31 37 32 31 35 32 33 31 |1Z..170817215231|
+00000070 5a 30 12 31 10 30 0e 06 03 55 04 0a 13 07 41 63 |Z0.1.0...U....Ac|
+00000080 6d 65 20 43 6f 30 81 9f 30 0d 06 09 2a 86 48 86 |me Co0..0...*.H.|
+00000090 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 |...........0....|
+000000a0 81 00 ba 6f aa 86 bd cf bf 9f f2 ef 5c 94 60 78 |...o........\.`x|
+000000b0 6f e8 13 f2 d1 96 6f cd d9 32 6e 22 37 ce 41 f9 |o.....o..2n"7.A.|
+000000c0 ca 5d 29 ac e1 27 da 61 a2 ee 81 cb 10 c7 df 34 |.])..'.a.......4|
+000000d0 58 95 86 e9 3d 19 e6 5c 27 73 60 c8 8d 78 02 f4 |X...=..\'s`..x..|
+000000e0 1d a4 98 09 a3 19 70 69 3c 25 62 66 2a ab 22 23 |......pi<%bf*."#|
+000000f0 c5 7b 85 38 4f 2e 09 73 32 a7 bd 3e 9b ad ca 84 |.{.8O..s2..>....|
+00000100 07 e6 0f 3a ff 77 c5 9d 41 85 00 8a b6 9b ee b0 |...:.w..A.......|
+00000110 a4 3f 2d 4c 4c e6 42 3e bb 51 c8 dd 48 54 f4 0c |.?-LL.B>.Q..HT..|
+00000120 8e 47 02 03 01 00 01 a3 46 30 44 30 0e 06 03 55 |.G......F0D0...U|
+00000130 1d 0f 01 01 ff 04 04 03 02 05 a0 30 13 06 03 55 |...........0...U|
+00000140 1d 25 04 0c 30 0a 06 08 2b 06 01 05 05 07 03 01 |.%..0...+.......|
+00000150 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 0f |0...U.......0.0.|
+00000160 06 03 55 1d 11 04 08 30 06 87 04 7f 00 00 01 30 |..U....0.......0|
+00000170 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 |...*.H..........|
+00000180 81 00 46 ab 44 a2 fb 28 54 f8 5a 67 f8 62 94 f1 |..F.D..(T.Zg.b..|
+00000190 9a b2 18 9e f2 b1 de 1d 7e 6f 76 95 a9 ba e7 5d |........~ov....]|
+000001a0 a8 16 6c 9c f7 09 d3 37 e4 4b 2b 36 7c 01 ad 41 |..l....7.K+6|..A|
+000001b0 d2 32 d8 c3 d2 93 f9 10 6b 8e 95 b9 2c 17 8a a3 |.2......k...,...|
+000001c0 44 48 bc 59 13 83 16 04 88 a4 81 5c 25 0d 98 0c |DH.Y.......\%...|
+000001d0 ac 11 b1 28 56 be 1d cd 61 62 84 09 bf d6 80 c6 |...(V...ab......|
+000001e0 45 8d 82 2c b4 d8 83 9b db c9 22 b7 2a 12 11 7b |E..,......".*..{|
+000001f0 fa 02 3b c1 c9 ff ea c9 9d a8 49 d3 95 d7 d5 0e |..;.......I.....|
+00000200 e5 35 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 |.5....%...! /.}.|
+00000210 47 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 |G.bC.(.._.).0...|
+00000220 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 16 03 03 00 |......._X.;t....|
+00000230 88 0f 00 00 84 08 04 00 80 47 44 b3 b1 39 6e 07 |.........GD..9n.|
+00000240 14 9c 0d 2f bd 5e 39 06 7a af b2 d0 52 9c 6b b8 |.../.^9.z...R.k.|
+00000250 6e 07 59 e7 a2 c2 33 83 31 d6 42 79 25 ed 37 b0 |n.Y...3.1.By%.7.|
+00000260 97 25 d5 cc a7 7b 54 36 a3 a2 7c 67 38 c2 92 e9 |.%...{T6..|g8...|
+00000270 ab 58 59 4f 22 89 57 2b 27 2c d4 e8 7b 1d 5f 0b |.XYO".W+',..{._.|
+00000280 1f 94 15 b0 38 67 0d a7 ff 66 2d fd 02 65 d6 8b |....8g...f-..e..|
+00000290 ce e2 2a 3c 83 70 56 26 00 e6 1b 47 69 9e 9d 3b |..*<.pV&...Gi..;|
+000002a0 81 88 49 58 a6 3a a1 5f 27 dc 7e 79 86 40 af 8c |..IX.:._'.~y.@..|
+000002b0 35 17 83 92 da 81 7c 41 0d 14 03 03 00 01 01 16 |5.....|A........|
+000002c0 03 03 00 40 00 00 00 00 00 00 00 00 00 00 00 00 |...@............|
+000002d0 00 00 00 00 09 20 b3 66 7d 40 5d 62 f0 21 0c 02 |..... .f}@]b.!..|
+000002e0 66 75 9e 32 f7 28 e4 8e ad 90 18 7d 6a 2b f0 1c |fu.2.(.....}j+..|
+000002f0 3e d4 6d 55 c7 a6 74 88 58 25 c3 69 df 0f 86 10 |>.mU..t.X%.i....|
+00000300 3c 51 88 26 |<Q.&|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 40 80 4c 52 cc b6 |..........@.LR..|
+00000010 b3 e1 4d 8c a7 26 70 f3 47 21 ed ff 01 45 41 91 |..M..&p.G!...EA.|
+00000020 b7 ce 09 87 4d 5b d8 48 c5 9e b1 5d 42 e4 43 1c |....M[.H...]B.C.|
+00000030 e0 90 c6 e2 20 64 80 30 6a e7 25 0f 7b 40 fe 8c |.... d.0j.%.{@..|
+00000040 5f 80 b3 92 25 96 2b e9 38 f2 e3 |_...%.+.8..|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
+00000010 00 00 00 00 00 6c d5 26 50 49 6f 1a 46 3a d2 3a |.....l.&PIo.F:.:|
+00000020 ff b2 0b 17 65 ed 7f a4 b8 e8 82 f6 89 af 07 04 |....e...........|
+00000030 bc 77 d6 74 34 15 03 03 00 30 00 00 00 00 00 00 |.w.t4....0......|
+00000040 00 00 00 00 00 00 00 00 00 00 ca b6 5b 91 20 9d |............[. .|
+00000050 91 42 33 eb f4 49 b6 38 24 fc 3c 8b f7 6c 6b fd |.B3..I.8$.<..lk.|
+00000060 df e8 aa 07 18 29 cd 04 85 70 |.....)...p|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSA b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSA
new file mode 100644
index 0000000..c36f282
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSA
@@ -0,0 +1,138 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 5d 02 00 00 59 03 03 04 e5 45 68 3b |....]...Y....Eh;|
+00000010 73 6e 96 92 17 2a e1 5e f8 6a 16 a1 5e a9 55 d0 |sn...*.^.j..^.U.|
+00000020 f5 2a 30 1d 94 96 5b 76 d4 c3 d5 20 2b 8a eb 6d |.*0...[v... +..m|
+00000030 9c 5a 72 4e a9 df e0 5b 91 7e eb c7 e4 12 6d 1d |.ZrN...[.~....m.|
+00000040 a5 3f 54 e2 27 dd 07 4f df be b2 e7 c0 2f 00 00 |.?T.'..O...../..|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 03 02 59 0b 00 02 55 00 02 52 00 02 |......Y...U..R..|
+00000070 4f 30 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 |O0..K0..........|
+00000080 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 |....?.[..0...*.H|
+00000090 86 f7 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 |........0.1.0...|
+000000a0 55 04 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 |U....Go1.0...U..|
+000000b0 13 07 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 |..Go Root0...160|
+000000c0 31 30 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 |101000000Z..2501|
+000000d0 30 31 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 |01000000Z0.1.0..|
+000000e0 03 55 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 |.U....Go1.0...U.|
+000000f0 03 13 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 |...Go0..0...*.H.|
+00000100 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 |...........0....|
+00000110 81 00 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab |...F}...'.H..(!.|
+00000120 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d |~...]..RE.z6G...|
+00000130 92 42 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd |.B[.....y.@.Om..|
+00000140 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a |+.....g....."8.J|
+00000150 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 |.ts+.4......t{.X|
+00000160 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c |.la<..A..++$#w[.|
+00000170 3b bd 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 |;.u]. T..c...$..|
+00000180 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 |..P....C...ub...|
+00000190 52 d7 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 |R.........0..0..|
+000001a0 03 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 |.U...........0..|
+000001b0 03 55 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 |.U.%..0...+.....|
+000001c0 03 01 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 |....+.......0...|
+000001d0 55 1d 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d |U.......0.0...U.|
+000001e0 0e 04 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d |.........CC>I..m|
+000001f0 b6 80 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 |....`0...U.#..0.|
+00000200 80 10 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab |..H.IM.~.1......|
+00000210 6e 7b 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 |n{0...U....0...e|
+00000220 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 |xample.golang0..|
+00000230 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 |.*.H............|
+00000240 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed |.0.@+[P.a...SX..|
+00000250 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 |.(.X..8....1Z..f|
+00000260 3d 43 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a |=C.-...... d8.$:|
+00000270 00 bc cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 |....}.@ ._...a..|
+00000280 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed |v......\.....l..|
+00000290 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 |s..Cw.......@.a.|
+000002a0 4c 72 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 |Lr+...F..M...>..|
+000002b0 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 |.B...=.`.\!.;...|
+000002c0 16 03 03 00 ac 0c 00 00 a8 03 00 1d 20 77 dc b7 |............ w..|
+000002d0 44 64 c9 3b e9 e2 bf b5 01 47 c9 64 f8 ef ee 33 |Dd.;.....G.d...3|
+000002e0 e2 81 a1 af 05 c0 31 37 1f 8d 3c 55 45 08 04 00 |......17..<UE...|
+000002f0 80 5f fe b0 72 52 a4 24 39 0b ef c5 c0 30 c8 21 |._..rR.$9....0.!|
+00000300 89 14 a0 08 0a 78 13 5f 68 ab 4b 73 6b cd 82 9b |.....x._h.Ksk...|
+00000310 d0 4e 4f 3e fb bf 0f a4 6b 32 d0 a6 44 dc be 0d |.NO>....k2..D...|
+00000320 54 7e 57 74 92 a3 4e f9 cf 70 52 b1 50 9a 60 4f |T~Wt..N..pR.P.`O|
+00000330 79 72 5d c4 53 ba 19 ff 05 56 1d 41 be 18 77 71 |yr].S....V.A..wq|
+00000340 5c 00 84 5e 70 fa cf 9e 8e d2 62 7d 48 6a fe 75 |\..^p.....b}Hj.u|
+00000350 6a 67 5b 82 52 76 d4 fc 96 a4 ad fa a9 ea fc e5 |jg[.Rv..........|
+00000360 97 dd 53 a0 ef 53 00 27 72 ae 5b c9 06 f6 43 c8 |..S..S.'r.[...C.|
+00000370 d5 16 03 03 00 3a 0d 00 00 36 03 01 02 40 00 2e |.....:...6...@..|
+00000380 04 03 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b |................|
+00000390 08 04 08 05 08 06 04 01 05 01 06 01 03 03 02 03 |................|
+000003a0 03 01 02 01 03 02 02 02 04 02 05 02 06 02 00 00 |................|
+000003b0 16 03 03 00 04 0e 00 00 00 |.........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 01 fd 0b 00 01 f9 00 01 f6 00 01 f3 30 |...............0|
+00000010 82 01 ef 30 82 01 58 a0 03 02 01 02 02 10 5c 19 |...0..X.......\.|
+00000020 c1 89 65 83 55 6f dc 0b c9 b9 93 9f e9 bc 30 0d |..e.Uo........0.|
+00000030 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 12 31 |..*.H........0.1|
+00000040 10 30 0e 06 03 55 04 0a 13 07 41 63 6d 65 20 43 |.0...U....Acme C|
+00000050 6f 30 1e 17 0d 31 36 30 38 31 37 32 31 35 32 33 |o0...16081721523|
+00000060 31 5a 17 0d 31 37 30 38 31 37 32 31 35 32 33 31 |1Z..170817215231|
+00000070 5a 30 12 31 10 30 0e 06 03 55 04 0a 13 07 41 63 |Z0.1.0...U....Ac|
+00000080 6d 65 20 43 6f 30 81 9f 30 0d 06 09 2a 86 48 86 |me Co0..0...*.H.|
+00000090 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 |...........0....|
+000000a0 81 00 ba 6f aa 86 bd cf bf 9f f2 ef 5c 94 60 78 |...o........\.`x|
+000000b0 6f e8 13 f2 d1 96 6f cd d9 32 6e 22 37 ce 41 f9 |o.....o..2n"7.A.|
+000000c0 ca 5d 29 ac e1 27 da 61 a2 ee 81 cb 10 c7 df 34 |.])..'.a.......4|
+000000d0 58 95 86 e9 3d 19 e6 5c 27 73 60 c8 8d 78 02 f4 |X...=..\'s`..x..|
+000000e0 1d a4 98 09 a3 19 70 69 3c 25 62 66 2a ab 22 23 |......pi<%bf*."#|
+000000f0 c5 7b 85 38 4f 2e 09 73 32 a7 bd 3e 9b ad ca 84 |.{.8O..s2..>....|
+00000100 07 e6 0f 3a ff 77 c5 9d 41 85 00 8a b6 9b ee b0 |...:.w..A.......|
+00000110 a4 3f 2d 4c 4c e6 42 3e bb 51 c8 dd 48 54 f4 0c |.?-LL.B>.Q..HT..|
+00000120 8e 47 02 03 01 00 01 a3 46 30 44 30 0e 06 03 55 |.G......F0D0...U|
+00000130 1d 0f 01 01 ff 04 04 03 02 05 a0 30 13 06 03 55 |...........0...U|
+00000140 1d 25 04 0c 30 0a 06 08 2b 06 01 05 05 07 03 01 |.%..0...+.......|
+00000150 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 0f |0...U.......0.0.|
+00000160 06 03 55 1d 11 04 08 30 06 87 04 7f 00 00 01 30 |..U....0.......0|
+00000170 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 |...*.H..........|
+00000180 81 00 46 ab 44 a2 fb 28 54 f8 5a 67 f8 62 94 f1 |..F.D..(T.Zg.b..|
+00000190 9a b2 18 9e f2 b1 de 1d 7e 6f 76 95 a9 ba e7 5d |........~ov....]|
+000001a0 a8 16 6c 9c f7 09 d3 37 e4 4b 2b 36 7c 01 ad 41 |..l....7.K+6|..A|
+000001b0 d2 32 d8 c3 d2 93 f9 10 6b 8e 95 b9 2c 17 8a a3 |.2......k...,...|
+000001c0 44 48 bc 59 13 83 16 04 88 a4 81 5c 25 0d 98 0c |DH.Y.......\%...|
+000001d0 ac 11 b1 28 56 be 1d cd 61 62 84 09 bf d6 80 c6 |...(V...ab......|
+000001e0 45 8d 82 2c b4 d8 83 9b db c9 22 b7 2a 12 11 7b |E..,......".*..{|
+000001f0 fa 02 3b c1 c9 ff ea c9 9d a8 49 d3 95 d7 d5 0e |..;.......I.....|
+00000200 e5 35 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 |.5....%...! /.}.|
+00000210 47 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 |G.bC.(.._.).0...|
+00000220 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 16 03 03 00 |......._X.;t....|
+00000230 88 0f 00 00 84 08 04 00 80 56 b9 1d 6a ed f4 b2 |.........V..j...|
+00000240 e9 2b 9c 6b a3 18 78 1c 76 18 57 7d a3 05 6f 7e |.+.k..x.v.W}..o~|
+00000250 36 52 e2 d7 35 f9 c2 2d 81 db ca ee 85 f9 45 d8 |6R..5..-......E.|
+00000260 d7 ec 76 9c 1d 85 b7 38 9d 12 f6 64 dc fe ca 16 |..v....8...d....|
+00000270 2f ad 91 ae b5 a1 18 bf 85 df 07 bc 7b 42 5b 6d |/...........{B[m|
+00000280 ad 54 c7 ae 42 b0 3b e7 b7 70 b9 80 ef a1 65 e7 |.T..B.;..p....e.|
+00000290 46 aa e4 9a 22 d9 ce 1f 7d 33 b9 62 4d 3d 77 8a |F..."...}3.bM=w.|
+000002a0 b8 ac 38 64 f0 aa 95 be be 78 bc ad 94 b8 90 29 |..8d.....x.....)|
+000002b0 72 7f d1 ed f0 bf 79 13 00 14 03 03 00 01 01 16 |r.....y.........|
+000002c0 03 03 00 28 00 00 00 00 00 00 00 00 b6 3d 7b 87 |...(.........={.|
+000002d0 c8 a0 18 96 ec f8 36 f4 4c 18 7e 13 6b 56 1e de |......6.L.~.kV..|
+000002e0 80 8a 37 1b 4e 84 85 3f 60 e8 50 55 |..7.N..?`.PU|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 28 38 5d b5 b3 a8 |..........(8]...|
+00000010 94 65 de ee 2e e9 4f f3 13 9e ff 0a f4 d2 b0 9e |.e....O.........|
+00000020 e7 ec 8c 7c 03 8f c3 fc c6 97 75 5b 96 1d 64 ad |...|......u[..d.|
+00000030 4f ee dd |O..|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 a5 03 23 |...............#|
+00000010 3a 39 6b b5 e5 71 c8 87 07 b4 c9 79 2b 84 d9 9d |:9k..q.....y+...|
+00000020 1b 21 26 15 03 03 00 1a 00 00 00 00 00 00 00 02 |.!&.............|
+00000030 f5 e9 fb d2 c8 57 34 45 e1 27 8e 35 6d 36 95 10 |.....W4E.'.5m6..|
+00000040 76 0d |v.|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSAPKCS1v15 b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSAPKCS1v15
new file mode 100644
index 0000000..bf2f5c4
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSAPKCS1v15
@@ -0,0 +1,135 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 5d 02 00 00 59 03 03 0d ab 4e 27 0a |....]...Y....N'.|
+00000010 9c 1b 91 00 41 33 eb a7 d6 84 45 e0 dd f7 8a a1 |....A3....E.....|
+00000020 62 c4 e0 2d 2f 51 4f 33 21 2a 6d 20 24 2d d0 3f |b..-/QO3!*m $-.?|
+00000030 cc 5a 9c 5f b7 53 54 fc c7 bf a9 2c 8e 39 16 e4 |.Z._.ST....,.9..|
+00000040 7d 80 72 6b 95 93 51 41 8a da 67 29 c0 2f 00 00 |}.rk..QA..g)./..|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 03 02 59 0b 00 02 55 00 02 52 00 02 |......Y...U..R..|
+00000070 4f 30 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 |O0..K0..........|
+00000080 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 |....?.[..0...*.H|
+00000090 86 f7 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 |........0.1.0...|
+000000a0 55 04 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 |U....Go1.0...U..|
+000000b0 13 07 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 |..Go Root0...160|
+000000c0 31 30 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 |101000000Z..2501|
+000000d0 30 31 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 |01000000Z0.1.0..|
+000000e0 03 55 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 |.U....Go1.0...U.|
+000000f0 03 13 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 |...Go0..0...*.H.|
+00000100 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 |...........0....|
+00000110 81 00 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab |...F}...'.H..(!.|
+00000120 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d |~...]..RE.z6G...|
+00000130 92 42 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd |.B[.....y.@.Om..|
+00000140 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a |+.....g....."8.J|
+00000150 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 |.ts+.4......t{.X|
+00000160 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c |.la<..A..++$#w[.|
+00000170 3b bd 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 |;.u]. T..c...$..|
+00000180 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 |..P....C...ub...|
+00000190 52 d7 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 |R.........0..0..|
+000001a0 03 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 |.U...........0..|
+000001b0 03 55 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 |.U.%..0...+.....|
+000001c0 03 01 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 |....+.......0...|
+000001d0 55 1d 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d |U.......0.0...U.|
+000001e0 0e 04 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d |.........CC>I..m|
+000001f0 b6 80 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 |....`0...U.#..0.|
+00000200 80 10 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab |..H.IM.~.1......|
+00000210 6e 7b 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 |n{0...U....0...e|
+00000220 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 |xample.golang0..|
+00000230 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 |.*.H............|
+00000240 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed |.0.@+[P.a...SX..|
+00000250 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 |.(.X..8....1Z..f|
+00000260 3d 43 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a |=C.-...... d8.$:|
+00000270 00 bc cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 |....}.@ ._...a..|
+00000280 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed |v......\.....l..|
+00000290 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 |s..Cw.......@.a.|
+000002a0 4c 72 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 |Lr+...F..M...>..|
+000002b0 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 |.B...=.`.\!.;...|
+000002c0 16 03 03 00 ac 0c 00 00 a8 03 00 1d 20 94 9e e3 |............ ...|
+000002d0 41 3b c6 0c cc 05 92 ac ea 8c 9e 2d e5 bc 42 30 |A;.........-..B0|
+000002e0 47 87 d6 b3 6e d5 73 9f ca 2a 48 9a 04 04 01 00 |G...n.s..*H.....|
+000002f0 80 d6 f2 ef 4a 3f ca 47 9a 13 e4 38 3b d8 23 77 |....J?.G...8;.#w|
+00000300 b4 84 fa 89 c4 e6 e2 84 e2 a7 50 81 e4 b2 b8 1f |..........P.....|
+00000310 04 15 0d 50 5f 4a 95 e3 0d 27 c3 2f 96 9b 92 c0 |...P_J...'./....|
+00000320 fb 6a 52 c1 a4 39 39 7e 8f da 53 5e 34 db 62 01 |.jR..99~..S^4.b.|
+00000330 6d 0a 14 bd b5 0a 24 b5 df b2 99 56 cd 68 a6 75 |m.....$....V.h.u|
+00000340 9f 70 1a f6 d3 6b f6 68 ef bc 75 09 69 c4 18 4a |.p...k.h..u.i..J|
+00000350 dc 51 c2 65 01 36 f1 c0 d9 34 66 d1 c2 dc d9 0d |.Q.e.6...4f.....|
+00000360 f5 74 4f 84 df b0 c2 d2 0a d6 51 fc 6e 3c d8 74 |.tO.......Q.n<.t|
+00000370 35 16 03 03 00 0c 0d 00 00 08 01 01 00 02 04 01 |5...............|
+00000380 00 00 16 03 03 00 04 0e 00 00 00 |...........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 01 fd 0b 00 01 f9 00 01 f6 00 01 f3 30 |...............0|
+00000010 82 01 ef 30 82 01 58 a0 03 02 01 02 02 10 5c 19 |...0..X.......\.|
+00000020 c1 89 65 83 55 6f dc 0b c9 b9 93 9f e9 bc 30 0d |..e.Uo........0.|
+00000030 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 12 31 |..*.H........0.1|
+00000040 10 30 0e 06 03 55 04 0a 13 07 41 63 6d 65 20 43 |.0...U....Acme C|
+00000050 6f 30 1e 17 0d 31 36 30 38 31 37 32 31 35 32 33 |o0...16081721523|
+00000060 31 5a 17 0d 31 37 30 38 31 37 32 31 35 32 33 31 |1Z..170817215231|
+00000070 5a 30 12 31 10 30 0e 06 03 55 04 0a 13 07 41 63 |Z0.1.0...U....Ac|
+00000080 6d 65 20 43 6f 30 81 9f 30 0d 06 09 2a 86 48 86 |me Co0..0...*.H.|
+00000090 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 |...........0....|
+000000a0 81 00 ba 6f aa 86 bd cf bf 9f f2 ef 5c 94 60 78 |...o........\.`x|
+000000b0 6f e8 13 f2 d1 96 6f cd d9 32 6e 22 37 ce 41 f9 |o.....o..2n"7.A.|
+000000c0 ca 5d 29 ac e1 27 da 61 a2 ee 81 cb 10 c7 df 34 |.])..'.a.......4|
+000000d0 58 95 86 e9 3d 19 e6 5c 27 73 60 c8 8d 78 02 f4 |X...=..\'s`..x..|
+000000e0 1d a4 98 09 a3 19 70 69 3c 25 62 66 2a ab 22 23 |......pi<%bf*."#|
+000000f0 c5 7b 85 38 4f 2e 09 73 32 a7 bd 3e 9b ad ca 84 |.{.8O..s2..>....|
+00000100 07 e6 0f 3a ff 77 c5 9d 41 85 00 8a b6 9b ee b0 |...:.w..A.......|
+00000110 a4 3f 2d 4c 4c e6 42 3e bb 51 c8 dd 48 54 f4 0c |.?-LL.B>.Q..HT..|
+00000120 8e 47 02 03 01 00 01 a3 46 30 44 30 0e 06 03 55 |.G......F0D0...U|
+00000130 1d 0f 01 01 ff 04 04 03 02 05 a0 30 13 06 03 55 |...........0...U|
+00000140 1d 25 04 0c 30 0a 06 08 2b 06 01 05 05 07 03 01 |.%..0...+.......|
+00000150 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 0f |0...U.......0.0.|
+00000160 06 03 55 1d 11 04 08 30 06 87 04 7f 00 00 01 30 |..U....0.......0|
+00000170 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 |...*.H..........|
+00000180 81 00 46 ab 44 a2 fb 28 54 f8 5a 67 f8 62 94 f1 |..F.D..(T.Zg.b..|
+00000190 9a b2 18 9e f2 b1 de 1d 7e 6f 76 95 a9 ba e7 5d |........~ov....]|
+000001a0 a8 16 6c 9c f7 09 d3 37 e4 4b 2b 36 7c 01 ad 41 |..l....7.K+6|..A|
+000001b0 d2 32 d8 c3 d2 93 f9 10 6b 8e 95 b9 2c 17 8a a3 |.2......k...,...|
+000001c0 44 48 bc 59 13 83 16 04 88 a4 81 5c 25 0d 98 0c |DH.Y.......\%...|
+000001d0 ac 11 b1 28 56 be 1d cd 61 62 84 09 bf d6 80 c6 |...(V...ab......|
+000001e0 45 8d 82 2c b4 d8 83 9b db c9 22 b7 2a 12 11 7b |E..,......".*..{|
+000001f0 fa 02 3b c1 c9 ff ea c9 9d a8 49 d3 95 d7 d5 0e |..;.......I.....|
+00000200 e5 35 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 |.5....%...! /.}.|
+00000210 47 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 |G.bC.(.._.).0...|
+00000220 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 16 03 03 00 |......._X.;t....|
+00000230 88 0f 00 00 84 04 01 00 80 81 fe 69 7d 68 10 74 |...........i}h.t|
+00000240 e4 9a d0 11 7a c4 e4 11 4c 7c 8a 13 f1 cf 0e 33 |....z...L|.....3|
+00000250 a5 3d d2 1f a2 73 c4 8e 2d 9e 87 45 b6 d2 dc 98 |.=...s..-..E....|
+00000260 fe 4d 86 8d ad 87 a8 2c e3 9f 08 a0 4f 78 4d 9c |.M.....,....OxM.|
+00000270 de c2 92 7e dc 48 6b a9 e7 cc 58 a9 45 41 04 fb |...~.Hk...X.EA..|
+00000280 48 fa d1 e4 5c 71 92 d5 bf e4 92 a1 66 07 b8 73 |H...\q......f..s|
+00000290 b0 45 98 12 8e d8 2d e8 3e 85 05 e5 d3 38 ea 3a |.E....-.>....8.:|
+000002a0 5d 33 4a 32 f9 ff 8b 18 ae 55 b7 f3 d2 0e e7 b8 |]3J2.....U......|
+000002b0 4e e8 bc 4f c6 a3 65 c1 a1 14 03 03 00 01 01 16 |N..O..e.........|
+000002c0 03 03 00 28 00 00 00 00 00 00 00 00 da 49 06 a7 |...(.........I..|
+000002d0 0e a4 7a df 94 f1 57 43 21 ef 85 ee 9f 52 f2 03 |..z...WC!....R..|
+000002e0 5a 79 58 7a a0 b2 1f 9e 1d f9 5a d3 |ZyXz......Z.|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 28 22 7a 58 97 ef |..........("zX..|
+00000010 f2 e6 4a c1 10 ca 63 52 e0 82 87 b4 9d d5 2f c4 |..J...cR....../.|
+00000020 68 f1 4a d5 e8 ae 3a 22 9e f7 b3 07 8f a4 8c 18 |h.J...:"........|
+00000030 2c 44 65 |,De|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 2c ee 44 |.............,.D|
+00000010 2d 89 8f 1f bd c2 de ac 8b 3c f2 35 d1 bd 17 4e |-........<.5...N|
+00000020 65 3c 47 15 03 03 00 1a 00 00 00 00 00 00 00 02 |e<G.............|
+00000030 d3 45 69 d3 9e 36 be 2c 0e ac c8 d6 00 30 4f 96 |.Ei..6.,.....0O.|
+00000040 40 50 |@P|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSAPSS b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSAPSS
new file mode 100644
index 0000000..8f71f95
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSAPSS
@@ -0,0 +1,143 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 5d 02 00 00 59 03 03 87 97 ae 0d d7 |....]...Y.......|
+00000010 e4 be cd c5 ca 90 a8 85 23 c8 e3 32 15 f4 29 d8 |........#..2..).|
+00000020 47 d7 ae e7 d8 7b 71 f5 c4 ea 07 20 e4 fd d6 48 |G....{q.... ...H|
+00000030 10 13 e0 9b 06 e1 d7 b1 93 94 38 16 b7 a0 ef 80 |..........8.....|
+00000040 2e b7 67 d6 ff 73 99 bf 67 cc 62 a1 c0 2f 00 00 |..g..s..g.b../..|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 03 02 66 0b 00 02 62 00 02 5f 00 02 |......f...b.._..|
+00000070 5c 30 82 02 58 30 82 01 8d a0 03 02 01 02 02 11 |\0..X0..........|
+00000080 00 f2 99 26 eb 87 ea 8a 0d b9 fc c2 47 34 7c 11 |...&........G4|.|
+00000090 b0 30 41 06 09 2a 86 48 86 f7 0d 01 01 0a 30 34 |.0A..*.H......04|
+000000a0 a0 0f 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 |..0...`.H.e.....|
+000000b0 00 a1 1c 30 1a 06 09 2a 86 48 86 f7 0d 01 01 08 |...0...*.H......|
+000000c0 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 a2 |0...`.H.e.......|
+000000d0 03 02 01 20 30 12 31 10 30 0e 06 03 55 04 0a 13 |... 0.1.0...U...|
+000000e0 07 41 63 6d 65 20 43 6f 30 1e 17 0d 31 37 31 31 |.Acme Co0...1711|
+000000f0 32 33 31 36 31 36 31 30 5a 17 0d 31 38 31 31 32 |23161610Z..18112|
+00000100 33 31 36 31 36 31 30 5a 30 12 31 10 30 0e 06 03 |3161610Z0.1.0...|
+00000110 55 04 0a 13 07 41 63 6d 65 20 43 6f 30 81 9f 30 |U....Acme Co0..0|
+00000120 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 |...*.H..........|
+00000130 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 27 |..0.......F}...'|
+00000140 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 |.H..(!.~...]..RE|
+00000150 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 |.z6G....B[.....y|
+00000160 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 |.@.Om..+.....g..|
+00000170 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 |..."8.J.ts+.4...|
+00000180 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 |...t{.X.la<..A..|
+00000190 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 |++$#w[.;.u]. T..|
+000001a0 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed |c...$....P....C.|
+000001b0 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 46 |..ub...R.......F|
+000001c0 30 44 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 |0D0...U.........|
+000001d0 05 a0 30 13 06 03 55 1d 25 04 0c 30 0a 06 08 2b |..0...U.%..0...+|
+000001e0 06 01 05 05 07 03 01 30 0c 06 03 55 1d 13 01 01 |.......0...U....|
+000001f0 ff 04 02 30 00 30 0f 06 03 55 1d 11 04 08 30 06 |...0.0...U....0.|
+00000200 87 04 7f 00 00 01 30 41 06 09 2a 86 48 86 f7 0d |......0A..*.H...|
+00000210 01 01 0a 30 34 a0 0f 30 0d 06 09 60 86 48 01 65 |...04..0...`.H.e|
+00000220 03 04 02 01 05 00 a1 1c 30 1a 06 09 2a 86 48 86 |........0...*.H.|
+00000230 f7 0d 01 01 08 30 0d 06 09 60 86 48 01 65 03 04 |.....0...`.H.e..|
+00000240 02 01 05 00 a2 03 02 01 20 03 81 81 00 cd ac 4e |........ ......N|
+00000250 f2 ce 5f 8d 79 88 10 42 70 7f 7c bf 1b 5a 8a 00 |.._.y..Bp.|..Z..|
+00000260 ef 19 15 4b 40 15 17 71 00 6c d4 16 26 e5 49 6d |...K@..q.l..&.Im|
+00000270 56 da 0c 1a 13 9f d8 46 95 59 3c b6 7f 87 76 5e |V......F.Y<...v^|
+00000280 18 aa 03 ea 06 75 22 dd 78 d2 a5 89 b8 c9 23 64 |.....u".x.....#d|
+00000290 e1 28 38 ce 34 6c 6e 06 7b 51 f1 a7 e6 f4 b3 7f |.(8.4ln.{Q......|
+000002a0 fa b1 3f 14 11 89 66 79 d1 8e 88 0e 0b a0 9e 30 |..?...fy.......0|
+000002b0 2a c0 67 ef ca 46 02 88 e9 53 81 22 69 22 97 ad |*.g..F...S."i"..|
+000002c0 80 93 d4 f7 dd 70 14 24 d7 70 0a 46 a1 16 03 03 |.....p.$.p.F....|
+000002d0 00 ac 0c 00 00 a8 03 00 1d 20 19 11 2f cc 8b d4 |......... ../...|
+000002e0 74 7c 77 34 b0 c7 4f 49 85 d1 f3 b0 2c 0e 83 26 |t|w4..OI....,..&|
+000002f0 ee c1 2c 32 c1 82 43 3c cd 1b 08 04 00 80 68 33 |..,2..C<......h3|
+00000300 a3 71 38 a8 70 34 04 91 e0 7b b3 44 46 45 54 a9 |.q8.p4...{.DFET.|
+00000310 af ad 50 0d b6 91 7c 87 c7 4c 99 2d 02 9d 57 57 |..P...|..L.-..WW|
+00000320 ae 2a 25 63 82 32 f0 4a 14 cd d3 b4 ca b8 bc d9 |.*%c.2.J........|
+00000330 ff 1e 01 93 20 6e 27 97 04 31 c4 d8 e9 a6 84 1e |.... n'..1......|
+00000340 96 6c a6 25 cc 93 e7 2d 15 32 e1 ad 01 7d fb 2c |.l.%...-.2...}.,|
+00000350 12 04 5d 59 f6 bc 90 e8 cc d7 48 6d 46 c4 ed 64 |..]Y......HmF..d|
+00000360 6b 41 5b 9d 9a 3b c8 11 57 bb b8 b1 cb c6 54 d6 |kA[..;..W.....T.|
+00000370 08 34 7e ad e3 59 7b f7 90 77 e6 50 95 aa 16 03 |.4~..Y{..w.P....|
+00000380 03 00 0c 0d 00 00 08 01 01 00 02 08 04 00 00 16 |................|
+00000390 03 03 00 04 0e 00 00 00 |........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 02 66 0b 00 02 62 00 02 5f 00 02 5c 30 |....f...b.._..\0|
+00000010 82 02 58 30 82 01 8d a0 03 02 01 02 02 11 00 f2 |..X0............|
+00000020 99 26 eb 87 ea 8a 0d b9 fc c2 47 34 7c 11 b0 30 |.&........G4|..0|
+00000030 41 06 09 2a 86 48 86 f7 0d 01 01 0a 30 34 a0 0f |A..*.H......04..|
+00000040 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 a1 |0...`.H.e.......|
+00000050 1c 30 1a 06 09 2a 86 48 86 f7 0d 01 01 08 30 0d |.0...*.H......0.|
+00000060 06 09 60 86 48 01 65 03 04 02 01 05 00 a2 03 02 |..`.H.e.........|
+00000070 01 20 30 12 31 10 30 0e 06 03 55 04 0a 13 07 41 |. 0.1.0...U....A|
+00000080 63 6d 65 20 43 6f 30 1e 17 0d 31 37 31 31 32 33 |cme Co0...171123|
+00000090 31 36 31 36 31 30 5a 17 0d 31 38 31 31 32 33 31 |161610Z..1811231|
+000000a0 36 31 36 31 30 5a 30 12 31 10 30 0e 06 03 55 04 |61610Z0.1.0...U.|
+000000b0 0a 13 07 41 63 6d 65 20 43 6f 30 81 9f 30 0d 06 |...Acme Co0..0..|
+000000c0 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 |.*.H............|
+000000d0 30 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 |0.......F}...'.H|
+000000e0 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a |..(!.~...]..RE.z|
+000000f0 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 |6G....B[.....y.@|
+00000100 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e |.Om..+.....g....|
+00000110 d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 |."8.J.ts+.4.....|
+00000120 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b |.t{.X.la<..A..++|
+00000130 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 |$#w[.;.u]. T..c.|
+00000140 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 |..$....P....C...|
+00000150 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 46 30 44 |ub...R.......F0D|
+00000160 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 a0 |0...U...........|
+00000170 30 13 06 03 55 1d 25 04 0c 30 0a 06 08 2b 06 01 |0...U.%..0...+..|
+00000180 05 05 07 03 01 30 0c 06 03 55 1d 13 01 01 ff 04 |.....0...U......|
+00000190 02 30 00 30 0f 06 03 55 1d 11 04 08 30 06 87 04 |.0.0...U....0...|
+000001a0 7f 00 00 01 30 41 06 09 2a 86 48 86 f7 0d 01 01 |....0A..*.H.....|
+000001b0 0a 30 34 a0 0f 30 0d 06 09 60 86 48 01 65 03 04 |.04..0...`.H.e..|
+000001c0 02 01 05 00 a1 1c 30 1a 06 09 2a 86 48 86 f7 0d |......0...*.H...|
+000001d0 01 01 08 30 0d 06 09 60 86 48 01 65 03 04 02 01 |...0...`.H.e....|
+000001e0 05 00 a2 03 02 01 20 03 81 81 00 cd ac 4e f2 ce |...... ......N..|
+000001f0 5f 8d 79 88 10 42 70 7f 7c bf 1b 5a 8a 00 ef 19 |_.y..Bp.|..Z....|
+00000200 15 4b 40 15 17 71 00 6c d4 16 26 e5 49 6d 56 da |.K@..q.l..&.ImV.|
+00000210 0c 1a 13 9f d8 46 95 59 3c b6 7f 87 76 5e 18 aa |.....F.Y<...v^..|
+00000220 03 ea 06 75 22 dd 78 d2 a5 89 b8 c9 23 64 e1 28 |...u".x.....#d.(|
+00000230 38 ce 34 6c 6e 06 7b 51 f1 a7 e6 f4 b3 7f fa b1 |8.4ln.{Q........|
+00000240 3f 14 11 89 66 79 d1 8e 88 0e 0b a0 9e 30 2a c0 |?...fy.......0*.|
+00000250 67 ef ca 46 02 88 e9 53 81 22 69 22 97 ad 80 93 |g..F...S."i"....|
+00000260 d4 f7 dd 70 14 24 d7 70 0a 46 a1 16 03 03 00 25 |...p.$.p.F.....%|
+00000270 10 00 00 21 20 2f e5 7d a3 47 cd 62 43 15 28 da |...! /.}.G.bC.(.|
+00000280 ac 5f bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 |._.).0..........|
+00000290 5f 58 cb 3b 74 16 03 03 00 88 0f 00 00 84 08 04 |_X.;t...........|
+000002a0 00 80 a2 37 90 1d d9 05 16 91 e6 5d 93 ec d0 4c |...7.......]...L|
+000002b0 c9 eb ed d3 66 fc 36 55 ee cb e0 bc aa 41 11 fb |....f.6U.....A..|
+000002c0 91 d5 2c 81 d4 08 ee ce f8 96 cd 73 20 73 5b 8c |..,........s s[.|
+000002d0 85 45 17 fa 6d 06 db a6 68 49 5e a8 2b 86 83 0f |.E..m...hI^.+...|
+000002e0 e2 52 04 96 8c c9 a0 f8 ed 64 51 e3 6e b4 b1 48 |.R.......dQ.n..H|
+000002f0 c7 f6 21 c9 aa c0 8d 01 00 43 14 d3 16 ed 9a 3c |..!......C.....<|
+00000300 d2 14 57 90 22 f6 52 bc 44 64 88 40 03 93 56 8a |..W.".R.Dd.@..V.|
+00000310 4f 50 ad 73 ff bc b4 72 cd e2 01 01 50 88 f9 1c |OP.s...r....P...|
+00000320 4f 4d 14 03 03 00 01 01 16 03 03 00 28 00 00 00 |OM..........(...|
+00000330 00 00 00 00 00 07 15 02 d9 a8 bd 4b c4 61 57 e0 |...........K.aW.|
+00000340 a6 c0 11 05 bc 25 0b 4d fb 36 c4 19 80 e2 59 3e |.....%.M.6....Y>|
+00000350 00 a0 7b 87 42 |..{.B|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 28 8b ae 36 31 a0 |..........(..61.|
+00000010 0a ba f4 e8 45 6d e2 55 8d 9d 61 e4 80 b6 4e bb |....Em.U..a...N.|
+00000020 8c 7f e0 2b ea fc 4d e7 4c 60 c1 c6 91 92 ef 46 |...+..M.L`.....F|
+00000030 00 19 b9 |...|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 61 0d 4c |.............a.L|
+00000010 bf 57 34 f8 b3 f7 33 d6 49 46 66 14 e8 b2 e4 e0 |.W4...3.IFf.....|
+00000020 de 82 d1 15 03 03 00 1a 00 00 00 00 00 00 00 02 |................|
+00000030 76 2e 52 63 53 26 93 e3 32 59 de d9 62 e8 f4 93 |v.RcS&..2Y..b...|
+00000040 65 bc |e.|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES
new file mode 100644
index 0000000..dd7dfab
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES
@@ -0,0 +1,94 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 5d 02 00 00 59 03 03 53 0a a8 7d 57 |....]...Y..S..}W|
+00000010 28 ed 64 43 b5 dd b2 15 a8 6f 88 09 6a 90 4c 23 |(.dC.....o..j.L#|
+00000020 06 49 b6 1a 56 b5 a0 a2 68 af 7d 20 5a 4a d6 c3 |.I..V...h.} ZJ..|
+00000030 ed 18 12 98 b4 4e f8 f2 df d7 ee 6f e9 c6 c7 82 |.....N.....o....|
+00000040 5c bb 79 70 a5 59 51 c7 7f 41 7e 8e c0 09 00 00 |\.yp.YQ..A~.....|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 03 02 0e 0b 00 02 0a 00 02 07 00 02 |................|
+00000070 04 30 82 02 00 30 82 01 62 02 09 00 b8 bf 2d 47 |.0...0..b.....-G|
+00000080 a0 d2 eb f4 30 09 06 07 2a 86 48 ce 3d 04 01 30 |....0...*.H.=..0|
+00000090 45 31 0b 30 09 06 03 55 04 06 13 02 41 55 31 13 |E1.0...U....AU1.|
+000000a0 30 11 06 03 55 04 08 13 0a 53 6f 6d 65 2d 53 74 |0...U....Some-St|
+000000b0 61 74 65 31 21 30 1f 06 03 55 04 0a 13 18 49 6e |ate1!0...U....In|
+000000c0 74 65 72 6e 65 74 20 57 69 64 67 69 74 73 20 50 |ternet Widgits P|
+000000d0 74 79 20 4c 74 64 30 1e 17 0d 31 32 31 31 32 32 |ty Ltd0...121122|
+000000e0 31 35 30 36 33 32 5a 17 0d 32 32 31 31 32 30 31 |150632Z..2211201|
+000000f0 35 30 36 33 32 5a 30 45 31 0b 30 09 06 03 55 04 |50632Z0E1.0...U.|
+00000100 06 13 02 41 55 31 13 30 11 06 03 55 04 08 13 0a |...AU1.0...U....|
+00000110 53 6f 6d 65 2d 53 74 61 74 65 31 21 30 1f 06 03 |Some-State1!0...|
+00000120 55 04 0a 13 18 49 6e 74 65 72 6e 65 74 20 57 69 |U....Internet Wi|
+00000130 64 67 69 74 73 20 50 74 79 20 4c 74 64 30 81 9b |dgits Pty Ltd0..|
+00000140 30 10 06 07 2a 86 48 ce 3d 02 01 06 05 2b 81 04 |0...*.H.=....+..|
+00000150 00 23 03 81 86 00 04 00 c4 a1 ed be 98 f9 0b 48 |.#.............H|
+00000160 73 36 7e c3 16 56 11 22 f2 3d 53 c3 3b 4d 21 3d |s6~..V.".=S.;M!=|
+00000170 cd 6b 75 e6 f6 b0 dc 9a df 26 c1 bc b2 87 f0 72 |.ku......&.....r|
+00000180 32 7c b3 64 2f 1c 90 bc ea 68 23 10 7e fe e3 25 |2|.d/....h#.~..%|
+00000190 c0 48 3a 69 e0 28 6d d3 37 00 ef 04 62 dd 0d a0 |.H:i.(m.7...b...|
+000001a0 9c 70 62 83 d8 81 d3 64 31 aa 9e 97 31 bd 96 b0 |.pb....d1...1...|
+000001b0 68 c0 9b 23 de 76 64 3f 1a 5c 7f e9 12 0e 58 58 |h..#.vd?.\....XX|
+000001c0 b6 5f 70 dd 9b d8 ea d5 d7 f5 d5 cc b9 b6 9f 30 |._p............0|
+000001d0 66 5b 66 9a 20 e2 27 e5 bf fe 3b 30 09 06 07 2a |f[f. .'...;0...*|
+000001e0 86 48 ce 3d 04 01 03 81 8c 00 30 81 88 02 42 01 |.H.=......0...B.|
+000001f0 88 a2 4f eb e2 45 c5 48 7d 1b ac f5 ed 98 9d ae |..O..E.H}.......|
+00000200 47 70 c0 5e 1b b6 2f bd f1 b6 4d b7 61 40 d3 11 |Gp.^../...M.a@..|
+00000210 a2 ce ee 0b 7e 92 7e ff 76 9d c3 3b 7e a5 3f ce |....~.~.v..;~.?.|
+00000220 fa 10 e2 59 ec 47 2d 7c ac da 4e 97 0e 15 a0 6f |...Y.G-|..N....o|
+00000230 d0 02 42 01 4d fc be 67 13 9c 2d 05 0e bd 3f a3 |..B.M..g..-...?.|
+00000240 8c 25 c1 33 13 83 0d 94 06 bb d4 37 7a f6 ec 7a |.%.3.......7z..z|
+00000250 c9 86 2e dd d7 11 69 7f 85 7c 56 de fb 31 78 2b |......i..|V..1x+|
+00000260 e4 c7 78 0d ae cb be 9e 4e 36 24 31 7b 6a 0f 39 |..x.....N6$1{j.9|
+00000270 95 12 07 8f 2a 16 03 03 00 b7 0c 00 00 b3 03 00 |....*...........|
+00000280 1d 20 f5 a1 40 c1 31 8d 23 ee 2a 95 de 6f 22 a4 |. ..@.1.#.*..o".|
+00000290 98 03 77 82 92 67 0e cd 75 5a ac 95 90 07 70 77 |..w..g..uZ....pw|
+000002a0 c0 5b 04 03 00 8b 30 81 88 02 42 00 92 88 e3 97 |.[....0...B.....|
+000002b0 42 e5 0a ca b7 48 db 4a f0 a2 1d c7 b8 1b bb 4b |B....H.J.......K|
+000002c0 ea 5e 6c 40 b7 f7 de e1 b7 e5 b0 5e 8f fd 99 5b |.^l@.......^...[|
+000002d0 14 e4 4d 55 4b cb cd f7 9a 3a 77 a7 41 cf 15 26 |..MUK....:w.A..&|
+000002e0 79 a5 75 d8 c5 29 64 17 b7 16 7e e4 38 02 42 01 |y.u..)d...~.8.B.|
+000002f0 b2 74 0c 2f 4d 18 e3 88 6e fe 90 59 12 5d 2e ef |.t./M...n..Y.]..|
+00000300 36 c6 12 04 d5 aa 60 06 83 00 72 93 8c 5c f5 08 |6.....`...r..\..|
+00000310 26 38 f7 f6 64 b1 66 2f e4 35 cb 56 0c 67 61 1a |&8..d.f/.5.V.ga.|
+00000320 4d 16 8a ba 28 ba b5 ec 0b 61 38 79 db a3 65 c7 |M...(....a8y..e.|
+00000330 3e 16 03 03 00 04 0e 00 00 00 |>.........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.|
+00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....|
+00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 03 00 01 01 |....._X.;t......|
+00000030 16 03 03 00 40 00 00 00 00 00 00 00 00 00 00 00 |....@...........|
+00000040 00 00 00 00 00 7a 74 f0 c3 20 b7 87 3b 1b a6 86 |.....zt.. ..;...|
+00000050 0a cf c3 b9 0f 3e 40 39 ed 4e e0 db c0 77 69 b6 |.....>@9.N...wi.|
+00000060 79 cb 28 84 1f 88 72 5d 85 df 92 d2 05 ad bd 1b |y.(...r]........|
+00000070 34 ba 21 ee 46 |4.!.F|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 40 f3 23 7b 1c 0b |..........@.#{..|
+00000010 b3 07 a9 28 3f 33 84 7b 91 9c 7a b2 c2 df 89 6e |...(?3.{..z....n|
+00000020 aa 54 35 d7 09 ae 61 cf 90 3a 86 cd 7a 00 6b b1 |.T5...a..:..z.k.|
+00000030 1e 7f 55 4c f2 9e e5 4e 69 87 4f a1 eb bb d5 16 |..UL...Ni.O.....|
+00000040 03 11 08 24 1d bc 83 29 4d 48 41 |...$...)MHA|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
+00000010 00 00 00 00 00 f7 2c 65 61 5d 89 5d de 8d 42 92 |......,ea].]..B.|
+00000020 91 1e f4 71 39 42 a3 92 91 98 96 9f 95 04 86 99 |...q9B..........|
+00000030 c6 f3 e8 e1 e7 15 03 03 00 30 00 00 00 00 00 00 |.........0......|
+00000040 00 00 00 00 00 00 00 00 00 00 81 23 13 80 00 d8 |...........#....|
+00000050 1a 93 58 38 4d f0 6f 87 43 05 6d 63 6c e8 b9 80 |..X8M.o.C.mcl...|
+00000060 1c 52 12 59 ae ca a6 c8 3c e3 |.R.Y....<.|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES-GCM b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES-GCM
new file mode 100644
index 0000000..1b3e1e5
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES-GCM
@@ -0,0 +1,89 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 5d 02 00 00 59 03 03 d8 ac 8a ae 13 |....]...Y.......|
+00000010 8a e4 2d ac c0 a1 a3 d5 32 5b ca 18 5a 73 22 83 |..-.....2[..Zs".|
+00000020 d0 76 39 5c 48 40 b0 3a 75 87 5d 20 fd a3 fd b4 |.v9\H@.:u.] ....|
+00000030 32 cc 05 54 aa 59 cc 76 81 7b 29 c3 bc c6 32 c0 |2..T.Y.v.{)...2.|
+00000040 a9 52 fc ea 08 51 20 13 e3 e4 8e 68 c0 2b 00 00 |.R...Q ....h.+..|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 03 02 0e 0b 00 02 0a 00 02 07 00 02 |................|
+00000070 04 30 82 02 00 30 82 01 62 02 09 00 b8 bf 2d 47 |.0...0..b.....-G|
+00000080 a0 d2 eb f4 30 09 06 07 2a 86 48 ce 3d 04 01 30 |....0...*.H.=..0|
+00000090 45 31 0b 30 09 06 03 55 04 06 13 02 41 55 31 13 |E1.0...U....AU1.|
+000000a0 30 11 06 03 55 04 08 13 0a 53 6f 6d 65 2d 53 74 |0...U....Some-St|
+000000b0 61 74 65 31 21 30 1f 06 03 55 04 0a 13 18 49 6e |ate1!0...U....In|
+000000c0 74 65 72 6e 65 74 20 57 69 64 67 69 74 73 20 50 |ternet Widgits P|
+000000d0 74 79 20 4c 74 64 30 1e 17 0d 31 32 31 31 32 32 |ty Ltd0...121122|
+000000e0 31 35 30 36 33 32 5a 17 0d 32 32 31 31 32 30 31 |150632Z..2211201|
+000000f0 35 30 36 33 32 5a 30 45 31 0b 30 09 06 03 55 04 |50632Z0E1.0...U.|
+00000100 06 13 02 41 55 31 13 30 11 06 03 55 04 08 13 0a |...AU1.0...U....|
+00000110 53 6f 6d 65 2d 53 74 61 74 65 31 21 30 1f 06 03 |Some-State1!0...|
+00000120 55 04 0a 13 18 49 6e 74 65 72 6e 65 74 20 57 69 |U....Internet Wi|
+00000130 64 67 69 74 73 20 50 74 79 20 4c 74 64 30 81 9b |dgits Pty Ltd0..|
+00000140 30 10 06 07 2a 86 48 ce 3d 02 01 06 05 2b 81 04 |0...*.H.=....+..|
+00000150 00 23 03 81 86 00 04 00 c4 a1 ed be 98 f9 0b 48 |.#.............H|
+00000160 73 36 7e c3 16 56 11 22 f2 3d 53 c3 3b 4d 21 3d |s6~..V.".=S.;M!=|
+00000170 cd 6b 75 e6 f6 b0 dc 9a df 26 c1 bc b2 87 f0 72 |.ku......&.....r|
+00000180 32 7c b3 64 2f 1c 90 bc ea 68 23 10 7e fe e3 25 |2|.d/....h#.~..%|
+00000190 c0 48 3a 69 e0 28 6d d3 37 00 ef 04 62 dd 0d a0 |.H:i.(m.7...b...|
+000001a0 9c 70 62 83 d8 81 d3 64 31 aa 9e 97 31 bd 96 b0 |.pb....d1...1...|
+000001b0 68 c0 9b 23 de 76 64 3f 1a 5c 7f e9 12 0e 58 58 |h..#.vd?.\....XX|
+000001c0 b6 5f 70 dd 9b d8 ea d5 d7 f5 d5 cc b9 b6 9f 30 |._p............0|
+000001d0 66 5b 66 9a 20 e2 27 e5 bf fe 3b 30 09 06 07 2a |f[f. .'...;0...*|
+000001e0 86 48 ce 3d 04 01 03 81 8c 00 30 81 88 02 42 01 |.H.=......0...B.|
+000001f0 88 a2 4f eb e2 45 c5 48 7d 1b ac f5 ed 98 9d ae |..O..E.H}.......|
+00000200 47 70 c0 5e 1b b6 2f bd f1 b6 4d b7 61 40 d3 11 |Gp.^../...M.a@..|
+00000210 a2 ce ee 0b 7e 92 7e ff 76 9d c3 3b 7e a5 3f ce |....~.~.v..;~.?.|
+00000220 fa 10 e2 59 ec 47 2d 7c ac da 4e 97 0e 15 a0 6f |...Y.G-|..N....o|
+00000230 d0 02 42 01 4d fc be 67 13 9c 2d 05 0e bd 3f a3 |..B.M..g..-...?.|
+00000240 8c 25 c1 33 13 83 0d 94 06 bb d4 37 7a f6 ec 7a |.%.3.......7z..z|
+00000250 c9 86 2e dd d7 11 69 7f 85 7c 56 de fb 31 78 2b |......i..|V..1x+|
+00000260 e4 c7 78 0d ae cb be 9e 4e 36 24 31 7b 6a 0f 39 |..x.....N6$1{j.9|
+00000270 95 12 07 8f 2a 16 03 03 00 b7 0c 00 00 b3 03 00 |....*...........|
+00000280 1d 20 1b e5 74 f7 2a 8e 86 7d 32 5b 99 f7 e0 2d |. ..t.*..}2[...-|
+00000290 0d 96 a7 38 59 6c d9 50 7c 8a a2 2a 06 76 85 1f |...8Yl.P|..*.v..|
+000002a0 77 7b 04 03 00 8b 30 81 88 02 42 01 9e 35 d1 fc |w{....0...B..5..|
+000002b0 b8 16 97 b6 7b c4 6e 16 a9 de 5c 90 78 a6 d8 78 |....{.n...\.x..x|
+000002c0 be 38 98 ba 50 bc 88 bb f0 15 30 62 29 96 43 15 |.8..P.....0b).C.|
+000002d0 a7 7e 93 d4 3a 8c 2c 24 a5 7b e3 51 eb ef d4 16 |.~..:.,$.{.Q....|
+000002e0 9b d7 c2 c3 b1 10 54 fe 26 55 05 a7 79 02 42 01 |......T.&U..y.B.|
+000002f0 ca 62 10 6d b0 be 85 cf 3d ef a1 2f 9a 04 b9 6b |.b.m....=../...k|
+00000300 1d ec bf fc 4e 77 81 b2 70 50 98 26 b4 89 5f a9 |....Nw..pP.&.._.|
+00000310 d8 63 1a 54 79 f2 39 83 88 57 a0 25 cc a6 36 fa |.c.Ty.9..W.%..6.|
+00000320 31 c1 45 c5 8d 04 83 42 89 a4 15 c3 3e 61 71 1c |1.E....B....>aq.|
+00000330 53 16 03 03 00 04 0e 00 00 00 |S.........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.|
+00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....|
+00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 03 00 01 01 |....._X.;t......|
+00000030 16 03 03 00 28 00 00 00 00 00 00 00 00 4f 28 16 |....(........O(.|
+00000040 51 9e e7 01 d2 5c 25 d7 bb 42 4c fc d9 dc d7 7f |Q....\%..BL.....|
+00000050 2b 6c 5e 03 63 ce 19 ae 92 b8 c1 46 20 |+l^.c......F |
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 28 31 c5 7a e8 49 |..........(1.z.I|
+00000010 52 3d 85 b0 c4 7d 82 fa 08 a3 84 a9 58 8a 05 8c |R=...}......X...|
+00000020 9a 7c 6c 4e 29 fd 46 53 06 27 09 d2 38 f5 7c 5c |.|lN).FS.'..8.|\|
+00000030 fb ba 6b |..k|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 df 67 c1 |..............g.|
+00000010 b4 dd 34 b2 32 ea b4 00 1b b9 67 60 03 91 bf 17 |..4.2.....g`....|
+00000020 0d dd dc 15 03 03 00 1a 00 00 00 00 00 00 00 02 |................|
+00000030 7c a9 51 36 43 33 ab e4 35 15 cf 6f ef c5 ed c7 ||.Q6C3..5..o....|
+00000040 2f 4d |/M|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES128-SHA256 b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES128-SHA256
new file mode 100644
index 0000000..1e871a4
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES128-SHA256
@@ -0,0 +1,98 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 5d 02 00 00 59 03 03 32 b8 00 e5 21 |....]...Y..2...!|
+00000010 98 b0 8b 40 56 f2 af 06 fa 7d 1c 23 6a 01 c6 95 |...@V....}.#j...|
+00000020 41 9d 08 ac 5d de 0e 7e 39 57 07 20 b5 df a0 9a |A...]..~9W. ....|
+00000030 13 3f b4 ae 1f 54 eb 47 6a 5a d5 f1 07 22 8f 29 |.?...T.GjZ...".)|
+00000040 00 e8 9e e9 f6 76 80 ab 7d a8 23 4a c0 23 00 00 |.....v..}.#J.#..|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 03 02 0e 0b 00 02 0a 00 02 07 00 02 |................|
+00000070 04 30 82 02 00 30 82 01 62 02 09 00 b8 bf 2d 47 |.0...0..b.....-G|
+00000080 a0 d2 eb f4 30 09 06 07 2a 86 48 ce 3d 04 01 30 |....0...*.H.=..0|
+00000090 45 31 0b 30 09 06 03 55 04 06 13 02 41 55 31 13 |E1.0...U....AU1.|
+000000a0 30 11 06 03 55 04 08 13 0a 53 6f 6d 65 2d 53 74 |0...U....Some-St|
+000000b0 61 74 65 31 21 30 1f 06 03 55 04 0a 13 18 49 6e |ate1!0...U....In|
+000000c0 74 65 72 6e 65 74 20 57 69 64 67 69 74 73 20 50 |ternet Widgits P|
+000000d0 74 79 20 4c 74 64 30 1e 17 0d 31 32 31 31 32 32 |ty Ltd0...121122|
+000000e0 31 35 30 36 33 32 5a 17 0d 32 32 31 31 32 30 31 |150632Z..2211201|
+000000f0 35 30 36 33 32 5a 30 45 31 0b 30 09 06 03 55 04 |50632Z0E1.0...U.|
+00000100 06 13 02 41 55 31 13 30 11 06 03 55 04 08 13 0a |...AU1.0...U....|
+00000110 53 6f 6d 65 2d 53 74 61 74 65 31 21 30 1f 06 03 |Some-State1!0...|
+00000120 55 04 0a 13 18 49 6e 74 65 72 6e 65 74 20 57 69 |U....Internet Wi|
+00000130 64 67 69 74 73 20 50 74 79 20 4c 74 64 30 81 9b |dgits Pty Ltd0..|
+00000140 30 10 06 07 2a 86 48 ce 3d 02 01 06 05 2b 81 04 |0...*.H.=....+..|
+00000150 00 23 03 81 86 00 04 00 c4 a1 ed be 98 f9 0b 48 |.#.............H|
+00000160 73 36 7e c3 16 56 11 22 f2 3d 53 c3 3b 4d 21 3d |s6~..V.".=S.;M!=|
+00000170 cd 6b 75 e6 f6 b0 dc 9a df 26 c1 bc b2 87 f0 72 |.ku......&.....r|
+00000180 32 7c b3 64 2f 1c 90 bc ea 68 23 10 7e fe e3 25 |2|.d/....h#.~..%|
+00000190 c0 48 3a 69 e0 28 6d d3 37 00 ef 04 62 dd 0d a0 |.H:i.(m.7...b...|
+000001a0 9c 70 62 83 d8 81 d3 64 31 aa 9e 97 31 bd 96 b0 |.pb....d1...1...|
+000001b0 68 c0 9b 23 de 76 64 3f 1a 5c 7f e9 12 0e 58 58 |h..#.vd?.\....XX|
+000001c0 b6 5f 70 dd 9b d8 ea d5 d7 f5 d5 cc b9 b6 9f 30 |._p............0|
+000001d0 66 5b 66 9a 20 e2 27 e5 bf fe 3b 30 09 06 07 2a |f[f. .'...;0...*|
+000001e0 86 48 ce 3d 04 01 03 81 8c 00 30 81 88 02 42 01 |.H.=......0...B.|
+000001f0 88 a2 4f eb e2 45 c5 48 7d 1b ac f5 ed 98 9d ae |..O..E.H}.......|
+00000200 47 70 c0 5e 1b b6 2f bd f1 b6 4d b7 61 40 d3 11 |Gp.^../...M.a@..|
+00000210 a2 ce ee 0b 7e 92 7e ff 76 9d c3 3b 7e a5 3f ce |....~.~.v..;~.?.|
+00000220 fa 10 e2 59 ec 47 2d 7c ac da 4e 97 0e 15 a0 6f |...Y.G-|..N....o|
+00000230 d0 02 42 01 4d fc be 67 13 9c 2d 05 0e bd 3f a3 |..B.M..g..-...?.|
+00000240 8c 25 c1 33 13 83 0d 94 06 bb d4 37 7a f6 ec 7a |.%.3.......7z..z|
+00000250 c9 86 2e dd d7 11 69 7f 85 7c 56 de fb 31 78 2b |......i..|V..1x+|
+00000260 e4 c7 78 0d ae cb be 9e 4e 36 24 31 7b 6a 0f 39 |..x.....N6$1{j.9|
+00000270 95 12 07 8f 2a 16 03 03 00 b6 0c 00 00 b2 03 00 |....*...........|
+00000280 1d 20 f1 d6 ed a5 69 28 d2 bd 97 e3 00 e0 81 74 |. ....i(.......t|
+00000290 8d 36 6e 77 73 40 10 a1 73 b3 4d 8e 04 41 b1 0e |.6nws@..s.M..A..|
+000002a0 08 28 04 03 00 8a 30 81 87 02 42 01 4b b4 14 32 |.(....0...B.K..2|
+000002b0 13 88 f1 8d 3a 66 e2 a2 d6 d4 de 26 50 7d 74 22 |....:f.....&P}t"|
+000002c0 f9 56 83 00 0a b7 34 b3 96 99 0e c4 1d 8d 86 df |.V....4.........|
+000002d0 22 2b 1c d7 75 f5 c9 45 2a c7 8a 74 40 ae 04 ac |"+..u..E*..t@...|
+000002e0 b3 b4 5e c1 c5 e6 9c c3 01 ad 10 37 2b 02 41 4f |..^........7+.AO|
+000002f0 74 33 31 aa c0 f8 8e ac cf 5a 90 a5 b8 d1 52 76 |t31......Z....Rv|
+00000300 c3 a3 4f 0d 7d d7 8a 50 d3 bb 49 ce 22 ec d0 d3 |..O.}..P..I."...|
+00000310 b5 e3 5c c2 a9 54 2e 6f 9c d1 24 3d 70 7f 2b a3 |..\..T.o..$=p.+.|
+00000320 fe 24 fc 48 14 d3 8a f0 70 f3 1f af fe ae e3 fe |.$.H....p.......|
+00000330 16 03 03 00 04 0e 00 00 00 |.........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.|
+00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....|
+00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 03 00 01 01 |....._X.;t......|
+00000030 16 03 03 00 50 00 00 00 00 00 00 00 00 00 00 00 |....P...........|
+00000040 00 00 00 00 00 ea c6 10 80 cf 85 ad 7c 5f 6b 98 |............|_k.|
+00000050 7b 5a d6 47 84 dc 95 c9 ed 6e e6 c3 56 d5 91 93 |{Z.G.....n..V...|
+00000060 0e 3f b5 6c 2f 73 d9 72 9b f7 64 47 29 9e 75 4f |.?.l/s.r..dG).uO|
+00000070 97 2e 6d 94 52 f7 8f c9 24 5b d0 fe 05 aa e6 93 |..m.R...$[......|
+00000080 79 ea 37 0f 9e |y.7..|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 50 ed 02 93 7e 89 |..........P...~.|
+00000010 d5 d7 e9 0b 21 71 a9 cd b6 ac 65 6f 83 b2 0f 35 |....!q....eo...5|
+00000020 d6 1c bb df c5 c2 d6 6c b6 32 37 14 a0 0c fd ae |.......l.27.....|
+00000030 18 75 9e 82 df 00 ec 6c 99 e2 31 a3 35 e0 82 6d |.u.....l..1.5..m|
+00000040 57 5b 60 82 ec 69 8a 79 30 96 4f 96 bb 99 66 75 |W[`..i.y0.O...fu|
+00000050 5d 41 f9 04 fc f2 c6 bb 92 1c cb |]A.........|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 40 00 00 00 00 00 00 00 00 00 00 00 |....@...........|
+00000010 00 00 00 00 00 23 62 3f ed a2 99 3b ac 03 f5 8c |.....#b?...;....|
+00000020 3c 9f 71 25 b5 5c ec 2c 79 d5 70 ae 23 cf 2f 65 |<.q%.\.,y.p.#./e|
+00000030 3d 28 5f dd fb d6 6a 12 b5 5f eb 9f 2a 8e 79 80 |=(_...j.._..*.y.|
+00000040 eb 77 6e 7e b0 15 03 03 00 40 00 00 00 00 00 00 |.wn~.....@......|
+00000050 00 00 00 00 00 00 00 00 00 00 13 e1 0c 7b 01 90 |.............{..|
+00000060 e8 0d 2d 41 b5 c3 67 0a 37 c4 28 fa b6 88 cc 99 |..-A..g.7.(.....|
+00000070 f7 0a d9 25 09 24 88 f7 38 78 c4 1c 37 b4 3c a8 |...%.$..8x..7.<.|
+00000080 3d 2d ac a7 0d 45 62 9c 61 53 |=-...Eb.aS|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES256-GCM-SHA384 b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES256-GCM-SHA384
new file mode 100644
index 0000000..6477993
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES256-GCM-SHA384
@@ -0,0 +1,89 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 5d 02 00 00 59 03 03 99 43 3d 42 93 |....]...Y...C=B.|
+00000010 5a 7a 04 30 74 51 61 36 15 df ef a7 26 ef b8 76 |Zz.0tQa6....&..v|
+00000020 87 35 7a 88 75 83 9e 0d 2c d4 3d 20 1f 29 99 ea |.5z.u...,.= .)..|
+00000030 71 f7 c3 c4 68 3e 7f 58 7a 07 c7 2d a3 38 47 8d |q...h>.Xz..-.8G.|
+00000040 c9 ed 05 b4 8e e7 b6 85 5d a1 62 6b c0 2c 00 00 |........].bk.,..|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 03 02 0e 0b 00 02 0a 00 02 07 00 02 |................|
+00000070 04 30 82 02 00 30 82 01 62 02 09 00 b8 bf 2d 47 |.0...0..b.....-G|
+00000080 a0 d2 eb f4 30 09 06 07 2a 86 48 ce 3d 04 01 30 |....0...*.H.=..0|
+00000090 45 31 0b 30 09 06 03 55 04 06 13 02 41 55 31 13 |E1.0...U....AU1.|
+000000a0 30 11 06 03 55 04 08 13 0a 53 6f 6d 65 2d 53 74 |0...U....Some-St|
+000000b0 61 74 65 31 21 30 1f 06 03 55 04 0a 13 18 49 6e |ate1!0...U....In|
+000000c0 74 65 72 6e 65 74 20 57 69 64 67 69 74 73 20 50 |ternet Widgits P|
+000000d0 74 79 20 4c 74 64 30 1e 17 0d 31 32 31 31 32 32 |ty Ltd0...121122|
+000000e0 31 35 30 36 33 32 5a 17 0d 32 32 31 31 32 30 31 |150632Z..2211201|
+000000f0 35 30 36 33 32 5a 30 45 31 0b 30 09 06 03 55 04 |50632Z0E1.0...U.|
+00000100 06 13 02 41 55 31 13 30 11 06 03 55 04 08 13 0a |...AU1.0...U....|
+00000110 53 6f 6d 65 2d 53 74 61 74 65 31 21 30 1f 06 03 |Some-State1!0...|
+00000120 55 04 0a 13 18 49 6e 74 65 72 6e 65 74 20 57 69 |U....Internet Wi|
+00000130 64 67 69 74 73 20 50 74 79 20 4c 74 64 30 81 9b |dgits Pty Ltd0..|
+00000140 30 10 06 07 2a 86 48 ce 3d 02 01 06 05 2b 81 04 |0...*.H.=....+..|
+00000150 00 23 03 81 86 00 04 00 c4 a1 ed be 98 f9 0b 48 |.#.............H|
+00000160 73 36 7e c3 16 56 11 22 f2 3d 53 c3 3b 4d 21 3d |s6~..V.".=S.;M!=|
+00000170 cd 6b 75 e6 f6 b0 dc 9a df 26 c1 bc b2 87 f0 72 |.ku......&.....r|
+00000180 32 7c b3 64 2f 1c 90 bc ea 68 23 10 7e fe e3 25 |2|.d/....h#.~..%|
+00000190 c0 48 3a 69 e0 28 6d d3 37 00 ef 04 62 dd 0d a0 |.H:i.(m.7...b...|
+000001a0 9c 70 62 83 d8 81 d3 64 31 aa 9e 97 31 bd 96 b0 |.pb....d1...1...|
+000001b0 68 c0 9b 23 de 76 64 3f 1a 5c 7f e9 12 0e 58 58 |h..#.vd?.\....XX|
+000001c0 b6 5f 70 dd 9b d8 ea d5 d7 f5 d5 cc b9 b6 9f 30 |._p............0|
+000001d0 66 5b 66 9a 20 e2 27 e5 bf fe 3b 30 09 06 07 2a |f[f. .'...;0...*|
+000001e0 86 48 ce 3d 04 01 03 81 8c 00 30 81 88 02 42 01 |.H.=......0...B.|
+000001f0 88 a2 4f eb e2 45 c5 48 7d 1b ac f5 ed 98 9d ae |..O..E.H}.......|
+00000200 47 70 c0 5e 1b b6 2f bd f1 b6 4d b7 61 40 d3 11 |Gp.^../...M.a@..|
+00000210 a2 ce ee 0b 7e 92 7e ff 76 9d c3 3b 7e a5 3f ce |....~.~.v..;~.?.|
+00000220 fa 10 e2 59 ec 47 2d 7c ac da 4e 97 0e 15 a0 6f |...Y.G-|..N....o|
+00000230 d0 02 42 01 4d fc be 67 13 9c 2d 05 0e bd 3f a3 |..B.M..g..-...?.|
+00000240 8c 25 c1 33 13 83 0d 94 06 bb d4 37 7a f6 ec 7a |.%.3.......7z..z|
+00000250 c9 86 2e dd d7 11 69 7f 85 7c 56 de fb 31 78 2b |......i..|V..1x+|
+00000260 e4 c7 78 0d ae cb be 9e 4e 36 24 31 7b 6a 0f 39 |..x.....N6$1{j.9|
+00000270 95 12 07 8f 2a 16 03 03 00 b5 0c 00 00 b1 03 00 |....*...........|
+00000280 1d 20 fb 11 a5 85 16 55 f9 09 56 4a 4c f7 c8 a1 |. .....U..VJL...|
+00000290 fd 57 e3 4d 1e b5 78 df 7a b1 02 0c 42 60 80 f9 |.W.M..x.z...B`..|
+000002a0 4b 6e 04 03 00 89 30 81 86 02 41 4d 4a 3c 11 e1 |Kn....0...AMJ<..|
+000002b0 72 33 71 38 77 52 4d d8 78 ee 23 f9 f3 00 20 76 |r3q8wRM.x.#... v|
+000002c0 04 19 b2 4c 28 34 9d 22 b7 3e 1d 35 8f 93 ab 66 |...L(4.".>.5...f|
+000002d0 09 c4 7a 8e 8c 5a fc ae 1d c7 ba 2e 36 ea e7 0b |..z..Z......6...|
+000002e0 43 ae 03 e3 ec 6b f7 81 2e 22 e5 f0 02 41 39 95 |C....k..."...A9.|
+000002f0 22 5f b0 1a 5c 13 a0 c5 08 47 a7 51 9c fa 15 32 |"_..\....G.Q...2|
+00000300 95 84 95 8f 2f ed 38 19 bb b5 2b ac 39 90 a1 4c |..../.8...+.9..L|
+00000310 b5 20 49 cd 87 17 9d ef b4 c3 22 05 56 23 7d bc |. I.......".V#}.|
+00000320 6a d6 ae d9 e5 50 65 6c 8b df 4b 2e 6d e9 e3 16 |j....Pel..K.m...|
+00000330 03 03 00 04 0e 00 00 00 |........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.|
+00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....|
+00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 03 00 01 01 |....._X.;t......|
+00000030 16 03 03 00 28 00 00 00 00 00 00 00 00 ef cc 31 |....(..........1|
+00000040 f9 de 58 68 c9 6a c7 c4 3e 60 1f 4e f9 bf 27 87 |..Xh.j..>`.N..'.|
+00000050 b0 17 ed 83 17 a0 45 b7 a9 d8 95 b6 51 |......E.....Q|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 28 61 eb 42 a7 10 |..........(a.B..|
+00000010 6f 1a ef 4d e5 4d df 75 cb 8e 59 f8 06 e0 f9 ee |o..M.M.u..Y.....|
+00000020 d1 a9 11 7b 89 97 62 b9 76 d1 8e eb ee 30 dd 0f |...{..b.v....0..|
+00000030 60 b1 e1 |`..|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 fb 32 66 |..............2f|
+00000010 d6 d5 e1 52 31 8d 63 4f 5c a0 ac b5 f3 64 dc 40 |...R1.cO\....d.@|
+00000020 f5 93 5a 15 03 03 00 1a 00 00 00 00 00 00 00 02 |..Z.............|
+00000030 6b 66 c3 db e8 33 66 14 9b 4b 1c 59 bf 9e 6c 7e |kf...3f..K.Y..l~|
+00000040 2d 1e |-.|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-CHACHA20-POLY1305 b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-CHACHA20-POLY1305
new file mode 100644
index 0000000..e1b45cb
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-CHACHA20-POLY1305
@@ -0,0 +1,84 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 d4 01 00 00 d0 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 08 cc a9 |................|
+00000050 13 03 13 01 13 02 01 00 00 7f 00 05 00 05 01 00 |................|
+00000060 00 00 00 00 0a 00 0a 00 08 00 1d 00 17 00 18 00 |................|
+00000070 19 00 0b 00 02 01 00 00 0d 00 1a 00 18 08 04 04 |................|
+00000080 03 08 07 08 05 08 06 04 01 05 01 06 01 05 03 06 |................|
+00000090 03 02 01 02 03 ff 01 00 01 00 00 17 00 00 00 12 |................|
+000000a0 00 00 00 2b 00 09 08 03 04 03 03 03 02 03 01 00 |...+............|
+000000b0 33 00 26 00 24 00 1d 00 20 2f e5 7d a3 47 cd 62 |3.&.$... /.}.G.b|
+000000c0 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 cf |C.(.._.).0......|
+000000d0 c2 ed 90 99 5f 58 cb 3b 74 |...._X.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 5d 02 00 00 59 03 03 f0 39 6d 08 4c |....]...Y...9m.L|
+00000010 1e c8 06 4d 9e 1e 2a 27 d9 17 6f 39 19 38 ba 49 |...M..*'..o9.8.I|
+00000020 a5 fa b2 6d a2 70 e8 9d b2 03 92 20 09 ef 68 cb |...m.p..... ..h.|
+00000030 58 2a fd 4b 60 9a 1e af f4 02 c0 cb 10 b2 dd 73 |X*.K`..........s|
+00000040 0c e0 6a da 3f cd 3a a3 a3 55 58 00 cc a9 00 00 |..j.?.:..UX.....|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 03 02 0e 0b 00 02 0a 00 02 07 00 02 |................|
+00000070 04 30 82 02 00 30 82 01 62 02 09 00 b8 bf 2d 47 |.0...0..b.....-G|
+00000080 a0 d2 eb f4 30 09 06 07 2a 86 48 ce 3d 04 01 30 |....0...*.H.=..0|
+00000090 45 31 0b 30 09 06 03 55 04 06 13 02 41 55 31 13 |E1.0...U....AU1.|
+000000a0 30 11 06 03 55 04 08 13 0a 53 6f 6d 65 2d 53 74 |0...U....Some-St|
+000000b0 61 74 65 31 21 30 1f 06 03 55 04 0a 13 18 49 6e |ate1!0...U....In|
+000000c0 74 65 72 6e 65 74 20 57 69 64 67 69 74 73 20 50 |ternet Widgits P|
+000000d0 74 79 20 4c 74 64 30 1e 17 0d 31 32 31 31 32 32 |ty Ltd0...121122|
+000000e0 31 35 30 36 33 32 5a 17 0d 32 32 31 31 32 30 31 |150632Z..2211201|
+000000f0 35 30 36 33 32 5a 30 45 31 0b 30 09 06 03 55 04 |50632Z0E1.0...U.|
+00000100 06 13 02 41 55 31 13 30 11 06 03 55 04 08 13 0a |...AU1.0...U....|
+00000110 53 6f 6d 65 2d 53 74 61 74 65 31 21 30 1f 06 03 |Some-State1!0...|
+00000120 55 04 0a 13 18 49 6e 74 65 72 6e 65 74 20 57 69 |U....Internet Wi|
+00000130 64 67 69 74 73 20 50 74 79 20 4c 74 64 30 81 9b |dgits Pty Ltd0..|
+00000140 30 10 06 07 2a 86 48 ce 3d 02 01 06 05 2b 81 04 |0...*.H.=....+..|
+00000150 00 23 03 81 86 00 04 00 c4 a1 ed be 98 f9 0b 48 |.#.............H|
+00000160 73 36 7e c3 16 56 11 22 f2 3d 53 c3 3b 4d 21 3d |s6~..V.".=S.;M!=|
+00000170 cd 6b 75 e6 f6 b0 dc 9a df 26 c1 bc b2 87 f0 72 |.ku......&.....r|
+00000180 32 7c b3 64 2f 1c 90 bc ea 68 23 10 7e fe e3 25 |2|.d/....h#.~..%|
+00000190 c0 48 3a 69 e0 28 6d d3 37 00 ef 04 62 dd 0d a0 |.H:i.(m.7...b...|
+000001a0 9c 70 62 83 d8 81 d3 64 31 aa 9e 97 31 bd 96 b0 |.pb....d1...1...|
+000001b0 68 c0 9b 23 de 76 64 3f 1a 5c 7f e9 12 0e 58 58 |h..#.vd?.\....XX|
+000001c0 b6 5f 70 dd 9b d8 ea d5 d7 f5 d5 cc b9 b6 9f 30 |._p............0|
+000001d0 66 5b 66 9a 20 e2 27 e5 bf fe 3b 30 09 06 07 2a |f[f. .'...;0...*|
+000001e0 86 48 ce 3d 04 01 03 81 8c 00 30 81 88 02 42 01 |.H.=......0...B.|
+000001f0 88 a2 4f eb e2 45 c5 48 7d 1b ac f5 ed 98 9d ae |..O..E.H}.......|
+00000200 47 70 c0 5e 1b b6 2f bd f1 b6 4d b7 61 40 d3 11 |Gp.^../...M.a@..|
+00000210 a2 ce ee 0b 7e 92 7e ff 76 9d c3 3b 7e a5 3f ce |....~.~.v..;~.?.|
+00000220 fa 10 e2 59 ec 47 2d 7c ac da 4e 97 0e 15 a0 6f |...Y.G-|..N....o|
+00000230 d0 02 42 01 4d fc be 67 13 9c 2d 05 0e bd 3f a3 |..B.M..g..-...?.|
+00000240 8c 25 c1 33 13 83 0d 94 06 bb d4 37 7a f6 ec 7a |.%.3.......7z..z|
+00000250 c9 86 2e dd d7 11 69 7f 85 7c 56 de fb 31 78 2b |......i..|V..1x+|
+00000260 e4 c7 78 0d ae cb be 9e 4e 36 24 31 7b 6a 0f 39 |..x.....N6$1{j.9|
+00000270 95 12 07 8f 2a 16 03 03 00 b7 0c 00 00 b3 03 00 |....*...........|
+00000280 1d 20 f0 e0 d6 3e 40 a0 97 de 26 8a 52 25 2c a7 |. ...>@...&.R%,.|
+00000290 78 c5 ed 73 5c 59 ca 02 a8 9e 0d 69 bd cc bb 4b |x..s\Y.....i...K|
+000002a0 11 3d 04 03 00 8b 30 81 88 02 42 00 ed 4d bc dc |.=....0...B..M..|
+000002b0 d7 5e 95 b4 13 b3 fb 40 38 1a 53 09 71 a4 14 2a |.^.....@8.S.q..*|
+000002c0 45 6f e3 fe db 0a c8 32 05 e6 98 17 bb f8 e9 72 |Eo.....2.......r|
+000002d0 db 5d e8 f5 b2 ad df 1b 62 dd b2 98 f8 6b 38 13 |.]......b....k8.|
+000002e0 a9 2f 13 1b ea db 58 24 4b e2 3a b9 5a 02 42 00 |./....X$K.:.Z.B.|
+000002f0 ea cd 03 cb b9 67 5c f3 99 35 cc 57 2a 58 12 45 |.....g\..5.W*X.E|
+00000300 c9 f1 e4 27 1a 42 2c ce 9c ba 10 f8 6f 15 41 67 |...'.B,.....o.Ag|
+00000310 07 33 38 94 dd 34 57 90 41 cf 16 04 b7 fc af ae |.38..4W.A.......|
+00000320 6b ac 16 87 75 6d 60 52 e7 b9 1e 85 a3 45 92 a4 |k...um`R.....E..|
+00000330 cf 16 03 03 00 04 0e 00 00 00 |..........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.|
+00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....|
+00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 03 00 01 01 |....._X.;t......|
+00000030 16 03 03 00 20 24 01 e0 f7 26 b8 69 62 f7 98 45 |.... $...&.ib..E|
+00000040 6f 6d fc eb 37 c9 69 f1 21 eb 13 70 57 a9 5b de |om..7.i.!..pW.[.|
+00000050 37 30 64 cc c1 |70d..|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 20 8d fd f9 fd 18 |.......... .....|
+00000010 08 fa c1 5b 1c d1 03 bc ba 36 6b 69 30 72 9c 92 |...[.....6ki0r..|
+00000020 f9 56 0c 5e ed 7b 91 e8 42 6c 26 |.V.^.{..Bl&|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 16 94 1f 97 8b 5b 66 15 63 a5 1e 78 |.........[f.c..x|
+00000010 c2 e3 4e 96 ae 08 16 d6 33 b8 60 15 03 03 00 12 |..N.....3.`.....|
+00000020 f9 71 c8 e5 93 b4 0d 17 97 0f 6d cb 58 0f 59 64 |.q........m.X.Yd|
+00000030 12 0f |..|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES
new file mode 100644
index 0000000..d5665da
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES
@@ -0,0 +1,98 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 5d 02 00 00 59 03 03 1e 8b e8 b6 ab |....]...Y.......|
+00000010 28 56 58 92 6d 03 e6 46 aa 94 dc 6d a0 7b 6f db |(VX.m..F...m.{o.|
+00000020 09 22 9f 48 14 de 37 bf 54 68 42 20 f8 0f 31 09 |.".H..7.ThB ..1.|
+00000030 56 de 8f ad db d7 ab 38 66 8b cf 86 1c 84 0d 9c |V......8f.......|
+00000040 ad 24 c8 35 a8 28 8d 06 10 23 5e 34 c0 13 00 00 |.$.5.(...#^4....|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 03 02 59 0b 00 02 55 00 02 52 00 02 |......Y...U..R..|
+00000070 4f 30 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 |O0..K0..........|
+00000080 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 |....?.[..0...*.H|
+00000090 86 f7 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 |........0.1.0...|
+000000a0 55 04 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 |U....Go1.0...U..|
+000000b0 13 07 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 |..Go Root0...160|
+000000c0 31 30 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 |101000000Z..2501|
+000000d0 30 31 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 |01000000Z0.1.0..|
+000000e0 03 55 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 |.U....Go1.0...U.|
+000000f0 03 13 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 |...Go0..0...*.H.|
+00000100 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 |...........0....|
+00000110 81 00 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab |...F}...'.H..(!.|
+00000120 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d |~...]..RE.z6G...|
+00000130 92 42 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd |.B[.....y.@.Om..|
+00000140 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a |+.....g....."8.J|
+00000150 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 |.ts+.4......t{.X|
+00000160 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c |.la<..A..++$#w[.|
+00000170 3b bd 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 |;.u]. T..c...$..|
+00000180 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 |..P....C...ub...|
+00000190 52 d7 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 |R.........0..0..|
+000001a0 03 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 |.U...........0..|
+000001b0 03 55 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 |.U.%..0...+.....|
+000001c0 03 01 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 |....+.......0...|
+000001d0 55 1d 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d |U.......0.0...U.|
+000001e0 0e 04 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d |.........CC>I..m|
+000001f0 b6 80 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 |....`0...U.#..0.|
+00000200 80 10 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab |..H.IM.~.1......|
+00000210 6e 7b 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 |n{0...U....0...e|
+00000220 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 |xample.golang0..|
+00000230 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 |.*.H............|
+00000240 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed |.0.@+[P.a...SX..|
+00000250 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 |.(.X..8....1Z..f|
+00000260 3d 43 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a |=C.-...... d8.$:|
+00000270 00 bc cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 |....}.@ ._...a..|
+00000280 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed |v......\.....l..|
+00000290 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 |s..Cw.......@.a.|
+000002a0 4c 72 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 |Lr+...F..M...>..|
+000002b0 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 |.B...=.`.\!.;...|
+000002c0 16 03 03 00 ac 0c 00 00 a8 03 00 1d 20 e6 56 06 |............ .V.|
+000002d0 58 6f 5d 7a 59 32 f5 3e 7b 07 17 de 27 62 9e e8 |Xo]zY2.>{...'b..|
+000002e0 d0 42 f1 97 56 66 d0 d5 c1 06 b9 48 2f 08 04 00 |.B..Vf.....H/...|
+000002f0 80 1d 63 88 8e ed 58 f2 0e d3 b3 17 46 f3 9c 49 |..c...X.....F..I|
+00000300 bb 22 22 eb e2 77 13 6c a5 aa 77 fe ad 16 06 23 |.""..w.l..w....#|
+00000310 c3 2a ec b9 76 43 4a 7f 41 72 5f 53 ae de 70 3a |.*..vCJ.Ar_S..p:|
+00000320 f2 e9 60 92 30 2e f3 df a1 3d 4a c1 1f 26 fa 42 |..`.0....=J..&.B|
+00000330 c8 31 cb 97 c0 5c 6b 8e d9 18 28 be 99 7c d1 75 |.1...\k...(..|.u|
+00000340 05 ad 22 91 4f 55 ae 50 2c fa 37 ee 28 e9 64 1c |..".OU.P,.7.(.d.|
+00000350 2b 2a c5 95 f5 90 ae ae d4 a3 50 f3 fe 26 71 4f |+*........P..&qO|
+00000360 55 db 32 03 1f 5c 3f 91 20 85 d5 e1 73 45 43 59 |U.2..\?. ...sECY|
+00000370 e5 16 03 03 00 04 0e 00 00 00 |..........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.|
+00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....|
+00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 03 00 01 01 |....._X.;t......|
+00000030 16 03 03 00 40 00 00 00 00 00 00 00 00 00 00 00 |....@...........|
+00000040 00 00 00 00 00 f9 b1 38 55 39 80 ba c1 07 e1 40 |.......8U9.....@|
+00000050 b9 ac 39 da bc 66 ad c3 6d dc 1b f0 bd 2a 92 ce |..9..f..m....*..|
+00000060 4b b5 97 33 5b 3b 21 6d 91 f4 dd 09 07 73 5d a2 |K..3[;!m.....s].|
+00000070 b4 a3 a0 6d 43 |...mC|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 40 82 12 f1 e0 35 |..........@....5|
+00000010 74 0c e5 68 7c 6b b6 fb e9 36 b3 5e 95 13 6b 04 |t..h|k...6.^..k.|
+00000020 00 59 18 f0 51 50 93 2e e9 1b c6 e9 11 62 7c 01 |.Y..QP.......b|.|
+00000030 43 e8 68 7b 87 a9 d5 17 3f 73 de f2 06 12 9f c7 |C.h{....?s......|
+00000040 a4 81 45 52 dd 9f 6f fa ab 82 86 |..ER..o....|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
+00000010 00 00 00 00 00 21 96 5b 74 b3 c1 96 e9 4f 6d 97 |.....!.[t....Om.|
+00000020 70 1c 5d c2 60 32 a1 98 12 2b 0d 4c 11 03 fe 17 |p.].`2...+.L....|
+00000030 28 92 06 2f 84 15 03 03 00 30 00 00 00 00 00 00 |(../.....0......|
+00000040 00 00 00 00 00 00 00 00 00 00 78 bf 75 9e 08 8d |..........x.u...|
+00000050 57 5a 22 17 e9 d3 bd 3c e4 ac e6 58 7a e8 5e 45 |WZ"....<...Xz.^E|
+00000060 63 10 b6 b8 df 78 c5 10 48 c0 |c....x..H.|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES128-SHA256 b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES128-SHA256
new file mode 100644
index 0000000..03679a4
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES128-SHA256
@@ -0,0 +1,102 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 5d 02 00 00 59 03 03 3d 4c 61 a3 1e |....]...Y..=La..|
+00000010 dd 9a c3 52 42 9d ee 2b 7b f6 24 a4 38 d7 93 e9 |...RB..+{.$.8...|
+00000020 f5 f4 09 a2 0f 2b 45 ae 7d fd 97 20 3b b6 27 a6 |.....+E.}.. ;.'.|
+00000030 88 dd af 75 8d 27 1c c6 ef 8f 4b 33 c6 30 be 08 |...u.'....K3.0..|
+00000040 7d bd 8d cd 2e d8 37 0b 67 e3 39 30 c0 27 00 00 |}.....7.g.90.'..|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 03 02 59 0b 00 02 55 00 02 52 00 02 |......Y...U..R..|
+00000070 4f 30 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 |O0..K0..........|
+00000080 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 |....?.[..0...*.H|
+00000090 86 f7 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 |........0.1.0...|
+000000a0 55 04 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 |U....Go1.0...U..|
+000000b0 13 07 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 |..Go Root0...160|
+000000c0 31 30 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 |101000000Z..2501|
+000000d0 30 31 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 |01000000Z0.1.0..|
+000000e0 03 55 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 |.U....Go1.0...U.|
+000000f0 03 13 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 |...Go0..0...*.H.|
+00000100 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 |...........0....|
+00000110 81 00 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab |...F}...'.H..(!.|
+00000120 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d |~...]..RE.z6G...|
+00000130 92 42 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd |.B[.....y.@.Om..|
+00000140 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a |+.....g....."8.J|
+00000150 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 |.ts+.4......t{.X|
+00000160 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c |.la<..A..++$#w[.|
+00000170 3b bd 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 |;.u]. T..c...$..|
+00000180 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 |..P....C...ub...|
+00000190 52 d7 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 |R.........0..0..|
+000001a0 03 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 |.U...........0..|
+000001b0 03 55 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 |.U.%..0...+.....|
+000001c0 03 01 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 |....+.......0...|
+000001d0 55 1d 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d |U.......0.0...U.|
+000001e0 0e 04 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d |.........CC>I..m|
+000001f0 b6 80 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 |....`0...U.#..0.|
+00000200 80 10 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab |..H.IM.~.1......|
+00000210 6e 7b 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 |n{0...U....0...e|
+00000220 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 |xample.golang0..|
+00000230 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 |.*.H............|
+00000240 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed |.0.@+[P.a...SX..|
+00000250 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 |.(.X..8....1Z..f|
+00000260 3d 43 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a |=C.-...... d8.$:|
+00000270 00 bc cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 |....}.@ ._...a..|
+00000280 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed |v......\.....l..|
+00000290 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 |s..Cw.......@.a.|
+000002a0 4c 72 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 |Lr+...F..M...>..|
+000002b0 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 |.B...=.`.\!.;...|
+000002c0 16 03 03 00 ac 0c 00 00 a8 03 00 1d 20 a4 26 51 |............ .&Q|
+000002d0 47 58 cf 92 87 27 f0 c1 c0 39 55 dd 20 16 39 de |GX...'...9U. .9.|
+000002e0 ed 79 66 3a 97 54 75 35 27 20 7b 99 76 08 04 00 |.yf:.Tu5' {.v...|
+000002f0 80 34 32 55 55 c1 56 69 b8 4a f7 a6 d1 9d ae f6 |.42UU.Vi.J......|
+00000300 0d de 13 e2 bd b8 9a 5c 42 f2 b5 42 d9 25 69 fe |.......\B..B.%i.|
+00000310 ef b3 c3 0f 1b b7 a0 61 1d 1d 59 31 1c 4c 61 17 |.......a..Y1.La.|
+00000320 6e 2d bc b4 08 76 ee d2 46 d4 81 c1 cc e9 96 22 |n-...v..F......"|
+00000330 10 07 a5 c0 c6 26 42 c6 37 42 56 e5 47 f2 44 d1 |.....&B.7BV.G.D.|
+00000340 57 1d c8 8d c1 2c 28 be e9 7a 82 2e f1 8e 1a bf |W....,(..z......|
+00000350 4a f0 f2 22 de 78 00 c2 d3 f4 99 ba e9 d3 7e fc |J..".x........~.|
+00000360 83 bf ef 7c 64 c6 c4 dd fb 30 e2 f9 43 43 91 60 |...|d....0..CC.`|
+00000370 83 16 03 03 00 04 0e 00 00 00 |..........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.|
+00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....|
+00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 03 00 01 01 |....._X.;t......|
+00000030 16 03 03 00 50 00 00 00 00 00 00 00 00 00 00 00 |....P...........|
+00000040 00 00 00 00 00 06 06 f1 9b b7 1f f1 0d 24 fe 76 |.............$.v|
+00000050 8a 72 84 58 8c 56 bd c3 73 4e c8 99 3c 5b 21 79 |.r.X.V..sN..<[!y|
+00000060 17 23 21 bd 72 0d fb f7 22 36 99 78 1f 88 d1 87 |.#!.r..."6.x....|
+00000070 73 c3 62 aa a5 22 a6 63 68 41 bb 61 34 50 b9 e7 |s.b..".chA.a4P..|
+00000080 ce 6d 0b 18 f0 |.m...|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 50 f4 00 f2 81 78 |..........P....x|
+00000010 0f 4b d9 3a 2d 62 34 77 74 6e b6 d5 e8 62 55 88 |.K.:-b4wtn...bU.|
+00000020 7e 60 e4 e7 b7 35 9d dc 50 02 d2 10 ae 36 7a 5d |~`...5..P....6z]|
+00000030 36 c5 89 2c 4e db 9c 83 9e d0 ec de 6e 63 1c 94 |6..,N.......nc..|
+00000040 4c ed 12 ca ef 62 a1 26 a7 f9 fd 52 ad b9 1a 2b |L....b.&...R...+|
+00000050 cc bc 01 bb cc 86 b5 1b 74 60 80 |........t`.|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 40 00 00 00 00 00 00 00 00 00 00 00 |....@...........|
+00000010 00 00 00 00 00 67 6b 64 7b 02 ce ad 5c df 4d 26 |.....gkd{...\.M&|
+00000020 f9 ef d5 94 ec 34 28 de 52 1a d9 1b e3 af 89 11 |.....4(.R.......|
+00000030 7b aa f6 46 8a 27 e7 15 c0 81 89 78 20 09 ca 37 |{..F.'.....x ..7|
+00000040 dc a3 c2 5c 4f 15 03 03 00 40 00 00 00 00 00 00 |...\O....@......|
+00000050 00 00 00 00 00 00 00 00 00 00 61 45 e8 a0 f8 70 |..........aE...p|
+00000060 7b a3 75 09 42 b2 41 54 79 b3 75 48 47 f1 36 1b |{.u.B.ATy.uHG.6.|
+00000070 4c cd 29 57 fe 9f 41 a7 7f 5c a9 12 7a ec c6 1d |L.)W..A..\..z...|
+00000080 9c fb ff 1e e5 58 04 ae 16 50 |.....X...P|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-CHACHA20-POLY1305 b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-CHACHA20-POLY1305
new file mode 100644
index 0000000..3c5779c
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-CHACHA20-POLY1305
@@ -0,0 +1,88 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 d4 01 00 00 d0 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 08 cc a8 |................|
+00000050 13 03 13 01 13 02 01 00 00 7f 00 05 00 05 01 00 |................|
+00000060 00 00 00 00 0a 00 0a 00 08 00 1d 00 17 00 18 00 |................|
+00000070 19 00 0b 00 02 01 00 00 0d 00 1a 00 18 08 04 04 |................|
+00000080 03 08 07 08 05 08 06 04 01 05 01 06 01 05 03 06 |................|
+00000090 03 02 01 02 03 ff 01 00 01 00 00 17 00 00 00 12 |................|
+000000a0 00 00 00 2b 00 09 08 03 04 03 03 03 02 03 01 00 |...+............|
+000000b0 33 00 26 00 24 00 1d 00 20 2f e5 7d a3 47 cd 62 |3.&.$... /.}.G.b|
+000000c0 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 cf |C.(.._.).0......|
+000000d0 c2 ed 90 99 5f 58 cb 3b 74 |...._X.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 5d 02 00 00 59 03 03 fa 07 a1 2e 81 |....]...Y.......|
+00000010 44 c8 72 44 5b 86 21 61 2f 3e 37 92 0f d5 7f d3 |D.rD[.!a/>7.....|
+00000020 0b 11 9a 5f d9 40 db 25 e4 2d da 20 11 0f ba 98 |..._.@.%.-. ....|
+00000030 8b fd 6f 93 c7 05 08 69 d6 c5 bc ef 3e 2b b8 98 |..o....i....>+..|
+00000040 10 f6 bc 57 72 81 a9 c0 96 1e a4 d2 cc a8 00 00 |...Wr...........|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 03 02 59 0b 00 02 55 00 02 52 00 02 |......Y...U..R..|
+00000070 4f 30 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 |O0..K0..........|
+00000080 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 |....?.[..0...*.H|
+00000090 86 f7 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 |........0.1.0...|
+000000a0 55 04 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 |U....Go1.0...U..|
+000000b0 13 07 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 |..Go Root0...160|
+000000c0 31 30 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 |101000000Z..2501|
+000000d0 30 31 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 |01000000Z0.1.0..|
+000000e0 03 55 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 |.U....Go1.0...U.|
+000000f0 03 13 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 |...Go0..0...*.H.|
+00000100 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 |...........0....|
+00000110 81 00 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab |...F}...'.H..(!.|
+00000120 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d |~...]..RE.z6G...|
+00000130 92 42 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd |.B[.....y.@.Om..|
+00000140 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a |+.....g....."8.J|
+00000150 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 |.ts+.4......t{.X|
+00000160 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c |.la<..A..++$#w[.|
+00000170 3b bd 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 |;.u]. T..c...$..|
+00000180 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 |..P....C...ub...|
+00000190 52 d7 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 |R.........0..0..|
+000001a0 03 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 |.U...........0..|
+000001b0 03 55 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 |.U.%..0...+.....|
+000001c0 03 01 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 |....+.......0...|
+000001d0 55 1d 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d |U.......0.0...U.|
+000001e0 0e 04 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d |.........CC>I..m|
+000001f0 b6 80 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 |....`0...U.#..0.|
+00000200 80 10 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab |..H.IM.~.1......|
+00000210 6e 7b 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 |n{0...U....0...e|
+00000220 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 |xample.golang0..|
+00000230 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 |.*.H............|
+00000240 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed |.0.@+[P.a...SX..|
+00000250 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 |.(.X..8....1Z..f|
+00000260 3d 43 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a |=C.-...... d8.$:|
+00000270 00 bc cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 |....}.@ ._...a..|
+00000280 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed |v......\.....l..|
+00000290 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 |s..Cw.......@.a.|
+000002a0 4c 72 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 |Lr+...F..M...>..|
+000002b0 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 |.B...=.`.\!.;...|
+000002c0 16 03 03 00 ac 0c 00 00 a8 03 00 1d 20 c7 4c 84 |............ .L.|
+000002d0 aa 9d be 0a bb 72 d2 bc 76 73 59 9b 07 e1 6f 94 |.....r..vsY...o.|
+000002e0 25 e7 13 7a 4c a5 8d f9 ab 9d 30 d0 4c 08 04 00 |%..zL.....0.L...|
+000002f0 80 88 4d ea e2 83 d7 b6 50 fb 22 e0 a9 32 87 8e |..M.....P."..2..|
+00000300 cf e3 3d 94 bc 07 99 c3 b7 53 9d f6 0c 80 77 f7 |..=......S....w.|
+00000310 96 50 39 eb 85 33 9e 17 72 14 f7 3f e6 c2 9b 94 |.P9..3..r..?....|
+00000320 bb bc 26 b9 c6 68 1f 2a 19 d6 40 f5 8b 85 a4 8d |..&..h.*..@.....|
+00000330 c8 29 96 bf d1 e1 15 f7 f8 75 66 42 00 45 d3 ff |.).......ufB.E..|
+00000340 4d ef f7 ad 7b b5 00 3e 9f 08 b8 ce 87 df d9 fa |M...{..>........|
+00000350 79 b9 d1 a4 a3 a7 ad 0b 2b fc 65 c2 51 dc 8c 29 |y.......+.e.Q..)|
+00000360 85 31 92 f9 b3 dd 1a a1 f1 f0 9c 21 9d a0 6e 49 |.1.........!..nI|
+00000370 ff 16 03 03 00 04 0e 00 00 00 |..........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.|
+00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....|
+00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 03 00 01 01 |....._X.;t......|
+00000030 16 03 03 00 20 61 fc dc e1 f7 bf 7b 90 e4 af 71 |.... a.....{...q|
+00000040 03 22 10 79 6d d9 e9 aa 1d 60 8e 40 d1 1e 3a 94 |.".ym....`.@..:.|
+00000050 ca 78 86 ad e6 |.x...|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 20 39 ee c6 1c d9 |.......... 9....|
+00000010 83 3e d3 bf 8a c3 3d bb 0a 27 7a 95 84 ef 82 e1 |.>....=..'z.....|
+00000020 80 6b 25 bf 68 dc 58 63 21 80 7d |.k%.h.Xc!.}|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 16 e6 75 bb fe 46 1a 4c 75 41 36 eb |......u..F.LuA6.|
+00000010 a9 31 d9 59 74 9d 75 76 db 00 94 15 03 03 00 12 |.1.Yt.uv........|
+00000020 f0 a9 56 8e bd a5 bb c8 2d ea be d7 7f 9e 39 7a |..V.....-.....9z|
+00000030 4f de |O.|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-Ed25519 b/src/crypto/tls/testdata/Client-TLSv12-Ed25519
new file mode 100644
index 0000000..b2380ed
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-Ed25519
@@ -0,0 +1,69 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 5d 02 00 00 59 03 03 17 80 d3 0b 73 |....]...Y......s|
+00000010 6d e4 3e 2d 7a 35 ab ab 65 ad a0 03 14 cb e8 98 |m.>-z5..e.......|
+00000020 3a d3 c6 41 39 b2 78 c2 1b 06 da 20 ec 80 a9 c4 |:..A9.x.... ....|
+00000030 7c b8 9b cc b3 98 7a cd 97 40 41 39 b7 75 13 7a ||.....z..@A9.u.z|
+00000040 40 33 ec 9d 69 97 32 5b f5 6e 4f bc cc a9 00 00 |@3..i.2[.nO.....|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 03 01 3c 0b 00 01 38 00 01 35 00 01 |......<...8..5..|
+00000070 32 30 82 01 2e 30 81 e1 a0 03 02 01 02 02 10 0f |20...0..........|
+00000080 43 1c 42 57 93 94 1d e9 87 e4 f1 ad 15 00 5d 30 |C.BW..........]0|
+00000090 05 06 03 2b 65 70 30 12 31 10 30 0e 06 03 55 04 |...+ep0.1.0...U.|
+000000a0 0a 13 07 41 63 6d 65 20 43 6f 30 1e 17 0d 31 39 |...Acme Co0...19|
+000000b0 30 35 31 36 32 31 33 38 30 31 5a 17 0d 32 30 30 |0516213801Z..200|
+000000c0 35 31 35 32 31 33 38 30 31 5a 30 12 31 10 30 0e |515213801Z0.1.0.|
+000000d0 06 03 55 04 0a 13 07 41 63 6d 65 20 43 6f 30 2a |..U....Acme Co0*|
+000000e0 30 05 06 03 2b 65 70 03 21 00 3f e2 15 2e e6 e3 |0...+ep.!.?.....|
+000000f0 ef 3f 4e 85 4a 75 77 a3 64 9e ed e0 bf 84 2c cc |.?N.Juw.d.....,.|
+00000100 92 26 8f fa 6f 34 83 aa ec 8f a3 4d 30 4b 30 0e |.&..o4.....M0K0.|
+00000110 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 13 |..U...........0.|
+00000120 06 03 55 1d 25 04 0c 30 0a 06 08 2b 06 01 05 05 |..U.%..0...+....|
+00000130 07 03 01 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 |...0...U.......0|
+00000140 00 30 16 06 03 55 1d 11 04 0f 30 0d 82 0b 65 78 |.0...U....0...ex|
+00000150 61 6d 70 6c 65 2e 63 6f 6d 30 05 06 03 2b 65 70 |ample.com0...+ep|
+00000160 03 41 00 63 44 ed 9c c4 be 53 24 53 9f d2 10 8d |.A.cD....S$S....|
+00000170 9f e8 21 08 90 95 39 e5 0d c1 55 ff 2c 16 b7 1d |..!...9...U.,...|
+00000180 fc ab 7d 4d d4 e0 93 13 d0 a9 42 e0 b6 6b fe 5d |..}M......B..k.]|
+00000190 67 48 d7 9f 50 bc 6c cd 4b 03 83 7c f2 08 58 cd |gH..P.l.K..|..X.|
+000001a0 ac cf 0c 16 03 03 00 6c 0c 00 00 68 03 00 1d 20 |.......l...h... |
+000001b0 6b 23 39 84 eb 4d db d0 0c f4 5a 9f ce bf 3a a8 |k#9..M....Z...:.|
+000001c0 52 df 00 9b 14 10 31 95 21 35 07 f1 7f 22 bf 14 |R.....1.!5..."..|
+000001d0 08 07 00 40 f6 b8 53 ed 97 7f 5a 28 88 84 f4 aa |...@..S...Z(....|
+000001e0 64 30 dc 4c 80 1f 8f 62 9d 52 aa bb e7 98 e1 7f |d0.L...b.R......|
+000001f0 12 19 b5 84 d2 4b 92 b1 38 a9 4e c2 09 1a 91 bf |.....K..8.N.....|
+00000200 4a 83 5e a4 82 a0 36 84 85 0d bd b5 a9 4f 2f 60 |J.^...6......O/`|
+00000210 a4 2f 33 0d 16 03 03 00 04 0e 00 00 00 |./3..........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.|
+00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....|
+00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 03 00 01 01 |....._X.;t......|
+00000030 16 03 03 00 20 a2 a9 10 50 bb d9 12 ee 74 a1 79 |.... ...P....t.y|
+00000040 cb fa 36 73 26 89 4e a4 2d 14 c0 ac f3 7b 82 c6 |..6s&.N.-....{..|
+00000050 cf fb 00 88 9e |.....|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 20 22 85 b9 b0 e7 |.......... "....|
+00000010 14 c0 a6 a9 91 4e 08 80 83 75 92 b5 45 9d 13 e9 |.....N...u..E...|
+00000020 0f 45 e7 55 ac b7 68 93 b4 bb 00 |.E.U..h....|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 16 0a c8 36 60 97 80 1c d5 d5 3c 3d |.......6`.....<=|
+00000010 07 4f 9b 2c 75 6c a0 b1 9a 2c b8 15 03 03 00 12 |.O.,ul...,......|
+00000020 fc a4 95 ae ee fe e2 4f ad b2 13 e0 c9 a7 2a 5a |.......O......*Z|
+00000030 54 2c |T,|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ExportKeyingMaterial b/src/crypto/tls/testdata/Client-TLSv12-ExportKeyingMaterial
new file mode 100644
index 0000000..cbd1fbd
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ExportKeyingMaterial
@@ -0,0 +1,91 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 5d 02 00 00 59 03 03 86 45 94 b6 f3 |....]...Y...E...|
+00000010 30 74 36 25 50 09 38 f6 3e 4a 5a b6 bf 06 fd 01 |0t6%P.8.>JZ.....|
+00000020 4b 35 b0 bc ef 77 bf f6 e9 a2 84 20 97 96 9b ba |K5...w..... ....|
+00000030 24 5f 28 cd 16 3f d3 f4 2b 92 da 09 a5 18 2f 21 |$_(..?..+...../!|
+00000040 d8 23 85 9a c9 4a 69 36 93 ab c2 5a cc a8 00 00 |.#...Ji6...Z....|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 03 02 59 0b 00 02 55 00 02 52 00 02 |......Y...U..R..|
+00000070 4f 30 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 |O0..K0..........|
+00000080 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 |....?.[..0...*.H|
+00000090 86 f7 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 |........0.1.0...|
+000000a0 55 04 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 |U....Go1.0...U..|
+000000b0 13 07 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 |..Go Root0...160|
+000000c0 31 30 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 |101000000Z..2501|
+000000d0 30 31 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 |01000000Z0.1.0..|
+000000e0 03 55 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 |.U....Go1.0...U.|
+000000f0 03 13 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 |...Go0..0...*.H.|
+00000100 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 |...........0....|
+00000110 81 00 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab |...F}...'.H..(!.|
+00000120 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d |~...]..RE.z6G...|
+00000130 92 42 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd |.B[.....y.@.Om..|
+00000140 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a |+.....g....."8.J|
+00000150 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 |.ts+.4......t{.X|
+00000160 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c |.la<..A..++$#w[.|
+00000170 3b bd 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 |;.u]. T..c...$..|
+00000180 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 |..P....C...ub...|
+00000190 52 d7 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 |R.........0..0..|
+000001a0 03 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 |.U...........0..|
+000001b0 03 55 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 |.U.%..0...+.....|
+000001c0 03 01 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 |....+.......0...|
+000001d0 55 1d 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d |U.......0.0...U.|
+000001e0 0e 04 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d |.........CC>I..m|
+000001f0 b6 80 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 |....`0...U.#..0.|
+00000200 80 10 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab |..H.IM.~.1......|
+00000210 6e 7b 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 |n{0...U....0...e|
+00000220 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 |xample.golang0..|
+00000230 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 |.*.H............|
+00000240 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed |.0.@+[P.a...SX..|
+00000250 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 |.(.X..8....1Z..f|
+00000260 3d 43 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a |=C.-...... d8.$:|
+00000270 00 bc cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 |....}.@ ._...a..|
+00000280 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed |v......\.....l..|
+00000290 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 |s..Cw.......@.a.|
+000002a0 4c 72 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 |Lr+...F..M...>..|
+000002b0 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 |.B...=.`.\!.;...|
+000002c0 16 03 03 00 ac 0c 00 00 a8 03 00 1d 20 34 09 94 |............ 4..|
+000002d0 56 6a c3 3b 88 60 42 3d 1d f2 99 a1 8e 56 72 e3 |Vj.;.`B=.....Vr.|
+000002e0 09 83 17 04 60 08 ad db 70 c6 f6 77 2a 08 04 00 |....`...p..w*...|
+000002f0 80 80 1c d5 53 c0 5b 1f 86 e9 d7 16 18 0d 50 3c |....S.[.......P<|
+00000300 b6 40 1f 58 ea 79 e6 af cf a1 cf 55 3f e1 fe 04 |.@.X.y.....U?...|
+00000310 bc e5 1c 4a ae 36 e9 7b 64 a1 76 ea 43 bc 8f a7 |...J.6.{d.v.C...|
+00000320 0a 8a 8b d1 af 54 57 21 9b 55 10 90 91 07 f7 96 |.....TW!.U......|
+00000330 68 68 33 ec 4b c4 70 08 88 92 59 2d 4d 86 47 d9 |hh3.K.p...Y-M.G.|
+00000340 8a a7 d2 22 b4 ab 83 0e 3b 29 79 fd 1b f7 5b c8 |..."....;)y...[.|
+00000350 b2 d5 3a be 74 e7 b5 c8 6e 4e c4 8d c5 70 6c 98 |..:.t...nN...pl.|
+00000360 fe 57 f9 2e c0 8c d3 38 39 e9 0e c1 17 c9 8d 36 |.W.....89......6|
+00000370 47 16 03 03 00 04 0e 00 00 00 |G.........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.|
+00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....|
+00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 03 00 01 01 |....._X.;t......|
+00000030 16 03 03 00 20 35 b3 34 ef 69 93 b1 31 f1 da 9c |.... 5.4.i..1...|
+00000040 3f 49 e5 99 8f af 4f 3b 48 52 b9 a3 fa 42 e7 3e |?I....O;HR...B.>|
+00000050 29 4c 22 b7 0a |)L"..|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 20 cd 8f ee d3 57 |.......... ....W|
+00000010 a5 e4 c0 4c 83 91 37 e2 5b 30 aa a1 52 ed 6c 42 |...L..7.[0..R.lB|
+00000020 5b d6 59 1c 9f f7 c6 69 c9 2a 5d |[.Y....i.*]|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 16 c9 3b 66 6a 59 3a b6 be 39 a0 db |......;fjY:..9..|
+00000010 e9 b4 d8 e1 f5 a6 15 70 4a fc e7 15 03 03 00 12 |.......pJ.......|
+00000020 1b c5 fe f3 89 a3 0d d6 1e 23 2d 54 d6 01 62 3c |.........#-T..b<|
+00000030 af 0c |..|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-P256-ECDHE b/src/crypto/tls/testdata/Client-TLSv12-P256-ECDHE
new file mode 100644
index 0000000..9b6c750
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-P256-ECDHE
@@ -0,0 +1,98 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 01 19 01 00 01 15 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 9a 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 04 00 02 00 17 00 0b 00 02 01 00 00 0d 00 1a 00 |................|
+000000a0 18 08 04 04 03 08 07 08 05 08 06 04 01 05 01 06 |................|
+000000b0 01 05 03 06 03 02 01 02 03 ff 01 00 01 00 00 17 |................|
+000000c0 00 00 00 12 00 00 00 2b 00 09 08 03 04 03 03 03 |.......+........|
+000000d0 02 03 01 00 33 00 47 00 45 00 17 00 41 04 1e 18 |....3.G.E...A...|
+000000e0 37 ef 0d 19 51 88 35 75 71 b5 e5 54 5b 12 2e 8f |7...Q.5uq..T[...|
+000000f0 09 67 fd a7 24 20 3e b2 56 1c ce 97 28 5e f8 2b |.g..$ >.V...(^.+|
+00000100 2d 4f 9e f1 07 9f 6c 4b 5b 83 56 e2 32 42 e9 58 |-O....lK[.V.2B.X|
+00000110 b6 d7 49 a6 b5 68 1a 41 03 56 6b dc 5a 89 |..I..h.A.Vk.Z.|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 5d 02 00 00 59 03 03 a4 cd 94 7e 17 |....]...Y.....~.|
+00000010 86 6e 81 dc 58 f5 86 34 fc 66 25 77 df 05 e5 85 |.n..X..4.f%w....|
+00000020 98 2e b4 38 e3 54 98 93 f5 ef 9e 20 db e9 53 1a |...8.T..... ..S.|
+00000030 67 e3 18 c1 64 66 4f 92 7f d6 44 42 a0 b3 04 d9 |g...dfO...DB....|
+00000040 c3 5f f2 6a 89 e6 fd e9 6d bf 2c a6 c0 2f 00 00 |._.j....m.,../..|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 03 02 59 0b 00 02 55 00 02 52 00 02 |......Y...U..R..|
+00000070 4f 30 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 |O0..K0..........|
+00000080 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 |....?.[..0...*.H|
+00000090 86 f7 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 |........0.1.0...|
+000000a0 55 04 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 |U....Go1.0...U..|
+000000b0 13 07 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 |..Go Root0...160|
+000000c0 31 30 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 |101000000Z..2501|
+000000d0 30 31 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 |01000000Z0.1.0..|
+000000e0 03 55 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 |.U....Go1.0...U.|
+000000f0 03 13 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 |...Go0..0...*.H.|
+00000100 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 |...........0....|
+00000110 81 00 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab |...F}...'.H..(!.|
+00000120 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d |~...]..RE.z6G...|
+00000130 92 42 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd |.B[.....y.@.Om..|
+00000140 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a |+.....g....."8.J|
+00000150 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 |.ts+.4......t{.X|
+00000160 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c |.la<..A..++$#w[.|
+00000170 3b bd 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 |;.u]. T..c...$..|
+00000180 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 |..P....C...ub...|
+00000190 52 d7 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 |R.........0..0..|
+000001a0 03 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 |.U...........0..|
+000001b0 03 55 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 |.U.%..0...+.....|
+000001c0 03 01 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 |....+.......0...|
+000001d0 55 1d 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d |U.......0.0...U.|
+000001e0 0e 04 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d |.........CC>I..m|
+000001f0 b6 80 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 |....`0...U.#..0.|
+00000200 80 10 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab |..H.IM.~.1......|
+00000210 6e 7b 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 |n{0...U....0...e|
+00000220 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 |xample.golang0..|
+00000230 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 |.*.H............|
+00000240 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed |.0.@+[P.a...SX..|
+00000250 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 |.(.X..8....1Z..f|
+00000260 3d 43 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a |=C.-...... d8.$:|
+00000270 00 bc cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 |....}.@ ._...a..|
+00000280 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed |v......\.....l..|
+00000290 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 |s..Cw.......@.a.|
+000002a0 4c 72 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 |Lr+...F..M...>..|
+000002b0 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 |.B...=.`.\!.;...|
+000002c0 16 03 03 00 cd 0c 00 00 c9 03 00 17 41 04 28 4d |............A.(M|
+000002d0 03 04 41 d2 e5 04 f6 34 90 21 2e bc da 53 95 9d |..A....4.!...S..|
+000002e0 2b 10 d8 b5 e2 e1 47 06 08 b7 7a 4a d4 13 3a f9 |+.....G...zJ..:.|
+000002f0 50 22 c0 fb 4e 13 b9 1f b9 43 20 71 be b8 e1 9b |P"..N....C q....|
+00000300 c8 6b 48 fb 80 22 87 8a 61 54 fb c1 7a 7e 08 04 |.kH.."..aT..z~..|
+00000310 00 80 86 09 16 06 8e 1c c9 02 ec 9d d9 4d c0 d1 |.............M..|
+00000320 d1 d0 48 96 f6 31 4a 69 02 9e 27 26 ca ff bb 1e |..H..1Ji..'&....|
+00000330 94 3b fb 41 fa 11 a5 cd ec a7 a0 6f 4c 35 dc 7a |.;.A.......oL5.z|
+00000340 fb fd c4 41 ab 5b ee 21 96 16 9d 42 8f ce b6 50 |...A.[.!...B...P|
+00000350 6a 48 9f 92 d2 00 70 53 30 c3 3d 5e a9 cb e3 f1 |jH....pS0.=^....|
+00000360 52 19 c8 1a 58 f5 19 9a 11 a2 ea 9d a2 29 5e b2 |R...X........)^.|
+00000370 ef bb c1 a6 c5 2c e4 33 2f 6d 60 ac 34 42 dc 42 |.....,.3/m`.4B.B|
+00000380 85 69 e3 c6 b8 2d af c4 37 8e b8 b6 39 4e 07 ff |.i...-..7...9N..|
+00000390 88 d0 16 03 03 00 04 0e 00 00 00 |...........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 46 10 00 00 42 41 04 1e 18 37 ef 0d |....F...BA...7..|
+00000010 19 51 88 35 75 71 b5 e5 54 5b 12 2e 8f 09 67 fd |.Q.5uq..T[....g.|
+00000020 a7 24 20 3e b2 56 1c ce 97 28 5e f8 2b 2d 4f 9e |.$ >.V...(^.+-O.|
+00000030 f1 07 9f 6c 4b 5b 83 56 e2 32 42 e9 58 b6 d7 49 |...lK[.V.2B.X..I|
+00000040 a6 b5 68 1a 41 03 56 6b dc 5a 89 14 03 03 00 01 |..h.A.Vk.Z......|
+00000050 01 16 03 03 00 28 00 00 00 00 00 00 00 00 e3 ce |.....(..........|
+00000060 26 ff 24 7b cf 1a 6e 65 68 3d 56 ca 11 6c 7c a6 |&.${..neh=V..l|.|
+00000070 de 97 f1 f3 cd 04 4e 38 bd 0c 5b 08 1b dd |......N8..[...|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 28 38 ac 96 e8 6f |..........(8...o|
+00000010 bc 22 ba 46 a9 64 f6 dc 19 79 5e 01 cd 50 db 9e |.".F.d...y^..P..|
+00000020 98 23 19 2a f2 25 49 b9 f1 cb 63 c5 5e 32 85 c4 |.#.*.%I...c.^2..|
+00000030 e0 e5 16 |...|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 b7 b1 9c |................|
+00000010 5d 9f f1 b7 21 b3 30 00 9d 39 26 5f 6e 99 67 e8 |]...!.0..9&_n.g.|
+00000020 47 01 62 15 03 03 00 1a 00 00 00 00 00 00 00 02 |G.b.............|
+00000030 2a 2f 3f 76 2a 10 9b ee c0 86 41 8a fe cf c5 70 |*/?v*.....A....p|
+00000040 c7 ac |..|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-RSA-RC4 b/src/crypto/tls/testdata/Client-TLSv12-RSA-RC4
new file mode 100644
index 0000000..f995680
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-RSA-RC4
@@ -0,0 +1,86 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 55 02 00 00 51 03 03 d4 a4 5a fb c9 |....U...Q....Z..|
+00000010 93 ee 7e 5a c4 04 8e bb 72 da ad a4 0f 9c 0f 6e |..~Z....r......n|
+00000020 2b 28 9a ef 28 be d4 49 9b 50 56 20 f8 5a e3 7b |+(..(..I.PV .Z.{|
+00000030 c7 96 74 ff 52 4f 68 32 08 15 2b 46 ad 47 3e 49 |..t.ROh2..+F.G>I|
+00000040 f9 a7 f8 65 78 fe 01 c0 8f ab 8e 14 00 05 00 00 |...ex...........|
+00000050 09 ff 01 00 01 00 00 17 00 00 16 03 03 02 59 0b |..............Y.|
+00000060 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..|
+00000070 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.|
+00000080 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........|
+00000090 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1|
+000000a0 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo|
+000000b0 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000|
+000000c0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000|
+000000d0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go|
+000000e0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..|
+000000f0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........|
+00000100 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...|
+00000110 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R|
+00000120 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....|
+00000130 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.|
+00000140 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..|
+00000150 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.|
+00000160 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.|
+00000170 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C|
+00000180 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......|
+00000190 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......|
+000001a0 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.|
+000001b0 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...|
+000001c0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......|
+000001d0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........|
+000001e0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..|
+000001f0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~|
+00000200 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.|
+00000210 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g|
+00000220 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....|
+00000230 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.|
+00000240 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.|
+00000250 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....|
+00000260 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ |
+00000270 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\|
+00000280 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...|
+00000290 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.|
+000002a0 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`|
+000002b0 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e 00 00 |.\!.;...........|
+000002c0 00 |.|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 86 10 00 00 82 00 80 b9 65 8d bf a7 |............e...|
+00000010 c8 4b 79 ce 6f cb 8b 13 1c ac b9 7d 66 5e e9 ba |.Ky.o......}f^..|
+00000020 1d 71 4e a9 e9 34 ae f6 64 65 90 3b d8 16 52 a2 |.qN..4..de.;..R.|
+00000030 6f f4 cb 8a 13 74 a2 ee b7 27 69 b4 41 c0 90 68 |o....t...'i.A..h|
+00000040 bc 02 69 e1 c6 48 4f 39 36 30 25 ca 4c 17 ce 83 |..i..HO960%.L...|
+00000050 9e 08 56 e3 05 49 93 9e 2e c4 fb e6 c8 01 f1 0f |..V..I..........|
+00000060 c5 70 0f 08 83 48 e9 48 ef 6e 50 8b 05 7e e5 84 |.p...H.H.nP..~..|
+00000070 25 fa 55 c7 ae 31 02 27 00 ef 3f 98 86 20 12 89 |%.U..1.'..?.. ..|
+00000080 91 59 28 b4 f7 d7 af d2 69 61 35 14 03 03 00 01 |.Y(.....ia5.....|
+00000090 01 16 03 03 00 24 f7 3b 92 e7 9f 80 de 5b d4 9e |.....$.;.....[..|
+000000a0 d3 02 d3 d9 2c e1 74 2e 98 90 fe d9 ee 08 57 28 |....,.t.......W(|
+000000b0 47 99 86 84 f5 95 c5 a6 7f 82 |G.........|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 24 c9 09 6c e8 0b |..........$..l..|
+00000010 44 56 62 ed 1f f1 ef 9d a9 cd a4 49 01 0d 2b e3 |DVb........I..+.|
+00000020 8f 3d 31 6d bf c5 63 af d4 59 30 47 c6 cd 20 |.=1m..c..Y0G.. |
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 1a 65 05 a9 14 f7 fd 4e e1 68 20 7e |.....e.....N.h ~|
+00000010 32 79 ca e6 e7 79 a3 d6 ce fd 28 37 c7 e2 c5 15 |2y...y....(7....|
+00000020 03 03 00 16 87 82 bc 62 e3 c0 4d 2e 75 86 21 05 |.......b..M.u.!.|
+00000030 c0 3d 40 d4 1d fc 1b 42 ef 55 |.=@....B.U|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-RenegotiateOnce b/src/crypto/tls/testdata/Client-TLSv12-RenegotiateOnce
new file mode 100644
index 0000000..30db289
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-RenegotiateOnce
@@ -0,0 +1,246 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 5d 02 00 00 59 03 03 6d a7 e6 c4 60 |....]...Y..m...`|
+00000010 8e dd 95 85 14 dc 69 2b d5 16 35 dd 4f a1 43 d4 |......i+..5.O.C.|
+00000020 3c 8f 0f 55 4b f1 86 68 51 5b 17 20 d8 44 06 84 |<..UK..hQ[. .D..|
+00000030 d5 1d 9b ed 45 25 d0 e8 a2 73 fd 44 01 fa 38 63 |....E%...s.D..8c|
+00000040 c3 18 35 1c b8 54 ec 78 ab 5f 3d f3 cc a8 00 00 |..5..T.x._=.....|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 03 02 59 0b 00 02 55 00 02 52 00 02 |......Y...U..R..|
+00000070 4f 30 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 |O0..K0..........|
+00000080 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 |....?.[..0...*.H|
+00000090 86 f7 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 |........0.1.0...|
+000000a0 55 04 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 |U....Go1.0...U..|
+000000b0 13 07 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 |..Go Root0...160|
+000000c0 31 30 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 |101000000Z..2501|
+000000d0 30 31 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 |01000000Z0.1.0..|
+000000e0 03 55 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 |.U....Go1.0...U.|
+000000f0 03 13 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 |...Go0..0...*.H.|
+00000100 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 |...........0....|
+00000110 81 00 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab |...F}...'.H..(!.|
+00000120 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d |~...]..RE.z6G...|
+00000130 92 42 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd |.B[.....y.@.Om..|
+00000140 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a |+.....g....."8.J|
+00000150 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 |.ts+.4......t{.X|
+00000160 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c |.la<..A..++$#w[.|
+00000170 3b bd 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 |;.u]. T..c...$..|
+00000180 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 |..P....C...ub...|
+00000190 52 d7 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 |R.........0..0..|
+000001a0 03 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 |.U...........0..|
+000001b0 03 55 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 |.U.%..0...+.....|
+000001c0 03 01 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 |....+.......0...|
+000001d0 55 1d 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d |U.......0.0...U.|
+000001e0 0e 04 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d |.........CC>I..m|
+000001f0 b6 80 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 |....`0...U.#..0.|
+00000200 80 10 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab |..H.IM.~.1......|
+00000210 6e 7b 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 |n{0...U....0...e|
+00000220 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 |xample.golang0..|
+00000230 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 |.*.H............|
+00000240 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed |.0.@+[P.a...SX..|
+00000250 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 |.(.X..8....1Z..f|
+00000260 3d 43 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a |=C.-...... d8.$:|
+00000270 00 bc cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 |....}.@ ._...a..|
+00000280 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed |v......\.....l..|
+00000290 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 |s..Cw.......@.a.|
+000002a0 4c 72 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 |Lr+...F..M...>..|
+000002b0 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 |.B...=.`.\!.;...|
+000002c0 16 03 03 00 ac 0c 00 00 a8 03 00 1d 20 f1 ac a3 |............ ...|
+000002d0 08 ba 9d 89 8e 71 c3 db b1 46 f0 ac 2f 32 13 ad |.....q...F../2..|
+000002e0 f7 42 ee b5 9f e5 5c 52 46 0a 9a 53 75 08 04 00 |.B....\RF..Su...|
+000002f0 80 89 8c 5b cd e9 fe 7f 6b 15 36 bc d7 43 ed f3 |...[....k.6..C..|
+00000300 96 df 69 7c 65 26 f8 68 4f 5b fb 53 75 2c 5a 65 |..i|e&.hO[.Su,Ze|
+00000310 4d b4 7b c5 bd 36 71 ea 43 bb 84 ec f3 8f 6b 49 |M.{..6q.C.....kI|
+00000320 26 cb fa c1 4c 8b 92 e1 91 ed 09 61 7d 85 44 ea |&...L......a}.D.|
+00000330 a7 1c a4 47 02 d2 b4 c0 bf 44 14 e8 03 64 8d 86 |...G.....D...d..|
+00000340 80 5c 63 eb ab a0 66 ca 30 2e d7 04 54 d8 91 94 |.\c...f.0...T...|
+00000350 37 e8 6c b8 00 a0 06 98 5c 67 c2 46 a2 e9 5c b8 |7.l.....\g.F..\.|
+00000360 66 46 b8 82 65 22 29 80 b8 af 50 37 5c 00 96 a5 |fF..e")...P7\...|
+00000370 85 16 03 03 00 04 0e 00 00 00 |..........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.|
+00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....|
+00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 03 00 01 01 |....._X.;t......|
+00000030 16 03 03 00 20 ca 08 57 0f 80 64 62 ad 11 01 27 |.... ..W..db...'|
+00000040 39 d8 80 6c a6 05 f6 75 a1 b6 0d 72 c0 25 f7 bc |9..l...u...r.%..|
+00000050 f0 de 76 ee 29 |..v.)|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 20 27 45 9d b0 c3 |.......... 'E...|
+00000010 18 c6 34 cb 1a 38 33 ac 91 4f f1 e5 d5 02 ed 62 |..4..83..O.....b|
+00000020 c0 46 1e a0 4a b3 46 35 2e e1 a2 |.F..J.F5...|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 16 50 48 06 41 d8 9d 1b e9 8b 55 9b |.....PH.A.....U.|
+00000010 3c ba ea 58 93 5b 56 17 6e 94 18 |<..X.[V.n..|
+>>> Flow 6 (server to client)
+00000000 16 03 03 00 14 4c 65 ba 49 aa 53 4c 73 0a 51 ac |.....Le.I.SLs.Q.|
+00000010 43 0d 4c 1f 83 6b d9 b1 06 |C.L..k...|
+>>> Flow 7 (client to server)
+00000000 16 03 03 01 1a fd 7a 4e 2b 7b 8a 07 cc cb 5b 82 |......zN+{....[.|
+00000010 df d1 00 69 f8 6f 89 28 4b 91 87 c8 18 20 ec 41 |...i.o.(K.... .A|
+00000020 ec c7 bd 04 3d 02 a5 42 fe e1 23 cc 20 aa 22 e8 |....=..B..#. .".|
+00000030 31 2e 09 a3 ac c1 3d 04 29 2e 82 1c 31 27 8e e2 |1.....=.)...1'..|
+00000040 50 de ca 3d 4d ad 7e 01 74 94 40 3d 7c 2d 08 56 |P..=M.~.t.@=|-.V|
+00000050 d2 89 7b 3a b8 2a b1 34 22 65 25 48 bb 24 1b 4b |..{:.*.4"e%H.$.K|
+00000060 a2 96 a8 7f ac f2 46 84 4f e2 c8 1c 25 41 eb df |......F.O...%A..|
+00000070 52 ec 9b bd 89 b8 a8 c3 62 f2 75 16 de 61 63 b0 |R.......b.u..ac.|
+00000080 70 9c d2 c5 b0 86 6b 2a 17 64 9a d1 6d 5c e9 48 |p.....k*.d..m\.H|
+00000090 f5 02 e3 0f 16 df f9 6e 99 56 93 85 2b 10 bc da |.......n.V..+...|
+000000a0 6e 02 8b 94 ac d2 dc 56 93 ad 8b 1d d6 ff e3 d9 |n......V........|
+000000b0 f8 ee 11 15 c7 e4 ae 4d fe 88 0c c9 7f 30 1a 2a |.......M.....0.*|
+000000c0 99 ab f8 0d a2 a9 57 87 35 a4 a9 87 b0 4f 46 8a |......W.5....OF.|
+000000d0 ec 47 39 32 a7 94 3a 15 08 80 e5 1e 81 4b cd 2e |.G92..:......K..|
+000000e0 76 9d 99 5b 86 89 37 09 a0 08 86 6e bb 67 ad 3f |v..[..7....n.g.?|
+000000f0 a2 e9 1f 37 75 4b 0f 07 8c f3 e7 34 05 74 33 a9 |...7uK.....4.t3.|
+00000100 5a e3 5b 0e 68 d0 54 e4 24 c9 6c 42 2d 81 8f 29 |Z.[.h.T.$.lB-..)|
+00000110 17 97 3d a8 00 00 27 50 ae 5d 97 6d fa 7e c0 |..=...'P.].m.~.|
+>>> Flow 8 (server to client)
+00000000 16 03 03 00 85 74 29 5c 40 48 b9 9c 76 e4 eb a1 |.....t)\@H..v...|
+00000010 44 7e f1 72 cd 7b fe 11 47 4d 48 fe bc 75 4e e1 |D~.r.{..GMH..uN.|
+00000020 b4 8d cb d1 0e d7 16 cc 4b d4 61 f9 47 69 cd aa |........K.a.Gi..|
+00000030 c4 ad bf fd 01 6b 5c a6 63 d4 73 a4 21 f8 fe 72 |.....k\.c.s.!..r|
+00000040 00 48 55 4e 40 6b 85 e5 1c f2 36 c1 91 2e e2 70 |.HUN@k....6....p|
+00000050 38 95 5a aa 0c c7 32 c9 a5 ac 94 dc 6c 50 f5 e9 |8.Z...2.....lP..|
+00000060 9f 14 48 f0 b3 d1 45 99 d3 aa 68 28 22 4a ae 66 |..H...E...h("J.f|
+00000070 3a 2f 06 c1 86 fb 0c f2 b0 ca 6f e2 93 fe 47 e6 |:/........o...G.|
+00000080 2f 33 2d 60 38 42 2f 56 f7 52 16 03 03 02 69 46 |/3-`8B/V.R....iF|
+00000090 86 2d bb 38 d9 57 1c 29 bd 28 17 a8 ef 4e 26 68 |.-.8.W.).(...N&h|
+000000a0 16 73 f7 2c 52 fb 54 f8 4d 6d 1e c2 57 0d 44 16 |.s.,R.T.Mm..W.D.|
+000000b0 24 3d 5d b5 22 8c 13 b0 09 10 45 65 48 ec 5c 3f |$=].".....EeH.\?|
+000000c0 c4 9f c1 ee ff 2b 6e 36 76 bc 01 5d f4 96 44 43 |.....+n6v..]..DC|
+000000d0 bb 90 04 ec 18 d6 0b 29 2d 1f 08 0b 02 0d cf 43 |.......)-......C|
+000000e0 7c a0 76 40 6d f0 eb 14 42 5a 9d df 29 35 1c 4f ||.v@m...BZ..)5.O|
+000000f0 35 ef ad 60 18 16 51 97 2c 73 40 e5 74 1c 48 a7 |5..`..Q.,s@.t.H.|
+00000100 e5 4d 35 2c 1a 4c 35 f6 9a eb 0d d7 49 5f 04 06 |.M5,.L5.....I_..|
+00000110 da 56 8d f4 3b 3f 20 09 91 fd d3 51 31 65 05 f5 |.V..;? ....Q1e..|
+00000120 fa 85 4b 1b 3a 00 33 b0 96 28 d7 3b d7 92 d0 5c |..K.:.3..(.;...\|
+00000130 04 13 4d d9 a5 02 19 19 13 1d 8a 9d f4 68 c0 98 |..M..........h..|
+00000140 2f f0 86 b2 6b 05 af af 65 a5 0d ab 8e af 74 dc |/...k...e.....t.|
+00000150 a6 fa 41 0a 23 4b e6 1a 13 8d 96 01 9a 40 5b 09 |..A.#K.......@[.|
+00000160 3b 8f 70 ab 1f d6 8c 27 f6 3d bf 85 b0 f5 66 f7 |;.p....'.=....f.|
+00000170 ae 94 df ee 5f 75 47 19 e4 a1 a6 58 bf f2 8b 0e |...._uG....X....|
+00000180 05 8a 3a 40 13 35 05 f1 7d 89 f6 6d 14 1c 5f 1c |..:@.5..}..m.._.|
+00000190 e7 86 cc b5 83 52 55 9f 28 bf 56 54 96 91 92 7e |.....RU.(.VT...~|
+000001a0 18 a6 21 8f e0 98 ee 6d 6b 19 53 0e f1 25 86 ec |..!....mk.S..%..|
+000001b0 0e 5d 97 34 36 55 e3 a7 a8 5a 9f 43 8a ed ad c6 |.].46U...Z.C....|
+000001c0 cb 81 96 6f 9f 3b 2c db 24 4c 32 05 c0 8e d8 5a |...o.;,.$L2....Z|
+000001d0 b3 87 33 b8 5c d8 57 6b d0 94 7f 22 62 7c 15 d8 |..3.\.Wk..."b|..|
+000001e0 0f 05 b0 e7 04 85 94 5f 7b b2 25 e2 a2 46 c1 43 |......._{.%..F.C|
+000001f0 ac ef f7 c3 89 06 11 d6 c5 a9 0f 3d e0 7a fa 66 |...........=.z.f|
+00000200 31 44 1b a8 ff 2c 11 a7 1e 43 73 1d dd c4 a8 36 |1D...,...Cs....6|
+00000210 85 45 9e 34 46 78 ba 9a 9c 6a da 58 82 9a b0 2b |.E.4Fx...j.X...+|
+00000220 6b 74 98 bb 6a 9d 2d 54 1b 80 09 01 13 85 60 8a |kt..j.-T......`.|
+00000230 75 96 df 35 33 72 a4 d6 d3 6e 1a 0a 11 0a 0b b3 |u..53r...n......|
+00000240 5c 87 82 69 09 9d 22 a9 8b e4 b2 fb af 5c fd 82 |\..i.."......\..|
+00000250 32 30 f4 a8 ca a1 83 3e 8b 4d 3b 00 a6 63 7f c2 |20.....>.M;..c..|
+00000260 36 60 80 f2 b5 40 76 98 a6 f9 e8 49 04 62 c0 31 |6`...@v....I.b.1|
+00000270 06 da 4c a7 ff 6b 52 e2 7e af 22 b2 2c 84 df 8c |..L..kR.~.".,...|
+00000280 d1 5e 7d 19 7b c7 9e da 14 e0 7e 9f 78 4a 0c bb |.^}.{.....~.xJ..|
+00000290 77 28 3e 12 03 c3 59 91 2a b1 6c 7e 78 ce d6 ac |w(>...Y.*.l~x...|
+000002a0 a0 57 06 20 d1 2b 74 59 20 e0 7f 4d 35 31 1a 3d |.W. .+tY ..M51.=|
+000002b0 67 e9 1b 84 92 17 81 04 10 a4 5e 4d c2 00 ea 64 |g.........^M...d|
+000002c0 b9 fb 82 41 2e c0 66 68 2a 9e 1d 86 ee df f4 f9 |...A..fh*.......|
+000002d0 c5 6b d0 f6 07 61 93 22 31 a7 31 ee bc f3 c8 a7 |.k...a."1.1.....|
+000002e0 dc 21 ea eb 61 94 aa 6f 9a a2 0a 74 d9 db 39 48 |.!..a..o...t..9H|
+000002f0 21 8a f4 0a 6d f0 e7 07 16 03 03 00 bc 03 03 f8 |!...m...........|
+00000300 01 78 b0 ea 48 3d 57 b3 c7 69 62 74 ee 0e 92 a4 |.x..H=W..ibt....|
+00000310 d0 96 ed fe 94 2b 11 cd d1 13 f7 e8 cc 61 0c 6e |.....+.......a.n|
+00000320 8a 28 70 e1 c2 01 fe 19 66 eb 47 b3 e8 7b ff fc |.(p.....f.G..{..|
+00000330 e6 c0 4e 5e 15 ae b6 14 04 64 33 d3 77 bc ce ea |..N^.....d3.w...|
+00000340 47 4a 85 ef ff 16 79 33 1b 2e db 42 ab ee 7c 7f |GJ....y3...B..|.|
+00000350 37 65 b5 ee 70 71 f1 7b 99 9b 63 c5 23 dd 7b 0c |7e..pq.{..c.#.{.|
+00000360 ed 48 07 a4 d5 a2 63 5b fd 99 01 f4 df b6 a7 95 |.H....c[........|
+00000370 23 a5 c0 00 e9 b4 2b f4 f8 3e 9b ca b3 34 ff e6 |#.....+..>...4..|
+00000380 5a 2f 0a 7a 55 81 77 3b 7a c5 66 e8 2c 4a 01 50 |Z/.zU.w;z.f.,J.P|
+00000390 13 13 79 8a b3 9f 9b 49 e9 e7 0a a7 d4 c9 7f 10 |..y....I........|
+000003a0 29 89 70 d9 83 5d 21 a9 40 7a 17 1f 6e 3d 4e 2a |).p..]!.@z..n=N*|
+000003b0 48 e7 1c fa 07 2f 3f 5d 32 16 03 03 00 4a f9 74 |H..../?]2....J.t|
+000003c0 d5 eb 38 ef d8 bf 7a 69 2f b0 d3 e0 e1 57 d7 fc |..8...zi/....W..|
+000003d0 01 57 2e e6 99 ba 0c 23 07 59 f3 75 28 1d 77 26 |.W.....#.Y.u(.w&|
+000003e0 2f 4d f4 f3 16 0a d6 2e 38 50 48 e3 a2 90 e1 0b |/M......8PH.....|
+000003f0 78 99 35 81 d1 d9 4a 7b 47 a2 e1 95 39 f6 02 87 |x.5...J{G...9...|
+00000400 1f fe 4f 7e 2e ee 9a 17 16 03 03 00 14 98 8e a2 |..O~............|
+00000410 b6 b6 79 35 d1 fe b2 cb 90 ea 7c 91 5a 37 53 e4 |..y5......|.Z7S.|
+00000420 73 |s|
+>>> Flow 9 (client to server)
+00000000 16 03 03 02 69 ad fd 5e 51 7c 1a 62 01 a3 c7 84 |....i..^Q|.b....|
+00000010 d6 d8 2d 47 2b 00 d5 d4 7c e6 16 94 7e 32 74 85 |..-G+...|...~2t.|
+00000020 ce 13 d9 af d7 27 77 86 43 77 1b ca 68 f5 1f da |.....'w.Cw..h...|
+00000030 20 d8 61 29 b0 11 3d 40 66 62 a0 82 ff 38 85 07 | .a)..=@fb...8..|
+00000040 52 fc 59 92 44 c4 ea 12 70 62 cd 05 66 0a b4 cb |R.Y.D...pb..f...|
+00000050 38 23 f4 35 58 a0 4c 1e bc 1a 5a 6a be ad 81 c9 |8#.5X.L...Zj....|
+00000060 22 97 dc 7d 77 76 da e8 b5 30 be d3 28 be b2 30 |"..}wv...0..(..0|
+00000070 05 52 8f 41 d3 a1 78 68 9b 76 ad 29 42 ec 90 c5 |.R.A..xh.v.)B...|
+00000080 61 f2 aa f2 f0 fb dd 08 42 f3 5a a8 3c 8d f9 98 |a.......B.Z.<...|
+00000090 90 00 2e e1 aa 7c ac 3f cf 34 9d ed 56 09 30 d3 |.....|.?.4..V.0.|
+000000a0 1b 03 9e fb 0c 16 4c 99 0f 86 a9 03 44 ce 8b 66 |......L.....D..f|
+000000b0 a6 42 bb 0b dc a4 82 47 7d fc 09 48 1d 47 85 da |.B.....G}..H.G..|
+000000c0 3f 30 d1 94 36 a0 ac 44 72 2f a4 cc 5a fd 6c 96 |?0..6..Dr/..Z.l.|
+000000d0 05 14 0c 25 5c 19 44 1e c2 40 12 57 be 30 1d bb |...%\.D..@.W.0..|
+000000e0 62 f4 2c c2 f1 46 83 1b ad bd f4 e0 ff b2 de 62 |b.,..F.........b|
+000000f0 85 04 61 3d 61 67 aa d1 f7 ba db 6f 80 75 1e 9c |..a=ag.....o.u..|
+00000100 70 42 ff 6f 35 83 32 34 fc 12 08 e5 44 92 cb 99 |pB.o5.24....D...|
+00000110 a5 d0 ef c3 f2 9e b2 86 ff c1 e5 87 01 bf d1 7a |...............z|
+00000120 d9 57 ef 21 cf c9 fd 5f 30 6c 54 7c ac 95 54 72 |.W.!..._0lT|..Tr|
+00000130 3d 46 88 4d 9f 8e a8 75 81 a0 81 50 11 1e f7 92 |=F.M...u...P....|
+00000140 f5 a2 5d 49 5a f8 c1 b8 06 f3 6f 99 64 77 ee fe |..]IZ.....o.dw..|
+00000150 40 fe 94 51 67 db e1 a0 d7 a4 09 cc 52 9c 1b 27 |@..Qg.......R..'|
+00000160 5b 45 4a 71 ff 60 aa 52 56 07 f6 4e ad 23 b8 2c |[EJq.`.RV..N.#.,|
+00000170 87 d3 2b 04 56 21 ed 51 ce 81 59 ae 3d a7 1b f5 |..+.V!.Q..Y.=...|
+00000180 75 3f 8a 83 c3 ee e9 76 94 dd 48 c4 d1 69 2f af |u?.....v..H..i/.|
+00000190 b1 f9 2f db 72 ef da 33 6b 87 78 64 24 3a 42 46 |../.r..3k.xd$:BF|
+000001a0 e0 ed 91 60 89 dd 5a 9e 9b 93 4a 0e a3 30 32 4d |...`..Z...J..02M|
+000001b0 0e 5f c6 49 26 49 18 73 8d 2d 73 d5 4c 49 3f df |._.I&I.s.-s.LI?.|
+000001c0 d9 55 b7 11 7e 24 1b d6 cb 71 68 ba 6c c7 72 b2 |.U..~$...qh.l.r.|
+000001d0 2e aa 39 89 ac 1b 96 a3 78 11 4d 37 ba 25 88 43 |..9.....x.M7.%.C|
+000001e0 d2 8a 55 28 99 b3 f0 59 d5 92 cc 94 51 e2 f2 18 |..U(...Y....Q...|
+000001f0 3b d1 1a 9b a6 ee f1 b1 91 62 6b a0 da 75 f6 69 |;........bk..u.i|
+00000200 23 56 22 29 dd d0 63 05 be a9 f7 38 fc 0d a2 64 |#V")..c....8...d|
+00000210 e4 09 2c d5 5f ca ee 91 81 91 d1 ee 62 04 e9 ce |..,._.......b...|
+00000220 5f 49 8e 70 cf fd 5a b5 cf c1 e5 ae 53 3e 16 d0 |_I.p..Z.....S>..|
+00000230 f0 49 9b 61 32 14 38 27 b5 c9 93 13 be e4 5a f0 |.I.a2.8'......Z.|
+00000240 10 5f 7c 14 11 68 70 4d 6d 02 9f 51 51 94 e0 0e |._|..hpMm..QQ...|
+00000250 04 a2 ae 6c 3c f0 94 11 9c 66 58 b3 a2 e8 04 f1 |...l<....fX.....|
+00000260 01 b7 88 0d 74 cf 8a 63 f8 e6 c4 bb 10 bb 16 03 |....t..c........|
+00000270 03 00 35 7b 36 f4 cf b3 8a 4a 7c 7e fc 7a 6d ae |..5{6....J|~.zm.|
+00000280 5e fe 3b c5 e1 16 44 ab 72 0a 07 10 69 e1 11 db |^.;...D.r...i...|
+00000290 6d 86 f9 43 d0 87 82 3a 28 83 b4 15 76 76 2a f9 |m..C...:(...vv*.|
+000002a0 52 80 7f 2f c2 52 e1 2c 16 03 03 00 98 e8 a2 d5 |R../.R.,........|
+000002b0 d6 57 15 7c 33 27 e2 29 d4 82 7b fd 2d c3 00 db |.W.|3'.)..{.-...|
+000002c0 83 90 44 4b 3a be 01 4d d7 76 a5 03 cf ec 60 b5 |..DK:..M.v....`.|
+000002d0 93 ba 4d 4d 74 30 a3 bb 47 3b a2 94 98 1e e9 b8 |..MMt0..G;......|
+000002e0 d2 99 55 05 c7 59 cb e4 55 3e c0 c9 8c 90 40 91 |..U..Y..U>....@.|
+000002f0 2e c0 64 f2 6e 09 96 7c b6 0a e0 ad fd a2 7a c4 |..d.n..|......z.|
+00000300 b0 e6 0f 40 2a e5 37 fa 72 f3 89 1c 78 47 ca c7 |...@*.7.r...xG..|
+00000310 e5 83 7b 1f a6 e5 39 32 c6 94 1e e4 7a 51 d9 36 |..{...92....zQ.6|
+00000320 67 d9 b3 78 58 f9 ae 65 60 ee 41 c8 81 8a 04 49 |g..xX..e`.A....I|
+00000330 35 2a d8 22 b3 8b 64 49 13 a0 36 e0 37 68 ea b7 |5*."..dI..6.7h..|
+00000340 99 9e 1f e1 ea 14 03 03 00 11 b9 18 a2 5e 19 5f |.............^._|
+00000350 77 58 6c a3 e9 97 4b 34 5e ff ff 16 03 03 00 20 |wXl...K4^...... |
+00000360 71 d4 9f 5a 6f fa e4 28 bb f1 9d e5 0b c3 da 4b |q..Zo..(.......K|
+00000370 ef a3 78 28 c5 e3 43 ff f7 5c a1 94 57 0d ee 41 |..x(..C..\..W..A|
+>>> Flow 10 (server to client)
+00000000 14 03 03 00 11 ed 11 8d d8 09 71 3a d8 53 25 f9 |..........q:.S%.|
+00000010 a9 2f 70 b9 21 fb 16 03 03 00 20 14 a7 ba 54 0e |./p.!..... ...T.|
+00000020 5c a9 53 ab d4 d6 c0 3f 10 6b 2d 84 8d 66 e5 04 |\.S....?.k-..f..|
+00000030 96 f9 a9 18 1d f8 c1 76 49 18 35 17 03 03 00 19 |.......vI.5.....|
+00000040 5e b0 d2 83 83 7d 35 ac e5 74 9a 68 b5 d8 4d 32 |^....}5..t.h..M2|
+00000050 a1 d0 bf 8d 8f 1a 2f f7 33 |....../.3|
+>>> Flow 11 (client to server)
+00000000 15 03 03 00 12 3d 6c 11 84 f3 af 5e 9b ee c3 56 |.....=l....^...V|
+00000010 96 c1 78 a9 12 31 ba |..x..1.|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwice b/src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwice
new file mode 100644
index 0000000..ff6da0a
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwice
@@ -0,0 +1,346 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 5d 02 00 00 59 03 03 bc 20 d6 8b 64 |....]...Y... ..d|
+00000010 c1 9f de ba 8e c1 6f 37 b8 5c 82 c3 1b 5e 11 3d |......o7.\...^.=|
+00000020 ac 5d 16 4b 40 96 d6 ae 29 74 91 20 65 7d d0 51 |.].K@...)t. e}.Q|
+00000030 d8 a2 2d c6 db 53 f6 04 16 dd 70 4a bd 44 a4 b6 |..-..S....pJ.D..|
+00000040 ef e0 f0 d3 ec 6a 31 18 91 df 09 90 cc a8 00 00 |.....j1.........|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 03 02 59 0b 00 02 55 00 02 52 00 02 |......Y...U..R..|
+00000070 4f 30 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 |O0..K0..........|
+00000080 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 |....?.[..0...*.H|
+00000090 86 f7 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 |........0.1.0...|
+000000a0 55 04 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 |U....Go1.0...U..|
+000000b0 13 07 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 |..Go Root0...160|
+000000c0 31 30 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 |101000000Z..2501|
+000000d0 30 31 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 |01000000Z0.1.0..|
+000000e0 03 55 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 |.U....Go1.0...U.|
+000000f0 03 13 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 |...Go0..0...*.H.|
+00000100 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 |...........0....|
+00000110 81 00 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab |...F}...'.H..(!.|
+00000120 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d |~...]..RE.z6G...|
+00000130 92 42 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd |.B[.....y.@.Om..|
+00000140 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a |+.....g....."8.J|
+00000150 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 |.ts+.4......t{.X|
+00000160 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c |.la<..A..++$#w[.|
+00000170 3b bd 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 |;.u]. T..c...$..|
+00000180 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 |..P....C...ub...|
+00000190 52 d7 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 |R.........0..0..|
+000001a0 03 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 |.U...........0..|
+000001b0 03 55 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 |.U.%..0...+.....|
+000001c0 03 01 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 |....+.......0...|
+000001d0 55 1d 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d |U.......0.0...U.|
+000001e0 0e 04 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d |.........CC>I..m|
+000001f0 b6 80 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 |....`0...U.#..0.|
+00000200 80 10 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab |..H.IM.~.1......|
+00000210 6e 7b 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 |n{0...U....0...e|
+00000220 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 |xample.golang0..|
+00000230 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 |.*.H............|
+00000240 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed |.0.@+[P.a...SX..|
+00000250 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 |.(.X..8....1Z..f|
+00000260 3d 43 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a |=C.-...... d8.$:|
+00000270 00 bc cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 |....}.@ ._...a..|
+00000280 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed |v......\.....l..|
+00000290 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 |s..Cw.......@.a.|
+000002a0 4c 72 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 |Lr+...F..M...>..|
+000002b0 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 |.B...=.`.\!.;...|
+000002c0 16 03 03 00 ac 0c 00 00 a8 03 00 1d 20 71 9d 55 |............ q.U|
+000002d0 00 99 f1 f9 90 c2 8f 82 27 d7 5c 0e 96 97 a9 f7 |........'.\.....|
+000002e0 be ab c4 76 41 9b 86 86 43 d7 43 78 0c 08 04 00 |...vA...C.Cx....|
+000002f0 80 96 cb 93 b2 0c 1e e3 92 b1 4e 28 30 48 85 09 |..........N(0H..|
+00000300 c1 cf 73 66 7b 3b 3d 7d 83 c2 a3 2a 93 14 58 c0 |..sf{;=}...*..X.|
+00000310 1c 6c 7c 92 9c 3f 8b 80 d1 c4 54 d8 2b 65 38 35 |.l|..?....T.+e85|
+00000320 08 a6 d2 ec 4e 84 e7 49 78 13 3f 2a 41 60 1d ea |....N..Ix.?*A`..|
+00000330 09 c8 30 37 35 88 b3 eb 5c ad 16 46 19 5f f1 62 |..075...\..F._.b|
+00000340 8b 49 8a 9a 47 87 a4 14 d3 17 e1 d5 79 0e 9f c4 |.I..G.......y...|
+00000350 4e db 6f 38 8e 77 ec 37 74 e8 20 01 54 75 e1 8e |N.o8.w.7t. .Tu..|
+00000360 5c d1 19 51 d8 c8 89 6c 27 01 54 ca 18 dd d9 2e |\..Q...l'.T.....|
+00000370 8f 16 03 03 00 04 0e 00 00 00 |..........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.|
+00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....|
+00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 03 00 01 01 |....._X.;t......|
+00000030 16 03 03 00 20 46 e6 c1 9e c0 cc 46 24 6e 0c 6c |.... F.....F$n.l|
+00000040 1b c5 7d b4 dc a1 b5 d4 bf db 32 69 12 8a 89 ea |..}.......2i....|
+00000050 c1 bf 26 b8 ee |..&..|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 20 08 9b ed a2 75 |.......... ....u|
+00000010 a9 2d 92 f7 dc e1 93 7a 3d c3 75 33 a8 43 17 2b |.-.....z=.u3.C.+|
+00000020 50 71 58 d7 40 2a ea 1b 0a 3b 0b |PqX.@*...;.|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 16 7e a3 48 7f 20 07 19 31 8b d2 18 |.....~.H. ..1...|
+00000010 81 1d 4a a1 db 72 4a 88 2d ee 18 |..J..rJ.-..|
+>>> Flow 6 (server to client)
+00000000 16 03 03 00 14 b4 c3 67 a8 fc 66 ad 48 f9 3f 6b |.......g..f.H.?k|
+00000010 97 4b 55 f8 4d 92 a1 2e d8 |.KU.M....|
+>>> Flow 7 (client to server)
+00000000 16 03 03 01 1a 57 92 7f 92 07 a2 88 ca ea e3 5d |.....W.........]|
+00000010 38 79 fd 42 41 5b 73 e5 52 34 c3 f5 10 67 3d 0b |8y.BA[s.R4...g=.|
+00000020 42 58 50 d7 f1 da 6b a6 4f 6a 89 2b f7 3c 4d a0 |BXP...k.Oj.+.<M.|
+00000030 db 8c c0 1e 30 08 15 fe 9e 9f 97 80 df 7c a4 ce |....0........|..|
+00000040 3f ab 9d 9c 05 12 e6 75 2a 3e c4 d8 f4 01 06 c9 |?......u*>......|
+00000050 48 06 3b 1e df 97 26 e9 59 34 59 c8 e3 05 0b 22 |H.;...&.Y4Y...."|
+00000060 d1 66 0e 42 ac e0 4a e1 89 c3 80 ae ee 32 65 93 |.f.B..J......2e.|
+00000070 09 6b 1f bc 03 4d 0d 85 bc e8 46 12 09 0b 0c 44 |.k...M....F....D|
+00000080 20 a0 26 12 70 80 45 9c ba c2 9d 6a 7a ec bb 92 | .&.p.E....jz...|
+00000090 c5 b3 49 2e 18 99 e8 19 a8 37 9d e2 28 c8 69 19 |..I......7..(.i.|
+000000a0 ed 12 a6 f2 e7 84 a3 7f 7e 49 74 34 67 66 1f fc |........~It4gf..|
+000000b0 02 58 0d 8e 6c ec 1c 14 8c 2a 74 b8 f2 b1 8e 6a |.X..l....*t....j|
+000000c0 5f 4d 76 13 d6 7f cf c3 2d 85 18 9b 04 87 d9 9a |_Mv.....-.......|
+000000d0 db 8f 09 ce 3f 47 55 fc e9 bf 6c cb 42 bf d4 c4 |....?GU...l.B...|
+000000e0 76 91 3e d6 d8 32 4e fe 24 39 1b 66 38 83 32 7f |v.>..2N.$9.f8.2.|
+000000f0 ee 84 d3 13 39 73 bb 41 a2 d4 ef a7 1c aa cb e3 |....9s.A........|
+00000100 c2 25 6a a3 f2 fb 6f 94 eb 9d 08 1b 4e 6b 09 8a |.%j...o.....Nk..|
+00000110 00 0a e3 1b e1 57 7b 58 14 d1 0a 1d 11 7a e0 |.....W{X.....z.|
+>>> Flow 8 (server to client)
+00000000 16 03 03 00 85 f1 26 e0 cc 3f 3d a3 e6 57 21 a0 |......&..?=..W!.|
+00000010 25 c6 fd 11 f5 92 2e 73 21 32 2b 07 76 73 2b e3 |%......s!2+.vs+.|
+00000020 0a 45 1e 01 c8 28 01 1b ba 23 d8 4e 7c 9f 2b 2e |.E...(...#.N|.+.|
+00000030 5a ef df 4f 0d 77 76 27 8b 1e df 94 a4 90 1e cb |Z..O.wv'........|
+00000040 5a 19 6b f0 c6 85 71 7b 6b cd 59 e1 32 a5 a5 18 |Z.k...q{k.Y.2...|
+00000050 01 25 13 84 09 e5 30 6a d3 f2 80 07 1d 48 9b 72 |.%....0j.....H.r|
+00000060 d2 6e 76 e3 de 85 0b 9d ec 5f e3 48 02 61 6c b1 |.nv......_.H.al.|
+00000070 1a 1b 89 7e 44 f8 af fd a9 42 63 3e f6 3c f6 22 |...~D....Bc>.<."|
+00000080 ff 45 b4 f2 ec 31 65 58 8c 06 16 03 03 02 69 50 |.E...1eX......iP|
+00000090 e3 4b 21 fd f3 73 28 b1 b2 dc f4 46 d3 37 c1 c9 |.K!..s(....F.7..|
+000000a0 15 9c 83 a0 4d b5 6e c1 8c 97 26 05 20 4d cf 92 |....M.n...&. M..|
+000000b0 9a e4 e6 ff c2 d1 d4 c9 28 ca 08 00 ed ba 2a e1 |........(.....*.|
+000000c0 d2 71 62 4a 1a ca 7d db 19 86 81 a1 4b c4 f7 19 |.qbJ..}.....K...|
+000000d0 d2 b1 99 4a 82 39 e5 d2 90 59 ca 19 a5 1c 07 1c |...J.9...Y......|
+000000e0 c1 44 d5 f3 a4 e5 33 ce 98 fc 24 e9 65 04 b9 08 |.D....3...$.e...|
+000000f0 2f f7 d6 87 91 33 64 8c 9e e9 50 35 28 76 3d 77 |/....3d...P5(v=w|
+00000100 b2 84 16 23 a1 6f d1 92 da 37 28 88 63 51 db 55 |...#.o...7(.cQ.U|
+00000110 5d d4 29 ab 64 e8 dd 1f ef 06 31 78 ab f1 11 82 |].).d.....1x....|
+00000120 76 35 17 66 87 62 bc 9e 18 be 35 96 4d 5c 2d c6 |v5.f.b....5.M\-.|
+00000130 84 13 08 00 ec f9 bd b8 24 88 f5 2a 2b 11 0b ec |........$..*+...|
+00000140 55 a2 f3 c7 b4 7d cf 56 90 1f d9 c0 4a 0e 8c 8c |U....}.V....J...|
+00000150 d4 72 60 18 f6 eb 6a ae 83 35 bf d2 4f 0e f3 06 |.r`...j..5..O...|
+00000160 73 3f e1 3a 03 1f 51 02 2f dc e1 f8 87 95 8a 13 |s?.:..Q./.......|
+00000170 d3 89 ac af 36 c8 1d 19 08 61 97 c9 e3 0a b9 1a |....6....a......|
+00000180 12 6e f1 fd d5 e3 78 bc 34 b7 6b 1d b4 48 3e d5 |.n....x.4.k..H>.|
+00000190 61 99 04 e5 74 ca 53 66 65 21 c2 2c fb e6 12 3d |a...t.Sfe!.,...=|
+000001a0 5e 48 ac b9 ef d8 a3 75 32 85 eb 6f 88 84 b6 2f |^H.....u2..o.../|
+000001b0 d4 67 e7 25 26 80 c0 39 73 97 fb e5 8d ed 65 7e |.g.%&..9s.....e~|
+000001c0 a4 35 4e b7 e3 92 72 23 80 c2 f5 db b4 02 26 33 |.5N...r#......&3|
+000001d0 ff 46 3e 0d e6 e0 02 b1 65 e0 3f 8e 7d fd 12 73 |.F>.....e.?.}..s|
+000001e0 62 20 6a fc 00 2b 19 cb 17 c7 de 14 05 4b b5 f6 |b j..+.......K..|
+000001f0 49 78 92 f4 84 1d 94 1b b1 23 67 5e b2 ae 75 4e |Ix.......#g^..uN|
+00000200 f3 52 72 af fb 2e 12 7c cc 6b b6 f3 3a 8a e4 ae |.Rr....|.k..:...|
+00000210 03 db ed 20 b1 e5 a9 7b 0d df ae 75 c9 71 42 c4 |... ...{...u.qB.|
+00000220 e5 c9 a7 ac c8 f4 a5 e6 84 05 a0 be ca d8 d0 d1 |................|
+00000230 30 a0 84 42 82 df ba ba d7 11 a5 f9 93 fd 8e 91 |0..B............|
+00000240 89 2e 2f b2 98 05 06 dc 2c a4 2a 6f f4 0f 9d 1d |../.....,.*o....|
+00000250 16 2f d8 b9 06 02 43 92 cc 96 bc 6a a4 93 86 ef |./....C....j....|
+00000260 43 11 ec b7 4e 39 9f 1f 75 71 76 1a 7b 1d 2e 68 |C...N9..uqv.{..h|
+00000270 ad 36 c7 ae 3a 7a 70 10 46 4e 76 9b f5 8c 1d b7 |.6..:zp.FNv.....|
+00000280 5d 62 86 70 1c 27 84 ae 8a 05 65 a2 01 bf 3b 0f |]b.p.'....e...;.|
+00000290 d3 43 74 9d a0 ed 7f e4 63 dc b9 e6 7b d6 c1 2d |.Ct.....c...{..-|
+000002a0 96 ae 51 6e 07 47 8b f8 f7 e2 71 19 3a df 7d cb |..Qn.G....q.:.}.|
+000002b0 ef 82 2a 11 fd 9c e9 24 9d b0 9e e4 1f f2 4e 8b |..*....$......N.|
+000002c0 17 02 4a 27 33 85 61 d3 55 6d 82 77 ce 55 d3 be |..J'3.a.Um.w.U..|
+000002d0 94 9f 6d 1d f0 16 1d 19 bd 1f ac 77 e7 13 32 94 |..m........w..2.|
+000002e0 86 8c c8 c9 33 f0 b0 47 cf 9c 7c ef 97 c3 37 25 |....3..G..|...7%|
+000002f0 bf a7 09 82 35 ff 9f 79 16 03 03 00 bc 8c 34 16 |....5..y......4.|
+00000300 37 9c cb db aa dc 23 ba 07 28 88 be 6f f0 cc 42 |7.....#..(..o..B|
+00000310 22 31 2c fc a4 ce d8 bf 58 54 a7 62 6b 54 8b b1 |"1,.....XT.bkT..|
+00000320 0b 44 29 a9 64 2f af ee f1 7b 79 1c 26 02 a3 bd |.D).d/...{y.&...|
+00000330 e5 dd 60 89 ef e9 31 bc 5d 17 fc a9 05 77 38 00 |..`...1.]....w8.|
+00000340 e8 d9 8c b3 c6 7d fb a0 f8 d1 87 2a c6 74 d6 2c |.....}.....*.t.,|
+00000350 39 c8 3c d8 0d 0d a6 e2 ea 6b 88 9d 7d ee cc 4e |9.<......k..}..N|
+00000360 69 2a ac 41 7e ac b8 fe b4 8f 43 ef 2d a7 45 78 |i*.A~.....C.-.Ex|
+00000370 bf 29 72 b5 4b cf bb aa 1a 64 3c dd 38 07 ab 60 |.)r.K....d<.8..`|
+00000380 b3 ee e3 0b 40 a1 72 4d 61 1a ba d8 24 a7 46 3f |....@.rMa...$.F?|
+00000390 77 c9 bd 11 37 d7 ae c9 92 d8 78 a5 13 f8 2c 2f |w...7.....x...,/|
+000003a0 10 50 7c e5 16 2c 56 e7 a6 10 cb fc 62 a2 6f 83 |.P|..,V.....b.o.|
+000003b0 30 74 d3 94 23 78 c8 6d 28 16 03 03 00 4a 76 dc |0t..#x.m(....Jv.|
+000003c0 db 13 a2 52 07 65 62 35 36 56 42 95 1d 34 8f 2a |...R.eb56VB..4.*|
+000003d0 cd 5e 63 aa 56 70 ac 16 76 7b 7d b6 3f a4 57 6b |.^c.Vp..v{}.?.Wk|
+000003e0 f1 9e 6a a7 ca e5 cb b0 44 5e 8b 6a ea 78 45 ad |..j.....D^.j.xE.|
+000003f0 0c 9d 44 8c 1f 03 27 9b 90 2e 9e fc 50 44 1f 4d |..D...'.....PD.M|
+00000400 f3 ac 1f 2f 6d ed 49 29 16 03 03 00 14 ba 05 de |.../m.I)........|
+00000410 4f 96 62 af d1 e0 a6 64 0d f3 ee 50 ca 1f d1 50 |O.b....d...P...P|
+00000420 bb |.|
+>>> Flow 9 (client to server)
+00000000 16 03 03 02 69 54 06 eb 58 fb 0c cd 83 50 78 6d |....iT..X....Pxm|
+00000010 e1 63 b0 24 eb 11 2b b3 76 77 c9 7b e4 ad c8 a9 |.c.$..+.vw.{....|
+00000020 71 73 68 a2 89 ba bc fd 0d d4 cc 7b 33 0a 11 c6 |qsh........{3...|
+00000030 a0 56 0f b4 86 e6 e5 31 85 2d 98 1b f0 28 67 2b |.V.....1.-...(g+|
+00000040 d2 c8 9a 32 83 c1 50 10 16 08 70 72 fb 80 c7 a4 |...2..P...pr....|
+00000050 fa 95 88 bc 7c 45 67 1d 43 24 7b 56 9a 09 b6 38 |....|Eg.C${V...8|
+00000060 e2 4c 25 93 7a 02 f8 c4 f2 52 7e e4 8e 99 ad 9c |.L%.z....R~.....|
+00000070 1d 8f 54 a5 67 d1 27 5d c7 d0 76 47 a8 7f 54 79 |..T.g.']..vG..Ty|
+00000080 4c f2 98 bc 8c 3c 78 9b 6e c1 8b 2c 09 40 77 a9 |L....<x.n..,.@w.|
+00000090 69 3b 80 2f b7 a3 d0 54 66 4d 39 ec 30 ad 31 a4 |i;./...TfM9.0.1.|
+000000a0 a7 e2 3a 37 96 0e f8 e3 e5 b2 03 fc ce 72 d0 f0 |..:7.........r..|
+000000b0 84 08 c4 ff 95 9c 6c dc e7 03 1f 45 d8 8a ec 92 |......l....E....|
+000000c0 98 87 eb 61 16 a9 b5 10 81 d1 ea 03 a5 62 d5 25 |...a.........b.%|
+000000d0 62 71 e8 56 4c a4 47 5f 6b cb 8c 50 c3 4c 17 8f |bq.VL.G_k..P.L..|
+000000e0 64 f9 ab 22 9a 94 c7 68 7d c0 79 f2 5c 36 54 8c |d.."...h}.y.\6T.|
+000000f0 53 31 d4 0a 52 5c 7f 11 87 e4 a8 83 b0 77 3e 73 |S1..R\.......w>s|
+00000100 d5 cd e8 4e 1b a2 4a 52 38 43 6a b1 fc 85 98 7e |...N..JR8Cj....~|
+00000110 db 7d 0a 9c d9 bc 6e 7b 19 ce 3c 49 2f 8a d1 6d |.}....n{..<I/..m|
+00000120 93 39 7f b2 3b ab 6b 19 4c cd 53 d7 6b ff ff 89 |.9..;.k.L.S.k...|
+00000130 fc bc cf cc 22 c9 aa 46 08 c4 7a e0 d1 44 c4 c5 |...."..F..z..D..|
+00000140 8b 2d 93 b5 70 d7 19 4f 2c 4b c6 52 16 7b a8 bd |.-..p..O,K.R.{..|
+00000150 0c 46 a9 c2 b0 8f 3f 99 ef b4 13 c9 ad 26 a1 9e |.F....?......&..|
+00000160 4a 64 ce 22 a7 de 98 f9 d4 1c 73 c7 e8 59 cf 8c |Jd."......s..Y..|
+00000170 28 b4 39 f7 a6 08 76 d7 6d 7d b3 63 9b d1 64 e1 |(.9...v.m}.c..d.|
+00000180 10 ad b8 ff b5 93 5f 91 87 e2 72 93 47 b9 fc 8c |......_...r.G...|
+00000190 5e e4 c6 28 72 90 5c 66 25 23 74 f9 e6 fc 0e da |^..(r.\f%#t.....|
+000001a0 65 83 18 85 49 c6 d3 25 fe e2 90 02 0b 06 78 b0 |e...I..%......x.|
+000001b0 0d 2e fc 44 f6 5a 65 9f 55 e8 78 c2 a7 05 97 b6 |...D.Ze.U.x.....|
+000001c0 52 a5 18 51 61 eb 58 46 65 c1 51 8e 1f a0 3e 96 |R..Qa.XFe.Q...>.|
+000001d0 3a 52 24 2f 0a 33 c1 3b 34 74 ef 06 c5 5e 14 fb |:R$/.3.;4t...^..|
+000001e0 b8 30 a3 80 2e c4 11 f3 a2 4c 03 65 60 c0 b0 0c |.0.......L.e`...|
+000001f0 aa cd e8 2e f1 d8 f2 5a 4b 48 c0 5b 47 57 1d 9a |.......ZKH.[GW..|
+00000200 a0 cc 9e dd 6f 22 7c 8b f8 e3 21 2c fc 87 6e b0 |....o"|...!,..n.|
+00000210 cd bf 90 e4 05 f7 93 af 4a f0 73 73 4e af 70 ce |........J.ssN.p.|
+00000220 8d 96 e3 b0 bc e8 3e e2 92 09 a4 74 52 1c 7c 55 |......>....tR.|U|
+00000230 5c 5c 64 07 05 9d f5 54 0f ff 1b 02 0c c4 22 94 |\\d....T......".|
+00000240 aa 7b 43 e0 9d 67 25 23 da 8b 03 26 02 1b 22 92 |.{C..g%#...&..".|
+00000250 ff f8 f6 be 40 54 c2 9b 18 af 53 63 70 76 7c ce |....@T....Scpv|.|
+00000260 d4 e7 b6 f6 89 43 ec 11 af b3 05 ee de ad 16 03 |.....C..........|
+00000270 03 00 35 72 0c 52 b0 32 0a 1f fc 27 13 34 67 25 |..5r.R.2...'.4g%|
+00000280 a8 39 89 9e 6c ea 6f 25 72 f7 40 63 b2 c9 e2 e0 |.9..l.o%r.@c....|
+00000290 d4 eb 44 ad ae d0 58 1e 54 9c db 31 ba 03 44 9d |..D...X.T..1..D.|
+000002a0 95 f5 f3 bb ef d6 4d f5 16 03 03 00 98 d6 86 68 |......M........h|
+000002b0 3d 68 f6 6d 2d cf 30 e8 32 2d 8e 1e b9 67 a1 8d |=h.m-.0.2-...g..|
+000002c0 91 ae 10 8a d6 ce 3c f0 98 01 6a 96 c1 41 cc d4 |......<...j..A..|
+000002d0 b1 dc 49 25 be 0f 5b 59 6d f2 12 4d 49 92 e7 2d |..I%..[Ym..MI..-|
+000002e0 3d 59 53 38 ff ca 2c 52 ea 30 1c 55 9d 7c 7c 3b |=YS8..,R.0.U.||;|
+000002f0 2b 4f 53 0d d7 0f 50 1e ac f9 97 de cb 46 f9 74 |+OS...P......F.t|
+00000300 78 ac 4b 82 e4 25 10 63 04 5c 64 c1 d6 e3 4b c1 |x.K..%.c.\d...K.|
+00000310 5a 41 02 79 06 bd 75 6f 54 8e a4 a8 6d 7d 30 98 |ZA.y..uoT...m}0.|
+00000320 3f 65 fb 6c dd 59 39 e5 8e a4 08 96 62 70 12 2f |?e.l.Y9.....bp./|
+00000330 c5 94 3a 1b 2a 99 cc da fb d3 85 19 5b 10 3c d9 |..:.*.......[.<.|
+00000340 b4 f9 e8 df c8 14 03 03 00 11 c3 3f 56 55 75 1b |...........?VUu.|
+00000350 90 77 ff 04 f4 24 0d 0b 04 ac 2b 16 03 03 00 20 |.w...$....+.... |
+00000360 63 1a 0b 3e 2b 0b f0 d7 11 11 03 b0 0d f8 0c ce |c..>+...........|
+00000370 25 c6 b4 0d ee 5c 95 40 9a 86 29 1d ee 06 29 88 |%....\.@..)...).|
+>>> Flow 10 (server to client)
+00000000 14 03 03 00 11 5e 2d 5e 29 92 98 7e cd a8 00 b6 |.....^-^)..~....|
+00000010 08 53 39 b6 a2 d1 16 03 03 00 20 6e 0e 3e 92 3a |.S9....... n.>.:|
+00000020 b5 a6 ec 3e f2 38 3e 78 86 77 3e 50 9d 29 de bc |...>.8>x.w>P.)..|
+00000030 07 e7 d3 eb 20 ee a7 e9 5e 4c f6 17 03 03 00 19 |.... ...^L......|
+00000040 06 47 a1 60 72 a7 0d 81 84 86 5e 80 a7 73 7e d9 |.G.`r.....^..s~.|
+00000050 db f7 d6 97 f7 9c 12 66 b3 16 03 03 00 14 2b 6d |.......f......+m|
+00000060 1a cb 48 9f a3 84 45 a6 d7 c9 ed 4f 15 44 ec c8 |..H...E....O.D..|
+00000070 9b a5 |..|
+>>> Flow 11 (client to server)
+00000000 16 03 03 01 1a 57 f6 a3 85 62 29 d9 5d b5 40 f7 |.....W...b).].@.|
+00000010 71 ce d5 59 fa a4 5f a7 b7 a0 37 4a 5c 6c 9c 85 |q..Y.._...7J\l..|
+00000020 e5 df be 22 14 a5 75 e5 79 0f 0f f9 91 00 74 f3 |..."..u.y.....t.|
+00000030 5f b9 2f a8 1b e4 4a d4 7b 7d 79 e1 81 e4 7e 6c |_./...J.{}y...~l|
+00000040 7b b8 d4 c9 69 85 2a e7 4e 33 75 47 84 e6 7a 1c |{...i.*.N3uG..z.|
+00000050 9f 14 76 07 2c 53 e0 ab ba 5a c6 e3 a4 08 12 9e |..v.,S...Z......|
+00000060 99 15 ed ce 17 e1 6e 20 a8 f2 24 84 53 da c6 0f |......n ..$.S...|
+00000070 2f d5 c7 bf 23 00 90 1f 9f af 0f f7 d6 ad f6 4a |/...#..........J|
+00000080 3f 88 ec c2 a7 04 08 0f 97 e4 b5 6b a5 19 a4 98 |?..........k....|
+00000090 f7 ab a3 e1 44 56 39 b0 1d 2d c4 59 a7 3c d6 b4 |....DV9..-.Y.<..|
+000000a0 44 8d ae 56 0e d5 6b ab a4 33 da d1 c3 38 4b fe |D..V..k..3...8K.|
+000000b0 cc 40 3b 78 67 26 50 dd 75 3e a5 23 37 05 32 cf |.@;xg&P.u>.#7.2.|
+000000c0 b4 6d a3 c1 a3 83 f8 1d a4 80 7c e9 69 84 5c 55 |.m........|.i.\U|
+000000d0 92 7a 99 d7 86 27 dc be 54 27 d3 1d 1e ad 01 6d |.z...'..T'.....m|
+000000e0 58 27 e2 82 a1 e4 55 03 67 b9 ee 51 b1 2d f9 25 |X'....U.g..Q.-.%|
+000000f0 28 a3 c7 44 08 b0 3b 60 46 23 2c 17 76 f2 78 1e |(..D..;`F#,.v.x.|
+00000100 3c f2 b5 5c b0 1e 5d a7 9c e6 4f c3 ba 34 40 30 |<..\..]...O..4@0|
+00000110 d6 e3 68 2a d6 d2 75 04 d5 44 2d 41 87 c8 96 |..h*..u..D-A...|
+>>> Flow 12 (server to client)
+00000000 16 03 03 00 85 77 11 78 f7 3a 59 c7 f1 a4 e6 6c |.....w.x.:Y....l|
+00000010 3d e2 e0 1e 96 f7 2c d6 ce ef 27 3b 7f 37 cb bc |=.....,...';.7..|
+00000020 8e ca c0 57 ab 03 1e cc d1 fb 6c 49 e2 89 48 a1 |...W......lI..H.|
+00000030 84 00 a2 9b cb ae 2a ec 7c 60 9c 0c bf ff 07 ae |......*.|`......|
+00000040 13 16 7b 7b a2 80 35 d3 5d 17 18 5a fb d8 87 46 |..{{..5.]..Z...F|
+00000050 43 6e e7 e9 35 5f bb 5c 87 03 0d 3c 93 6d f9 9b |Cn..5_.\...<.m..|
+00000060 28 b9 42 c3 ea f0 11 60 a1 f4 72 c0 f9 4c e9 36 |(.B....`..r..L.6|
+00000070 77 c7 d0 e4 4b 7e d8 b4 68 d9 7f 97 bc 07 c5 4b |w...K~..h......K|
+00000080 5e 11 1d ab 6e a4 24 41 2c d3 16 03 03 02 69 e7 |^...n.$A,.....i.|
+00000090 68 ab 42 56 cb b5 70 a0 3b 63 c4 a6 10 49 1d d5 |h.BV..p.;c...I..|
+000000a0 15 33 29 54 8f 36 a8 3c b7 8e 79 5a e7 45 6d cc |.3)T.6.<..yZ.Em.|
+000000b0 c0 5f da 0a c1 13 56 b5 2d 8e 56 16 b4 ca 48 1d |._....V.-.V...H.|
+000000c0 30 3f 58 c6 79 06 a2 c0 3f 6f 59 4a dc f0 09 5d |0?X.y...?oYJ...]|
+000000d0 45 2a 23 4f ab 72 f4 4c 4d e0 05 44 7f 4c ab 25 |E*#O.r.LM..D.L.%|
+000000e0 6f 9c 6a c4 cf c0 bd 86 03 c1 b2 b2 12 4e c2 0b |o.j..........N..|
+000000f0 3e 8d 06 89 bb 46 70 79 51 33 eb 0d be ed 6e 0e |>....FpyQ3....n.|
+00000100 33 08 48 53 2a 2a fb da 13 61 da 21 df 8b 74 85 |3.HS**...a.!..t.|
+00000110 42 25 1f cf 7f 00 4c ca 80 9a 3d 25 07 da 22 bd |B%....L...=%..".|
+00000120 17 47 75 e5 da 60 88 67 65 19 55 b6 05 fc 6d fa |.Gu..`.ge.U...m.|
+00000130 9c 3d 19 fd 61 87 92 87 c5 95 80 06 d0 1a 71 7f |.=..a.........q.|
+00000140 05 67 f3 f6 af da 35 1f d1 49 63 49 89 28 d1 21 |.g....5..IcI.(.!|
+00000150 14 e0 06 14 14 83 a9 d9 86 21 68 0f 66 86 62 4d |.........!h.f.bM|
+00000160 cc 7f 9e dc 79 fd eb 14 59 e7 cc bd 5c 29 86 4a |....y...Y...\).J|
+00000170 5f 64 d2 7b 37 d1 72 4b ae 5b 12 c3 0c b0 a6 8a |_d.{7.rK.[......|
+00000180 99 e5 89 e7 9e 76 1e 85 fc b6 ae 4b fd 20 8b 6a |.....v.....K. .j|
+00000190 7d 7d 2b ff 11 d4 82 f0 2a d7 d6 9e e7 48 6e 1c |}}+.....*....Hn.|
+000001a0 1d 33 2b 31 af aa 67 a7 66 b0 47 10 b8 f7 b8 0e |.3+1..g.f.G.....|
+000001b0 0c ef 09 93 0a 42 2b 68 c8 30 cf d6 d4 8c 23 71 |.....B+h.0....#q|
+000001c0 ef c3 bd f6 eb 74 b5 4e 1a 94 44 43 98 c8 ec b3 |.....t.N..DC....|
+000001d0 51 10 44 2c f3 ae 27 c7 f3 5c 63 74 a8 1c f8 ff |Q.D,..'..\ct....|
+000001e0 a9 38 c2 7f b4 66 fd 3b 9d a7 9c 7a 93 fd a3 09 |.8...f.;...z....|
+000001f0 a6 51 c5 fd 6f 82 cc fb d2 58 bf 6e be 0d f2 4e |.Q..o....X.n...N|
+00000200 2c 8c 08 6f 25 ae 82 bf b6 bf b7 71 44 b6 4f 90 |,..o%......qD.O.|
+00000210 2e 1d 4e 1d 62 19 ee c7 4b 47 08 af 14 e3 cd 43 |..N.b...KG.....C|
+00000220 fb 37 e0 d2 58 d7 03 7e f6 81 74 e9 a8 33 a2 7f |.7..X..~..t..3..|
+00000230 06 94 5a 74 63 15 e1 f9 95 d3 b5 d6 52 e4 a4 5f |..Ztc.......R.._|
+00000240 7d 16 3d 6e c6 53 3c 45 f5 f3 bc 91 7d 48 55 58 |}.=n.S<E....}HUX|
+00000250 51 a2 8e fc e4 aa e0 24 0f 9c 0c fb d9 2f d9 5a |Q......$...../.Z|
+00000260 b8 02 df e6 71 30 64 e7 27 f9 b4 bc 3b 3a 5d a0 |....q0d.'...;:].|
+00000270 dd 7a fe 15 81 1d c2 41 02 65 a8 68 1e 29 ea 3a |.z.....A.e.h.).:|
+00000280 0e 6a 0e 3f bf 61 4f 5f b9 ce 5d 60 8e 55 0e ef |.j.?.aO_..]`.U..|
+00000290 26 b5 5a d2 c8 f2 94 fd b4 5e da e8 14 47 64 d8 |&.Z......^...Gd.|
+000002a0 3e 5c 2d 70 5b 9e 3a 74 eb 80 63 fe 7a 2f ac bd |>\-p[.:t..c.z/..|
+000002b0 4b 53 31 72 3d 20 89 60 8c 6e ce c7 07 d4 a9 6d |KS1r= .`.n.....m|
+000002c0 28 76 a3 78 e0 ae 11 3f 31 e5 64 fe 35 39 d8 88 |(v.x...?1.d.59..|
+000002d0 40 eb d0 f2 df db 1b 16 3a 11 33 ce 7c 63 cd 34 |@.......:.3.|c.4|
+000002e0 17 8c a3 d5 d1 8f 34 21 a7 fa b3 8f f1 84 b0 06 |......4!........|
+000002f0 d1 83 15 ac 26 1b 68 74 16 03 03 00 bc d2 f0 3d |....&.ht.......=|
+00000300 2b a9 8c 75 e9 24 7a e8 0a ec 11 d7 cf 08 8e 5d |+..u.$z........]|
+00000310 00 13 51 7f 2e 7a 6c 4b e2 35 c2 e0 9d c3 cb 79 |..Q..zlK.5.....y|
+00000320 8f ec 2b 21 8f 96 4d b8 b8 0c b7 d8 d1 7f dc 5b |..+!..M........[|
+00000330 85 8b b9 54 ba f6 65 76 5f b4 99 20 47 52 d8 96 |...T..ev_.. GR..|
+00000340 ac 12 b0 84 77 9b 42 09 fe c4 cf b4 22 e3 e8 3c |....w.B....."..<|
+00000350 a0 a0 e8 8e ab 61 0b 16 98 f3 bd ae 60 36 55 5a |.....a......`6UZ|
+00000360 6b 85 8b 79 03 4f 65 15 83 06 45 eb c7 d9 de 41 |k..y.Oe...E....A|
+00000370 53 0f 1f 12 ef 13 33 cc a6 fc 91 e4 7e a7 a3 31 |S.....3.....~..1|
+00000380 6f 40 f4 d3 0e 2c 22 de 72 64 0d cd e0 e8 ee 21 |o@...,".rd.....!|
+00000390 4b bd ef 53 78 9e 41 ce 04 96 3a 2f bc e7 41 6b |K..Sx.A...:/..Ak|
+000003a0 e0 a8 9e 40 02 1b 09 ab 8b 37 4c 2b b4 bc e1 72 |...@.....7L+...r|
+000003b0 06 af 88 24 75 6d 10 3a d5 16 03 03 00 14 8d 09 |...$um.:........|
+000003c0 7b 2e 7a 58 f8 1c 63 44 0a a9 c4 5d 9f 5c cc 73 |{.zX..cD...].\.s|
+000003d0 47 1a |G.|
+>>> Flow 13 (client to server)
+00000000 16 03 03 00 35 e1 bc fd 92 30 16 7d 71 c5 fc 15 |....5....0.}q...|
+00000010 6f eb 98 2b 8c bb b6 d3 0b 6d 71 12 54 7d 08 a6 |o..+.....mq.T}..|
+00000020 f1 a0 5b 37 6b 8b b7 f9 d6 11 53 c9 2c a4 b2 d3 |..[7k.....S.,...|
+00000030 52 db 73 f4 75 3d 45 78 68 e5 14 03 03 00 11 51 |R.s.u=Exh......Q|
+00000040 52 83 7e bd 5f 63 51 a4 1e 78 06 3b f1 f9 f8 a3 |R.~._cQ..x.;....|
+00000050 16 03 03 00 20 44 02 6e 8f fe 3a 25 40 e5 63 29 |.... D.n..:%@.c)|
+00000060 51 ce 94 55 cb 16 5a 9e 0d ec a8 73 f9 e8 46 06 |Q..U..Z....s..F.|
+00000070 b5 98 7f c2 98 |.....|
+>>> Flow 14 (server to client)
+00000000 14 03 03 00 11 da c7 c6 7f 04 1e 65 7a cb 53 02 |...........ez.S.|
+00000010 57 f7 6c f5 3b ca 16 03 03 00 20 9e 0e 55 81 35 |W.l.;..... ..U.5|
+00000020 15 c9 22 94 be 1e f4 5e 1e 95 99 e5 ba 4a b6 1a |.."....^.....J..|
+00000030 38 b5 31 25 85 4c a9 a8 39 fc 10 17 03 03 00 19 |8.1%.L..9.......|
+00000040 61 c9 ca 41 f7 9d 66 08 bd 30 42 b2 7f 56 a7 46 |a..A..f..0B..V.F|
+00000050 f4 23 18 30 c3 ec 96 cf 7f |.#.0.....|
+>>> Flow 15 (client to server)
+00000000 15 03 03 00 12 3a 24 58 49 ca a4 b1 6e 58 f2 e1 |.....:$XI...nX..|
+00000010 df 3c c2 63 3d 59 e4 |.<.c=Y.|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwiceRejected b/src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwiceRejected
new file mode 100644
index 0000000..898f5f2
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwiceRejected
@@ -0,0 +1,249 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 5d 02 00 00 59 03 03 cc a3 9c c7 68 |....]...Y......h|
+00000010 f8 de 98 95 45 68 9f 10 2e ba 1f cf 81 a9 51 52 |....Eh........QR|
+00000020 14 b7 ed a8 36 5a 40 43 e8 e8 bb 20 9a 57 99 f3 |....6Z@C... .W..|
+00000030 a8 be d3 2a 86 8d b5 9b af 91 83 13 00 33 5e 4e |...*.........3^N|
+00000040 f3 1c 42 67 08 65 54 40 dc 88 fb 90 cc a8 00 00 |..Bg.eT@........|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 03 02 59 0b 00 02 55 00 02 52 00 02 |......Y...U..R..|
+00000070 4f 30 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 |O0..K0..........|
+00000080 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 |....?.[..0...*.H|
+00000090 86 f7 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 |........0.1.0...|
+000000a0 55 04 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 |U....Go1.0...U..|
+000000b0 13 07 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 |..Go Root0...160|
+000000c0 31 30 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 |101000000Z..2501|
+000000d0 30 31 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 |01000000Z0.1.0..|
+000000e0 03 55 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 |.U....Go1.0...U.|
+000000f0 03 13 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 |...Go0..0...*.H.|
+00000100 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 |...........0....|
+00000110 81 00 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab |...F}...'.H..(!.|
+00000120 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d |~...]..RE.z6G...|
+00000130 92 42 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd |.B[.....y.@.Om..|
+00000140 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a |+.....g....."8.J|
+00000150 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 |.ts+.4......t{.X|
+00000160 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c |.la<..A..++$#w[.|
+00000170 3b bd 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 |;.u]. T..c...$..|
+00000180 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 |..P....C...ub...|
+00000190 52 d7 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 |R.........0..0..|
+000001a0 03 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 |.U...........0..|
+000001b0 03 55 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 |.U.%..0...+.....|
+000001c0 03 01 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 |....+.......0...|
+000001d0 55 1d 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d |U.......0.0...U.|
+000001e0 0e 04 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d |.........CC>I..m|
+000001f0 b6 80 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 |....`0...U.#..0.|
+00000200 80 10 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab |..H.IM.~.1......|
+00000210 6e 7b 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 |n{0...U....0...e|
+00000220 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 |xample.golang0..|
+00000230 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 |.*.H............|
+00000240 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed |.0.@+[P.a...SX..|
+00000250 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 |.(.X..8....1Z..f|
+00000260 3d 43 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a |=C.-...... d8.$:|
+00000270 00 bc cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 |....}.@ ._...a..|
+00000280 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed |v......\.....l..|
+00000290 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 |s..Cw.......@.a.|
+000002a0 4c 72 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 |Lr+...F..M...>..|
+000002b0 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 |.B...=.`.\!.;...|
+000002c0 16 03 03 00 ac 0c 00 00 a8 03 00 1d 20 1e f7 67 |............ ..g|
+000002d0 0a a6 d0 af 27 2d 0d 36 24 23 a5 97 90 ef 75 4a |....'-.6$#....uJ|
+000002e0 fc 0b 12 91 5d 92 bd bf 2d 7c 0c a2 06 08 04 00 |....]...-|......|
+000002f0 80 71 f3 c0 ff 7a 01 b2 15 21 06 ae a1 f8 fa b5 |.q...z...!......|
+00000300 19 f2 d0 f6 25 b2 7e 9f f1 8a 1c a1 a8 5d 2a 0a |....%.~......]*.|
+00000310 ec 42 5c f8 6e 8e 8d c9 38 53 d0 c2 f3 7d f3 c8 |.B\.n...8S...}..|
+00000320 12 f1 30 4b 7f 9a 9e 7c f8 78 56 9c ff 11 fd 36 |..0K...|.xV....6|
+00000330 60 c9 3d b5 f7 6e 0f 7a 22 aa 3d a1 30 98 93 1d |`.=..n.z".=.0...|
+00000340 7c 48 1f 79 24 cd a6 c2 d2 e8 f6 90 fe 19 6f 0d ||H.y$.........o.|
+00000350 3a a6 65 35 8d 19 e4 3c cb 3a 07 5e 62 57 3d 67 |:.e5...<.:.^bW=g|
+00000360 37 fa 23 26 0a 92 db 30 16 a8 37 3d d2 16 9d e4 |7.#&...0..7=....|
+00000370 a7 16 03 03 00 04 0e 00 00 00 |..........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.|
+00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....|
+00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 03 00 01 01 |....._X.;t......|
+00000030 16 03 03 00 20 22 30 b4 cc f8 e7 83 e4 72 5a 41 |.... "0......rZA|
+00000040 39 fa 92 4e ef c5 bb 6b 6e ec d5 55 9d 2f 53 99 |9..N...kn..U./S.|
+00000050 72 b6 99 55 a6 |r..U.|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 20 b7 be 6c 7a 7f |.......... ..lz.|
+00000010 00 e7 aa 12 ca 2d 29 6f eb f0 f1 5c 97 e5 d4 a2 |.....-)o...\....|
+00000020 08 ab e3 04 ba e4 4d 15 08 ef 86 |......M....|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 16 5f 25 54 0e dd 48 23 b4 d9 00 3f |....._%T..H#...?|
+00000010 1f 43 46 8e 32 64 3b 6a 42 70 ec |.CF.2d;jBp.|
+>>> Flow 6 (server to client)
+00000000 16 03 03 00 14 f7 db b2 a3 97 fd 00 16 52 c6 bf |.............R..|
+00000010 57 78 21 37 02 02 ed 25 32 |Wx!7...%2|
+>>> Flow 7 (client to server)
+00000000 16 03 03 01 1a 9e a2 a0 cc d3 e9 25 e7 3c 11 9b |...........%.<..|
+00000010 ab c4 a1 eb 5a 4a 5d c1 38 74 7e dc 8b 4c 1d 41 |....ZJ].8t~..L.A|
+00000020 69 18 a6 b8 4c 67 3f 5b 90 50 ed f4 ab 34 ad 77 |i...Lg?[.P...4.w|
+00000030 f6 28 f3 5b c9 db 16 ca 89 19 7c 90 f3 27 9e 0b |.(.[......|..'..|
+00000040 8c ca 7e 9e a4 9e 2c ba 22 9e 85 be 8e ba 58 c7 |..~...,.".....X.|
+00000050 c2 a3 da a2 55 ca 64 04 53 a5 92 43 8f 52 c0 63 |....U.d.S..C.R.c|
+00000060 b5 9b 6d eb 0e 09 2e 0f 42 a7 c5 72 87 34 c2 d2 |..m.....B..r.4..|
+00000070 9f 32 ce 25 58 be 94 21 4b d3 3b d8 9b 42 68 e3 |.2.%X..!K.;..Bh.|
+00000080 27 75 a3 15 57 8b cf e0 a8 ac 23 94 8e 4a b0 92 |'u..W.....#..J..|
+00000090 96 6f e4 a1 62 7d 24 67 92 b9 8a ec 76 1e bd ed |.o..b}$g....v...|
+000000a0 1e 05 d9 c1 03 6c 6a 43 f6 22 8d bb c6 c0 58 7e |.....ljC."....X~|
+000000b0 8e 49 f8 ef 9a 72 7c 3f 1b ff 98 fa 88 f4 ec b5 |.I...r|?........|
+000000c0 47 b1 29 19 c8 85 98 86 bd 75 9a bc ad 02 30 41 |G.)......u....0A|
+000000d0 21 e8 8f c1 69 d9 e0 b9 c2 b8 d7 91 8a 13 5b b5 |!...i.........[.|
+000000e0 7f 9a df 12 2e 61 4c 54 b1 ca 12 dd bf 83 0b e7 |.....aLT........|
+000000f0 68 fe 90 d9 2c 9c 86 9f 0e 57 19 e1 ba e5 2e c4 |h...,....W......|
+00000100 f0 c4 b4 dd e5 0f 36 98 0f 94 26 cb 92 32 03 57 |......6...&..2.W|
+00000110 78 15 19 3d bc 1e dd d1 46 28 24 06 c5 3d ed |x..=....F($..=.|
+>>> Flow 8 (server to client)
+00000000 16 03 03 00 85 90 29 5c 91 ed 28 4f 54 29 f4 e7 |......)\..(OT)..|
+00000010 b2 41 c9 38 5d ec 4a 38 22 0d a9 13 e9 65 fe 8c |.A.8].J8"....e..|
+00000020 a4 e8 1a a0 6e 07 d2 4d 35 55 a7 65 92 cd da 75 |....n..M5U.e...u|
+00000030 ca 0e 61 e3 6a 83 a0 30 bb 03 2a 6a e8 f0 69 3f |..a.j..0..*j..i?|
+00000040 95 8d 97 c3 1b ef 74 58 68 f0 88 82 16 96 62 0a |......tXh.....b.|
+00000050 49 7f 5b ec ee a1 6b 14 f6 5b 17 88 80 f6 70 e2 |I.[...k..[....p.|
+00000060 d9 a3 3a dc 46 65 63 ec 37 aa b6 53 a8 13 f3 44 |..:.Fec.7..S...D|
+00000070 5b 16 bd 4b ce 03 da 6f ba 2c 6a 5d 71 45 db 49 |[..K...o.,j]qE.I|
+00000080 1c 00 17 d5 d8 40 0a 14 bb e8 16 03 03 02 69 d3 |.....@........i.|
+00000090 cf e0 f6 ea fa 19 64 e9 af c4 47 2e 0d a5 14 20 |......d...G.... |
+000000a0 cd 7e 97 0d 45 16 85 34 e7 f0 ed c1 fe 3c 12 f2 |.~..E..4.....<..|
+000000b0 3f 2e f5 93 b0 95 f5 2c cd b1 ab 4b 8b e7 0d af |?......,...K....|
+000000c0 7d 99 41 1e 9e 9e 18 90 6c e3 35 15 0b 89 fe 0f |}.A.....l.5.....|
+000000d0 2f a2 e5 5c 67 bd 07 54 af 23 f2 ab 59 de 71 a2 |/..\g..T.#..Y.q.|
+000000e0 5e 04 21 2c d9 da bf 3a 41 53 18 c8 c9 d5 82 ac |^.!,...:AS......|
+000000f0 ba 31 25 fe e8 0f 94 c8 41 42 a0 43 d3 3f fb ea |.1%.....AB.C.?..|
+00000100 0a b5 3f 66 ff da 49 a9 1b 20 f6 26 b3 48 4a 75 |..?f..I.. .&.HJu|
+00000110 3f 88 74 d9 54 71 af d1 05 e3 9d 32 41 08 b8 8f |?.t.Tq.....2A...|
+00000120 a9 fb f9 dd 5a c0 10 23 0d 8c 60 33 c1 2e b5 57 |....Z..#..`3...W|
+00000130 dc 4c e2 95 82 be d0 39 10 f9 8c 48 62 df 11 f5 |.L.....9...Hb...|
+00000140 d8 be 5e 46 26 3b 44 3a 36 31 8c 53 4e c6 6e 65 |..^F&;D:61.SN.ne|
+00000150 28 e1 db 36 07 73 38 00 64 d6 ae fb 4e 35 a1 89 |(..6.s8.d...N5..|
+00000160 03 f7 f3 22 5e 7a 69 0b 6c fa c2 5a d3 b1 ba ad |..."^zi.l..Z....|
+00000170 e8 af 1f 21 31 c6 9d be 24 5d 4a f4 c3 69 61 36 |...!1...$]J..ia6|
+00000180 8f ce 81 10 d4 99 82 94 66 53 f7 50 dd e3 d0 5a |........fS.P...Z|
+00000190 ce 79 d8 0f 43 09 2a 2b 67 da 31 b5 0c ff c6 32 |.y..C.*+g.1....2|
+000001a0 13 a4 cd 26 1d 16 49 24 45 f8 24 40 12 ea 7a f1 |...&..I$E.$@..z.|
+000001b0 33 47 2d b7 1f 09 b4 fc 7e 00 dc 0d 3f a8 52 11 |3G-.....~...?.R.|
+000001c0 f6 03 b0 c0 87 e4 be f7 0c 2b 6a c9 e5 ef 00 62 |.........+j....b|
+000001d0 6d b6 b3 93 5f 60 08 f0 4f 3f be b7 8e 02 a8 c8 |m..._`..O?......|
+000001e0 5f 38 0a 6d c1 f3 4d df 49 b5 6d 31 80 d9 5b 81 |_8.m..M.I.m1..[.|
+000001f0 99 45 5d 43 cb 58 4e 28 5f 4f 6f e8 49 de cf ab |.E]C.XN(_Oo.I...|
+00000200 2a ab 85 7a ef 9f 10 77 00 9e 38 99 57 25 14 40 |*..z...w..8.W%.@|
+00000210 47 46 4a 30 4e 6a 75 f0 51 de 37 a0 6f 9a e6 17 |GFJ0Nju.Q.7.o...|
+00000220 f5 6b 48 16 62 0d 38 2d 3f 99 ff 94 b3 e7 6e 5b |.kH.b.8-?.....n[|
+00000230 3d 6f 15 5a e2 df c3 45 66 d6 52 1d a3 79 eb 01 |=o.Z...Ef.R..y..|
+00000240 94 3a 4f 30 2e 6b 30 82 8e 58 3b 9a fe c8 a1 a2 |.:O0.k0..X;.....|
+00000250 84 8b cd 0b 71 16 9e ea 81 23 b7 78 29 ba 5a 59 |....q....#.x).ZY|
+00000260 8c 89 60 8c f8 d4 a9 80 02 b9 fb 41 fc 21 3f 4a |..`........A.!?J|
+00000270 0f b3 c1 13 eb 07 f9 a0 13 d1 aa 3d c3 83 1e 53 |...........=...S|
+00000280 b3 b6 f9 61 51 28 60 ab 1f 5e f0 f5 e4 94 43 c2 |...aQ(`..^....C.|
+00000290 fc 53 aa d7 a3 47 f0 2e a0 e2 12 ee 21 c0 f6 81 |.S...G......!...|
+000002a0 cc 60 51 66 1b fc e9 f2 64 78 d3 b3 0c 96 6b b5 |.`Qf....dx....k.|
+000002b0 dc 22 7f d1 90 e9 ec ae 2f 50 81 b8 16 e7 07 83 |."....../P......|
+000002c0 db 75 8c b0 fd 63 a5 c9 b1 bc 01 08 e6 53 86 3c |.u...c.......S.<|
+000002d0 fe 98 67 ef 7a 7a 0a 33 2c 0b d7 57 25 8f 9d d2 |..g.zz.3,..W%...|
+000002e0 ce ba 62 2c 81 f9 f9 87 6c a3 64 ba 32 34 23 02 |..b,....l.d.24#.|
+000002f0 97 d7 42 cf f2 04 a9 08 16 03 03 00 bc c2 93 00 |..B.............|
+00000300 26 dc ce 86 67 d7 7d 15 52 0e de 5c 2c 87 da 62 |&...g.}.R..\,..b|
+00000310 4a 4f f5 cf 95 b0 c0 df 09 4a 4f 59 01 04 4b 3b |JO.......JOY..K;|
+00000320 db 90 f7 ec 64 5a 71 1a 34 6c 67 ff e6 88 b1 39 |....dZq.4lg....9|
+00000330 67 11 84 fc 30 26 16 00 2c 8e 0e e5 bd 3f d9 24 |g...0&..,....?.$|
+00000340 46 ad c9 71 bc 2a c0 09 11 32 36 38 38 91 8d 96 |F..q.*...2688...|
+00000350 73 e5 8b a4 b7 6e fb 80 fc 68 d5 a8 c7 ff 04 00 |s....n...h......|
+00000360 b8 31 e8 30 17 97 db 43 ba b3 d8 4e 9f 48 c6 4b |.1.0...C...N.H.K|
+00000370 23 7a a0 cb 2f 68 db 02 f2 f0 df 38 8f 4c d8 a8 |#z../h.....8.L..|
+00000380 f5 27 e5 fe ca 10 2c 26 51 3c 37 07 14 66 93 9b |.'....,&Q<7..f..|
+00000390 15 b0 c9 e2 f2 78 74 4d c6 e4 42 79 ff f1 cf 9d |.....xtM..By....|
+000003a0 a1 c6 a5 5b 7f 4d 85 b3 fb 2b 46 96 c9 49 99 b6 |...[.M...+F..I..|
+000003b0 08 58 8e 6f 95 1e 2e 6d 93 16 03 03 00 4a 55 ef |.X.o...m.....JU.|
+000003c0 94 9b f2 d3 38 44 2c 39 17 07 2f 2c 76 0b c0 81 |....8D,9../,v...|
+000003d0 d4 0b 5c df cf c3 07 62 c8 dc 82 bb 92 04 84 76 |..\....b.......v|
+000003e0 e2 74 57 21 f6 7f ee 8f 5f c8 57 bd 97 c8 35 e7 |.tW!...._.W...5.|
+000003f0 25 12 00 4b 72 c0 de c4 9e 82 5a 4d bf 05 f9 ab |%..Kr.....ZM....|
+00000400 b1 5c 2e 64 66 38 95 0a 16 03 03 00 14 35 f4 4d |.\.df8.......5.M|
+00000410 20 b9 38 cb 40 3e 46 83 28 b0 c7 19 ba 83 6a cd | .8.@>F.(.....j.|
+00000420 e4 |.|
+>>> Flow 9 (client to server)
+00000000 16 03 03 02 69 6d 51 fa 86 0f dd 19 19 7a e9 f5 |....imQ......z..|
+00000010 40 f7 4f 7a 10 c0 33 01 b8 14 32 92 7b 92 e0 c0 |@.Oz..3...2.{...|
+00000020 04 84 cf 1c d8 15 2a be 12 0b 65 15 f2 bc 96 cf |......*...e.....|
+00000030 9e d7 eb 5a f6 06 ee b0 8e e4 fc b9 c6 d6 81 52 |...Z...........R|
+00000040 c1 4c a9 d7 33 a1 f8 b6 cd 79 eb 7d 44 5a 99 c0 |.L..3....y.}DZ..|
+00000050 5b 8b 9d 8c 93 53 b6 27 f2 a0 e2 7a a2 66 de 3f |[....S.'...z.f.?|
+00000060 65 0d 13 14 09 8b 1c 2a 85 7d 24 26 9a 64 b2 d1 |e......*.}$&.d..|
+00000070 7c 10 ce b2 1e 86 df f1 a8 2c 2a 47 ae fe fe 1c ||........,*G....|
+00000080 23 14 eb 78 40 bf 88 25 db 1a 7e 60 4d 3e b8 cb |#..x@..%..~`M>..|
+00000090 7d 3c 2f d1 a7 6b 22 ee 99 21 88 50 d7 2d 06 2d |}</..k"..!.P.-.-|
+000000a0 08 2e c3 c1 56 44 9f 3f aa 29 f8 1c aa c6 2c e2 |....VD.?.)....,.|
+000000b0 ad 61 b2 7f 4f 3a 14 e7 cc 0f 0e e9 b1 5a 0b af |.a..O:.......Z..|
+000000c0 28 60 18 50 4d 98 07 5e 69 04 af c1 5b fa b5 ab |(`.PM..^i...[...|
+000000d0 16 24 68 b0 48 8b 34 b0 25 bd 8f 92 76 b2 44 06 |.$h.H.4.%...v.D.|
+000000e0 02 53 de 34 82 ff c6 bc ea f5 c6 41 e4 24 08 82 |.S.4.......A.$..|
+000000f0 b7 3a 02 97 11 c4 07 6b 51 9b 70 d1 7c 77 d4 23 |.:.....kQ.p.|w.#|
+00000100 80 6b 6e c7 68 60 f8 4c 6d bc 11 1e d2 40 38 c3 |.kn.h`.Lm....@8.|
+00000110 ff db d1 2e bf 9b 30 86 45 5a 23 8c 01 9f 05 68 |......0.EZ#....h|
+00000120 2e 54 4e 2d c3 f0 5c 8c 94 27 6a 9e 3a df 35 0a |.TN-..\..'j.:.5.|
+00000130 f9 20 8a cc ef 0f cc b8 ca d0 8e 1e 8d 24 a4 12 |. ...........$..|
+00000140 d1 e6 12 80 b9 3d c5 fc 3a 08 41 ef ff 0b 0a c7 |.....=..:.A.....|
+00000150 3c 7d a7 4a 8c c2 39 33 f1 3f b9 b9 55 ae f2 c0 |<}.J..93.?..U...|
+00000160 7a 26 80 c5 a8 00 6a 53 de 0f 7b e1 62 05 26 7b |z&....jS..{.b.&{|
+00000170 f5 bd dc 4c ec 6e b3 01 66 6b bd c6 f3 12 72 39 |...L.n..fk....r9|
+00000180 03 6c ac ac b4 26 82 b3 4b 7b e2 9d c3 ea 27 c1 |.l...&..K{....'.|
+00000190 e9 98 9d 21 c6 50 1a f0 a2 2d 8b cb 24 3d 68 ce |...!.P...-..$=h.|
+000001a0 3e 9c 74 03 9c 4e 17 25 c2 af d8 e3 04 37 56 d5 |>.t..N.%.....7V.|
+000001b0 fc 69 fe ad 75 67 34 7b ac e4 4f d5 82 b9 36 3e |.i..ug4{..O...6>|
+000001c0 74 51 a5 32 3b 77 27 15 22 d8 8b c9 ad a6 98 5b |tQ.2;w'."......[|
+000001d0 c5 4e 8d 62 bf ef 2d 41 b8 6d 5b 09 13 b3 40 ea |.N.b..-A.m[...@.|
+000001e0 19 c4 08 78 e3 c1 a1 5e 05 a3 79 6a 27 d5 41 3e |...x...^..yj'.A>|
+000001f0 c5 a6 f4 20 4c 93 92 77 c5 4a e8 1f f5 4b 83 87 |... L..w.J...K..|
+00000200 66 40 c2 c1 aa 89 69 00 5b fb 54 94 1f b7 39 cd |f@....i.[.T...9.|
+00000210 cd 9b 53 ad 08 63 30 05 e4 72 33 f0 ba b9 9d d9 |..S..c0..r3.....|
+00000220 d1 fe c3 fc de 07 a2 a3 b2 85 0b 33 4a bd 54 77 |...........3J.Tw|
+00000230 53 7c 8e 70 ed 9f ae 9d 2f 56 19 ce d6 1b 7a 64 |S|.p..../V....zd|
+00000240 80 72 bc 86 b7 1a d6 5b ac a2 0c b2 c4 fa 79 f2 |.r.....[......y.|
+00000250 16 7f 06 01 47 d3 f3 9b 4b 24 e2 f7 6b 33 45 4e |....G...K$..k3EN|
+00000260 b0 84 f8 f6 4d b4 4a 3f 37 20 49 77 ff 6f 16 03 |....M.J?7 Iw.o..|
+00000270 03 00 35 3b d6 d8 46 3a 93 f9 f4 29 b3 b7 9c cf |..5;..F:...)....|
+00000280 b9 2d 90 58 78 91 ee d5 30 bd 59 e2 5a 1f 30 8c |.-.Xx...0.Y.Z.0.|
+00000290 6e f9 1e d8 64 85 aa 1c 8b 41 10 07 d5 b2 7d 55 |n...d....A....}U|
+000002a0 13 73 ad 0e 2d e0 d4 ff 16 03 03 00 98 75 4a 72 |.s..-........uJr|
+000002b0 0f 07 ff 07 e3 80 96 7d c6 1b ab b8 c4 fc 38 0f |.......}......8.|
+000002c0 f6 f8 f9 06 95 d4 7b 93 85 0f b3 34 11 cd 70 6f |......{....4..po|
+000002d0 9b 3b a3 33 e5 fe e7 6a df 4b 02 e1 91 18 f3 e2 |.;.3...j.K......|
+000002e0 3e d0 7c e4 95 c2 e7 ef dc 20 c3 6b b7 9e 1d 9a |>.|...... .k....|
+000002f0 8c 23 c7 22 91 e7 7d 17 e4 5e 02 39 c3 6a b3 46 |.#."..}..^.9.j.F|
+00000300 31 32 4a 8b 7b 0a 4a f4 51 ba a7 01 58 a9 bc 52 |12J.{.J.Q...X..R|
+00000310 64 a9 e2 93 ad 34 c8 16 ad 66 67 e3 e7 3c 2c 66 |d....4...fg..<,f|
+00000320 59 e8 df f7 cf 96 00 57 85 63 f1 4b 45 c6 8a e7 |Y......W.c.KE...|
+00000330 54 9f 22 0c 74 2e 0c 1a cb df d0 98 55 bc d1 fd |T.".t.......U...|
+00000340 2a e2 73 eb 1b 14 03 03 00 11 02 c8 fe cd 2a 0d |*.s...........*.|
+00000350 c2 35 3c ff dd 23 e7 15 bf fe a0 16 03 03 00 20 |.5<..#......... |
+00000360 7b ea 15 d3 2d 51 57 39 76 4b ef 16 0d 19 5d e0 |{...-QW9vK....].|
+00000370 22 5e 68 19 c9 94 7e e9 67 41 12 85 2c e2 7c b8 |"^h...~.gA..,.|.|
+>>> Flow 10 (server to client)
+00000000 14 03 03 00 11 6b a1 f5 7f f5 64 ff 54 2a 67 95 |.....k....d.T*g.|
+00000010 f5 25 5b fe 38 39 16 03 03 00 20 be 49 c4 6c 7a |.%[.89.... .I.lz|
+00000020 12 cf 16 5b 1c b3 14 53 79 3e 8d 01 85 75 91 1a |...[...Sy>...u..|
+00000030 3a fe bc a9 c5 11 3f d5 88 4b 3e 17 03 03 00 19 |:.....?..K>.....|
+00000040 89 9c 38 5f 11 ba 1e 81 8a 09 ae 95 03 28 47 6c |..8_.........(Gl|
+00000050 db 9b 38 9d e7 37 75 01 af 16 03 03 00 14 c3 86 |..8..7u.........|
+00000060 cd a6 a3 dd 62 c9 4b be e5 2d 3f 31 a0 cc 87 f8 |....b.K..-?1....|
+00000070 78 61 |xa|
+>>> Flow 11 (client to server)
+00000000 15 03 03 00 12 35 45 94 25 9c 40 dd df 00 a9 13 |.....5E.%.@.....|
+00000010 f2 7c 47 63 98 22 c5 15 03 03 00 12 60 26 66 bb |.|Gc."......`&f.|
+00000020 8b 92 9d da 32 e3 97 92 ae 89 a9 2a d0 9a |....2......*..|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-RenegotiationRejected b/src/crypto/tls/testdata/Client-TLSv12-RenegotiationRejected
new file mode 100644
index 0000000..8307ee3
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-RenegotiationRejected
@@ -0,0 +1,96 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 5d 02 00 00 59 03 03 8a 1d c8 bd c6 |....]...Y.......|
+00000010 43 4c 78 5c 99 f4 8f e3 72 4b 73 a3 20 10 5b 8b |CLx\....rKs. .[.|
+00000020 3e 04 7f 4c 5c 58 fb d5 ed c6 d9 20 ff 23 98 81 |>..L\X..... .#..|
+00000030 0a 7f d2 f4 ed ae 87 2e ad e7 a9 60 31 b1 36 ab |...........`1.6.|
+00000040 f4 b6 cc 98 a0 8b 62 ca 57 ed 58 87 cc a8 00 00 |......b.W.X.....|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 03 02 59 0b 00 02 55 00 02 52 00 02 |......Y...U..R..|
+00000070 4f 30 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 |O0..K0..........|
+00000080 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 |....?.[..0...*.H|
+00000090 86 f7 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 |........0.1.0...|
+000000a0 55 04 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 |U....Go1.0...U..|
+000000b0 13 07 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 |..Go Root0...160|
+000000c0 31 30 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 |101000000Z..2501|
+000000d0 30 31 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 |01000000Z0.1.0..|
+000000e0 03 55 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 |.U....Go1.0...U.|
+000000f0 03 13 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 |...Go0..0...*.H.|
+00000100 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 |...........0....|
+00000110 81 00 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab |...F}...'.H..(!.|
+00000120 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d |~...]..RE.z6G...|
+00000130 92 42 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd |.B[.....y.@.Om..|
+00000140 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a |+.....g....."8.J|
+00000150 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 |.ts+.4......t{.X|
+00000160 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c |.la<..A..++$#w[.|
+00000170 3b bd 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 |;.u]. T..c...$..|
+00000180 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 |..P....C...ub...|
+00000190 52 d7 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 |R.........0..0..|
+000001a0 03 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 |.U...........0..|
+000001b0 03 55 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 |.U.%..0...+.....|
+000001c0 03 01 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 |....+.......0...|
+000001d0 55 1d 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d |U.......0.0...U.|
+000001e0 0e 04 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d |.........CC>I..m|
+000001f0 b6 80 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 |....`0...U.#..0.|
+00000200 80 10 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab |..H.IM.~.1......|
+00000210 6e 7b 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 |n{0...U....0...e|
+00000220 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 |xample.golang0..|
+00000230 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 |.*.H............|
+00000240 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed |.0.@+[P.a...SX..|
+00000250 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 |.(.X..8....1Z..f|
+00000260 3d 43 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a |=C.-...... d8.$:|
+00000270 00 bc cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 |....}.@ ._...a..|
+00000280 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed |v......\.....l..|
+00000290 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 |s..Cw.......@.a.|
+000002a0 4c 72 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 |Lr+...F..M...>..|
+000002b0 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 |.B...=.`.\!.;...|
+000002c0 16 03 03 00 ac 0c 00 00 a8 03 00 1d 20 ba 3a 8d |............ .:.|
+000002d0 07 bd 2e fa bd 85 70 45 e9 b6 eb 1f 2c 15 a2 15 |......pE....,...|
+000002e0 d7 29 2c a9 a8 ec 46 b0 77 0a 49 c2 49 08 04 00 |.),...F.w.I.I...|
+000002f0 80 5c a8 eb 85 8d 5f 01 9f 19 b8 6b 9a 66 ed 07 |.\...._....k.f..|
+00000300 ad e9 2e 85 c1 b8 94 56 17 84 0d d4 14 7b e2 c1 |.......V.....{..|
+00000310 89 80 f5 92 31 a0 90 6f 59 fb e7 af a9 e9 6d f3 |....1..oY.....m.|
+00000320 72 aa aa e5 d9 4c d9 ac bb 05 ac 51 e2 3f 64 05 |r....L.....Q.?d.|
+00000330 e8 e4 fd 80 b3 b9 6f 54 91 13 72 8d 45 ea 0f 13 |......oT..r.E...|
+00000340 f7 22 19 92 ce 66 fc d0 be af d3 8e 01 ef a5 7a |."...f.........z|
+00000350 08 6e f3 f7 28 55 33 bf e9 2a b6 60 d5 32 3f df |.n..(U3..*.`.2?.|
+00000360 e7 df 11 21 e4 c5 6e 13 bb f7 ad c7 ca 2e 11 2e |...!..n.........|
+00000370 22 16 03 03 00 04 0e 00 00 00 |".........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.|
+00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....|
+00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 03 00 01 01 |....._X.;t......|
+00000030 16 03 03 00 20 46 20 45 1d b3 e5 62 1d 89 b7 67 |.... F E...b...g|
+00000040 23 76 0b f4 fb c3 fd 57 80 09 ee 69 e3 ad bb 42 |#v.....W...i...B|
+00000050 56 55 b6 6b 73 |VU.ks|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 20 69 d6 1d dd 67 |.......... i...g|
+00000010 bb 02 a5 41 a5 11 6d e2 54 9a e8 c7 e5 b5 60 b5 |...A..m.T.....`.|
+00000020 77 fb e6 61 22 c7 0d 2f bb bf d4 |w..a"../...|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 16 bb a9 4d d8 15 fc 1f 99 96 03 80 |.......M........|
+00000010 5e fc b5 f8 ac 14 10 82 f5 08 c6 |^..........|
+>>> Flow 6 (server to client)
+00000000 16 03 03 00 14 0f 7d 98 6c 60 b3 cc cf c5 f3 0a |......}.l`......|
+00000010 8f d2 40 6a 5b e5 45 1b 8b |..@j[.E..|
+>>> Flow 7 (client to server)
+00000000 15 03 03 00 12 f4 9f 10 dc f2 69 4c 21 0c a0 8f |..........iL!...|
+00000010 6b fd aa a1 93 9a 3a 15 03 03 00 12 be 68 f2 b8 |k.....:......h..|
+00000020 8b 0d a5 1f 98 f0 c2 dd d4 0a 8c 46 b8 f5 |...........F..|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-SCT b/src/crypto/tls/testdata/Client-TLSv12-SCT
new file mode 100644
index 0000000..01fa299
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-SCT
@@ -0,0 +1,114 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 01 ca 02 00 01 c6 03 03 37 df c1 4d 8a |...........7..M.|
+00000010 eb 27 a3 6c ec 70 05 9f f0 86 80 01 6e ad 88 55 |.'.l.p......n..U|
+00000020 f2 1a 44 fb 42 d6 03 5d f8 74 18 20 0a f5 d0 22 |..D.B..].t. ..."|
+00000030 aa f2 9f e3 9a 0c 86 27 2e 66 be d5 3a c2 4d 77 |.......'.f..:.Mw|
+00000040 f8 5e 78 2b 71 ab 5e 0a 09 bc e1 d6 cc a8 00 01 |.^x+q.^.........|
+00000050 7e 00 12 01 69 01 67 00 75 00 a4 b9 09 90 b4 18 |~...i.g.u.......|
+00000060 58 14 87 bb 13 a2 cc 67 70 0a 3c 35 98 04 f9 1b |X......gp.<5....|
+00000070 df b8 e3 77 cd 0e c8 0d dc 10 00 00 01 47 97 99 |...w.........G..|
+00000080 ee 16 00 00 04 03 00 46 30 44 02 20 1c 4b 82 5d |.......F0D. .K.]|
+00000090 95 6e 67 5b db 04 95 4b f6 ce f4 32 3e 86 7a 7a |.ng[...K...2>.zz|
+000000a0 32 ab 18 60 74 de 08 da 05 91 4c 2f 02 20 73 54 |2..`t.....L/. sT|
+000000b0 1b 6e 7f a1 b0 7d 11 bc e6 f3 85 2f 97 66 1a f7 |.n...}...../.f..|
+000000c0 8a e4 10 25 8f 12 f4 6f 39 0f d2 9e 18 f0 00 76 |...%...o9......v|
+000000d0 00 68 f6 98 f8 1f 64 82 be 3a 8c ee b9 28 1d 4c |.h....d..:...(.L|
+000000e0 fc 71 51 5d 67 93 d4 44 d1 0a 67 ac bb 4f 4f fb |.qQ]g..D..g..OO.|
+000000f0 c4 00 00 01 47 97 e1 b5 70 00 00 04 03 00 47 30 |....G...p.....G0|
+00000100 45 02 20 32 21 14 38 06 d8 72 2e 00 30 64 1a e2 |E. 2!.8..r..0d..|
+00000110 e8 6d 4e 5a e1 d9 42 1e 82 4b 96 25 89 d5 26 13 |.mNZ..B..K.%..&.|
+00000120 d3 9c fa 02 21 00 8f 12 28 64 51 4f 44 d5 8c 18 |....!...(dQOD...|
+00000130 62 23 b2 43 93 33 05 f3 43 55 a1 d9 ee cd c5 71 |b#.C.3..CU.....q|
+00000140 35 91 dd 49 d1 0b 00 76 00 ee 4b bd b7 75 ce 60 |5..I...v..K..u.`|
+00000150 ba e1 42 69 1f ab e1 9e 66 a3 0f 7e 5f b0 72 d8 |..Bi....f..~_.r.|
+00000160 83 00 c4 7b 89 7a a8 fd cb 00 00 01 48 5c 64 8a |...{.z......H\d.|
+00000170 87 00 00 04 03 00 47 30 45 02 20 29 89 d6 b0 53 |......G0E. )...S|
+00000180 d3 d2 e9 91 bc f1 b5 40 be 1e 2e e7 5c b4 74 27 |.......@....\.t'|
+00000190 ed 8f 9b 02 e9 fa c2 4c ba a2 be 02 21 00 af 43 |.......L....!..C|
+000001a0 64 52 71 15 29 58 40 91 c7 08 16 96 03 a8 73 a5 |dRq.)X@.......s.|
+000001b0 65 a0 6c b8 48 56 5a b6 29 83 64 6d 2a 9d ff 01 |e.l.HVZ.).dm*...|
+000001c0 00 01 00 00 0b 00 04 03 00 01 02 00 17 00 00 16 |................|
+000001d0 03 03 02 59 0b 00 02 55 00 02 52 00 02 4f 30 82 |...Y...U..R..O0.|
+000001e0 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 |.K0.............|
+000001f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d |.?.[..0...*.H...|
+00000200 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 55 04 0a |.....0.1.0...U..|
+00000210 13 02 47 6f 31 10 30 0e 06 03 55 04 03 13 07 47 |..Go1.0...U....G|
+00000220 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 |o Root0...160101|
+00000230 30 30 30 30 30 30 5a 17 0d 32 35 30 31 30 31 30 |000000Z..2501010|
+00000240 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 |00000Z0.1.0...U.|
+00000250 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 03 13 02 |...Go1.0...U....|
+00000260 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 |Go0..0...*.H....|
+00000270 01 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 db |........0.......|
+00000280 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 |F}...'.H..(!.~..|
+00000290 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b |.]..RE.z6G....B[|
+000002a0 c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b |.....y.@.Om..+..|
+000002b0 c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 |...g....."8.J.ts|
+000002c0 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 |+.4......t{.X.la|
+000002d0 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 |<..A..++$#w[.;.u|
+000002e0 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 |]. T..c...$....P|
+000002f0 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 |....C...ub...R..|
+00000300 03 01 00 01 a3 81 93 30 81 90 30 0e 06 03 55 1d |.......0..0...U.|
+00000310 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d |..........0...U.|
+00000320 25 04 16 30 14 06 08 2b 06 01 05 05 07 03 01 06 |%..0...+........|
+00000330 08 2b 06 01 05 05 07 03 02 30 0c 06 03 55 1d 13 |.+.......0...U..|
+00000340 01 01 ff 04 02 30 00 30 19 06 03 55 1d 0e 04 12 |.....0.0...U....|
+00000350 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 |......CC>I..m...|
+00000360 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 80 10 48 |.`0...U.#..0...H|
+00000370 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 |.IM.~.1......n{0|
+00000380 19 06 03 55 1d 11 04 12 30 10 82 0e 65 78 61 6d |...U....0...exam|
+00000390 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 |ple.golang0...*.|
+000003a0 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc |H.............0.|
+000003b0 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 |@+[P.a...SX...(.|
+000003c0 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 |X..8....1Z..f=C.|
+000003d0 2d d9 0b f2 97 df d3 20 64 38 92 24 3a 00 bc cf |-...... d8.$:...|
+000003e0 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 |.}.@ ._...a..v..|
+000003f0 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 |....\.....l..s..|
+00000400 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b |Cw.......@.a.Lr+|
+00000410 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 |...F..M...>...B.|
+00000420 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 |..=.`.\!.;......|
+00000430 00 ac 0c 00 00 a8 03 00 1d 20 63 41 30 1c 95 79 |......... cA0..y|
+00000440 1b a6 85 f4 e1 b6 d7 f5 82 e2 4f 2b ae cd 7b 4b |..........O+..{K|
+00000450 20 e2 7e 43 f1 59 e5 83 92 55 08 04 00 80 5c aa | .~C.Y...U....\.|
+00000460 39 6d 57 d3 b6 15 4d 9e c8 e1 dc 50 b3 89 69 99 |9mW...M....P..i.|
+00000470 da 07 64 74 c4 ab d3 83 f0 9b fc 3a da 26 9f ce |..dt.......:.&..|
+00000480 37 e9 7a 50 e5 70 d1 71 0b 0d 73 03 9c c1 3f 81 |7.zP.p.q..s...?.|
+00000490 f9 1d 57 32 6b 48 50 1d 5d 7d 64 56 f0 c9 8c 69 |..W2kHP.]}dV...i|
+000004a0 d6 91 15 85 95 9a 0c 76 f0 9c d2 fe d4 df 65 00 |.......v......e.|
+000004b0 a1 cc 65 4a a2 8e 06 fc 50 77 ff 00 44 b5 cc f5 |..eJ....Pw..D...|
+000004c0 9f 39 2f 95 72 4f 51 af 21 09 6a 6a 21 60 24 65 |.9/.rOQ.!.jj!`$e|
+000004d0 78 20 9b 06 0e 24 1b 79 f2 8d 15 35 49 44 16 03 |x ...$.y...5ID..|
+000004e0 03 00 04 0e 00 00 00 |.......|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.|
+00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....|
+00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 03 00 01 01 |....._X.;t......|
+00000030 16 03 03 00 20 d0 2b f9 13 8b 71 de 1b 1d 63 2e |.... .+...q...c.|
+00000040 66 05 12 ee 11 d5 9b 75 ee 51 fa 42 fa 5d 86 eb |f......u.Q.B.]..|
+00000050 f0 c5 c5 cb 5b |....[|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 20 71 ac 7b 2e ba |.......... q.{..|
+00000010 d5 7e 70 6c 7c 94 0e 55 0f 65 8c 1d ff 5e 79 d6 |.~pl|..U.e...^y.|
+00000020 21 9b 8a f4 82 35 69 b8 5a d9 1a |!....5i.Z..|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 16 82 6e 37 1a 95 19 06 bf da ca 8c |......n7........|
+00000010 f4 07 3a 63 69 c7 00 ce 5c b9 bf 15 03 03 00 12 |..:ci...\.......|
+00000020 eb 05 f5 6f 8c 59 16 ed 26 1b f9 1f 2e 4e b8 89 |...o.Y..&....N..|
+00000030 80 77 |.w|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-X25519-ECDHE b/src/crypto/tls/testdata/Client-TLSv12-X25519-ECDHE
new file mode 100644
index 0000000..372abea
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-X25519-ECDHE
@@ -0,0 +1,92 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 f8 01 00 00 f4 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 79 00 05 00 05 01 00 00 00 00 00 0a 00 |...y............|
+00000090 04 00 02 00 1d 00 0b 00 02 01 00 00 0d 00 1a 00 |................|
+000000a0 18 08 04 04 03 08 07 08 05 08 06 04 01 05 01 06 |................|
+000000b0 01 05 03 06 03 02 01 02 03 ff 01 00 01 00 00 17 |................|
+000000c0 00 00 00 12 00 00 00 2b 00 09 08 03 04 03 03 03 |.......+........|
+000000d0 02 03 01 00 33 00 26 00 24 00 1d 00 20 2f e5 7d |....3.&.$... /.}|
+000000e0 a3 47 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 |.G.bC.(.._.).0..|
+000000f0 84 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 |........_X.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 5d 02 00 00 59 03 03 19 05 85 f6 4a |....]...Y......J|
+00000010 53 c9 c6 4f ac 38 b7 cc d8 5d 00 dc 3b 97 9c 0d |S..O.8...]..;...|
+00000020 d0 e0 9f d8 71 28 a1 ab e8 b7 cc 20 a6 a4 8c 69 |....q(..... ...i|
+00000030 6e 9c ee ae 75 14 b8 0f 93 b3 c2 82 ff 01 9b d7 |n...u...........|
+00000040 25 90 d7 53 02 6d 3b ec e9 1a 21 e5 c0 2f 00 00 |%..S.m;...!../..|
+00000050 11 ff 01 00 01 00 00 0b 00 04 03 00 01 02 00 17 |................|
+00000060 00 00 16 03 03 02 59 0b 00 02 55 00 02 52 00 02 |......Y...U..R..|
+00000070 4f 30 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 |O0..K0..........|
+00000080 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 |....?.[..0...*.H|
+00000090 86 f7 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 |........0.1.0...|
+000000a0 55 04 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 |U....Go1.0...U..|
+000000b0 13 07 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 |..Go Root0...160|
+000000c0 31 30 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 |101000000Z..2501|
+000000d0 30 31 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 |01000000Z0.1.0..|
+000000e0 03 55 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 |.U....Go1.0...U.|
+000000f0 03 13 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 |...Go0..0...*.H.|
+00000100 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 |...........0....|
+00000110 81 00 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab |...F}...'.H..(!.|
+00000120 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d |~...]..RE.z6G...|
+00000130 92 42 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd |.B[.....y.@.Om..|
+00000140 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a |+.....g....."8.J|
+00000150 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 |.ts+.4......t{.X|
+00000160 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c |.la<..A..++$#w[.|
+00000170 3b bd 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 |;.u]. T..c...$..|
+00000180 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 |..P....C...ub...|
+00000190 52 d7 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 |R.........0..0..|
+000001a0 03 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 |.U...........0..|
+000001b0 03 55 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 |.U.%..0...+.....|
+000001c0 03 01 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 |....+.......0...|
+000001d0 55 1d 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d |U.......0.0...U.|
+000001e0 0e 04 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d |.........CC>I..m|
+000001f0 b6 80 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 |....`0...U.#..0.|
+00000200 80 10 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab |..H.IM.~.1......|
+00000210 6e 7b 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 |n{0...U....0...e|
+00000220 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 |xample.golang0..|
+00000230 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 |.*.H............|
+00000240 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed |.0.@+[P.a...SX..|
+00000250 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 |.(.X..8....1Z..f|
+00000260 3d 43 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a |=C.-...... d8.$:|
+00000270 00 bc cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 |....}.@ ._...a..|
+00000280 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed |v......\.....l..|
+00000290 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 |s..Cw.......@.a.|
+000002a0 4c 72 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 |Lr+...F..M...>..|
+000002b0 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 |.B...=.`.\!.;...|
+000002c0 16 03 03 00 ac 0c 00 00 a8 03 00 1d 20 3d 1d f3 |............ =..|
+000002d0 d4 cb 57 6a d8 c4 23 34 84 30 2a 80 02 0c 86 de |..Wj..#4.0*.....|
+000002e0 94 ae c8 78 07 f5 0c eb 61 f2 2f a6 2d 08 04 00 |...x....a./.-...|
+000002f0 80 08 5e b0 4b ed 7b e1 48 45 80 6a 63 5c 1e 9a |..^.K.{.HE.jc\..|
+00000300 01 4e f1 c3 92 b2 a4 83 18 ee 55 01 36 55 57 59 |.N........U.6UWY|
+00000310 84 46 70 60 43 32 05 25 18 de 05 76 24 57 69 a3 |.Fp`C2.%...v$Wi.|
+00000320 34 a6 bd 4c b5 45 2c 6e 63 81 a3 82 a7 4a a5 5f |4..L.E,nc....J._|
+00000330 27 c2 a2 58 2b 77 9f cf cb 63 e0 2b da 75 eb 9c |'..X+w...c.+.u..|
+00000340 6e 6b cd d5 ae 59 8d c8 0f c6 34 30 68 42 67 d5 |nk...Y....40hBg.|
+00000350 1f e7 b1 22 60 b5 ca 4b a5 bd ce a0 44 50 df 45 |..."`..K....DP.E|
+00000360 8b d8 e4 04 53 8a f8 fa 91 b2 09 fb 42 92 5f dd |....S.......B._.|
+00000370 05 16 03 03 00 04 0e 00 00 00 |..........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 2f e5 7d a3 47 cd |....%...! /.}.G.|
+00000010 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....|
+00000020 cf c2 ed 90 99 5f 58 cb 3b 74 14 03 03 00 01 01 |....._X.;t......|
+00000030 16 03 03 00 28 00 00 00 00 00 00 00 00 bb 7a 8d |....(.........z.|
+00000040 2b 4d 9e e9 b6 b7 bf 30 e3 fd 4b e6 2e 6c ba 61 |+M.....0..K..l.a|
+00000050 2b 15 58 52 d0 70 36 e5 da 64 21 28 06 |+.XR.p6..d!(.|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 28 11 6b 33 c7 32 |..........(.k3.2|
+00000010 9b 34 14 98 1d 90 97 cc 3a fe c1 98 f7 9d e3 dc |.4......:.......|
+00000020 dc f2 e2 34 c9 5d aa 5b 02 e3 9f 33 88 5b 21 65 |...4.].[...3.[!e|
+00000030 b0 f1 36 |..6|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 4b 49 39 |.............KI9|
+00000010 01 d1 34 c1 b9 72 f6 25 39 c9 e6 77 5c f3 7a 4f |..4..r.%9..w\.zO|
+00000020 fa f7 43 15 03 03 00 1a 00 00 00 00 00 00 00 02 |..C.............|
+00000030 99 cf 0c 0e 51 f8 37 22 50 2e 98 30 bc 13 e9 f5 |....Q.7"P..0....|
+00000040 d3 75 |.u|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-AES128-SHA256 b/src/crypto/tls/testdata/Client-TLSv13-AES128-SHA256
new file mode 100644
index 0000000..1097116
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv13-AES128-SHA256
@@ -0,0 +1,91 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 7a 02 00 00 76 03 03 0e f8 bf 2d c5 |....z...v.....-.|
+00000010 14 c9 b0 54 dd 64 27 22 ce 6e e1 cb 24 46 76 5c |...T.d'".n..$Fv\|
+00000020 3c 6b cf 3a 1a bb ca d9 55 18 d2 20 00 00 00 00 |<k.:....U.. ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 13 01 00 00 |................|
+00000050 2e 00 2b 00 02 03 04 00 33 00 24 00 1d 00 20 f0 |..+.....3.$... .|
+00000060 f3 c3 c9 89 b9 92 ce df d1 bd f1 11 25 4d 73 3b |............%Ms;|
+00000070 da 10 b8 4c c8 22 00 6a 24 6b b8 73 4e de 42 14 |...L.".j$k.sN.B.|
+00000080 03 03 00 01 01 17 03 03 00 17 0d c6 b2 56 f3 da |.............V..|
+00000090 2d 18 93 c6 59 8c be b9 7f 1d 48 bd 7a a2 85 d3 |-...Y.....H.z...|
+000000a0 74 17 03 03 02 6d d5 8a aa 3c ca d2 98 eb 0c bb |t....m...<......|
+000000b0 54 00 49 eb 94 48 be 31 a5 c6 13 a6 98 1a df 43 |T.I..H.1.......C|
+000000c0 b8 5d 11 6e c2 80 18 88 a0 84 f2 4b 67 58 64 ae |.].n.......KgXd.|
+000000d0 e9 7d 97 6a ec af 1f 80 c9 1b 5e ce d5 88 7d c3 |.}.j......^...}.|
+000000e0 05 36 7c 8d ac 70 8d 36 84 d6 12 ed a7 86 87 0c |.6|..p.6........|
+000000f0 a0 b3 8c c4 20 0c c3 01 04 ef 27 1b cc bd 27 72 |.... .....'...'r|
+00000100 4f 92 61 6f 1c 21 1e 6a 27 22 3f a9 3c a7 b9 b3 |O.ao.!.j'"?.<...|
+00000110 d4 3c 1f 7b 78 97 f1 52 ca b9 cc a8 2b 2b be a2 |.<.{x..R....++..|
+00000120 fb 9b 47 f1 d4 c0 8e eb 3b c2 5b 4d 74 18 c3 ce |..G.....;.[Mt...|
+00000130 0c a7 8d 3e 1c f8 13 5e 8e 20 68 a8 1c 75 bd f4 |...>...^. h..u..|
+00000140 5a ba 16 71 8c 97 db 6d 90 7c 64 56 0d 29 99 16 |Z..q...m.|dV.)..|
+00000150 9b f2 85 4c 84 11 b0 c4 76 f2 d8 bd 7f 19 cb 80 |...L....v.......|
+00000160 ec ad 18 e0 d5 c7 a7 f7 70 08 36 c6 0c 8a 88 ef |........p.6.....|
+00000170 d9 20 7e e2 b8 a7 c9 18 26 d3 8e c6 d6 48 02 1c |. ~.....&....H..|
+00000180 cb 02 7b 52 93 dc 4b da 82 9d 07 b9 65 0d 2a 7a |..{R..K.....e.*z|
+00000190 3a 8b 3a 3d 58 79 e2 a8 14 83 25 06 64 e0 48 71 |:.:=Xy....%.d.Hq|
+000001a0 ef 2f 28 74 3f 46 04 f5 60 01 fb 53 d5 ff ca 7f |./(t?F..`..S....|
+000001b0 89 4c 80 e6 e7 44 cb ad 93 d0 6a 8a 14 13 cc 09 |.L...D....j.....|
+000001c0 bf 54 12 56 94 17 1e f3 c5 7a 06 d3 28 3d 61 0d |.T.V.....z..(=a.|
+000001d0 1e ad d3 55 28 1e e7 f6 6a e6 da 31 3d 99 61 df |...U(...j..1=.a.|
+000001e0 94 d1 1a 58 f6 06 55 0a 43 20 23 dc 58 2b d4 db |...X..U.C #.X+..|
+000001f0 35 91 16 e1 29 62 e7 fd aa fe 65 d7 ef b2 a6 2b |5...)b....e....+|
+00000200 6b c8 29 4b c0 94 ca bc 32 c4 d8 7a 2a 66 ea 25 |k.)K....2..z*f.%|
+00000210 ee 8f fc 85 28 5f b6 1a 11 0b cb dc 57 0b 70 7e |....(_......W.p~|
+00000220 58 fc f5 09 41 88 0d a0 fc 03 58 a6 e3 48 29 ed |X...A.....X..H).|
+00000230 4e e4 ff cc 4b 42 fd 53 e7 e5 2d 57 0e 6a 88 96 |N...KB.S..-W.j..|
+00000240 12 03 54 c3 de 8f 9a 46 98 2c ef ac cd 72 bc 7f |..T....F.,...r..|
+00000250 f6 1b cb 98 d4 0c 46 32 1e 18 51 39 d1 ee bf 83 |......F2..Q9....|
+00000260 71 e1 df 3a 31 82 22 2f ba 0e 69 a3 93 9d 0c 5c |q..:1."/..i....\|
+00000270 8f e5 ea e8 25 26 b1 40 8e 19 0c f4 55 ff 7b cb |....%&.@....U.{.|
+00000280 96 d2 0f 07 a0 da 99 38 df 63 9b 9e 33 5b 87 f2 |.......8.c..3[..|
+00000290 1b f7 3f 36 e4 65 ae 95 69 0f ec fc 34 fb 1e e5 |..?6.e..i...4...|
+000002a0 f7 ce 78 b0 c5 d6 94 e8 e5 ee 37 56 20 ac 58 c4 |..x.......7V .X.|
+000002b0 3a 5e cd e2 7f ac 23 c6 5e 2e 45 aa 8a d5 ea 0e |:^....#.^.E.....|
+000002c0 0b 1d 13 19 72 0f 8d 48 6b 2f aa 8d d3 74 bb d2 |....r..Hk/...t..|
+000002d0 ff fb 46 f7 7f 7d 03 50 9e 3b a8 2d 73 c4 e5 db |..F..}.P.;.-s...|
+000002e0 82 8a 48 5f b4 4e 49 35 4b 04 ca 70 35 30 c4 c9 |..H_.NI5K..p50..|
+000002f0 d5 94 cb 58 e3 40 e4 8f 3f 17 f5 dd c8 80 d9 41 |...X.@..?......A|
+00000300 e2 2a 7b 63 e7 87 84 9a aa 54 3c 1f 4b 64 7b 32 |.*{c.....T<.Kd{2|
+00000310 17 d4 f3 17 03 03 00 99 47 1a 1f d9 17 60 17 4a |........G....`.J|
+00000320 7a 68 c2 69 4f 59 6e b5 72 2f e9 a8 42 db 9c 49 |zh.iOYn.r/..B..I|
+00000330 62 3c db 0c fd 49 2f 0b 4f fa de db ef 7d 5e 60 |b<...I/.O....}^`|
+00000340 6b 99 39 ab b3 44 ac bc 68 2b 86 fd db 91 63 6c |k.9..D..h+....cl|
+00000350 da 2f 6b 32 c4 99 b4 51 84 5c a8 0d 1d 31 05 f3 |./k2...Q.\...1..|
+00000360 45 e3 b4 83 3d c8 17 2e f9 4e f7 61 6c 4b e5 d4 |E...=....N.alK..|
+00000370 24 04 2e 3f c9 f4 c9 8a 2d 8f 50 d0 c2 f8 35 56 |$..?....-.P...5V|
+00000380 1a 59 08 99 3d 0e 47 ea 54 44 75 d1 2b 31 28 71 |.Y..=.G.TDu.+1(q|
+00000390 fb 88 69 0a d2 50 30 77 41 ab ed 29 51 58 75 87 |..i..P0wA..)QXu.|
+000003a0 5a 59 bc 66 6b f3 d5 5f ad c4 26 9d e6 a8 7e 70 |ZY.fk.._..&...~p|
+000003b0 b3 17 03 03 00 35 fe f7 08 e7 c6 3e 00 c3 5e a3 |.....5.....>..^.|
+000003c0 87 23 df 10 46 4f bb 17 ee bf 93 df b7 6d f0 45 |.#..FO.......m.E|
+000003d0 77 bf 60 6d f9 bb ce 58 f2 59 4a 40 5e d6 dd 0b |w.`m...X.YJ@^...|
+000003e0 19 9a 41 8e 6b 03 16 e3 ce cd b6 |..A.k......|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 3c 85 dc 33 0a |..........5<..3.|
+00000010 bd 78 f0 fc 0a 07 3a 9e a5 31 ca b8 f6 23 d5 26 |.x....:..1...#.&|
+00000020 2a 60 ce d9 d2 da 37 e5 e8 27 bb 99 a3 43 ad 66 |*`....7..'...C.f|
+00000030 e2 07 33 de ca dc 2f d4 73 f4 71 50 d0 99 3b 7d |..3.../.s.qP..;}|
+00000040 17 03 03 00 17 de 7a 55 7a 1d e3 1e 51 10 df 9e |......zUz...Q...|
+00000050 30 a6 b9 15 79 b4 20 82 01 e5 b2 34 17 03 03 00 |0...y. ....4....|
+00000060 13 85 50 af bc 99 0b eb 84 58 b9 6c 46 88 22 b0 |..P......X.lF.".|
+00000070 7e 42 79 01 |~By.|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-AES256-SHA384 b/src/crypto/tls/testdata/Client-TLSv13-AES256-SHA384
new file mode 100644
index 0000000..39b2e09
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv13-AES256-SHA384
@@ -0,0 +1,93 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 7a 02 00 00 76 03 03 fc b2 8e 30 c0 |....z...v.....0.|
+00000010 a2 bd d8 1c 4b 68 bc e0 a1 56 5f 5b 05 54 b7 7a |....Kh...V_[.T.z|
+00000020 60 9a 49 68 f5 f4 f0 b1 49 27 79 20 00 00 00 00 |`.Ih....I'y ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 13 02 00 00 |................|
+00000050 2e 00 2b 00 02 03 04 00 33 00 24 00 1d 00 20 d3 |..+.....3.$... .|
+00000060 d7 9e 72 ae 5f f9 92 24 6b 76 e5 a1 00 71 78 cf |..r._..$kv...qx.|
+00000070 e9 55 29 5b fe a8 71 14 e9 02 b0 65 12 e8 04 14 |.U)[..q....e....|
+00000080 03 03 00 01 01 17 03 03 00 17 24 a0 73 a6 7b ab |..........$.s.{.|
+00000090 9c d8 69 e7 15 68 4b 26 0a 15 0c ff c4 40 7d b8 |..i..hK&.....@}.|
+000000a0 ad 17 03 03 02 6d 05 b2 f9 6e 05 48 18 92 2b 87 |.....m...n.H..+.|
+000000b0 29 1c 5b 8c a8 ae 0e 4b fc 3b 1e b9 2c c2 0c 33 |).[....K.;..,..3|
+000000c0 f8 5d 16 37 39 b3 b2 4e 12 a4 02 4c fb 3b 16 4e |.].79..N...L.;.N|
+000000d0 63 92 72 56 49 d6 5b 63 34 20 67 c8 07 a2 b6 0d |c.rVI.[c4 g.....|
+000000e0 f1 06 b4 bd 88 54 4d 33 66 1a d4 fc 42 9c 4e 00 |.....TM3f...B.N.|
+000000f0 40 34 5d cf c4 5d f1 ba 14 de 34 50 f5 2f 3d b7 |@4]..]....4P./=.|
+00000100 1c 17 33 6e 9a 2b 39 1b f1 a6 0d fb b7 0c c3 b3 |..3n.+9.........|
+00000110 02 f8 0c 30 e8 31 d7 ee bf a1 a0 64 28 67 64 50 |...0.1.....d(gdP|
+00000120 24 ce 37 fd 15 2e c7 13 1b 8b f0 22 19 e4 ec c8 |$.7........"....|
+00000130 8c b0 76 b8 d0 2d 87 99 86 8b ec ca e9 9d 8f 23 |..v..-.........#|
+00000140 bf 3d bf b8 ed 85 34 85 31 15 dd 7a 36 f7 3e 0e |.=....4.1..z6.>.|
+00000150 df e7 4c e8 ae 5a 98 05 f8 34 76 33 c3 4c 81 fb |..L..Z...4v3.L..|
+00000160 d8 29 14 b3 47 32 eb 5f 73 5a 95 4a c7 3d 89 2a |.)..G2._sZ.J.=.*|
+00000170 21 22 bd 97 b2 9d 4b dd 2c eb a5 e3 37 d6 a9 84 |!"....K.,...7...|
+00000180 0c b6 02 2f 1f 5c 18 1b be 92 be 58 a7 e1 a0 49 |.../.\.....X...I|
+00000190 95 dc d7 07 70 b1 5b 15 86 3f 55 fc ad 32 39 5d |....p.[..?U..29]|
+000001a0 95 63 fd d4 85 55 b2 e9 c2 68 d0 09 f9 53 f9 4f |.c...U...h...S.O|
+000001b0 0e 89 1c a0 85 74 7f 10 97 e7 86 8a 18 28 83 e6 |.....t.......(..|
+000001c0 66 3c 2a f5 8f 14 1d 90 58 ef ad 1f d3 7f 42 0a |f<*.....X.....B.|
+000001d0 08 d5 b4 96 b0 9d 3f 72 49 5a 06 13 7c 4b bc 79 |......?rIZ..|K.y|
+000001e0 8c db 1f 1f 5e 3d c2 fe ad 57 e6 d9 14 bb d0 72 |....^=...W.....r|
+000001f0 d7 90 14 35 ec 34 31 f6 fd b1 fd 3d 46 6e 4f a7 |...5.41....=FnO.|
+00000200 1e 7d 14 40 17 0c ef c0 c8 70 fe dc 6a f1 78 6a |.}.@.....p..j.xj|
+00000210 c6 df 70 2e ac 07 d9 6d f7 90 0e 4a 92 08 cf 88 |..p....m...J....|
+00000220 26 c0 11 4a 7d e4 34 ba 86 43 cb 94 f8 d7 61 5a |&..J}.4..C....aZ|
+00000230 05 f5 f9 49 b4 04 f1 c8 43 b6 12 52 ae cf 7c b9 |...I....C..R..|.|
+00000240 39 d1 90 91 6e 80 43 cf 4c 23 3d 7c c0 c8 88 46 |9...n.C.L#=|...F|
+00000250 e2 91 86 e4 41 cb ed f2 3a 92 01 9f 04 7c d2 81 |....A...:....|..|
+00000260 42 18 6c 04 91 25 8a 29 0e d9 23 aa 58 e5 e8 ee |B.l..%.)..#.X...|
+00000270 39 79 a5 a7 3a 4d e3 cc 15 79 3f 7b f9 e4 21 76 |9y..:M...y?{..!v|
+00000280 5c 9a d8 de d3 9a f3 9e 69 44 c0 2a 56 04 b4 d2 |\.......iD.*V...|
+00000290 c3 c1 4c d6 ad b8 d8 ad c8 c2 0d fa ea e1 bc 11 |..L.............|
+000002a0 67 15 80 ef c6 01 48 7f de f1 c2 36 a7 dd a9 38 |g.....H....6...8|
+000002b0 31 8b 14 ed 5c 2a 66 55 3b 25 e3 85 cb d9 a9 82 |1...\*fU;%......|
+000002c0 7a 95 99 b3 c8 aa ac 66 30 b0 c5 3d d1 2a ab b9 |z......f0..=.*..|
+000002d0 56 b3 5e 9d e0 d7 81 ac 6f 2e ae 62 a2 ef ca ef |V.^.....o..b....|
+000002e0 7b cf 0f af f6 0b 29 97 2d 27 33 58 ad b6 1b d2 |{.....).-'3X....|
+000002f0 0a c7 11 ec 89 b0 0d 2e ff 27 64 c2 bf 8e 85 a4 |.........'d.....|
+00000300 ea 14 52 71 55 1a ec ef 0d ff 14 00 ce 3d 9d 3d |..RqU........=.=|
+00000310 a9 d3 17 17 03 03 00 99 5e ba 1f f3 93 71 7a 88 |........^....qz.|
+00000320 bc 14 71 7e 85 15 c9 da fe ee c1 b1 3d f6 ff 67 |..q~........=..g|
+00000330 fd 28 96 f3 44 44 6f 8f 32 b4 22 be 69 29 e6 dd |.(..DDo.2.".i)..|
+00000340 60 07 1d 98 0b 0c 0f ec df fa 46 c0 67 66 f2 18 |`.........F.gf..|
+00000350 bf 5e 36 56 b2 b2 25 ef aa 76 51 ea f7 47 1d ee |.^6V..%..vQ..G..|
+00000360 7b 25 e5 97 89 4a 04 07 f8 ff 05 73 25 71 e4 28 |{%...J.....s%q.(|
+00000370 9e 91 45 ff 4c df 82 dc 85 16 02 ba 15 9b 37 91 |..E.L.........7.|
+00000380 eb 65 12 66 38 59 8a 85 a2 2e af 2f d7 74 75 c1 |.e.f8Y...../.tu.|
+00000390 7e f6 64 87 7e 4c 86 c8 25 bb 59 8d f8 9c e3 e5 |~.d.~L..%.Y.....|
+000003a0 a4 53 a5 c6 00 bd 78 d8 07 0e f5 42 92 e3 42 11 |.S....x....B..B.|
+000003b0 57 17 03 03 00 45 77 98 db b2 e4 66 e3 dc 3e 4f |W....Ew....f..>O|
+000003c0 49 92 b3 ac 74 cd 1c 3b e2 81 3c 64 0b a5 c9 8c |I...t..;..<d....|
+000003d0 7e 9a 22 9f df 7e e8 68 99 56 93 49 d5 81 3f c1 |~."..~.h.V.I..?.|
+000003e0 de 00 07 bd 6e ba 25 00 63 f0 82 41 46 ba 04 b7 |....n.%.c..AF...|
+000003f0 1f 37 aa 1c f6 49 8f e6 83 e8 23 |.7...I....#|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 45 75 66 f7 1c cc |..........Euf...|
+00000010 a5 d2 e0 60 37 ff ab 89 16 88 c1 27 ba 57 0c 0d |...`7......'.W..|
+00000020 28 c9 c3 8a 53 57 05 1c 2a 47 52 b6 98 f9 26 4f |(...SW..*GR...&O|
+00000030 34 7c 7a 71 00 87 47 c3 a5 b8 0c 8c 03 87 5e de |4|zq..G.......^.|
+00000040 a1 40 33 9b e1 7f ad 36 71 10 9a e7 28 45 e1 e2 |.@3....6q...(E..|
+00000050 17 03 03 00 17 a3 83 88 cd fa fc f4 60 12 e7 be |............`...|
+00000060 8d 11 31 74 3f 25 3e 32 6f 7f 73 57 17 03 03 00 |..1t?%>2o.sW....|
+00000070 13 7f ab 29 bc f6 7e ea f7 17 ee 7a ef 38 ff bc |...)..~....z.8..|
+00000080 82 68 f5 07 |.h..|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-ALPN b/src/crypto/tls/testdata/Client-TLSv13-ALPN
new file mode 100644
index 0000000..b291259
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv13-ALPN
@@ -0,0 +1,93 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 01 12 01 00 01 0e 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 93 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 10 00 10 00 0e 06 70 |...............p|
+000000d0 72 6f 74 6f 32 06 70 72 6f 74 6f 31 00 12 00 00 |roto2.proto1....|
+000000e0 00 2b 00 09 08 03 04 03 03 03 02 03 01 00 33 00 |.+............3.|
+000000f0 26 00 24 00 1d 00 20 2f e5 7d a3 47 cd 62 43 15 |&.$... /.}.G.bC.|
+00000100 28 da ac 5f bb 29 07 30 ff f6 84 af c4 cf c2 ed |(.._.).0........|
+00000110 90 99 5f 58 cb 3b 74 |.._X.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 7a 02 00 00 76 03 03 90 3b d5 53 eb |....z...v...;.S.|
+00000010 af 38 68 af fc 8f 47 f5 3f 13 5c c5 46 9d 97 b7 |.8h...G.?.\.F...|
+00000020 e2 c4 0c 93 d4 91 2b 45 77 11 1b 20 00 00 00 00 |......+Ew.. ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 13 03 00 00 |................|
+00000050 2e 00 2b 00 02 03 04 00 33 00 24 00 1d 00 20 a6 |..+.....3.$... .|
+00000060 5a 75 77 6c 3a 65 d9 7d c4 72 ef 66 3e 15 80 e4 |Zuwl:e.}.r.f>...|
+00000070 b6 c5 55 2e fb cf 3a 17 9e 28 de de b1 ce 06 14 |..U...:..(......|
+00000080 03 03 00 01 01 17 03 03 00 24 45 28 86 50 9e 48 |.........$E(.P.H|
+00000090 66 13 75 a6 43 19 b2 ce 79 2b 5c 06 d0 f7 ff 4c |f.u.C...y+\....L|
+000000a0 d5 bb 39 67 50 aa 78 97 1b 5a 58 a7 95 44 17 03 |..9gP.x..ZX..D..|
+000000b0 03 02 6d 10 9e 3c f4 7e c6 2d e4 2a 04 10 95 dd |..m..<.~.-.*....|
+000000c0 47 56 02 08 91 5e 60 c5 5c eb a1 65 f0 9d a6 2a |GV...^`.\..e...*|
+000000d0 55 bc fe 58 1a b0 3e f9 d6 f0 1c 7c 70 c5 bf 14 |U..X..>....|p...|
+000000e0 3c c7 bf a4 ac f8 c5 77 1c 7b f2 bb 15 01 f8 c6 |<......w.{......|
+000000f0 2c 19 dd 22 29 3b 32 09 33 b7 c5 be 2e 9b 43 7c |,..");2.3.....C||
+00000100 1f b7 a2 99 09 e6 42 c3 13 b0 10 2b 15 e8 8a 89 |......B....+....|
+00000110 62 ac 27 b1 09 cc e3 78 67 07 8e c9 21 d4 17 df |b.'....xg...!...|
+00000120 dc db 30 9b 8e a4 6f 8e fb 1b 5a d9 22 b0 5d 9b |..0...o...Z.".].|
+00000130 f1 d0 c7 d6 5e 64 00 23 36 96 8e 22 39 ab 52 3a |....^d.#6.."9.R:|
+00000140 10 02 c3 6b 02 c7 87 8f cd 45 40 18 26 41 ca 06 |...k.....E@.&A..|
+00000150 36 09 59 fc 0c d8 fc fe 35 b6 fb 9e 2a e3 db 29 |6.Y.....5...*..)|
+00000160 dc 1b 89 08 f2 e5 06 a1 2a 62 cb 89 39 be 30 47 |........*b..9.0G|
+00000170 81 5d 12 5d e5 f2 38 ae f9 6a 0a bc b6 7d 1a fc |.].]..8..j...}..|
+00000180 62 24 1f ab 25 1a 81 4e 29 c1 32 89 9e 75 3d e9 |b$..%..N).2..u=.|
+00000190 aa a7 ab 15 0f eb f6 e6 a4 1c c2 c6 48 8b 88 a9 |............H...|
+000001a0 24 34 92 49 f9 85 4e 2c b5 eb 69 d7 55 db e5 b6 |$4.I..N,..i.U...|
+000001b0 ec 09 5d 08 b0 d3 8f 0c 01 47 46 3f f8 ae eb ef |..]......GF?....|
+000001c0 72 37 2e 48 03 5a 03 ed 1c 5e 6e be 59 f1 16 98 |r7.H.Z...^n.Y...|
+000001d0 f9 0e 3e 04 6d 9f 53 72 29 62 5b b3 f1 b9 1a 72 |..>.m.Sr)b[....r|
+000001e0 61 06 ad 97 e1 e1 31 d4 ae a0 92 02 27 94 66 ca |a.....1.....'.f.|
+000001f0 21 37 dd 2e a4 b4 4b 8f 7d 47 1c 3c 3d 14 ca 92 |!7....K.}G.<=...|
+00000200 e3 fc 9f 73 4f 17 3e 2a 62 9b 45 bd 5d 6b d2 90 |...sO.>*b.E.]k..|
+00000210 b4 77 5b 61 81 52 10 b6 d4 0e 48 f4 d1 b4 a5 eb |.w[a.R....H.....|
+00000220 4c c2 29 dd e0 74 b0 2b d0 28 09 65 bc f2 f4 12 |L.)..t.+.(.e....|
+00000230 6d 25 c7 7d 84 39 4a 2a 36 4e 4c 94 bb 02 66 2e |m%.}.9J*6NL...f.|
+00000240 58 17 0c 3d 1f aa 6b 25 92 d5 a3 39 9c 50 28 43 |X..=..k%...9.P(C|
+00000250 5c 39 17 34 4a 59 f9 6c 65 a3 4d 35 74 65 11 04 |\9.4JY.le.M5te..|
+00000260 25 99 d1 42 93 70 95 28 6f 59 a0 13 95 2c bb 79 |%..B.p.(oY...,.y|
+00000270 05 dd 8c 82 e1 08 57 6d c4 8e fc c4 f5 49 17 1f |......Wm.....I..|
+00000280 94 4c cc ea 6f cd ab a9 33 ed 4b fa 47 02 1a f2 |.L..o...3.K.G...|
+00000290 5b 64 8d 3f e4 65 ea 78 82 78 f0 0d eb 74 c1 cc |[d.?.e.x.x...t..|
+000002a0 25 f7 d4 7c 74 fc 8d 53 76 f6 fb 31 62 8d d6 83 |%..|t..Sv..1b...|
+000002b0 57 56 43 dc 40 51 94 b0 44 db d2 7f f3 fe 58 ff |WVC.@Q..D.....X.|
+000002c0 c5 13 22 aa bf 77 ea 16 93 85 b0 89 cf b2 1d 0b |.."..w..........|
+000002d0 8c 89 9f 4c 68 43 98 53 c0 97 ba aa 82 d0 e5 e4 |...LhC.S........|
+000002e0 ce 8d 16 91 46 c0 ff 38 1f 2d 3d cd 9e 65 c9 7d |....F..8.-=..e.}|
+000002f0 a2 b6 21 b3 55 9d 2c ff b5 c7 aa cb 5a 51 ce e6 |..!.U.,.....ZQ..|
+00000300 5c 6f 72 58 fc 8d 49 68 13 b3 a9 14 03 8a 89 ff |\orX..Ih........|
+00000310 1e 05 91 a3 30 64 3a 10 06 c8 1f b0 b8 b6 4d 95 |....0d:.......M.|
+00000320 17 03 03 00 99 2f cd 21 80 f7 39 77 c5 ed 5f b8 |...../.!..9w.._.|
+00000330 75 fb bd 82 f1 84 09 d3 bc 2f 21 f6 d3 a2 4b b1 |u......../!...K.|
+00000340 e4 67 59 7d db 64 47 20 19 9b 9d 68 33 4a 9d e1 |.gY}.dG ...h3J..|
+00000350 c5 ec cc ab 66 25 a2 1b 89 6c a6 03 b6 20 3d c6 |....f%...l... =.|
+00000360 03 fd 12 80 70 b9 e5 2e 27 c8 25 d2 00 00 4e e9 |....p...'.%...N.|
+00000370 1a 65 4a 52 31 a0 3f e6 7c fc 77 48 83 76 11 34 |.eJR1.?.|.wH.v.4|
+00000380 c1 71 36 0d 56 13 7f a2 3c 4a ac 5c 73 82 b1 f5 |.q6.V...<J.\s...|
+00000390 a9 ab 84 ec ac 79 de ea ae 46 a0 41 53 33 e9 be |.....y...F.AS3..|
+000003a0 09 7f d5 f6 a4 93 6c 93 0f 98 c6 49 26 68 f9 6a |......l....I&h.j|
+000003b0 66 d7 04 15 ae e0 5e f6 2e 78 cf e3 a5 d2 17 03 |f.....^..x......|
+000003c0 03 00 35 35 ac 0b 2c c1 a1 90 3a 67 58 a8 3c 6c |..55..,...:gX.<l|
+000003d0 9c af e9 f5 e7 c2 e3 cd fd 56 a9 de 8f 33 c5 97 |.........V...3..|
+000003e0 a5 06 70 53 3b fb 3d 17 5a 05 f4 2b 72 b1 6b c5 |..pS;.=.Z..+r.k.|
+000003f0 92 25 8a c2 2d 18 20 5c |.%..-. \|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 fc ac 12 d4 36 |..........5....6|
+00000010 13 c6 fe 02 f8 ea 05 0b 5c cb 31 d4 8d ee ba 6f |........\.1....o|
+00000020 36 ac aa 89 b9 10 f3 b3 a1 89 03 0e d2 5a 92 c7 |6............Z..|
+00000030 62 4c 56 0c 42 69 68 a5 d7 79 cc b5 24 25 7b 80 |bLV.Bih..y..$%{.|
+00000040 17 03 03 00 17 a3 f6 4f 1d 36 bb 5f 0b 59 12 ef |.......O.6._.Y..|
+00000050 72 d4 c6 1d c8 82 94 1d f2 9c 46 d5 17 03 03 00 |r.........F.....|
+00000060 13 3c 66 6b 59 a1 b2 e9 47 e8 06 fe 15 3f 0c 39 |.<fkY...G....?.9|
+00000070 ab f9 20 57 |.. W|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-CHACHA20-SHA256 b/src/crypto/tls/testdata/Client-TLSv13-CHACHA20-SHA256
new file mode 100644
index 0000000..e029f00
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv13-CHACHA20-SHA256
@@ -0,0 +1,91 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 7a 02 00 00 76 03 03 ce bd 20 50 3d |....z...v.... P=|
+00000010 7e 80 5d e3 c4 d1 f4 d7 9b 28 0d ad c7 2c c9 b0 |~.]......(...,..|
+00000020 bb 25 e4 98 56 77 9a dd 7c 2e e7 20 00 00 00 00 |.%..Vw..|.. ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 13 03 00 00 |................|
+00000050 2e 00 2b 00 02 03 04 00 33 00 24 00 1d 00 20 75 |..+.....3.$... u|
+00000060 35 5d ce ae 93 0b e6 2c c7 aa 67 6d 9d bd b2 8d |5].....,..gm....|
+00000070 83 ac 17 7c 21 21 b2 c1 dc a1 4d 54 72 66 05 14 |...|!!....MTrf..|
+00000080 03 03 00 01 01 17 03 03 00 17 88 68 f2 3c 98 b5 |...........h.<..|
+00000090 ef 6e 2b ba aa d3 d4 0c 28 aa 3a 6f 51 a7 dc 89 |.n+.....(.:oQ...|
+000000a0 fb 17 03 03 02 6d ae f6 44 17 0d 3b ee 41 5b a9 |.....m..D..;.A[.|
+000000b0 d2 63 7c 98 25 e7 ca 46 29 05 9e 75 9f 71 58 99 |.c|.%..F)..u.qX.|
+000000c0 57 a3 c3 88 08 54 88 ea 8f ea ca 87 88 c0 53 d7 |W....T........S.|
+000000d0 de b6 3d 14 98 64 1a 6b 8f 90 e7 6a 10 e2 4b 42 |..=..d.k...j..KB|
+000000e0 13 59 f0 bc a0 74 3b 5b a8 15 74 3a 30 9f 28 ed |.Y...t;[..t:0.(.|
+000000f0 b2 a0 48 15 5a 3b 0c 61 26 4e 3f 5a 33 3d d9 88 |..H.Z;.a&N?Z3=..|
+00000100 97 9f fe 2a d5 df f7 01 40 84 75 90 89 7d 34 23 |...*....@.u..}4#|
+00000110 3e 70 85 82 94 b7 21 94 e6 0c d1 f1 88 06 ff 34 |>p....!........4|
+00000120 64 2f e5 e6 80 10 2b 0c fe 18 f5 2c cc b0 27 37 |d/....+....,..'7|
+00000130 2b 5a 4b 43 e8 b7 ad 97 a0 8c d1 49 bb f9 4a 65 |+ZKC.......I..Je|
+00000140 99 bf cd 7f 77 ef 0f b6 d7 91 ce 4d 53 79 d0 5e |....w......MSy.^|
+00000150 b7 51 5e 8d 0f 13 85 53 7d 81 27 b2 e1 5a e0 d0 |.Q^....S}.'..Z..|
+00000160 d9 b0 3b c6 30 15 ac 3e 60 7f 01 90 da b1 c5 8c |..;.0..>`.......|
+00000170 06 7c 8f 31 86 7e 53 5b 1a 4b 8f d0 ff 2c f9 9e |.|.1.~S[.K...,..|
+00000180 c4 08 02 12 e4 97 af 3f 07 d0 25 0d 50 90 21 1f |.......?..%.P.!.|
+00000190 fa 8d ea 02 16 a4 56 2e 2b e1 3f c2 e2 f5 53 d0 |......V.+.?...S.|
+000001a0 6e a2 d4 b9 b6 ae 69 12 74 d4 2f 8f 55 1e 5f b8 |n.....i.t./.U._.|
+000001b0 1f b6 29 ee 11 21 81 9f 37 6e 40 b1 27 22 15 7b |..)..!..7n@.'".{|
+000001c0 ba bb bd ee 7a 7e 1f e4 7e 63 a1 60 53 a1 c7 0f |....z~..~c.`S...|
+000001d0 f8 2e c3 07 cd 60 ec 83 0f 18 55 50 5c 11 ec 93 |.....`....UP\...|
+000001e0 85 dd 38 5c 7e 4a 0a af 4b c9 22 8d 43 ce 76 62 |..8\~J..K.".C.vb|
+000001f0 d7 73 3f ef 67 2d 6a 02 bd b5 8f c4 8b 64 b1 a3 |.s?.g-j......d..|
+00000200 c4 40 c1 ea 7e 57 b9 25 45 61 96 97 69 69 9f 2b |.@..~W.%Ea..ii.+|
+00000210 a7 56 b5 8b 80 25 3e 3c 73 14 b2 21 10 ee 47 cd |.V...%><s..!..G.|
+00000220 5f 6f 6f fa 71 bf 88 47 39 21 05 b9 e3 0b f2 ad |_oo.q..G9!......|
+00000230 68 52 8a fe 9d 90 60 49 bb ea 73 02 a6 2d 55 93 |hR....`I..s..-U.|
+00000240 d5 cd e1 f6 2b 40 8c 9a 22 e8 65 3f fb 5e 8e 88 |....+@..".e?.^..|
+00000250 d2 38 10 00 c6 25 26 77 78 a9 f9 fe 27 29 c7 5a |.8...%&wx...').Z|
+00000260 e1 24 97 a7 6b ea 3f 57 4f 1c b9 cf 0a 75 3b c7 |.$..k.?WO....u;.|
+00000270 81 df 4b 9c 37 80 15 01 22 a0 ac f7 a8 cc 72 f7 |..K.7...".....r.|
+00000280 63 df 49 31 8d 70 1c a6 c5 3c c5 4e 22 cf b7 b3 |c.I1.p...<.N"...|
+00000290 a5 27 ce 9f d5 34 1b d7 de 67 a9 af b2 d9 04 0c |.'...4...g......|
+000002a0 f6 bd 33 b8 91 c8 66 02 90 a8 82 76 9e 4b 86 7f |..3...f....v.K..|
+000002b0 d9 8a d1 ea fc 2a 9a 8e 2b 61 10 c9 5e 62 86 78 |.....*..+a..^b.x|
+000002c0 df 7d 09 14 0b ec ac 76 dc 62 7f 00 a3 16 9b 30 |.}.....v.b.....0|
+000002d0 f7 17 92 79 c1 03 af cd ef 4d 09 c3 a1 13 cd 83 |...y.....M......|
+000002e0 05 47 9b 61 80 54 56 de b9 9c 78 43 e9 70 af db |.G.a.TV...xC.p..|
+000002f0 bb f6 4f 17 6b c4 61 57 5f 57 91 3e e7 f4 dc 0c |..O.k.aW_W.>....|
+00000300 e2 01 51 80 b3 de cb ac 67 41 cb e9 92 4b ba 18 |..Q.....gA...K..|
+00000310 c5 58 f4 17 03 03 00 99 9c bf 47 cb 60 c1 51 50 |.X........G.`.QP|
+00000320 73 87 10 02 5b e7 b4 f5 4f 60 65 de 44 ae 5c 15 |s...[...O`e.D.\.|
+00000330 0e df 8b fa 47 0f 51 0a a1 05 70 a6 8f a0 2a 27 |....G.Q...p...*'|
+00000340 84 e9 a1 38 43 3d 2a e5 10 45 22 01 0a b2 8e 6d |...8C=*..E"....m|
+00000350 27 53 b9 ea b5 5d 6d a7 50 69 c2 4c 50 cf 3d d9 |'S...]m.Pi.LP.=.|
+00000360 47 82 62 4b 0b 42 6a 3f e5 4f a8 04 9b 7d f2 26 |G.bK.Bj?.O...}.&|
+00000370 15 ce 88 74 40 59 87 2b 11 a5 ac 9a e5 3f 03 db |...t@Y.+.....?..|
+00000380 33 cb 27 be d9 2a 69 1d 1e 68 6b 0e 54 0a f4 1c |3.'..*i..hk.T...|
+00000390 63 b3 bb 55 63 e7 b6 b7 0e 2c ad 9e b5 1d 51 b4 |c..Uc....,....Q.|
+000003a0 41 77 4b 80 17 47 c9 8f 9e 02 cd 87 2e 20 72 e4 |AwK..G....... r.|
+000003b0 44 17 03 03 00 35 0e 4f 8b e7 ae ca 38 35 85 d8 |D....5.O....85..|
+000003c0 fb 23 c3 39 d4 80 25 15 d3 39 4e 19 34 93 21 13 |.#.9..%..9N.4.!.|
+000003d0 a2 84 2c 0f 3e 5e c3 62 95 41 c7 4d a7 81 2d 60 |..,.>^.b.A.M..-`|
+000003e0 99 56 db d5 0e 2e 42 b3 16 72 22 |.V....B..r"|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 db e3 68 0f 7c |..........5..h.||
+00000010 36 8e c4 5b 10 11 89 61 b7 f1 a9 f3 43 a5 28 e6 |6..[...a....C.(.|
+00000020 86 8c f0 c3 3b 54 5b 86 3c b6 42 6e 3d 56 93 0a |....;T[.<.Bn=V..|
+00000030 2c ca 2e 39 27 1c 12 e2 d7 e7 b5 57 a6 29 5c 4a |,..9'......W.)\J|
+00000040 17 03 03 00 17 02 0d 23 ca 06 5e 1c 0f a8 a2 39 |.......#..^....9|
+00000050 32 00 01 b5 ba e7 52 82 fa 2c e3 27 17 03 03 00 |2.....R..,.'....|
+00000060 13 ea 39 b7 18 2d 01 1a c3 9c b5 51 cc d2 f3 40 |..9..-.....Q...@|
+00000070 55 69 87 65 |Ui.e|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-ClientCert-ECDSA-RSA b/src/crypto/tls/testdata/Client-TLSv13-ClientCert-ECDSA-RSA
new file mode 100644
index 0000000..8e87aa5
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv13-ClientCert-ECDSA-RSA
@@ -0,0 +1,140 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 7a 02 00 00 76 03 03 98 a2 b1 a3 c2 |....z...v.......|
+00000010 3a ad 0c cb df b0 4b 9d 37 a9 57 5f f0 c5 3f dd |:.....K.7.W_..?.|
+00000020 73 c1 e6 7f 1e 45 7d ef 17 e8 61 20 00 00 00 00 |s....E}...a ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 13 03 00 00 |................|
+00000050 2e 00 2b 00 02 03 04 00 33 00 24 00 1d 00 20 9b |..+.....3.$... .|
+00000060 8a e8 f7 9b f3 9a 73 54 81 4c aa 41 06 e8 fd 21 |......sT.L.A...!|
+00000070 f7 e6 62 2e 7a 1f 29 0e 1c 48 21 dc 82 3b 1b 14 |..b.z.)..H!..;..|
+00000080 03 03 00 01 01 17 03 03 00 17 07 dc 9b 84 a2 d4 |................|
+00000090 b9 80 93 7f 29 3e 7c 97 9e 46 e0 6d 0c 3d 24 4b |....)>|..F.m.=$K|
+000000a0 1c 17 03 03 00 42 2c 3c 9c 8d 63 93 a7 02 57 8b |.....B,<..c...W.|
+000000b0 3d e6 d1 f0 05 03 ff 91 77 55 01 6c 65 57 8f 67 |=.......wU.leW.g|
+000000c0 44 f8 c1 8f c5 ee 00 9f 45 66 b0 c5 f0 61 20 b7 |D.......Ef...a .|
+000000d0 4f f0 14 05 1d 47 10 af f9 11 ed 62 5e 78 12 60 |O....G.....b^x.`|
+000000e0 65 b7 65 33 a9 b3 38 61 17 03 03 02 6d 9e c3 b9 |e.e3..8a....m...|
+000000f0 0e 43 aa bd 17 a2 51 a8 9b a0 62 73 73 58 84 21 |.C....Q...bssX.!|
+00000100 d2 fa 4f ad fe c3 56 b6 7f 93 e9 4d 4b 83 59 0c |..O...V....MK.Y.|
+00000110 be 47 fd c5 f7 01 b2 03 18 77 9c ae 41 dd 26 44 |.G.......w..A.&D|
+00000120 a2 8a 45 56 6d 61 bc 16 ff 52 d0 1a 48 37 c5 e8 |..EVma...R..H7..|
+00000130 07 71 d1 3d c9 e2 75 3b 6f 16 43 9d a2 56 9c d6 |.q.=..u;o.C..V..|
+00000140 90 d1 d4 fd 23 5e 32 84 bc 97 9e 33 4e cd 54 b6 |....#^2....3N.T.|
+00000150 66 5c 52 be b0 b7 10 70 5c 3a 61 ec 4a e2 d4 43 |f\R....p\:a.J..C|
+00000160 b0 87 8a 48 bd f5 81 cb ee 5a 72 de 26 13 49 31 |...H.....Zr.&.I1|
+00000170 e7 02 53 54 b3 fc 86 b4 70 25 a6 f8 83 24 31 f3 |..ST....p%...$1.|
+00000180 22 dd b1 ca 96 7e f3 9e dc 3b ce 7c 1f 7e 44 37 |"....~...;.|.~D7|
+00000190 ba be 42 e3 14 29 14 8f ad 79 e6 d7 64 a9 11 ac |..B..)...y..d...|
+000001a0 78 f5 fc 3c af e7 0a 55 26 07 a1 7e 81 1f 16 b5 |x..<...U&..~....|
+000001b0 ad 4b cf 46 cf 7a ba d3 3b 2d 97 55 31 bb 20 68 |.K.F.z..;-.U1. h|
+000001c0 c6 f6 19 99 af 98 25 cd 6e 76 39 03 32 14 08 fd |......%.nv9.2...|
+000001d0 77 43 7d d0 f4 d4 8b 58 42 d6 6c 45 a5 b6 af 04 |wC}....XB.lE....|
+000001e0 14 28 47 9f 45 bb af e8 8d e0 d6 54 55 e5 d2 ae |.(G.E......TU...|
+000001f0 84 a1 0c 0b 42 5f 9a 9c 93 fb b9 cd e6 43 5f a3 |....B_.......C_.|
+00000200 cc 6a 6a da 85 7d c1 37 af 04 1a 8b e7 4a 40 82 |.jj..}.7.....J@.|
+00000210 82 88 0f dc 78 51 74 f7 2c c8 e0 01 eb f7 f9 ca |....xQt.,.......|
+00000220 28 0a 79 c9 f9 fb 35 c1 e7 8e 65 9e 8b 40 75 29 |(.y...5...e..@u)|
+00000230 f1 56 79 33 41 39 96 c4 ab 15 28 7c cc 5a cd 81 |.Vy3A9....(|.Z..|
+00000240 c4 57 d2 d9 86 f7 7f 63 30 2d 89 71 29 3c 99 cc |.W.....c0-.q)<..|
+00000250 d8 fb 01 03 f3 de 3d 57 5d f3 85 b5 7a a8 f1 5c |......=W]...z..\|
+00000260 05 39 d7 ac 15 03 be 88 fb e8 4c d2 8f 0f 3f 68 |.9........L...?h|
+00000270 c2 e0 e8 44 c0 97 83 f4 3f f2 4a ba 9e 4c b7 c1 |...D....?.J..L..|
+00000280 ea 55 e4 f4 ce 55 69 83 5b 6e 02 07 06 c4 f3 70 |.U...Ui.[n.....p|
+00000290 13 3e ed 76 f0 ec 7b 5d 1e 9b 5e 73 5f ef 5b 33 |.>.v..{]..^s_.[3|
+000002a0 41 e9 38 45 80 c8 f2 3e 17 ec 30 8b ce 35 87 00 |A.8E...>..0..5..|
+000002b0 a8 02 66 b4 fc d4 69 ae 12 df c6 a4 68 06 2d 8b |..f...i.....h.-.|
+000002c0 9c b6 e3 0e 2c 2a d9 05 cc ac f1 32 e9 57 6d e4 |....,*.....2.Wm.|
+000002d0 0e f5 ed d0 05 a4 4a 10 02 87 5b 90 f9 89 88 30 |......J...[....0|
+000002e0 3a 65 9d 2d 41 07 7a d7 8b 16 cb 57 01 9d ad bb |:e.-A.z....W....|
+000002f0 76 4a 6a 3f 77 ae 29 55 61 b5 04 6b 9f eb 6e 34 |vJj?w.)Ua..k..n4|
+00000300 a7 c6 97 92 6f d3 29 0e 65 1e 83 74 e9 2c 5a 8a |....o.).e..t.,Z.|
+00000310 a8 a7 7a b1 55 76 b9 6a 98 b9 09 d5 01 48 ae 06 |..z.Uv.j.....H..|
+00000320 ff 88 cb 59 f4 64 f2 ad 3b 4c 8c 39 85 b1 5f ae |...Y.d..;L.9.._.|
+00000330 07 c1 a9 0f f5 0e 02 27 28 74 0d 9f c5 b2 8e 18 |.......'(t......|
+00000340 6a 66 b9 86 ca 41 1f 6f 4a 05 d1 0d 69 ad f0 b6 |jf...A.oJ...i...|
+00000350 2d 6a 24 df 6f 9b 5c 07 b1 04 17 03 03 00 99 11 |-j$.o.\.........|
+00000360 46 8d 44 89 36 f4 ff dc 5a 8e 1e 68 f3 63 03 b6 |F.D.6...Z..h.c..|
+00000370 40 40 26 1b 28 41 d9 78 f5 5e 51 c6 21 b8 fa c5 |@@&.(A.x.^Q.!...|
+00000380 a7 c4 20 d3 b0 c0 f0 ec 9a 0e 1a 5b 1c 8d 57 58 |.. ........[..WX|
+00000390 32 f9 75 69 9a 5e 1d 96 0b fa 77 d8 c7 d1 a0 8b |2.ui.^....w.....|
+000003a0 e6 f8 33 3a f9 90 22 a7 19 37 50 d8 f0 90 34 4f |..3:.."..7P...4O|
+000003b0 c3 bb 1c a2 c3 b8 3e d3 6b ee a0 39 40 98 e5 93 |......>.k..9@...|
+000003c0 f8 16 29 6a 1e 12 20 4d 5c bd fd 11 f6 c5 cc d6 |..)j.. M\.......|
+000003d0 08 d9 bc f5 ce 95 70 2c dd 9f 70 08 7c c4 55 59 |......p,..p.|.UY|
+000003e0 8f 57 25 16 36 53 b4 3c 14 df af 1c 5f ec 2a 5a |.W%.6S.<...._.*Z|
+000003f0 61 7c c4 1e 96 9c aa 9b 17 03 03 00 35 ef b8 e8 |a|..........5...|
+00000400 5d ef 00 77 46 05 77 37 7b f6 3e b4 e9 b4 67 a8 |]..wF.w7{.>...g.|
+00000410 88 49 6d d8 2f 3a 88 db 48 47 e1 cb a5 f9 38 17 |.Im./:..HG....8.|
+00000420 09 c8 a7 0b 92 7c d9 17 9f 2d 34 9c 9a d0 da 02 |.....|...-4.....|
+00000430 a8 d0 |..|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 02 1e 57 f6 58 1b c5 |...........W.X..|
+00000010 ad 34 85 01 b8 a0 3f a6 b4 b8 e1 b1 7b fa 10 f8 |.4....?.....{...|
+00000020 05 c3 07 ba ef a7 08 ed d0 0e f4 4a e0 1e 49 d8 |...........J..I.|
+00000030 d8 a6 82 3c ca cd 4c b8 c3 27 40 28 49 69 47 a2 |...<..L..'@(IiG.|
+00000040 ab 4b 14 e2 b5 ac 02 aa 7c 92 17 c0 6e cc 42 dc |.K......|...n.B.|
+00000050 ce 10 d1 cb 25 9e fe 4f 21 a3 76 1b b4 d4 62 5b |....%..O!.v...b[|
+00000060 51 8a 64 4a 6c 4c 7b e8 87 79 50 51 4a b3 39 f3 |Q.dJlL{..yPQJ.9.|
+00000070 37 9f 30 23 eb 6a 26 bc 49 3f 41 76 d2 c9 06 63 |7.0#.j&.I?Av...c|
+00000080 41 11 58 02 0b ae ac 52 4b e6 4e 03 88 ef e6 8d |A.X....RK.N.....|
+00000090 51 7b 02 e2 a5 a3 70 79 d1 16 5f 8b b9 2e d6 48 |Q{....py.._....H|
+000000a0 87 2b c9 49 7f 1a 33 65 55 61 80 bd e5 cb dc 74 |.+.I..3eUa.....t|
+000000b0 84 4d dd c8 9a 6b 84 c2 b5 68 de 5e 9b 42 cf 99 |.M...k...h.^.B..|
+000000c0 a5 69 93 89 63 a7 94 60 0c 97 7c ab ec 18 61 a8 |.i..c..`..|...a.|
+000000d0 68 e3 c8 66 ab 08 2c 96 49 76 b2 3e 40 22 5e 95 |h..f..,.Iv.>@"^.|
+000000e0 7e 79 f0 53 43 2f 0d a0 c2 ec eb 6f ec 41 da ef |~y.SC/.....o.A..|
+000000f0 a0 6f cb 22 bb 55 19 2d 6d 6e 04 cc 77 fb 00 a2 |.o.".U.-mn..w...|
+00000100 99 53 cf b6 30 95 f4 04 83 9e ab a9 c4 cd 21 a4 |.S..0.........!.|
+00000110 4a d9 e4 f9 a6 96 5e ef 8d b7 c0 62 2a 25 68 a4 |J.....^....b*%h.|
+00000120 53 50 7c cf d5 9d b9 3d 78 2b 76 65 63 95 b4 8d |SP|....=x+vec...|
+00000130 87 41 68 3d dc 80 be 40 24 33 b5 c3 90 ee 8f fa |.Ah=...@$3......|
+00000140 f8 25 0d 48 6a c7 b5 e6 b5 ab b5 10 4b ad b3 95 |.%.Hj.......K...|
+00000150 62 6b 76 9b 21 b2 96 86 0d f6 c1 a8 d3 5a 9f 3e |bkv.!........Z.>|
+00000160 e8 50 2f 72 49 1c 0a fa 47 90 87 75 f8 a4 7e 95 |.P/rI...G..u..~.|
+00000170 d2 74 ca 78 c5 fa f8 8d ca 83 81 ec 93 89 e0 50 |.t.x...........P|
+00000180 62 49 15 87 5e 16 4c 17 aa f3 a1 1b 0c 4b 9a 68 |bI..^.L......K.h|
+00000190 1b d5 48 a5 da fe c8 84 fe e6 fc 24 3d 9d 14 e8 |..H........$=...|
+000001a0 e5 38 45 20 bd cb 22 2a 95 3e de 84 4f 85 6b e2 |.8E .."*.>..O.k.|
+000001b0 be dc e1 1a 55 78 68 dc fd c7 c8 e2 d6 90 a7 14 |....Uxh.........|
+000001c0 44 b6 6a a0 4e 01 0f 73 9b 97 ac ef 17 91 90 16 |D.j.N..s........|
+000001d0 14 e5 f7 88 df 08 8b d6 48 49 c5 9b 72 81 0b b8 |........HI..r...|
+000001e0 67 e4 5a b0 a6 a8 37 ef d3 96 28 dd f9 cc 24 c0 |g.Z...7...(...$.|
+000001f0 6f fc 7e 68 f5 25 df 38 73 1a ea b1 3d 8d 88 90 |o.~h.%.8s...=...|
+00000200 90 51 f3 f5 02 df 5a b2 5a 29 81 3c b6 aa 60 f2 |.Q....Z.Z).<..`.|
+00000210 79 ea 11 54 9d 6e ad e4 9b 48 35 6a 7b 95 ac 75 |y..T.n...H5j{..u|
+00000220 5e a5 dd 55 c7 97 10 aa 22 17 03 03 00 a2 12 24 |^..U...."......$|
+00000230 cd 8b fc be 73 28 ab a6 1e e6 f9 c2 d3 5e 98 db |....s(.......^..|
+00000240 a9 30 02 c7 87 20 c9 34 d3 11 ea 3e 9f 3e 12 c7 |.0... .4...>.>..|
+00000250 55 16 8d 3a 33 8f 71 08 b0 10 e4 0a 43 6d 1e 59 |U..:3.q.....Cm.Y|
+00000260 79 e4 f0 86 6a bb 4a 4e bf 03 7a 5a 7d 76 a1 be |y...j.JN..zZ}v..|
+00000270 26 95 87 e4 8c 14 85 f3 a6 ec 9c 44 e2 80 04 96 |&..........D....|
+00000280 12 6a c5 97 c0 0c 4e 94 49 ef f9 78 38 09 c7 65 |.j....N.I..x8..e|
+00000290 6c 51 2b 2a a3 da 9c 95 37 1a da 37 f6 da c2 79 |lQ+*....7..7...y|
+000002a0 be 5a 1f 0a 59 5b d8 31 b8 c5 b1 12 ef 57 1b fc |.Z..Y[.1.....W..|
+000002b0 62 8f de 94 3d 02 3c 96 cf 76 02 46 b7 64 0a 41 |b...=.<..v.F.d.A|
+000002c0 87 94 d6 98 61 82 8c ff 9f 42 dc f0 8e 6a 59 a5 |....a....B...jY.|
+000002d0 17 03 03 00 35 ec 44 9e 59 91 95 ae 8d f5 90 13 |....5.D.Y.......|
+000002e0 6e cf e5 4c a3 89 a0 65 54 f8 6c c0 b7 12 2b 26 |n..L...eT.l...+&|
+000002f0 fb d6 16 33 1e cd 5f dc c1 06 f3 6e 9a 5a 30 c8 |...3.._....n.Z0.|
+00000300 87 6a ee 13 06 b8 30 c6 33 3b 17 03 03 00 17 a4 |.j....0.3;......|
+00000310 d8 51 e6 cd d0 30 f3 2b 5d 17 fa d4 c8 96 d1 8c |.Q...0.+].......|
+00000320 2d b6 58 68 c7 93 17 03 03 00 13 1b a1 ec 18 a4 |-.Xh............|
+00000330 6f c6 5a 27 a3 1c a3 75 6d bd 68 61 28 cd |o.Z'...um.ha(.|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-ClientCert-Ed25519 b/src/crypto/tls/testdata/Client-TLSv13-ClientCert-Ed25519
new file mode 100644
index 0000000..94abf06
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv13-ClientCert-Ed25519
@@ -0,0 +1,123 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 7a 02 00 00 76 03 03 63 7c fe 18 f1 |....z...v..c|...|
+00000010 82 47 f8 e9 56 0a ef 41 1c da 7b ef 4e 37 f7 37 |.G..V..A..{.N7.7|
+00000020 9c 70 58 73 97 a4 2b df 93 24 98 20 00 00 00 00 |.pXs..+..$. ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 13 03 00 00 |................|
+00000050 2e 00 2b 00 02 03 04 00 33 00 24 00 1d 00 20 fe |..+.....3.$... .|
+00000060 8e 92 58 47 f1 85 83 58 b6 18 1a 05 fb 40 99 25 |..XG...X.....@.%|
+00000070 10 d0 6d 4c c0 43 8b b5 a9 18 51 8f 84 73 56 14 |..mL.C....Q..sV.|
+00000080 03 03 00 01 01 17 03 03 00 17 3e f9 39 72 d3 bd |..........>.9r..|
+00000090 1f 3f ff 30 cb 7e f8 3d a7 7d 8c 09 94 d3 79 24 |.?.0.~.=.}....y$|
+000000a0 10 17 03 03 00 42 28 16 54 10 dd db 62 c6 08 c9 |.....B(.T...b...|
+000000b0 56 43 8d 0e 04 bc d1 78 54 21 1f 08 c0 80 e2 76 |VC.....xT!.....v|
+000000c0 8b 64 e2 63 97 a8 73 8a 14 16 2f 92 39 9c 59 e9 |.d.c..s.../.9.Y.|
+000000d0 59 a0 88 4b 9d 19 49 cf 34 98 c5 2a 48 eb d2 0f |Y..K..I.4..*H...|
+000000e0 95 7a 25 f2 23 b3 88 61 17 03 03 02 6d 98 62 0c |.z%.#..a....m.b.|
+000000f0 ed 07 3e a7 5b 8e 69 20 90 cb ff 25 06 fb 80 dc |..>.[.i ...%....|
+00000100 b6 e6 bc 95 9c 6b 1e b4 11 a7 2f 72 17 c7 b5 67 |.....k..../r...g|
+00000110 93 a9 5c b8 ef aa e1 cb 6b f4 2d db e3 a4 c9 cf |..\.....k.-.....|
+00000120 66 45 d9 1d 02 1d 9c b7 84 4f 83 5b 7f f3 16 0a |fE.......O.[....|
+00000130 f7 37 86 19 c0 29 95 5a aa 46 62 10 c9 22 62 f0 |.7...).Z.Fb.."b.|
+00000140 4f a9 a3 75 ea 46 af 75 54 9e 69 87 ce a9 d9 b9 |O..u.F.uT.i.....|
+00000150 35 d6 c0 4a f0 22 0b d1 e5 4b 48 99 70 fa bc ed |5..J."...KH.p...|
+00000160 8a 8b 7d a2 f0 52 3d e0 bc d3 7e ca 1b 89 b6 78 |..}..R=...~....x|
+00000170 24 8d 13 0d 7d f2 3f d7 71 c9 d6 5a 00 8e 8c 7f |$...}.?.q..Z....|
+00000180 ed 5b 39 f3 67 76 c3 7a 75 1e 4a 4b 63 36 e7 d4 |.[9.gv.zu.JKc6..|
+00000190 04 46 e0 17 f4 d0 41 9d cf 01 f4 f7 b4 7e 11 73 |.F....A......~.s|
+000001a0 c4 46 ac d3 78 54 17 83 10 12 48 d1 36 ee 37 90 |.F..xT....H.6.7.|
+000001b0 f1 5f 7d f9 bc ac 95 ae 01 0e ca 0d 93 07 6e 87 |._}...........n.|
+000001c0 c9 27 79 46 0f 27 a1 31 f8 92 9e 73 3d 2e 29 f5 |.'yF.'.1...s=.).|
+000001d0 88 d1 67 a6 6a fb d5 59 39 65 46 b0 92 11 55 de |..g.j..Y9eF...U.|
+000001e0 6f 9f 1d ea a0 71 65 4c c8 03 b7 f1 25 ff f1 c9 |o....qeL....%...|
+000001f0 fa a7 1e 36 f3 91 bd d7 91 00 b5 3e 6f b1 67 5b |...6.......>o.g[|
+00000200 fc 64 1d 76 0e a7 36 15 93 a1 ea 53 06 15 2b cf |.d.v..6....S..+.|
+00000210 29 ea c6 5b 58 bb 08 a0 b8 9c e1 70 8d 2d 55 81 |)..[X......p.-U.|
+00000220 ac d9 0d 45 ec f9 c3 56 31 00 db 46 81 68 98 db |...E...V1..F.h..|
+00000230 8d 97 ce d1 b9 83 af 5f 6a a2 1a 22 2f 52 a0 d1 |......._j.."/R..|
+00000240 8c 40 35 68 a2 ee 30 ef d4 bf 08 46 76 7c dd 57 |.@5h..0....Fv|.W|
+00000250 c3 fb 7d fd af 01 37 cc c2 44 f6 cf 80 f4 ab c2 |..}...7..D......|
+00000260 2e 82 18 5e c4 91 a8 b7 ad 29 e7 54 4f 02 47 5e |...^.....).TO.G^|
+00000270 82 26 25 c6 b5 8e c9 a7 19 00 32 1b 3b e8 8c 35 |.&%.......2.;..5|
+00000280 25 01 ed e4 b2 29 e2 f4 d7 0f c8 39 f8 5d 7b 1e |%....).....9.]{.|
+00000290 db 7b 39 f4 e2 cd 1a 57 07 48 2b 15 e4 39 03 54 |.{9....W.H+..9.T|
+000002a0 cf 39 fe 3d 15 47 bb 87 cf a5 f4 17 cc ad dd fa |.9.=.G..........|
+000002b0 58 b6 e8 23 9c 1d 92 6b 32 36 12 ba 87 56 a4 2f |X..#...k26...V./|
+000002c0 fe cc 93 98 62 84 5c e6 f9 fd d4 86 df ce 42 32 |....b.\.......B2|
+000002d0 08 da a4 13 40 a0 33 c2 2a 54 2b da 50 5b 27 d9 |....@.3.*T+.P['.|
+000002e0 3a 76 16 6c 89 bf 31 48 a3 ad c3 a6 ee 17 7d 86 |:v.l..1H......}.|
+000002f0 88 52 57 77 01 94 ba dc f0 a6 c3 d3 30 ae be aa |.RWw........0...|
+00000300 11 0a e8 54 8c b2 cb 7f e6 b6 d3 17 f4 2e 54 94 |...T..........T.|
+00000310 31 43 33 07 5d 51 96 11 21 91 f9 7e 93 79 70 85 |1C3.]Q..!..~.yp.|
+00000320 d3 0b ee fd 0e eb db ad 71 fe ba fc fe fa ef 0e |........q.......|
+00000330 a1 a4 c5 99 e2 fa 3c df 8b 52 33 89 fd 15 45 1b |......<..R3...E.|
+00000340 4e 5f 0e ca e9 c5 6e 11 06 ae 37 2a db 4c 9f 2c |N_....n...7*.L.,|
+00000350 21 67 af e7 ae 09 e8 96 2f f0 17 03 03 00 99 ed |!g....../.......|
+00000360 df 2c ff 14 ed 8e 5e 83 63 5d 82 99 19 ef 4c b1 |.,....^.c]....L.|
+00000370 4b f6 88 29 27 72 b4 47 41 ab 61 58 67 7f 1c d0 |K..)'r.GA.aXg...|
+00000380 a5 6d 83 3a 4e be 98 7d 55 e3 cc a5 24 41 28 91 |.m.:N..}U...$A(.|
+00000390 33 b8 94 a8 e3 54 88 2b 22 89 c2 b8 86 96 d0 24 |3....T.+"......$|
+000003a0 99 6c 4c 26 ee 39 67 b6 8b 30 49 b9 d4 cd c0 b3 |.lL&.9g..0I.....|
+000003b0 bd f0 1d 2c 96 c7 9c 10 a7 4b 0e 2b 51 92 96 2f |...,.....K.+Q../|
+000003c0 70 40 12 f3 91 53 eb 25 34 e6 ae ef df d4 3e f5 |p@...S.%4.....>.|
+000003d0 fa 9f c2 85 71 5d 21 fd ee e0 3b 5a 23 db 19 e6 |....q]!...;Z#...|
+000003e0 ce 04 6c e6 37 2c 43 df 4c 1f 0a 84 36 5e 26 82 |..l.7,C.L...6^&.|
+000003f0 fa f4 38 ea 49 bb d2 65 17 03 03 00 35 a7 a0 78 |..8.I..e....5..x|
+00000400 91 74 da 83 6f bd 49 ae 52 e2 c2 a7 d9 b4 a1 bc |.t..o.I.R.......|
+00000410 b8 59 ab 56 25 60 05 39 db 3b 5e 95 6f a6 43 b9 |.Y.V%`.9.;^.o.C.|
+00000420 1b 7a 84 ac ea 8a 62 f2 7c 50 68 43 0a c8 71 25 |.z....b.|PhC..q%|
+00000430 44 a0 |D.|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 01 50 e5 d5 ff 01 ac |..........P.....|
+00000010 29 be dc aa 07 05 88 f6 e6 ae aa 3f 10 c6 72 1e |)..........?..r.|
+00000020 31 1a dc e5 64 ab 1f 82 60 0a a3 24 59 4a 91 86 |1...d...`..$YJ..|
+00000030 d0 90 e5 5a ca ad 5b c4 18 a6 c3 d8 56 7b 86 7c |...Z..[.....V{.||
+00000040 53 b4 59 7e 91 5d 9c 32 11 44 66 7c 75 43 d1 d9 |S.Y~.].2.Df|uC..|
+00000050 dc bd 99 7d 37 37 c1 be ef 61 bf fb b4 f4 2e 2e |...}77...a......|
+00000060 c5 66 fa d2 a1 86 4e 42 03 ed 7b 78 2b 82 f8 6d |.f....NB..{x+..m|
+00000070 f5 12 6f 60 c7 93 03 12 43 5a 4b 21 25 88 8b 54 |..o`....CZK!%..T|
+00000080 37 2e 9b 1d bb 86 4a 85 80 e2 cb b1 0b 38 05 b1 |7.....J......8..|
+00000090 d2 a7 04 c6 a3 db df cb 18 90 db 17 dd f1 04 44 |...............D|
+000000a0 c0 5a ce ed 39 4e 89 91 8c 00 a2 8e 5f c4 64 8d |.Z..9N......_.d.|
+000000b0 22 e5 53 7c ea 2d 09 65 0f 76 31 ef 50 b6 b7 6f |".S|.-.e.v1.P..o|
+000000c0 a4 63 83 c2 90 07 67 28 37 c2 56 cb 56 71 92 3c |.c....g(7.V.Vq.<|
+000000d0 ea 34 3b 54 58 78 b1 c0 ef 1c fc 4e c4 c5 f7 89 |.4;TXx.....N....|
+000000e0 55 f4 95 c0 bc af 1f 9e 0d f3 b8 35 54 64 c2 4b |U..........5Td.K|
+000000f0 cc 4b 30 6f e0 5c 7b 51 1c 05 51 b3 6a f2 60 1f |.K0o.\{Q..Q.j.`.|
+00000100 a5 26 ec ad 5f 93 1a 45 f9 88 73 5a 9a 51 fe c8 |.&.._..E..sZ.Q..|
+00000110 1a e7 9b 8c 9d a6 55 68 57 80 a5 81 8e bd 1a 5f |......UhW......_|
+00000120 9d 56 89 8f 32 9a 5b 4c 60 e0 b2 73 e5 5c 04 62 |.V..2.[L`..s.\.b|
+00000130 62 1c ee 89 6d 00 4a bb e0 b9 5f 6f f3 a7 5e bc |b...m.J..._o..^.|
+00000140 95 a1 a8 a7 94 c2 06 19 97 0f 2f ff b0 95 c6 39 |........../....9|
+00000150 8d 96 59 71 87 90 34 76 b2 3b 7d 17 03 03 00 59 |..Yq..4v.;}....Y|
+00000160 7d ba 65 99 35 1b 2b 93 b1 76 99 9a 5a 90 4c 2a |}.e.5.+..v..Z.L*|
+00000170 2a 14 1e 99 dd 23 10 95 fb 5b 9f 28 47 4d 41 3e |*....#...[.(GMA>|
+00000180 71 d4 93 20 ee 69 32 85 b5 59 2a d0 1c 19 53 84 |q.. .i2..Y*...S.|
+00000190 46 0d cc 6a 9b a3 83 68 22 79 e5 e3 f4 56 a9 76 |F..j...h"y...V.v|
+000001a0 a0 9f d9 3c 27 3f 28 cb ab eb f3 55 41 2b ce 6f |...<'?(....UA+.o|
+000001b0 5a e5 22 c1 c9 0f 44 fc 8f 17 03 03 00 35 f6 80 |Z."...D......5..|
+000001c0 8e d2 cc 5b 6d 94 18 83 d2 70 87 e5 2c f2 0a 7a |...[m....p..,..z|
+000001d0 44 a4 e9 6d f3 74 02 61 1b 87 6c b7 bf 8a ba 41 |D..m.t.a..l....A|
+000001e0 3b d8 18 2f 1d ad c3 9c c8 6c c9 a0 82 7c bf 2b |;../.....l...|.+|
+000001f0 f8 c2 09 17 03 03 00 17 79 0a 43 29 1d d6 b5 fc |........y.C)....|
+00000200 fe 27 55 b8 5a 69 f1 b9 ed 31 63 2f 51 76 e1 17 |.'U.Zi...1c/Qv..|
+00000210 03 03 00 13 72 86 7e a3 6c af 2b e3 85 4c 16 74 |....r.~.l.+..L.t|
+00000220 97 73 48 96 ba 46 bd |.sH..F.|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-ClientCert-RSA-ECDSA b/src/crypto/tls/testdata/Client-TLSv13-ClientCert-RSA-ECDSA
new file mode 100644
index 0000000..e0acf89
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv13-ClientCert-RSA-ECDSA
@@ -0,0 +1,135 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 7a 02 00 00 76 03 03 17 5d 17 94 35 |....z...v...]..5|
+00000010 cc 45 ba fc 44 dd 02 57 2c 67 67 c1 f9 7d bb 52 |.E..D..W,gg..}.R|
+00000020 fb 5e dd a2 29 43 14 95 be a7 98 20 00 00 00 00 |.^..)C..... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 13 03 00 00 |................|
+00000050 2e 00 2b 00 02 03 04 00 33 00 24 00 1d 00 20 8f |..+.....3.$... .|
+00000060 cd f2 33 7c ee 70 18 fa 98 64 43 1b 24 e2 80 80 |..3|.p...dC.$...|
+00000070 a9 e3 3c 49 f3 a2 68 b6 ba 09 3b ef f4 4e 20 14 |..<I..h...;..N .|
+00000080 03 03 00 01 01 17 03 03 00 17 cc f4 79 1c f5 ef |............y...|
+00000090 db b2 3b 82 f6 02 31 e7 2f 26 9a 6d 3b 8c 3d f1 |..;...1./&.m;.=.|
+000000a0 b5 17 03 03 00 42 74 b6 78 89 0f ce a8 80 4c 07 |.....Bt.x.....L.|
+000000b0 f5 3b 4d ce da 18 ee 39 c0 d9 9d c7 75 97 cc 50 |.;M....9....u..P|
+000000c0 8d de 0d a0 33 fc ab be 71 52 7c 7e fb 09 90 a3 |....3...qR|~....|
+000000d0 94 79 b7 16 04 4d db 57 29 dd 09 f1 94 b6 d4 ba |.y...M.W).......|
+000000e0 b9 79 c2 76 49 81 d6 06 17 03 03 02 22 d2 06 bc |.y.vI......."...|
+000000f0 ce f7 c8 18 26 55 74 75 6a 9d ff d7 0a 5b 19 a8 |....&Utuj....[..|
+00000100 c4 c7 66 2c 5b 94 09 0a f7 f4 3b 2b 22 e0 89 6b |..f,[.....;+"..k|
+00000110 2f 98 fa 03 55 3e 2d 08 ba 40 94 15 37 53 8a 0e |/...U>-..@..7S..|
+00000120 8a da 06 d7 26 a9 ae e0 f4 b3 d2 33 37 06 8d 76 |....&......37..v|
+00000130 24 63 42 33 65 ad dd 23 c3 cb b3 6f 8c 0c ee be |$cB3e..#...o....|
+00000140 63 1a 61 13 29 2a af 74 67 6a 19 d7 22 12 8a dc |c.a.)*.tgj.."...|
+00000150 ce 77 81 26 b1 1a 2b 5d 77 0c 9a 65 6d 75 f0 90 |.w.&..+]w..emu..|
+00000160 95 66 84 3d d6 fd 95 c5 dd fd 80 5b 8e ab 1b 0b |.f.=.......[....|
+00000170 f1 f0 b9 8c fc e2 3b ce 05 03 ef dc 4b 08 69 af |......;.....K.i.|
+00000180 22 58 7b ab 6b cf 8e 63 40 e4 8d c3 5c f4 29 cc |"X{.k..c@...\.).|
+00000190 d7 d2 17 94 af a3 ff 31 e4 75 78 c5 17 fb 84 f5 |.......1.ux.....|
+000001a0 e0 4b f8 70 3d 57 e0 dc 70 c5 5e 44 5a ea 2a 33 |.K.p=W..p.^DZ.*3|
+000001b0 22 47 a3 e4 7a 95 d6 10 7e 6f 87 b4 bc 5a 9a ba |"G..z...~o...Z..|
+000001c0 99 af 7c 0d 6f 4d cc c7 0d 12 c9 99 e1 d7 90 2d |..|.oM.........-|
+000001d0 8c 7b 24 11 c6 3e d0 16 fb a5 87 06 8f b5 e3 a5 |.{$..>..........|
+000001e0 f2 e5 d4 76 09 9e 9f ec ef 58 b0 34 9c ff 21 aa |...v.....X.4..!.|
+000001f0 48 a0 c8 2e ca 2d 8a cc ad aa 9a 07 bd cc e4 12 |H....-..........|
+00000200 cd 33 5d b2 a7 95 a2 8c e0 74 5b 6f e3 dd ce af |.3]......t[o....|
+00000210 05 8a fe 52 d8 23 b8 70 bd 45 90 38 05 bf d5 89 |...R.#.p.E.8....|
+00000220 0f 4b 08 83 03 07 f0 24 bc 9d a9 d7 f4 0a 2b 94 |.K.....$......+.|
+00000230 82 f1 7a 3b 49 85 06 0e d9 e6 c8 7c 69 f9 f6 61 |..z;I......|i..a|
+00000240 34 0e 6e 8c c5 76 18 f0 88 22 a0 3d b5 9a 92 55 |4.n..v...".=...U|
+00000250 88 37 ff 06 53 a9 64 4c 7d 12 c8 ac 72 de 74 d6 |.7..S.dL}...r.t.|
+00000260 62 ea 27 f5 e8 d1 09 a2 b1 df 1d 32 d3 15 b0 52 |b.'........2...R|
+00000270 98 fd 24 0b dd 33 0a 88 92 d1 cf c5 1a ef 27 8a |..$..3........'.|
+00000280 7d b2 59 74 97 24 9c c3 cc 0e 1c a5 26 c7 5a 10 |}.Yt.$......&.Z.|
+00000290 0d be 10 b2 bc 79 76 21 b5 b7 48 24 59 08 41 4d |.....yv!..H$Y.AM|
+000002a0 3c 31 ad cf 02 4b ed a5 fb 0d d7 55 60 fa cf 04 |<1...K.....U`...|
+000002b0 dd 84 0c 0b e9 eb ea 6d e2 33 9d 04 1d 0b fe b1 |.......m.3......|
+000002c0 e2 cd 2d c8 84 2d be fd ae 9e 1a 61 70 b9 d4 6e |..-..-.....ap..n|
+000002d0 74 9f 68 b3 60 aa 42 bc 98 8d d7 45 f4 3b 00 2b |t.h.`.B....E.;.+|
+000002e0 0d 55 f4 14 5d 9a ab f9 d1 af 9c b3 18 e3 8d f9 |.U..]...........|
+000002f0 8d 11 89 3e e7 6a f2 b8 52 fd 67 71 37 b4 ec c1 |...>.j..R.gq7...|
+00000300 6f d9 d6 57 67 4d 05 48 22 3a 4b 79 3b 2c 70 17 |o..WgM.H":Ky;,p.|
+00000310 03 03 00 a3 c6 8b 11 15 2c 6f 55 2f 96 01 24 f1 |........,oU/..$.|
+00000320 bd c2 79 09 2f d3 ff 9a bb a4 b8 f5 f3 fe 85 d7 |..y./...........|
+00000330 7a 21 b9 92 e6 b5 89 c9 fb fb e2 4a 8f 5a 5c 63 |z!.........J.Z\c|
+00000340 7d 8c 4e 9a 27 1b 4a bb e4 bb f0 cf 3f 5c c6 db |}.N.'.J.....?\..|
+00000350 d8 83 bf 57 be ac ed 5f 1a 2c 10 77 7c b7 70 0f |...W..._.,.w|.p.|
+00000360 4b 2d 93 e5 46 d1 75 fa e4 da 73 c2 72 d6 48 6f |K-..F.u...s.r.Ho|
+00000370 0d 21 eb 9d 2b d3 12 d9 d1 3c 9b 56 c3 90 2d 1b |.!..+....<.V..-.|
+00000380 79 9a ab e8 2c 55 0e 67 0b 58 f8 ac 24 3a 6c a5 |y...,U.g.X..$:l.|
+00000390 34 29 30 6a b3 84 5a bc 59 f8 9c 07 75 b1 e8 ed |4)0j..Z.Y...u...|
+000003a0 80 96 11 ad da 74 3b d8 9c 5c 71 8f a6 30 ad 77 |.....t;..\q..0.w|
+000003b0 e7 64 13 50 5e 76 ef 17 03 03 00 35 b3 db 05 94 |.d.P^v.....5....|
+000003c0 08 9b e0 1d 45 12 11 c7 b0 5e 61 ac a0 e7 8e 80 |....E....^a.....|
+000003d0 30 7f 20 19 69 da 73 06 a5 dd 7c 85 4e fa cc 37 |0. .i.s...|.N..7|
+000003e0 2c f8 4e fd ce 2b 4b f4 fd 68 de 23 15 36 00 8c |,.N..+K..h.#.6..|
+000003f0 e7 |.|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 02 11 ee 00 8e e7 34 |...............4|
+00000010 b5 6f 32 2e e9 11 e3 7f 24 ff 64 6a 47 04 6d f7 |.o2.....$.djG.m.|
+00000020 3a 92 d5 45 12 92 c7 67 ea 91 31 9e 6e 61 a1 52 |:..E...g..1.na.R|
+00000030 9c e6 16 17 d3 8e 9e 41 85 1f a5 6a 69 97 53 f8 |.......A...ji.S.|
+00000040 35 b8 81 43 af 59 25 fc 78 42 b4 6f c1 4b 54 e2 |5..C.Y%.xB.o.KT.|
+00000050 e1 c1 97 b5 74 ea c8 b7 42 20 b2 42 27 68 7d f7 |....t...B .B'h}.|
+00000060 8c e0 18 53 46 e1 fc 86 55 bc 28 8a e1 95 94 24 |...SF...U.(....$|
+00000070 d4 38 80 a7 7e 85 2c a9 81 c2 4b c7 51 d5 0f 1f |.8..~.,...K.Q...|
+00000080 88 8a 93 7d 74 53 1e f3 2b b6 b3 4a b5 a8 0c ea |...}tS..+..J....|
+00000090 c4 6e 10 c3 8f ac 96 2f c5 6b 63 f0 11 b0 38 81 |.n...../.kc...8.|
+000000a0 16 3c 96 fb d0 e9 18 5a 08 a0 f4 5e f0 6d 01 ff |.<.....Z...^.m..|
+000000b0 13 04 c3 f7 e8 23 2a 06 32 6d 2b f1 d4 cc 60 ab |.....#*.2m+...`.|
+000000c0 c9 9e c8 08 1d 8a 06 ff 7f 26 e1 db 13 d5 cd 3e |.........&.....>|
+000000d0 5f 61 11 9b 43 cc 1e 19 32 6e 01 f0 79 3e cb 02 |_a..C...2n..y>..|
+000000e0 7d 4c 27 ee b0 4a 24 44 c7 ff 16 e5 59 c0 b1 2f |}L'..J$D....Y../|
+000000f0 9a f6 c5 39 1f f2 f3 f0 70 89 e3 cb a4 43 81 16 |...9....p....C..|
+00000100 40 dd e2 3a e1 12 be 29 64 cb f3 f9 20 2c c9 62 |@..:...)d... ,.b|
+00000110 84 9c 31 fb 9b 95 a4 ac 3e 1d f4 19 bb 0a ce 89 |..1.....>.......|
+00000120 3a 33 9e 40 2b da 42 5c 71 59 54 bb 65 de eb 9e |:3.@+.B\qYT.e...|
+00000130 71 46 40 9f 3d 6d 88 3a 0d b9 08 63 7d 4f a3 5b |qF@.=m.:...c}O.[|
+00000140 9a 67 03 a0 d9 c6 47 4b 3b 11 d0 7b 13 fb 93 d1 |.g....GK;..{....|
+00000150 fc 63 dc 45 f2 b4 8b 22 12 31 20 48 6e 9a 4e 7d |.c.E...".1 Hn.N}|
+00000160 3f 7e cd 09 6a ea 5f a1 0a e5 d8 80 c0 ed 6a cb |?~..j._.......j.|
+00000170 0a af 1e 8f 88 63 63 13 49 02 d9 01 87 03 4f 9f |.....cc.I.....O.|
+00000180 cc a2 5f 2f a8 3d 2b 9f a2 f0 81 b5 b0 d2 92 6c |.._/.=+........l|
+00000190 8f 3b f6 5c 66 27 d4 98 6e 86 e5 a5 ab 3c 1b b8 |.;.\f'..n....<..|
+000001a0 eb cb 72 d9 6c d8 49 9a 33 db 75 e6 3f ff 2a b0 |..r.l.I.3.u.?.*.|
+000001b0 77 c6 02 f1 c0 a5 74 99 42 42 e8 97 b5 27 a9 11 |w.....t.BB...'..|
+000001c0 af b7 65 b3 a8 51 dd 44 35 6e 0c 34 d5 b2 38 75 |..e..Q.D5n.4..8u|
+000001d0 f0 cf 10 ff 5a 7a 16 ca bd 44 e8 99 91 50 9f db |....Zz...D...P..|
+000001e0 8c ff 54 3a 24 73 de d1 29 5a 49 fc b3 d0 31 80 |..T:$s..)ZI...1.|
+000001f0 6f 16 84 c1 83 cf 9d 75 d4 b5 a5 a0 a0 15 bc 03 |o......u........|
+00000200 38 61 89 f5 16 98 25 f0 e8 72 28 3e d4 d6 64 66 |8a....%..r(>..df|
+00000210 de ff be 71 34 7c b1 63 38 38 81 03 17 03 03 00 |...q4|.c88......|
+00000220 99 3d e0 6d 2f 4c 22 62 d8 5f 0b 53 8a 99 c4 b2 |.=.m/L"b._.S....|
+00000230 66 88 d0 71 0c 90 b3 2e 9c 24 d1 89 4d f0 4d 29 |f..q.....$..M.M)|
+00000240 a7 11 87 db 08 cd 04 6c 1f 60 54 12 47 83 c7 82 |.......l.`T.G...|
+00000250 be 1b d8 ed 2f 43 c1 cf 63 21 bc 21 80 ad 7b ed |..../C..c!.!..{.|
+00000260 5c 0b 41 0d 5e 63 eb 82 15 69 d7 11 c4 3f 0d fb |\.A.^c...i...?..|
+00000270 07 96 34 a9 2c 9f 7f d7 fa 2c 24 c8 52 59 c3 07 |..4.,....,$.RY..|
+00000280 03 c7 88 65 8a 20 f2 1a 23 f8 18 2e 94 c6 be 77 |...e. ..#......w|
+00000290 bc 6e ff 7e 83 3e 9f 1f 77 b5 2b 67 e9 3d 03 c7 |.n.~.>..w.+g.=..|
+000002a0 b4 be 58 d1 12 69 39 3c 2d b3 dd 2e fb 41 b3 0b |..X..i9<-....A..|
+000002b0 b2 74 d0 80 8a 90 40 ab 59 30 17 03 03 00 35 ef |.t....@.Y0....5.|
+000002c0 7c c8 f8 01 6b 69 36 b2 26 9f 65 d8 a8 04 8a 41 ||...ki6.&.e....A|
+000002d0 58 e3 7a 6d 55 94 ec 09 df 6a a8 0d 86 54 c3 00 |X.zmU....j...T..|
+000002e0 a8 c2 46 e1 c0 83 fd 16 40 98 b3 5d c6 cc dc 3f |..F.....@..]...?|
+000002f0 c2 4f 95 61 17 03 03 00 17 39 cc 91 bc 98 39 0c |.O.a.....9....9.|
+00000300 1c 43 3c b5 cb 3b c0 99 68 9c 31 b5 1a d0 41 f9 |.C<..;..h.1...A.|
+00000310 17 03 03 00 13 65 9c ec ea 6e ac de 8c aa 1d 5e |.....e...n.....^|
+00000320 ff 7f 0d 3e 84 7a 90 6a |...>.z.j|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-ClientCert-RSA-RSAPSS b/src/crypto/tls/testdata/Client-TLSv13-ClientCert-RSA-RSAPSS
new file mode 100644
index 0000000..ec18187
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv13-ClientCert-RSA-RSAPSS
@@ -0,0 +1,144 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 7a 02 00 00 76 03 03 60 e7 99 c9 b0 |....z...v..`....|
+00000010 be be 74 84 1e 55 cd 83 d6 0d ba 9c a0 44 fb b4 |..t..U.......D..|
+00000020 a8 f6 3c 93 12 de 47 4a 7f 32 a6 20 00 00 00 00 |..<...GJ.2. ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 13 03 00 00 |................|
+00000050 2e 00 2b 00 02 03 04 00 33 00 24 00 1d 00 20 1d |..+.....3.$... .|
+00000060 6d 42 7d 8f 02 04 a1 81 8a eb 36 fd 64 4b d1 6c |mB}.......6.dK.l|
+00000070 98 e8 69 82 2e 92 7a 27 53 4f 74 bb 68 f2 7d 14 |..i...z'SOt.h.}.|
+00000080 03 03 00 01 01 17 03 03 00 17 2d 08 0f 31 27 58 |..........-..1'X|
+00000090 7b 40 eb cc 81 b9 7b 78 b4 c1 60 1e 10 74 3e f7 |{@....{x..`..t>.|
+000000a0 dc 17 03 03 00 20 af 35 53 ab e6 10 47 24 e5 79 |..... .5S...G$.y|
+000000b0 70 53 da 8e a2 bf 9a 81 ab 4d ba 80 09 40 e4 02 |pS.......M...@..|
+000000c0 8c cb cc 78 1c d4 17 03 03 02 7a 9a eb 2c 4f f5 |...x......z..,O.|
+000000d0 1a b9 d5 bc 47 d1 bc 35 47 07 66 bf 6d c9 35 b2 |....G..5G.f.m.5.|
+000000e0 b2 78 ef 18 22 9a e4 fa b4 f8 12 0e fd aa a4 f7 |.x.."...........|
+000000f0 9f f6 5b 2a 7b 05 c1 52 f8 2e 53 84 6c ef 51 e7 |..[*{..R..S.l.Q.|
+00000100 4f e2 f5 e9 4b 20 da 94 5d 97 bb c2 66 fb 74 38 |O...K ..]...f.t8|
+00000110 d6 15 0c c9 6e c6 67 ac ad 6f 4d d2 bf a2 13 29 |....n.g..oM....)|
+00000120 87 69 9b 4d cd 2e 83 60 db 5f ee f3 80 64 02 93 |.i.M...`._...d..|
+00000130 4f 1e 35 0b 01 25 1f cd 27 24 7a 82 8d 00 94 3a |O.5..%..'$z....:|
+00000140 34 b0 f2 53 36 0b f6 04 d3 25 2a 4e 2a 7e 26 98 |4..S6....%*N*~&.|
+00000150 41 ce 68 64 17 c9 65 9e f7 f9 bb df ee fb cb 74 |A.hd..e........t|
+00000160 db 7d 8a 43 d2 49 03 f6 e5 be e1 5e 45 df 77 c4 |.}.C.I.....^E.w.|
+00000170 1d 6e 9c ec 29 51 2b 7f 5e 75 46 05 50 39 5f fa |.n..)Q+.^uF.P9_.|
+00000180 5f 53 04 56 25 87 09 26 36 8d 55 ac 03 87 35 28 |_S.V%..&6.U...5(|
+00000190 52 05 c0 23 ff d5 57 58 7a 63 09 9d 87 15 b4 35 |R..#..WXzc.....5|
+000001a0 d9 40 19 4e 67 ce cd be 5b a0 14 e2 a8 4a ad 44 |.@.Ng...[....J.D|
+000001b0 ea a9 1b 14 e7 30 05 c9 23 48 4a 7a 7a 3f cc 9a |.....0..#HJzz?..|
+000001c0 ce ca 0e 5f a0 79 17 e0 e7 5b 30 79 38 2d 5b 1e |..._.y...[0y8-[.|
+000001d0 5c ae 4e 1f 00 ed fb 9f b6 e7 92 42 7d f0 30 82 |\.N........B}.0.|
+000001e0 70 18 dc 07 c1 64 ec 09 7e d7 8f eb 68 31 75 cb |p....d..~...h1u.|
+000001f0 69 24 30 89 8b 69 df 69 86 23 77 d2 61 4b 66 7e |i$0..i.i.#w.aKf~|
+00000200 6d 34 50 a5 da 86 12 22 e3 51 ac 6a 23 55 d4 d5 |m4P....".Q.j#U..|
+00000210 51 73 ac 85 c9 3a 57 c2 4b 55 96 4b c6 cc 62 15 |Qs...:W.KU.K..b.|
+00000220 c9 10 09 ac ec 75 1a a6 3e e8 da aa 4d fe 7d 51 |.....u..>...M.}Q|
+00000230 80 c3 a7 98 5d 29 cf c6 a0 8c 37 6e a8 f0 ad 41 |....])....7n...A|
+00000240 34 60 44 98 57 3a 97 1f 29 08 f4 fc 4e 76 2e 0b |4`D.W:..)...Nv..|
+00000250 26 8d fa 6c 38 0e 17 8a 2c de 51 94 f5 37 63 a0 |&..l8...,.Q..7c.|
+00000260 40 71 51 c0 b9 d4 04 b2 ef 88 80 8f 34 74 35 5a |@qQ.........4t5Z|
+00000270 c4 96 68 4f 27 0c 53 db f4 3c d1 88 86 b2 24 4f |..hO'.S..<....$O|
+00000280 c7 a7 d9 b4 56 22 e5 9d 3f ec eb 1a af 77 9a 47 |....V"..?....w.G|
+00000290 26 bb d5 3d 90 1d 6d fb d9 29 7e b4 b2 b2 ec 10 |&..=..m..)~.....|
+000002a0 67 de d2 02 74 b3 91 a0 c4 b3 7c ba bb 90 b5 da |g...t.....|.....|
+000002b0 97 fb 84 cd 4b 5e 33 c0 0a 56 73 98 8c 81 5b 9d |....K^3..Vs...[.|
+000002c0 8d 83 df c3 8d 3d 3c 58 55 a3 e7 bd ef d0 37 0b |.....=<XU.....7.|
+000002d0 1d 0d 6d 59 81 d7 5d 34 b3 c9 bd ea 96 9a 33 02 |..mY..]4......3.|
+000002e0 50 6d 81 1f 58 36 95 0c c0 6d b6 3e 2e e0 0a b7 |Pm..X6...m.>....|
+000002f0 c8 ae d8 84 06 2c 64 3c 35 a7 39 e4 a6 9e 0c 59 |.....,d<5.9....Y|
+00000300 89 59 9a dd c3 fb 6c ae 34 ec 66 c5 d5 1f 7b 13 |.Y....l.4.f...{.|
+00000310 66 23 8d 22 93 da 53 6c 3f 85 bb 5c 52 75 ba 81 |f#."..Sl?..\Ru..|
+00000320 e8 bf 57 ce a8 45 68 ad 57 2f 4e 51 d3 65 f3 d0 |..W..Eh.W/NQ.e..|
+00000330 1f 09 1e 3f 5e a1 9e 56 61 ca 88 e7 44 f6 f6 93 |...?^..Va...D...|
+00000340 cb ae 28 2b 74 17 03 03 00 99 de 30 0f 41 8e d8 |..(+t......0.A..|
+00000350 37 a0 c4 f3 af c3 f8 39 b7 44 83 6a c4 11 9e a4 |7......9.D.j....|
+00000360 a9 f0 08 22 77 ce 09 a3 2d 94 99 2a c7 1b 9c 25 |..."w...-..*...%|
+00000370 b6 79 ec 7b 2f 70 6a bd 2f f0 0f e0 6d 6e c0 69 |.y.{/pj./...mn.i|
+00000380 0c 52 13 1f f9 99 97 04 2f fc fb f8 0a 4b ab bc |.R....../....K..|
+00000390 a3 00 02 7f 0f 30 e2 66 c2 df 63 69 ad 08 76 ec |.....0.f..ci..v.|
+000003a0 58 99 42 6a 11 e6 7a 27 57 98 71 c9 4d 78 c8 4a |X.Bj..z'W.q.Mx.J|
+000003b0 3a 62 59 62 fb 2b 6f 15 79 22 50 40 bf db 29 d5 |:bYb.+o.y"P@..).|
+000003c0 32 e5 e7 1e 76 50 05 e4 26 24 97 79 2a 9a a5 ec |2...vP..&$.y*...|
+000003d0 c7 8c 68 e3 71 97 0c 85 51 74 db 5b 86 fb fb 23 |..h.q...Qt.[...#|
+000003e0 e6 ef 57 17 03 03 00 35 5c 96 e3 26 e5 49 d8 02 |..W....5\..&.I..|
+000003f0 b0 d0 4d 20 15 72 76 49 48 ee 2b 0a 19 44 05 cd |..M .rvIH.+..D..|
+00000400 b1 0a 76 4e a9 21 45 5e de 00 6b c3 53 7c c9 8d |..vN.!E^..k.S|..|
+00000410 43 72 06 78 0c ce 78 0f 01 ca d1 92 e5 |Cr.x..x......|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 02 7a 98 e7 1d af de |..........z.....|
+00000010 f0 97 05 09 b8 cc a4 5e e2 ba 26 13 bd dd a4 de |.......^..&.....|
+00000020 c6 fd 81 dc 0c 55 68 d8 90 32 36 e2 1d 05 15 c4 |.....Uh..26.....|
+00000030 d2 c6 2b 99 b3 22 fd 4a 15 82 34 93 f8 39 04 6c |..+..".J..4..9.l|
+00000040 e0 d1 c3 d3 16 77 dc 51 65 f9 ac 04 1d 38 8e e7 |.....w.Qe....8..|
+00000050 10 ee 22 c6 25 6b 20 e7 1d e7 89 c1 88 ee d9 80 |..".%k .........|
+00000060 29 45 83 64 12 a6 50 18 42 04 1f 34 15 35 24 f9 |)E.d..P.B..4.5$.|
+00000070 86 0b a0 be c6 4b 9b ab 7f 07 7f 74 09 78 56 77 |.....K.....t.xVw|
+00000080 72 ef 57 52 22 14 38 ee 70 e8 93 38 b0 cc cc 13 |r.WR".8.p..8....|
+00000090 fe 3f 04 a2 af 20 f4 cf f4 bc 22 76 54 9e 43 63 |.?... ...."vT.Cc|
+000000a0 e6 2d 77 c3 b8 b2 79 79 b8 89 86 9e 3c 01 c2 4b |.-w...yy....<..K|
+000000b0 a7 48 3c 7b 5d 74 6e 79 88 e1 3b 73 e0 04 57 20 |.H<{]tny..;s..W |
+000000c0 f7 36 c8 1a 9a 09 b2 77 20 6d 1b 7c 01 d2 6a 66 |.6.....w m.|..jf|
+000000d0 8e 9a 14 02 ef 7d 26 52 eb 50 93 56 77 d7 04 3b |.....}&R.P.Vw..;|
+000000e0 62 6f 9e 64 f4 f5 d6 83 f6 27 d8 37 05 cb dc 86 |bo.d.....'.7....|
+000000f0 df 7f 0a 7e bc 23 bf 5a b4 72 b9 5e 1c 8b b5 e8 |...~.#.Z.r.^....|
+00000100 b8 d7 3e a8 72 0a 2b c0 cc b0 6b a2 f9 5a db 1d |..>.r.+...k..Z..|
+00000110 ea 5a b1 28 d0 ad 0c db 91 45 b9 b7 cd 25 51 1b |.Z.(.....E...%Q.|
+00000120 47 e8 9e bf 25 6b 65 a9 c7 ed 39 a1 68 49 83 55 |G...%ke...9.hI.U|
+00000130 3c 74 36 dc 71 f6 38 72 20 94 53 bf fb 0a 1c b4 |<t6.q.8r .S.....|
+00000140 80 d0 18 94 08 0f f5 a1 22 ee 4c d8 c3 b5 fa c6 |........".L.....|
+00000150 2c 53 bd 48 35 77 d9 68 9f a7 96 6d 6a fa 8e 8b |,S.H5w.h...mj...|
+00000160 3e 13 1e 72 10 e0 0c cb 76 f9 0b 5a 2f a7 f1 63 |>..r....v..Z/..c|
+00000170 70 06 40 a8 57 46 c5 02 e1 74 71 2b e3 16 9e 6e |p.@.WF...tq+...n|
+00000180 54 00 cc f1 9b ab e5 89 88 f8 84 47 c4 8a da 4a |T..........G...J|
+00000190 62 d2 8d 64 8d 38 58 23 29 fa e9 41 c3 72 7b 3a |b..d.8X#)..A.r{:|
+000001a0 5c fa b4 f5 12 be 1f cc 35 92 ec 24 8b c4 78 ef |\.......5..$..x.|
+000001b0 3e db 36 a1 78 6c e6 51 a7 c4 1b fd bd 4d 6f b9 |>.6.xl.Q.....Mo.|
+000001c0 7d 51 c3 a5 e7 cb 2a 20 99 74 4e 1d 1a 4f 6d ce |}Q....* .tN..Om.|
+000001d0 fb 11 77 1c e5 20 f1 0e 38 8b 5e 6c af f4 98 63 |..w.. ..8.^l...c|
+000001e0 e7 38 1c 31 62 12 0e e7 13 4b b9 ec c0 8d 84 aa |.8.1b....K......|
+000001f0 1c 18 6e 4d 90 13 dc 01 a2 87 0e d8 b2 36 c1 d6 |..nM.........6..|
+00000200 03 f6 a0 4c 83 de 88 b2 4e 97 be 4f 75 7b fb 42 |...L....N..Ou{.B|
+00000210 84 e2 94 28 68 b0 37 4f bc 86 5d d4 74 84 15 53 |...(h.7O..].t..S|
+00000220 a8 c8 47 86 0e fc d0 54 59 81 cb a6 c1 37 3b 1a |..G....TY....7;.|
+00000230 2d a3 d7 2c 8c 23 f6 1f 0e 31 98 09 57 00 45 dc |-..,.#...1..W.E.|
+00000240 35 e7 8f a7 24 74 e6 b0 3a 40 8c be e3 ff 0b 08 |5...$t..:@......|
+00000250 3d c8 3d 84 ce 2c 1c 05 81 0c b5 83 8a de 2f 9f |=.=..,......../.|
+00000260 6a 83 88 a0 c2 9d 26 2d 0f 9e 40 33 48 b7 59 c3 |j.....&-..@3H.Y.|
+00000270 98 9c aa 3c 95 4b 86 35 02 91 dd 62 e0 2c 67 b6 |...<.K.5...b.,g.|
+00000280 65 33 09 dc b4 17 03 03 00 99 94 6d 12 c3 3d 58 |e3.........m..=X|
+00000290 0d 5d 8b 94 ba 26 20 97 12 a8 65 02 d1 d2 8c 8d |.]...& ...e.....|
+000002a0 82 cb eb fa b3 e8 72 8b f2 4f 17 c8 52 53 9e 83 |......r..O..RS..|
+000002b0 54 dc 84 37 be 3b 79 81 59 61 6f 67 ff cb c3 ae |T..7.;y.Yaog....|
+000002c0 a1 9f d9 b0 a9 9d d0 8a 55 1f 58 48 a8 c6 2e c9 |........U.XH....|
+000002d0 8e 79 6d 16 1b 68 db 45 40 84 a5 6a b1 fe a6 76 |.ym..h.E@..j...v|
+000002e0 de 22 c9 a9 9a 95 a2 1d 96 86 9e 79 8f ed 0f fb |.".........y....|
+000002f0 63 10 a0 d5 38 d5 78 e2 a6 6d 97 09 6e 17 1a 85 |c...8.x..m..n...|
+00000300 2b 51 a4 a8 59 a1 06 6b 89 37 1e 5a 99 a3 66 89 |+Q..Y..k.7.Z..f.|
+00000310 50 bc f7 49 e7 a9 82 da ec cf eb 33 76 af 65 76 |P..I.......3v.ev|
+00000320 a5 84 93 17 03 03 00 35 5d 1d 31 e0 3b 1f 3f d6 |.......5].1.;.?.|
+00000330 6c f9 55 6e 8f 86 1f 4f 85 a1 b5 3f c3 1e 3e ff |l.Un...O...?..>.|
+00000340 29 9c a7 1d 06 e9 de d2 98 d5 fb 37 2e e6 2e ba |)..........7....|
+00000350 b3 77 d0 d0 e6 ef 84 4e 05 14 47 2c 5e 17 03 03 |.w.....N..G,^...|
+00000360 00 17 80 d7 97 10 67 71 db aa 0f 6f 76 86 20 37 |......gq...ov. 7|
+00000370 0e a7 f1 53 71 c1 fe f7 09 17 03 03 00 13 79 a8 |...Sq.........y.|
+00000380 bd 36 37 a9 5b b0 57 de c7 ea 2e 71 25 62 81 ea |.67.[.W....q%b..|
+00000390 b5 |.|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-ECDSA b/src/crypto/tls/testdata/Client-TLSv13-ECDSA
new file mode 100644
index 0000000..b1d1e6a
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv13-ECDSA
@@ -0,0 +1,87 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 7a 02 00 00 76 03 03 be 96 55 22 ae |....z...v....U".|
+00000010 2e be 57 a1 0a 48 2e e3 ac 8e a7 d0 d5 a6 47 a9 |..W..H........G.|
+00000020 c4 11 bb e1 37 73 19 6b de 6b 2e 20 00 00 00 00 |....7s.k.k. ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 13 03 00 00 |................|
+00000050 2e 00 2b 00 02 03 04 00 33 00 24 00 1d 00 20 0f |..+.....3.$... .|
+00000060 ae 71 f3 56 39 91 5f 75 18 40 73 b7 82 b9 67 05 |.q.V9._u.@s...g.|
+00000070 09 d6 be 04 1f 66 b4 c4 18 1a 19 1d e7 bb 15 14 |.....f..........|
+00000080 03 03 00 01 01 17 03 03 00 17 7d 5b c9 52 40 79 |..........}[.R@y|
+00000090 4b 2b 2e b9 cb 7c 16 1b 2e df 3c e9 69 24 ea 47 |K+...|....<.i$.G|
+000000a0 7f 17 03 03 02 22 a0 a0 bf fa 2c 0c 99 08 ad 4d |....."....,....M|
+000000b0 03 05 54 93 67 8f 95 31 61 16 cb ef 2f 30 7f b8 |..T.g..1a.../0..|
+000000c0 f8 97 c9 7a a8 71 e8 f2 ab 73 51 c4 1c a5 f4 6c |...z.q...sQ....l|
+000000d0 54 6e f0 42 ae 58 25 84 de 9b e1 08 2a df ba 1e |Tn.B.X%.....*...|
+000000e0 e5 c7 8e 57 b8 a6 e4 6a c8 02 0d 77 e7 79 f7 a2 |...W...j...w.y..|
+000000f0 3a 18 f2 c5 f5 74 71 83 26 49 a6 2f 5c ac a4 a7 |:....tq.&I./\...|
+00000100 0d f3 65 5a a9 ed a0 f5 f1 ce c9 80 bc 75 f2 e7 |..eZ.........u..|
+00000110 68 11 b5 fb aa a8 e0 85 b9 37 b6 04 f6 f3 6d 8a |h........7....m.|
+00000120 ed 5c 0e 9a 25 52 f2 84 ca 2c 19 54 c1 0c 5e 24 |.\..%R...,.T..^$|
+00000130 e2 32 3e 99 18 84 17 84 8c 03 55 06 4f a0 ff 16 |.2>.......U.O...|
+00000140 89 9e 1e d4 75 1e 3f a5 4d 0b 24 41 bc ca 6e 48 |....u.?.M.$A..nH|
+00000150 77 53 e3 12 ee 00 69 11 19 c8 9b 43 b0 49 d3 a7 |wS....i....C.I..|
+00000160 48 69 08 d0 14 fa d1 2b d5 66 a3 40 b4 51 4b e3 |Hi.....+.f.@.QK.|
+00000170 f0 d3 c2 97 de 19 e8 02 66 9a ba 9f 59 7a 77 a4 |........f...Yzw.|
+00000180 d1 29 71 5f 60 04 f6 f2 f5 d6 ce df 6a 19 6d 6a |.)q_`.......j.mj|
+00000190 ae a5 df 25 d3 fb da 4c 54 d1 1e d8 68 59 d0 a8 |...%...LT...hY..|
+000001a0 3d 6a ce 84 57 0e 01 8f d6 f1 7f cd 9f 4c 26 ae |=j..W........L&.|
+000001b0 88 b5 af 31 b4 15 c0 bc 70 86 d4 7e 3f 7c 69 39 |...1....p..~?|i9|
+000001c0 ff db 74 5b 18 54 dc 55 ec 7f 60 c8 38 03 1f e8 |..t[.T.U..`.8...|
+000001d0 a0 9f 3b 79 12 ca c4 3f 41 d3 3d 80 88 a2 7e fa |..;y...?A.=...~.|
+000001e0 a1 5c f0 df 1b 61 73 e0 2a d3 d8 88 0e 22 20 09 |.\...as.*...." .|
+000001f0 62 42 3a 09 77 e5 39 c1 f2 a1 e5 29 f8 ab 4b de |bB:.w.9....)..K.|
+00000200 0c 3c 39 e8 13 34 73 d0 e3 25 39 bf f7 23 c4 1b |.<9..4s..%9..#..|
+00000210 06 c0 c4 16 80 14 15 a0 09 ac f0 fb 77 40 30 14 |............w@0.|
+00000220 07 5d 1c 34 58 90 27 53 3f da c5 2a 7d 0f b7 4c |.].4X.'S?..*}..L|
+00000230 15 09 ea cf f1 51 6c 84 3a f1 f7 d0 66 b8 fb 0c |.....Ql.:...f...|
+00000240 82 1e 86 2d 23 84 b8 d2 df d7 db a6 f2 7c da d8 |...-#........|..|
+00000250 e3 f8 a9 2c 0a fb 65 e8 2a 16 f6 c8 b7 dc b5 03 |...,..e.*.......|
+00000260 fd bc 76 67 c5 0a 9e 8a c6 89 04 b4 e1 5b 23 89 |..vg.........[#.|
+00000270 ca 03 73 4c e2 49 3e a8 ce c9 4c 0a 98 8c 78 b9 |..sL.I>...L...x.|
+00000280 12 d4 32 94 84 66 5a d3 07 78 df 74 00 d7 ca df |..2..fZ..x.t....|
+00000290 40 e6 b6 37 08 bc a8 fa 9a 28 e7 77 e2 78 39 d8 |@..7.....(.w.x9.|
+000002a0 e3 71 e5 2b f6 dc 9b 20 3e 38 77 80 f7 c9 e2 81 |.q.+... >8w.....|
+000002b0 07 4c 06 43 b7 b1 ff 1d f9 b4 24 ca ad db d3 f5 |.L.C......$.....|
+000002c0 3b 05 d8 0f 1e 6d 1a 6d 17 03 03 00 a4 fd 5d 1f |;....m.m......].|
+000002d0 1c 88 af a8 df 19 44 bd 80 81 78 fd 2d 84 ff a4 |......D...x.-...|
+000002e0 51 45 9a 98 7c 45 cb 84 2c fb 54 d1 33 06 67 e4 |QE..|E..,.T.3.g.|
+000002f0 95 f2 c5 5e 1b 49 41 b3 73 6c 5e 4d 2c 2d 77 1f |...^.IA.sl^M,-w.|
+00000300 59 cb 39 e9 87 3a 10 83 72 ab b3 ce f8 28 94 8f |Y.9..:..r....(..|
+00000310 47 8f 3d 2e 65 0a 42 b0 a5 13 61 bb 3b c7 a9 52 |G.=.e.B...a.;..R|
+00000320 cd 26 f6 ab c1 d3 3a a4 51 a6 7a 74 3b 76 19 ee |.&....:.Q.zt;v..|
+00000330 71 09 b6 b8 e6 3d 3e a3 df db a9 69 52 fe 66 3a |q....=>....iR.f:|
+00000340 dc 19 f6 56 ea 81 10 ab 43 2e e2 17 20 08 92 62 |...V....C... ..b|
+00000350 62 98 73 cb 16 9a 13 7d b3 b4 6a fd 18 28 25 05 |b.s....}..j..(%.|
+00000360 b2 3f e7 14 94 cf 9d 67 74 11 83 21 da d8 36 da |.?.....gt..!..6.|
+00000370 8e 17 03 03 00 35 89 67 70 a6 1c 3b 7c 59 59 23 |.....5.gp..;|YY#|
+00000380 92 33 ee 35 11 5d 8c fb bd f0 21 a4 8d 09 e3 e7 |.3.5.]....!.....|
+00000390 dd 96 8c ad cc 57 97 6a 4d 33 49 cc f6 c6 a9 4d |.....W.jM3I....M|
+000003a0 9b 3f 22 88 f5 06 b3 c2 a3 34 46 |.?"......4F|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 f4 b7 bd 05 e3 |..........5.....|
+00000010 04 c1 da 80 2f 16 6c 14 fe 7e bd 74 65 ab 76 e8 |..../.l..~.te.v.|
+00000020 7a 62 dc 89 11 10 ee 58 93 fc 30 0e 30 fa b6 a0 |zb.....X..0.0...|
+00000030 48 11 5d 78 9a fc 6b 44 1c 67 52 21 b4 b8 69 18 |H.]x..kD.gR!..i.|
+00000040 17 03 03 00 17 12 f2 ed 80 d2 91 8a bc 19 25 1d |..............%.|
+00000050 54 d6 56 04 b4 4d 1a 01 9f ea 7f 0c 17 03 03 00 |T.V..M..........|
+00000060 13 aa bb f9 4e 8f 2e 49 9c 07 65 31 8a 14 05 d8 |....N..I..e1....|
+00000070 d5 3a 83 23 |.:.#|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-Ed25519 b/src/crypto/tls/testdata/Client-TLSv13-Ed25519
new file mode 100644
index 0000000..e509e8a
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv13-Ed25519
@@ -0,0 +1,69 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 7a 02 00 00 76 03 03 41 71 01 fb 3b |....z...v..Aq..;|
+00000010 86 8b 75 5d 8d 98 1d 98 e7 19 0c 87 87 d0 a6 b5 |..u]............|
+00000020 5f 51 70 32 37 bc 58 b6 93 fb b1 20 00 00 00 00 |_Qp27.X.... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 13 03 00 00 |................|
+00000050 2e 00 2b 00 02 03 04 00 33 00 24 00 1d 00 20 17 |..+.....3.$... .|
+00000060 4e 27 d2 df c9 6d 88 15 a2 02 f2 fc 4d 87 65 92 |N'...m......M.e.|
+00000070 67 92 90 6c 8b e0 fb 27 2b d6 e8 e1 0e b2 7b 14 |g..l...'+.....{.|
+00000080 03 03 00 01 01 17 03 03 00 17 ef ca 93 ae 3b 4b |..............;K|
+00000090 ef ba c7 f1 44 89 61 b5 6c 05 c5 d9 59 4d 50 ab |....D.a.l...YMP.|
+000000a0 ff 17 03 03 01 50 71 7e a6 0b 61 c5 f1 b0 9b ab |.....Pq~..a.....|
+000000b0 3e 15 7a 0c ac 01 d7 cb 3e 04 85 e1 7a 59 95 92 |>.z.....>...zY..|
+000000c0 cb 91 5f 91 a4 e2 1b 6a d7 72 d5 ee 70 ae 51 ed |.._....j.r..p.Q.|
+000000d0 c7 78 ea 69 e5 a6 0b cc 72 43 6f 2e da c3 74 4c |.x.i....rCo...tL|
+000000e0 00 53 79 38 3b 10 7e 98 25 32 ad 7f e4 0b 9b ad |.Sy8;.~.%2......|
+000000f0 4a 5d f4 d9 a1 fe d6 ce 32 ff 2d 2e 26 49 78 3f |J]......2.-.&Ix?|
+00000100 4e 37 e9 c7 d3 af b7 4d 75 f2 71 f2 20 b8 28 64 |N7.....Mu.q. .(d|
+00000110 7c 0c 7a 3c f0 35 4e c6 ba 2d fc 76 53 a5 76 f9 ||.z<.5N..-.vS.v.|
+00000120 3e e3 4e 41 b9 52 e1 dc 62 9f 13 bf b7 ef c2 c1 |>.NA.R..b.......|
+00000130 ef 9c 04 4d 4c d0 20 e8 7e 62 bc 23 8a c0 02 62 |...ML. .~b.#...b|
+00000140 1d 8e c1 6f e0 23 70 0e 08 5c a0 47 92 40 5c 31 |...o.#p..\.G.@\1|
+00000150 d9 03 5b a5 9a dd 2f b9 4f 8a 4a 8d d9 c3 63 cb |..[.../.O.J...c.|
+00000160 61 16 3c be 9e dc 9d 11 bf c8 b9 5b 2d 69 5d 94 |a.<........[-i].|
+00000170 ef 6b 87 2d 59 42 05 51 88 9d 5a 8d bc ae 7c 65 |.k.-YB.Q..Z...|e|
+00000180 e2 a1 b5 eb c6 23 30 3c ab 52 f1 a3 90 77 1c a2 |.....#0<.R...w..|
+00000190 65 e0 ef 9c c7 1f b3 ad 7a 63 01 d9 b6 5c de c5 |e.......zc...\..|
+000001a0 3e ec b0 0c 1c 34 ea e1 8e d9 68 67 d8 1b 0c 94 |>....4....hg....|
+000001b0 4d 0a e1 e7 c7 4f 6e 03 c2 0f d6 4e 87 b9 e4 5c |M....On....N...\|
+000001c0 d6 d7 4a f0 90 fb 8c 56 ce 20 d3 09 db a2 3a 8f |..J....V. ....:.|
+000001d0 56 bc 1f 5d d8 0f ab 05 9c 2e 96 7e 09 bf 0f 45 |V..].......~...E|
+000001e0 81 83 81 63 d5 0e ef fb bd db 1d c8 17 4a ef d1 |...c.........J..|
+000001f0 ce 9d 76 c5 1c 3a 17 03 03 00 59 f8 6e 9b 48 45 |..v..:....Y.n.HE|
+00000200 96 86 f0 87 4f 95 75 72 90 16 ee 40 e6 a5 da d6 |....O.ur...@....|
+00000210 9a 93 5a f2 e1 14 c7 ef 99 5e 55 80 9c 2b a5 f0 |..Z......^U..+..|
+00000220 24 d0 0c b3 5c cd 7e 9f a7 8d 80 6d 24 0f 55 44 |$...\.~....m$.UD|
+00000230 25 23 04 30 0a b8 4b 87 81 7d f6 46 af a0 e9 6c |%#.0..K..}.F...l|
+00000240 ce cc 3b 8f 93 75 2b d3 65 84 0d fc 11 b3 49 93 |..;..u+.e.....I.|
+00000250 21 8c 12 28 17 03 03 00 35 11 5a 66 4d 6e f2 a1 |!..(....5.ZfMn..|
+00000260 d5 c7 e0 0d fb c0 23 72 61 40 56 c9 2b cf 19 91 |......#ra@V.+...|
+00000270 1e 9a 0b 20 65 dd f2 ec 54 f8 6a 6f a0 7f bf d2 |... e...T.jo....|
+00000280 92 e0 41 ae 8c a0 4e 33 be a0 f8 8e b3 c7 |..A...N3......|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 a6 8b c2 c6 31 |..........5....1|
+00000010 c1 73 78 0f f6 09 bb 09 d5 bc da 6b e6 21 e7 3e |.sx........k.!.>|
+00000020 19 ba 60 74 d4 32 71 37 a0 13 d8 ae e0 85 f7 71 |..`t.2q7.......q|
+00000030 d0 4e 2f 29 81 bb 8b 86 24 67 5b c9 b7 6e 6a 11 |.N/)....$g[..nj.|
+00000040 17 03 03 00 17 43 59 8a 71 7c f9 e8 b9 36 56 bc |.....CY.q|...6V.|
+00000050 07 67 34 1c f9 47 b0 fa 3a a0 15 9a 17 03 03 00 |.g4..G..:.......|
+00000060 13 dc 3e d0 92 97 41 13 06 65 b2 af e5 fa 16 d5 |..>...A..e......|
+00000070 9b 82 57 91 |..W.|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-ExportKeyingMaterial b/src/crypto/tls/testdata/Client-TLSv13-ExportKeyingMaterial
new file mode 100644
index 0000000..13ac4fc
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv13-ExportKeyingMaterial
@@ -0,0 +1,91 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 7a 02 00 00 76 03 03 5a a0 51 7e b3 |....z...v..Z.Q~.|
+00000010 75 e4 ba 57 52 a0 56 68 55 2b 40 16 e3 d4 b1 4f |u..WR.VhU+@....O|
+00000020 5e 2c a0 ab 31 76 e8 c5 ab ca 60 20 00 00 00 00 |^,..1v....` ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 13 03 00 00 |................|
+00000050 2e 00 2b 00 02 03 04 00 33 00 24 00 1d 00 20 1e |..+.....3.$... .|
+00000060 8e a4 e9 85 bd af 87 81 48 56 10 3d 4d d2 07 42 |........HV.=M..B|
+00000070 7f a2 db 93 42 98 df 67 6d 79 b3 fb 4f bb 67 14 |....B..gmy..O.g.|
+00000080 03 03 00 01 01 17 03 03 00 17 db c6 9e 4c ff 07 |.............L..|
+00000090 33 5a d9 47 e2 08 d5 10 bf 70 c5 5b 22 48 a7 fd |3Z.G.....p.["H..|
+000000a0 8d 17 03 03 02 6d cd a7 97 1c 26 3c a9 70 93 c5 |.....m....&<.p..|
+000000b0 98 ac 09 11 75 24 a1 97 4a a7 65 a0 d7 40 08 c9 |....u$..J.e..@..|
+000000c0 fd 31 5f 47 c3 95 38 cf cd e0 77 52 db c1 fe 3a |.1_G..8...wR...:|
+000000d0 2e 5f ae 5a 9a cf 96 5f 83 f5 7e 6b b0 d7 bf 27 |._.Z..._..~k...'|
+000000e0 bd 22 af a1 05 79 48 c7 56 e9 56 a9 4f 34 82 9c |."...yH.V.V.O4..|
+000000f0 41 c5 cf 72 d1 56 18 d4 fb d7 94 e1 72 9f 2a c0 |A..r.V......r.*.|
+00000100 2f 3b fe de 46 36 4f 0d 15 12 4d e2 2a fb 42 20 |/;..F6O...M.*.B |
+00000110 1e 7f 0f 50 be 56 10 2d 83 9f c0 c4 9e 0a 29 c4 |...P.V.-......).|
+00000120 07 a1 ba c0 70 d4 93 8a 27 a1 e2 00 98 11 3e 4e |....p...'.....>N|
+00000130 07 46 54 68 5a d2 e3 85 ca 6d 66 b1 28 d7 a3 c9 |.FThZ....mf.(...|
+00000140 cb 9b 5b 4c 94 4a 56 69 dc 6e ba 84 08 7e 31 14 |..[L.JVi.n...~1.|
+00000150 5d a0 e0 00 b2 23 63 fe 67 8c ae 75 56 44 9c 9c |]....#c.g..uVD..|
+00000160 c4 4c 31 a9 d7 df 3b ec 59 1e 2e 85 fd 08 8d ba |.L1...;.Y.......|
+00000170 b2 09 f6 3e 19 7b 29 ab 6a b3 5a 00 be 76 fb 39 |...>.{).j.Z..v.9|
+00000180 98 c4 3e 4b a6 ae 68 ba 6c 9a a6 5d 20 33 96 55 |..>K..h.l..] 3.U|
+00000190 27 66 aa c2 c0 6d f0 80 cc c7 64 5f 7b 42 56 b4 |'f...m....d_{BV.|
+000001a0 a2 6b a3 29 9a 49 d2 fc 74 53 21 fe e3 87 ab d9 |.k.).I..tS!.....|
+000001b0 e4 3e e7 8a a0 c6 49 08 d1 45 14 53 fb 28 39 cb |.>....I..E.S.(9.|
+000001c0 99 86 c2 3f dc b3 f6 86 a7 87 b2 88 d9 4f 62 d6 |...?.........Ob.|
+000001d0 d4 bb 84 93 56 5a 99 8e 8a 5b 1b 9a 1c ef 4a f1 |....VZ...[....J.|
+000001e0 85 62 08 1f 27 c2 20 a1 9c 73 91 05 d8 9b 32 90 |.b..'. ..s....2.|
+000001f0 74 80 08 dd 52 87 9f 6e c3 89 14 f3 23 0e 1f d0 |t...R..n....#...|
+00000200 3c e0 51 48 a4 b2 f2 43 05 bd a3 95 35 70 37 cc |<.QH...C....5p7.|
+00000210 89 f3 23 b7 70 5f 36 24 78 ea 21 ec 7c 06 3a d6 |..#.p_6$x.!.|.:.|
+00000220 b5 fd d1 c4 bb 32 39 78 6a f6 ed 91 83 c8 d4 bd |.....29xj.......|
+00000230 33 55 cf a8 5a b9 46 ec fa 87 5a c0 35 d1 f6 5e |3U..Z.F...Z.5..^|
+00000240 1f 7a 8e 82 e1 97 38 f9 ad 6e 00 ba d1 4b 82 dd |.z....8..n...K..|
+00000250 b0 87 0e 18 70 27 6c cd dd 0d d7 4b 46 e9 a3 dc |....p'l....KF...|
+00000260 5d 60 e7 eb a9 b4 99 f2 bc 9f a4 ed dc c6 63 24 |]`............c$|
+00000270 f8 91 f3 ee 7f 47 40 03 95 34 53 8c 38 90 3f 0f |.....G@..4S.8.?.|
+00000280 a6 d8 a1 a7 39 64 45 7e 9e 94 aa 3e 19 df 28 f1 |....9dE~...>..(.|
+00000290 ab 14 22 ce e8 80 a6 73 59 f7 92 85 13 20 6c cf |.."....sY.... l.|
+000002a0 d8 ff ce f4 5d 79 f8 37 38 b6 9f 81 97 9f 72 31 |....]y.78.....r1|
+000002b0 e0 fe ca d2 03 cd 3b 00 9f cb 55 a7 de 79 80 d8 |......;...U..y..|
+000002c0 0b ae 5a e6 a7 ba a5 35 da d3 03 95 56 c0 ac c9 |..Z....5....V...|
+000002d0 2a 36 cf 53 d0 44 48 b3 19 6c 44 ab 6b a1 7f a2 |*6.S.DH..lD.k...|
+000002e0 f6 18 90 4f 16 a9 d5 77 ef 01 81 e1 ef a7 b9 3f |...O...w.......?|
+000002f0 35 82 66 c7 9c 82 cc 00 fa 74 71 ed 99 ab fc d5 |5.f......tq.....|
+00000300 ce 0a 05 80 56 5f 54 79 a9 b2 82 38 af 52 94 d1 |....V_Ty...8.R..|
+00000310 7e 15 1e 17 03 03 00 99 94 6e e7 f3 9a a6 90 24 |~........n.....$|
+00000320 c8 59 16 e6 58 d1 a2 55 ab 90 d6 59 00 06 0f 22 |.Y..X..U...Y..."|
+00000330 2d 7e 1a 13 ce 64 05 a0 e2 a2 22 36 d4 51 69 ce |-~...d...."6.Qi.|
+00000340 8c 13 85 2e ad a3 9d c9 cf 50 be 06 db 75 41 1e |.........P...uA.|
+00000350 01 64 8e 55 13 31 42 a0 b9 90 30 75 a3 b5 a1 36 |.d.U.1B...0u...6|
+00000360 e8 1d 5f 32 f4 8f 68 f3 ca d9 f2 36 cf 77 2a ae |.._2..h....6.w*.|
+00000370 03 db 01 bb 51 25 bb 65 76 0a 81 bf db 6a 0a 85 |....Q%.ev....j..|
+00000380 3d 2a ee 71 ff a5 91 75 3f 44 23 31 70 1f b4 4c |=*.q...u?D#1p..L|
+00000390 a1 f2 ec cb ac bb de 36 3a 46 a6 3d a8 c5 57 92 |.......6:F.=..W.|
+000003a0 a4 7c d4 54 fa de b6 77 62 95 24 aa 63 70 4a 04 |.|.T...wb.$.cpJ.|
+000003b0 cb 17 03 03 00 35 07 18 23 d6 3d 11 1c 50 e1 22 |.....5..#.=..P."|
+000003c0 c7 83 33 84 c3 e1 30 b0 43 68 19 2b c4 43 95 25 |..3...0.Ch.+.C.%|
+000003d0 8c b7 37 c1 d0 3c ef f4 4f 29 b7 18 34 25 d2 8a |..7..<..O)..4%..|
+000003e0 44 52 37 4e ff f9 aa 2b 33 61 4a |DR7N...+3aJ|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 7d e0 1b 46 05 |..........5}..F.|
+00000010 4a e2 11 2c a4 22 62 cb bc e7 f4 11 d2 05 ca c6 |J..,."b.........|
+00000020 17 98 10 88 03 12 d1 1e 6a dc e8 bb 91 df 65 47 |........j.....eG|
+00000030 78 f0 32 d1 7d c0 56 92 78 56 6b 75 cc 2d eb 2d |x.2.}.V.xVku.-.-|
+00000040 17 03 03 00 17 ad cc 95 e5 1c 77 7c de 6f e8 8d |..........w|.o..|
+00000050 06 8e b6 8e d0 95 3f 71 0b 15 6e 0e 17 03 03 00 |......?q..n.....|
+00000060 13 8e 23 c7 75 9d f7 e1 b9 b5 ed 79 86 e0 64 68 |..#.u......y..dh|
+00000070 01 ef 70 e1 |..p.|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-HelloRetryRequest b/src/crypto/tls/testdata/Client-TLSv13-HelloRetryRequest
new file mode 100644
index 0000000..d6b570f
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv13-HelloRetryRequest
@@ -0,0 +1,119 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fa 01 00 00 f6 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7b 00 05 00 05 01 00 00 00 00 00 0a 00 |...{............|
+00000090 06 00 04 00 1d 00 17 00 0b 00 02 01 00 00 0d 00 |................|
+000000a0 1a 00 18 08 04 04 03 08 07 08 05 08 06 04 01 05 |................|
+000000b0 01 06 01 05 03 06 03 02 01 02 03 ff 01 00 01 00 |................|
+000000c0 00 17 00 00 00 12 00 00 00 2b 00 09 08 03 04 03 |.........+......|
+000000d0 03 03 02 03 01 00 33 00 26 00 24 00 1d 00 20 2f |......3.&.$... /|
+000000e0 e5 7d a3 47 cd 62 43 15 28 da ac 5f bb 29 07 30 |.}.G.bC.(.._.).0|
+000000f0 ff f6 84 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 |.........._X.;t|
+>>> 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 00 00 00 00 |..^......3. ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 13 03 00 00 |................|
+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 1b 01 00 01 17 03 |................|
+00000010 03 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 00 00 00 00 00 |................|
+00000030 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |. ..............|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000050 00 00 00 32 cc a9 cc a8 c0 2b c0 2f c0 2c c0 30 |...2.....+./.,.0|
+00000060 c0 09 c0 13 c0 0a c0 14 00 9c 00 9d 00 2f 00 35 |............./.5|
+00000070 c0 12 00 0a c0 23 c0 27 00 3c c0 07 c0 11 00 05 |.....#.'.<......|
+00000080 13 03 13 01 13 02 01 00 00 9c 00 05 00 05 01 00 |................|
+00000090 00 00 00 00 0a 00 06 00 04 00 1d 00 17 00 0b 00 |................|
+000000a0 02 01 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 |................|
+000000b0 05 08 06 04 01 05 01 06 01 05 03 06 03 02 01 02 |................|
+000000c0 03 ff 01 00 01 00 00 17 00 00 00 12 00 00 00 2b |...............+|
+000000d0 00 09 08 03 04 03 03 03 02 03 01 00 33 00 47 00 |............3.G.|
+000000e0 45 00 17 00 41 04 1e 18 37 ef 0d 19 51 88 35 75 |E...A...7...Q.5u|
+000000f0 71 b5 e5 54 5b 12 2e 8f 09 67 fd a7 24 20 3e b2 |q..T[....g..$ >.|
+00000100 56 1c ce 97 28 5e f8 2b 2d 4f 9e f1 07 9f 6c 4b |V...(^.+-O....lK|
+00000110 5b 83 56 e2 32 42 e9 58 b6 d7 49 a6 b5 68 1a 41 |[.V.2B.X..I..h.A|
+00000120 03 56 6b dc 5a 89 |.Vk.Z.|
+>>> Flow 4 (server to client)
+00000000 16 03 03 00 9b 02 00 00 97 03 03 4f 5c 5c 6c f2 |...........O\\l.|
+00000010 79 f3 d8 d4 be 78 c3 a4 b6 82 a5 ee 37 c3 a1 f7 |y....x......7...|
+00000020 87 83 ac 75 62 29 48 80 55 64 9b 20 00 00 00 00 |...ub)H.Ud. ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 13 03 00 00 |................|
+00000050 4f 00 2b 00 02 03 04 00 33 00 45 00 17 00 41 04 |O.+.....3.E...A.|
+00000060 be 02 77 b3 71 8c 25 30 15 18 cd 54 f8 99 b7 a4 |..w.q.%0...T....|
+00000070 1b 43 6e a5 bf 94 d3 7e 8f 07 4e 78 15 af 48 fe |.Cn....~..Nx..H.|
+00000080 14 60 0d f1 1b 31 f5 30 5b 37 34 da d2 b8 a9 43 |.`...1.0[74....C|
+00000090 5e 5e 9e 32 9c 7c 94 21 fc 1e db 0a b3 e1 f5 7a |^^.2.|.!.......z|
+000000a0 17 03 03 00 17 fc 15 53 2f 26 26 78 e5 5e 22 74 |.......S/&&x.^"t|
+000000b0 8a cb 74 2c f8 4c 04 5d 0b 53 d9 93 17 03 03 02 |..t,.L.].S......|
+000000c0 6d 58 f2 20 bc 2e 2b c7 67 79 b1 19 09 d8 73 9c |mX. ..+.gy....s.|
+000000d0 74 b4 55 b4 24 5e a3 66 f1 a3 81 55 cb 77 5e c1 |t.U.$^.f...U.w^.|
+000000e0 5e b1 ba 4e ff 29 6e 10 a3 9c 20 68 fb c1 35 a8 |^..N.)n... h..5.|
+000000f0 02 10 0e b6 b1 a1 84 d1 e4 41 92 15 93 ea 9c c1 |.........A......|
+00000100 93 4b 54 28 da 49 f5 eb a5 a5 92 3b 91 37 48 8a |.KT(.I.....;.7H.|
+00000110 4a 0a 3c 3a b9 10 2b 1b e8 33 4f e2 1b a4 e1 0e |J.<:..+..3O.....|
+00000120 4c 81 38 13 36 f2 87 e9 58 be e4 16 d9 eb 17 9d |L.8.6...X.......|
+00000130 61 69 7b 41 c9 29 99 bd b1 5b 66 49 3d f1 e5 6f |ai{A.)...[fI=..o|
+00000140 e4 91 a1 48 a3 89 91 00 8c 33 2c 0b 07 82 10 26 |...H.....3,....&|
+00000150 fb 7b c6 b0 64 56 1b 2b 1f 21 3a be 72 6d 9b fe |.{..dV.+.!:.rm..|
+00000160 ad bd 1c 59 05 38 9b 27 88 55 76 88 45 cf 03 be |...Y.8.'.Uv.E...|
+00000170 2a 8d 5f a6 39 1f 5e b7 1c 68 28 60 f5 cb e4 5e |*._.9.^..h(`...^|
+00000180 08 6c 3c 85 72 6f 31 26 30 0c 25 94 0e 4d 5b 5b |.l<.ro1&0.%..M[[|
+00000190 46 ba 0e 27 e1 17 3d 68 95 7e 2f a4 a0 16 54 e2 |F..'..=h.~/...T.|
+000001a0 35 3b a5 79 c8 45 2d e0 57 33 02 4e 81 bd dc 6a |5;.y.E-.W3.N...j|
+000001b0 9b b7 1e a8 9e ff 75 7f 11 47 9c ac 60 05 bd 9d |......u..G..`...|
+000001c0 59 2b 92 5a 94 f4 ca 8f 3e 53 b3 8a a5 ab 28 e2 |Y+.Z....>S....(.|
+000001d0 9f ed 29 f2 8b c7 82 92 86 d8 12 71 b1 97 24 26 |..)........q..$&|
+000001e0 f5 96 fc 16 a8 ff 39 1c 87 62 ec 4a b4 c3 03 13 |......9..b.J....|
+000001f0 e8 17 57 6b 48 6c 08 08 b0 6d 1f 1a 8c 1f 48 66 |..WkHl...m....Hf|
+00000200 aa 51 38 59 ac 1e 58 e7 ff 85 e1 60 e0 e5 42 65 |.Q8Y..X....`..Be|
+00000210 9e ff ab 65 bb 06 b2 8b c6 f2 95 ad 3c eb c7 1c |...e........<...|
+00000220 d6 2a 60 d3 e4 5f cb 65 ee 3d 45 75 93 53 eb 70 |.*`.._.e.=Eu.S.p|
+00000230 5c f4 ae 5c 6b e0 f1 6d 2c fe 88 cb 32 b4 53 90 |\..\k..m,...2.S.|
+00000240 c5 5b 9e 8c de 08 ff 49 86 2a a5 ef 59 50 f8 68 |.[.....I.*..YP.h|
+00000250 2a 3b e5 44 2a e8 7d c9 6e 5c c1 4f 99 d7 2b 67 |*;.D*.}.n\.O..+g|
+00000260 98 72 38 64 b3 e9 64 95 c1 1c 9d 5c 82 d9 e7 1e |.r8d..d....\....|
+00000270 ac cf 12 05 d8 da eb 75 69 e3 fb 08 c3 c7 d2 2d |.......ui......-|
+00000280 aa 3f 9d cc b7 31 b5 03 59 67 03 32 6f ed bc 87 |.?...1..Yg.2o...|
+00000290 47 c6 69 79 23 98 94 b7 4a 58 5f 68 5c 14 77 b5 |G.iy#...JX_h\.w.|
+000002a0 4b db 6e d9 c2 74 d0 8a 94 a6 3f 61 7a 1d b8 53 |K.n..t....?az..S|
+000002b0 c7 fb 1c d7 b7 ae 2b f2 c7 fc ed c3 77 47 8a be |......+.....wG..|
+000002c0 c4 0a e2 3a da f6 f0 06 15 df 32 06 5e 81 17 aa |...:......2.^...|
+000002d0 25 5c b0 56 56 ce 93 11 42 4d b1 b5 b5 d4 c9 47 |%\.VV...BM.....G|
+000002e0 df 7c 44 ac 23 bc 49 f6 aa f8 9a e3 fc 4e 7e 11 |.|D.#.I......N~.|
+000002f0 e5 da cc 0e c3 4e 57 5e 0d 7c 5a 98 e8 25 65 2e |.....NW^.|Z..%e.|
+00000300 d0 9e 73 f1 eb 16 3b c4 bc 87 97 37 38 45 a0 77 |..s...;....78E.w|
+00000310 79 37 30 aa 05 0a 42 04 e2 e3 09 ce 5b d7 04 c1 |y70...B.....[...|
+00000320 b1 c4 89 bc 5d 92 eb 9a a2 b4 12 87 98 05 17 03 |....]...........|
+00000330 03 00 99 0d 23 22 ba 58 d1 0a 8d 15 c6 ab 47 92 |....#".X......G.|
+00000340 4b ab 8b 31 d3 cd f6 c9 17 31 62 e2 4f 78 3d 87 |K..1.....1b.Ox=.|
+00000350 9f f9 54 10 4b db 86 99 dd eb e7 75 9d d1 dc 1c |..T.K......u....|
+00000360 03 e2 b2 ae 61 69 66 33 e0 0f 95 4a 41 4f 36 6d |....aif3...JAO6m|
+00000370 ed bd 80 51 8b 6c 92 dc 29 af 8d 17 12 b8 3d d7 |...Q.l..).....=.|
+00000380 db 05 63 4f ad e5 6e 32 5b 02 27 f6 8f e3 7c 02 |..cO..n2[.'...|.|
+00000390 15 c8 5e c8 f3 14 45 7c 2f 2d 81 aa ec 01 4f 12 |..^...E|/-....O.|
+000003a0 f3 aa c8 e5 ca 52 62 41 7d ca f2 9e 40 c3 36 d3 |.....RbA}...@.6.|
+000003b0 d8 40 be 59 0c 6a 67 aa 75 03 1c b7 b7 4b 21 3f |.@.Y.jg.u....K!?|
+000003c0 13 28 10 e7 3f a1 25 1a 5d e4 a0 b9 17 03 03 00 |.(..?.%.].......|
+000003d0 35 93 e3 71 c4 3b b0 4a 37 6d 1a 97 a5 c4 17 c4 |5..q.;.J7m......|
+000003e0 cd 0c a0 f5 bb 06 1d 0c f6 0f c4 c3 de b9 0a b7 |................|
+000003f0 37 9c d6 d4 43 a6 37 78 76 69 31 33 ed d8 db b4 |7...C.7xvi13....|
+00000400 3a ac cc 0d db 1b |:.....|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 35 ee c2 44 be 17 16 64 cc e6 68 9b |....5..D...d..h.|
+00000010 4d 75 86 c5 b5 9b f3 1c 7c b5 98 3f 9c 7b 07 65 |Mu......|..?.{.e|
+00000020 53 f1 6c d9 cd 17 54 3f 64 d3 ca 47 9c 1e 2d 13 |S.l...T?d..G..-.|
+00000030 fa 29 5e d8 91 5a 05 e8 03 21 17 03 03 00 17 41 |.)^..Z...!.....A|
+00000040 a1 aa 11 80 44 b8 26 a8 06 62 46 65 59 35 0b 06 |....D.&..bFeY5..|
+00000050 8e bf 6c 02 9d 5f 17 03 03 00 13 40 6d 8b 65 c6 |..l.._.....@m.e.|
+00000060 9c 9d b1 ec 29 f3 3d 23 56 28 f6 5a 5b e3 |....).=#V(.Z[.|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-KeyUpdate b/src/crypto/tls/testdata/Client-TLSv13-KeyUpdate
new file mode 100644
index 0000000..02c0a1a
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv13-KeyUpdate
@@ -0,0 +1,103 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 fe 01 00 00 fa 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 7f 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 0a 00 08 00 1d 00 17 00 18 00 19 00 0b 00 02 01 |................|
+000000a0 00 00 0d 00 1a 00 18 08 04 04 03 08 07 08 05 08 |................|
+000000b0 06 04 01 05 01 06 01 05 03 06 03 02 01 02 03 ff |................|
+000000c0 01 00 01 00 00 17 00 00 00 12 00 00 00 2b 00 09 |.............+..|
+000000d0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000e0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+000000f0 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000100 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 7a 02 00 00 76 03 03 70 a7 d4 99 55 |....z...v..p...U|
+00000010 7d 12 fd ca 3a 43 97 78 16 66 c2 bd 22 8b 6c 91 |}...:C.x.f..".l.|
+00000020 85 92 99 76 c8 4c 0f 4c dc 94 0b 20 00 00 00 00 |...v.L.L... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 13 03 00 00 |................|
+00000050 2e 00 2b 00 02 03 04 00 33 00 24 00 1d 00 20 df |..+.....3.$... .|
+00000060 af ca 9c 12 9b 83 69 24 89 3e 44 fe 1c 31 dd 0d |......i$.>D..1..|
+00000070 3b 52 fd 8e b6 c6 7b 05 9e d4 cc 62 a5 f0 27 14 |;R....{....b..'.|
+00000080 03 03 00 01 01 17 03 03 00 17 a8 47 c6 45 41 bc |...........G.EA.|
+00000090 7e e3 fb 85 43 5d 6a 69 07 7f 62 05 9d 9e 5f 1f |~...C]ji..b..._.|
+000000a0 9a 17 03 03 02 6d 7d 46 ba ff 8a 8a 3d a2 d0 29 |.....m}F....=..)|
+000000b0 1e 0d 18 03 84 13 03 de cf 64 15 28 71 9a bb 80 |.........d.(q...|
+000000c0 d0 4f de 07 d8 f4 47 d5 78 1c 93 e1 50 27 70 81 |.O....G.x...P'p.|
+000000d0 34 c2 0d 63 ee 76 20 dd c7 34 71 e5 c7 04 91 62 |4..c.v ..4q....b|
+000000e0 06 73 5c 71 e9 ce 13 f9 1c 5b 29 b5 16 64 0f 5b |.s\q.....[)..d.[|
+000000f0 35 53 0d ba a6 26 1c 98 fa 20 41 a0 08 b1 d1 74 |5S...&... A....t|
+00000100 cd 00 92 7e b4 ce 0e b8 2a 6d e0 25 57 2f e1 af |...~....*m.%W/..|
+00000110 2c 23 03 03 1d b6 98 70 ec 7d 57 a9 6c 8f 25 3d |,#.....p.}W.l.%=|
+00000120 63 a3 0e 53 b2 15 8d 1d 62 14 04 50 a9 bc ab 7d |c..S....b..P...}|
+00000130 ac fa 6a 68 ed f0 72 fd 9a 04 ac bd 44 10 a6 f0 |..jh..r.....D...|
+00000140 df 55 30 54 eb a1 c8 27 4d 6d 97 a1 c0 fc ca a5 |.U0T...'Mm......|
+00000150 c0 9c b8 29 53 13 f2 c8 81 f1 3d f8 35 e5 8d b0 |...)S.....=.5...|
+00000160 d9 c1 68 31 80 4f fb 3a 7a fc 20 ce 75 22 dc f6 |..h1.O.:z. .u"..|
+00000170 94 e9 ff c4 5a c2 1d e9 a2 55 11 df 5d 29 92 17 |....Z....U..])..|
+00000180 5e 9d df 16 97 e3 f0 d0 b6 bd 88 cf 5f 53 e5 da |^..........._S..|
+00000190 08 98 37 ec d5 1d 8b 4b 59 33 6e 67 d7 e5 eb 9e |..7....KY3ng....|
+000001a0 31 90 6b 75 c7 41 7c 1d 84 c3 78 03 0e 2b ce 5c |1.ku.A|...x..+.\|
+000001b0 9a c2 e8 20 7c 8e bc 4a 6e e6 b9 30 ff b3 c0 33 |... |..Jn..0...3|
+000001c0 73 91 f7 b6 13 bc 2c 85 97 ed a6 23 ed c1 e0 ce |s.....,....#....|
+000001d0 8a 67 9a a3 b2 80 bb 06 ea 9c ec cd 27 f6 1f ae |.g..........'...|
+000001e0 22 6e e4 c6 ec 5d e3 d9 99 8d 5e 15 5c d0 f1 83 |"n...]....^.\...|
+000001f0 f2 dc 20 a0 67 ee e0 94 05 e3 d7 e9 a2 65 ae d8 |.. .g........e..|
+00000200 da 12 2a db cd 2b 31 c3 ec 12 5b e0 5e 48 66 00 |..*..+1...[.^Hf.|
+00000210 d9 f5 b8 28 1f ef 90 e8 8f a7 78 d7 1c 49 1d 10 |...(......x..I..|
+00000220 d0 79 08 23 12 e1 30 91 7f 26 43 e2 0d dd 0f 6b |.y.#..0..&C....k|
+00000230 ca ac 25 5f 18 86 40 fd 04 50 f6 dc fb 25 e4 67 |..%_..@..P...%.g|
+00000240 d5 94 fe 3a 55 7f 0e 63 31 f2 96 40 cd 61 c4 e1 |...:U..c1..@.a..|
+00000250 06 bc 5f 80 e9 1d 69 7c 70 7e e6 7f 25 00 75 ce |.._...i|p~..%.u.|
+00000260 49 e4 bc 4c f4 79 8a d7 67 f3 50 a3 85 d2 96 cb |I..L.y..g.P.....|
+00000270 51 f4 99 93 d6 20 cf 0d 5f 2d 87 83 df 7b d2 76 |Q.... .._-...{.v|
+00000280 da 9c 47 fb 08 80 43 8e 1f c7 db 8e a9 a7 d5 bb |..G...C.........|
+00000290 a3 af 0a 3e a3 a3 8c eb eb e0 93 45 56 a3 eb f0 |...>.......EV...|
+000002a0 6e cd be 8f 42 4c aa 39 36 0e f2 d6 cc 37 ce a4 |n...BL.96....7..|
+000002b0 31 c0 e0 24 3e 52 8c 3f dc 6e 73 e0 0e ef 54 b7 |1..$>R.?.ns...T.|
+000002c0 27 2f 80 f8 16 0b 27 ea 73 66 c1 59 0b 91 a6 ae |'/....'.sf.Y....|
+000002d0 f9 d7 d3 60 c0 b0 da 0f 83 19 c2 e0 6e e0 d0 a6 |...`........n...|
+000002e0 87 74 91 f8 6c 46 e3 cd 3a 4c e5 ee 48 94 5b bc |.t..lF..:L..H.[.|
+000002f0 e4 b5 ed 35 ba 11 c7 0d 76 e9 0a 52 11 a1 35 c2 |...5....v..R..5.|
+00000300 e3 c3 9d fa 9d 9b 45 59 6a de 5b 9c c8 7e c3 00 |......EYj.[..~..|
+00000310 16 06 d9 17 03 03 00 99 63 23 47 37 41 24 5e b5 |........c#G7A$^.|
+00000320 7a 9d 0c 74 c7 f8 c8 62 9e c1 8a 44 29 22 d0 96 |z..t...b...D)"..|
+00000330 c7 94 a1 c5 f6 80 1f 23 70 d5 61 cf b5 87 41 26 |.......#p.a...A&|
+00000340 74 74 9b f4 1c 9d eb b3 da 39 0f 93 74 6a 2d 44 |tt.......9..tj-D|
+00000350 b2 04 31 c0 b0 e8 27 1e eb 6e 1d 76 aa a7 15 11 |..1...'..n.v....|
+00000360 fd 5a 46 68 e2 76 ec 92 fe 25 41 10 0f 99 da cf |.ZFh.v...%A.....|
+00000370 1a 04 a2 09 8e a1 73 ca 74 7e f7 d2 0e f1 cf 74 |......s.t~.....t|
+00000380 14 c4 bc 66 6e 28 58 24 09 cb bc da 4d da 4f af |...fn(X$....M.O.|
+00000390 b8 c5 18 37 34 02 e2 60 b9 cc e9 4b 93 08 0a 22 |...74..`...K..."|
+000003a0 b6 a1 85 b2 ab cd 9c b6 1b 1d 18 46 63 4c 11 c5 |...........FcL..|
+000003b0 67 17 03 03 00 35 10 30 1b 3e 00 ea 4a 8a ab f7 |g....5.0.>..J...|
+000003c0 19 f8 3b 99 5f 56 a6 a3 ed dd 43 33 d9 8f 17 30 |..;._V....C3...0|
+000003d0 f5 a9 fb cd df 5e 95 e8 ff 35 1d 8d de d2 48 5a |.....^...5....HZ|
+000003e0 af a1 b5 60 4f 75 98 58 1c 24 a1 |...`Ou.X.$.|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 a5 8d 0a 81 b7 |..........5.....|
+00000010 76 39 48 24 74 8a a8 f0 91 9b b7 10 14 e3 1f fe |v9H$t...........|
+00000020 a5 2f 96 6a 7a c3 9d 90 66 99 46 78 c8 d0 1d ba |./.jz...f.Fx....|
+00000030 34 be 04 c1 a9 4d 17 60 06 a8 04 18 f3 53 9b 33 |4....M.`.....S.3|
+00000040 17 03 03 00 17 14 2c cf 98 1c b3 44 d5 cb 9a 8a |......,....D....|
+00000050 46 84 e8 d2 7d 81 bf 74 e6 08 4b 1c |F...}..t..K.|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 16 3e c3 0e 81 bd 7c e9 21 c8 d1 3f |.....>....|.!..?|
+00000010 94 a9 37 43 21 42 3b 81 ba 65 53 |..7C!B;..eS|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 16 63 a6 48 59 77 ae a9 a7 40 e2 57 |.....c.HYw...@.W|
+00000010 9b 41 bb e8 14 06 01 46 71 46 77 |.A.....FqFw|
+>>> Flow 6 (server to client)
+00000000 17 03 03 00 1a 20 8a 20 30 bc 48 17 8f ed 57 bb |..... . 0.H...W.|
+00000010 e8 2a da 2a 21 5b 4d 11 74 13 32 6f 1c d6 7c |.*.*![M.t.2o..||
+>>> Flow 7 (client to server)
+00000000 17 03 03 00 1d fb 5b 0c dc f1 6b 02 a7 f6 68 21 |......[...k...h!|
+00000010 a4 5c 29 7e 52 08 5f 4d fb cb e4 a6 ae c9 e0 09 |.\)~R._M........|
+00000020 01 02 17 03 03 00 13 4e 79 eb 2d 97 87 45 9d 73 |.......Ny.-..E.s|
+00000030 6f 13 be c5 68 50 ef 03 4c 18 |o...hP..L.|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-P256-ECDHE b/src/crypto/tls/testdata/Client-TLSv13-P256-ECDHE
new file mode 100644
index 0000000..7280daf
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv13-P256-ECDHE
@@ -0,0 +1,94 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 01 19 01 00 01 15 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 9a 00 05 00 05 01 00 00 00 00 00 0a 00 |................|
+00000090 04 00 02 00 17 00 0b 00 02 01 00 00 0d 00 1a 00 |................|
+000000a0 18 08 04 04 03 08 07 08 05 08 06 04 01 05 01 06 |................|
+000000b0 01 05 03 06 03 02 01 02 03 ff 01 00 01 00 00 17 |................|
+000000c0 00 00 00 12 00 00 00 2b 00 09 08 03 04 03 03 03 |.......+........|
+000000d0 02 03 01 00 33 00 47 00 45 00 17 00 41 04 1e 18 |....3.G.E...A...|
+000000e0 37 ef 0d 19 51 88 35 75 71 b5 e5 54 5b 12 2e 8f |7...Q.5uq..T[...|
+000000f0 09 67 fd a7 24 20 3e b2 56 1c ce 97 28 5e f8 2b |.g..$ >.V...(^.+|
+00000100 2d 4f 9e f1 07 9f 6c 4b 5b 83 56 e2 32 42 e9 58 |-O....lK[.V.2B.X|
+00000110 b6 d7 49 a6 b5 68 1a 41 03 56 6b dc 5a 89 |..I..h.A.Vk.Z.|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 9b 02 00 00 97 03 03 fe 3a 17 76 b0 |............:.v.|
+00000010 7f a1 ed 8e fa 88 7a c6 d0 78 62 83 db b8 a3 72 |......z..xb....r|
+00000020 77 c7 18 54 f3 07 3b 08 f0 fb be 20 00 00 00 00 |w..T..;.... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 13 03 00 00 |................|
+00000050 4f 00 2b 00 02 03 04 00 33 00 45 00 17 00 41 04 |O.+.....3.E...A.|
+00000060 e2 a0 62 23 50 9d 82 7d bc f4 f4 e7 ed d0 6c 6e |..b#P..}......ln|
+00000070 f2 46 f4 e6 11 5f e0 f3 02 e3 13 67 e3 92 da 39 |.F..._.....g...9|
+00000080 15 a2 3a c7 80 16 e6 25 fd 86 59 56 08 ee 78 eb |..:....%..YV..x.|
+00000090 d9 ba 36 69 d3 fe bc fc 92 a1 1b 48 a1 a5 6c 09 |..6i.......H..l.|
+000000a0 14 03 03 00 01 01 17 03 03 00 17 0f 26 b2 e7 86 |............&...|
+000000b0 1a 6f e5 19 28 d1 0c 5f 4d 45 7e e6 9f f8 16 03 |.o..(.._ME~.....|
+000000c0 d2 71 17 03 03 02 6d 2e bc 2a 2c eb e1 97 06 37 |.q....m..*,....7|
+000000d0 87 39 bf f1 79 3a ba 23 51 26 37 a1 ba 2c 30 d9 |.9..y:.#Q&7..,0.|
+000000e0 65 f8 8e 54 b7 1a 8a ff e8 eb 50 ab f4 e5 0f 07 |e..T......P.....|
+000000f0 94 6b 3d 40 2f bc f7 1c 51 b7 6a 22 78 da 4c ab |.k=@/...Q.j"x.L.|
+00000100 74 2b b5 f9 c5 2f f5 b8 8a c0 3b c3 56 d8 79 94 |t+.../....;.V.y.|
+00000110 d7 2c bc 7e 2d a8 aa 7d 93 1e 24 49 34 a2 c8 83 |.,.~-..}..$I4...|
+00000120 fc 0e b2 c7 f8 15 9c fd 6f 67 d8 32 e4 ce e6 c2 |........og.2....|
+00000130 a5 ae c2 8b 40 dd b5 46 dc b9 40 e1 21 47 0e 55 |....@..F..@.!G.U|
+00000140 7b f5 87 35 6d 10 22 04 a3 4f f8 95 54 0c 41 a6 |{..5m."..O..T.A.|
+00000150 95 7b 0e 96 4b 73 c2 75 c9 87 ce a9 89 06 a9 7a |.{..Ks.u.......z|
+00000160 26 ec 81 70 48 4d 24 f4 09 00 aa 92 ac a2 77 9d |&..pHM$.......w.|
+00000170 ad aa 18 0f e0 f7 91 c9 80 46 c2 db e7 87 fd 3d |.........F.....=|
+00000180 f2 8f ee cb 26 7d ae 1f 17 6e d0 d4 cd 11 80 a2 |....&}...n......|
+00000190 57 57 88 78 2e 32 ac 2f 1c ad 5b 86 d2 94 55 9f |WW.x.2./..[...U.|
+000001a0 cd 41 b7 cf 6d bb 45 6a 0b 72 79 91 81 1a 79 b3 |.A..m.Ej.ry...y.|
+000001b0 6e 7f f4 8a 7b c0 b0 a6 00 0e c0 fe 67 4e e3 96 |n...{.......gN..|
+000001c0 5b 0f 1b 47 b5 43 94 91 e9 c4 5f 0b 04 46 bd 53 |[..G.C...._..F.S|
+000001d0 f0 44 a9 0c 46 39 d0 e0 9c 25 76 4e 26 f4 49 12 |.D..F9...%vN&.I.|
+000001e0 42 7a a7 19 98 f0 93 1f 42 78 c7 1c 87 f0 92 ab |Bz......Bx......|
+000001f0 ec 8b f9 4f e3 60 ea fd 88 b5 9d 68 18 59 60 ee |...O.`.....h.Y`.|
+00000200 66 a9 0a 24 33 4a 9f c1 c0 e1 70 a0 c3 b1 8d f5 |f..$3J....p.....|
+00000210 4a eb 5e f6 8f a9 2f c7 df 88 40 41 61 b3 3e 18 |J.^.../...@Aa.>.|
+00000220 66 f7 e1 b7 a6 a9 3a 10 73 ab a4 ce 39 40 8a 78 |f.....:.s...9@.x|
+00000230 47 7f bc c9 08 c3 f0 0e 1e 09 87 bf fc e0 46 38 |G.............F8|
+00000240 e7 79 4e 9e 50 94 e7 94 ab 54 47 a7 07 7f 9d 7c |.yN.P....TG....||
+00000250 9e 83 9b ba dd 33 5d de db 80 9f a0 7d 9f c3 57 |.....3].....}..W|
+00000260 83 45 0d a6 82 61 75 b7 14 54 0c 7e 94 8a fb 4a |.E...au..T.~...J|
+00000270 9b 62 bf 8f ae 37 76 23 a0 e0 c0 e0 c1 2c 53 28 |.b...7v#.....,S(|
+00000280 4c 5b b7 b3 c1 4e bb e5 cd e8 b0 7b 8e 38 b0 bb |L[...N.....{.8..|
+00000290 74 d2 00 63 b4 7b 97 a3 48 52 0f f2 60 0c 0b e4 |t..c.{..HR..`...|
+000002a0 b4 0f 1c 9c 97 e1 fa ff 26 61 f8 3c ee 41 66 f8 |........&a.<.Af.|
+000002b0 b3 91 cd 30 bd ef 81 cf 23 3a ea fd b8 96 b6 e3 |...0....#:......|
+000002c0 bd 32 f2 0f 7a 3d 08 2c 50 a4 16 4e a6 2b 6b 2e |.2..z=.,P..N.+k.|
+000002d0 3e 7e a0 bc 10 c2 3c 30 65 fc 26 cd 2b 51 54 27 |>~....<0e.&.+QT'|
+000002e0 29 62 eb 99 bb 0b f8 29 ce 8a 21 87 c1 8e f8 6c |)b.....)..!....l|
+000002f0 17 fe 96 08 db 03 ef 22 ab 2a 55 8e 11 15 19 97 |.......".*U.....|
+00000300 66 9b f3 16 b4 ce 7c 29 f7 e0 ba 1a 14 46 42 20 |f.....|).....FB |
+00000310 38 8b 26 8a 53 13 83 a0 a5 76 2d 4c 3c 88 6e a0 |8.&.S....v-L<.n.|
+00000320 38 23 69 20 d1 3e c9 40 9b 46 4c 09 d9 50 80 49 |8#i .>.@.FL..P.I|
+00000330 bd 59 d9 ec 17 03 03 00 99 a2 f2 c7 ce c6 45 c8 |.Y............E.|
+00000340 45 9a 9d a8 83 d9 81 ff 2d ef 81 f9 b7 3d 0e 79 |E.......-....=.y|
+00000350 54 5f f4 ca f0 41 20 91 f7 5c 53 49 09 ee b6 27 |T_...A ..\SI...'|
+00000360 82 61 0f 1e b9 2d 0f 4e dd e7 3f 05 3c eb bc 2c |.a...-.N..?.<..,|
+00000370 81 ca 5d 2f e5 56 f8 ec e5 cb 69 da e9 16 79 ba |..]/.V....i...y.|
+00000380 61 8d a9 09 31 2f d3 4c 87 bf 6c 1a 50 df 81 cd |a...1/.L..l.P...|
+00000390 ba 4c 28 a1 47 05 13 65 f5 6d a0 fb 04 f6 5f 78 |.L(.G..e.m...._x|
+000003a0 d9 28 67 99 ee b9 a1 07 85 3c 5b 17 48 f3 87 43 |.(g......<[.H..C|
+000003b0 ca 40 12 59 85 34 da 67 8a 26 3e 0c 11 9f 42 82 |.@.Y.4.g.&>...B.|
+000003c0 81 80 56 5b a9 6f c2 73 9d 9a 5e ab 97 a2 a4 49 |..V[.o.s..^....I|
+000003d0 9f 73 17 03 03 00 35 7c 74 eb 0d 2b 2f b3 92 2e |.s....5|t..+/...|
+000003e0 54 12 f9 cb ae fb d4 8d 6f 7f 93 c5 bd 54 1d d5 |T.......o....T..|
+000003f0 06 71 bf 3f 43 71 7b ce 20 9d a9 12 bf dd 2c 3c |.q.?Cq{. .....,<|
+00000400 b5 7e 9d 3a 56 e3 8b d1 15 0e 69 35 |.~.:V.....i5|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 07 f8 0f 71 b3 |..........5...q.|
+00000010 74 36 f9 e0 2c a4 ac bc 9f 19 fc a7 aa 3d 8e cb |t6..,........=..|
+00000020 22 4b 8f 54 f3 4f b2 a5 85 8a c9 ab b0 b7 62 61 |"K.T.O........ba|
+00000030 58 dc 64 88 bb 43 6e 61 af 02 88 ca d8 15 b3 02 |X.d..Cna........|
+00000040 17 03 03 00 17 25 37 e4 43 40 29 dd 4b fd a6 22 |.....%7.C@).K.."|
+00000050 00 75 02 49 c6 64 a1 ed de ed 96 cb 17 03 03 00 |.u.I.d..........|
+00000060 13 d6 49 0b ba 13 f3 5b 80 63 79 c8 6a f6 2d df |..I....[.cy.j.-.|
+00000070 3f d3 2c 8b |?.,.|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-X25519-ECDHE b/src/crypto/tls/testdata/Client-TLSv13-X25519-ECDHE
new file mode 100644
index 0000000..b430ce0
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv13-X25519-ECDHE
@@ -0,0 +1,90 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 f8 01 00 00 f4 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 00 00 00 00 |........... ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 32 cc a9 |.............2..|
+00000050 cc a8 c0 2b c0 2f c0 2c c0 30 c0 09 c0 13 c0 0a |...+./.,.0......|
+00000060 c0 14 00 9c 00 9d 00 2f 00 35 c0 12 00 0a c0 23 |......./.5.....#|
+00000070 c0 27 00 3c c0 07 c0 11 00 05 13 03 13 01 13 02 |.'.<............|
+00000080 01 00 00 79 00 05 00 05 01 00 00 00 00 00 0a 00 |...y............|
+00000090 04 00 02 00 1d 00 0b 00 02 01 00 00 0d 00 1a 00 |................|
+000000a0 18 08 04 04 03 08 07 08 05 08 06 04 01 05 01 06 |................|
+000000b0 01 05 03 06 03 02 01 02 03 ff 01 00 01 00 00 17 |................|
+000000c0 00 00 00 12 00 00 00 2b 00 09 08 03 04 03 03 03 |.......+........|
+000000d0 02 03 01 00 33 00 26 00 24 00 1d 00 20 2f e5 7d |....3.&.$... /.}|
+000000e0 a3 47 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 |.G.bC.(.._.).0..|
+000000f0 84 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 |........_X.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 7a 02 00 00 76 03 03 94 fd 21 44 52 |....z...v....!DR|
+00000010 54 21 7e 4a 1c 83 6a ce c7 21 df b2 f3 1e 4c 73 |T!~J..j..!....Ls|
+00000020 d3 f0 8b cc 24 58 17 5c 9c 0c 28 20 00 00 00 00 |....$X.\..( ....|
+00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000040 00 00 00 00 00 00 00 00 00 00 00 00 13 03 00 00 |................|
+00000050 2e 00 2b 00 02 03 04 00 33 00 24 00 1d 00 20 a0 |..+.....3.$... .|
+00000060 72 12 62 31 e2 99 77 93 96 75 a3 64 33 87 33 ab |r.b1..w..u.d3.3.|
+00000070 be 61 78 45 34 c4 e7 14 d0 c1 3b cc bb cc 78 14 |.axE4.....;...x.|
+00000080 03 03 00 01 01 17 03 03 00 17 13 0e ae 6e fd 8b |.............n..|
+00000090 f0 27 06 82 41 f5 68 63 1c 58 38 ad 3a 9e 59 4d |.'..A.hc.X8.:.YM|
+000000a0 49 17 03 03 02 6d d8 a3 1c 91 84 93 3d 8d 27 4e |I....m......=.'N|
+000000b0 70 a7 fd ac be cb 87 bc 20 19 ef c3 1a be ad b2 |p....... .......|
+000000c0 b2 9d 4a e8 00 31 81 e0 43 09 4a b4 90 cc 1a d5 |..J..1..C.J.....|
+000000d0 e9 47 56 64 cc e6 cc 3e fa a6 a9 8f 79 0c ea 47 |.GVd...>....y..G|
+000000e0 55 5c 29 1a 3c ce 32 ea 45 30 66 01 07 30 22 60 |U\).<.2.E0f..0"`|
+000000f0 a0 2b 63 40 29 18 a2 7f 81 bd af 6a dd a9 44 8f |.+c@)......j..D.|
+00000100 d3 e8 58 8d 63 11 00 e2 31 9f 98 3c 15 a0 8b 9e |..X.c...1..<....|
+00000110 61 12 df a8 87 b5 2e 81 41 ed 3b a6 12 77 05 69 |a.......A.;..w.i|
+00000120 09 d1 9d cb 56 ee 86 24 cc ac 4c ff 17 b6 99 a2 |....V..$..L.....|
+00000130 c9 22 8a 9c 07 b3 a6 72 aa 33 30 8e 42 18 1d af |.".....r.30.B...|
+00000140 73 a5 28 99 12 05 bd 5e 34 cc 72 9a e4 51 2d 46 |s.(....^4.r..Q-F|
+00000150 35 55 8d 7b f3 ce f5 50 43 70 f1 4a ea 92 eb bd |5U.{...PCp.J....|
+00000160 18 72 b4 e9 90 fe e2 18 64 61 20 02 18 78 e8 75 |.r......da ..x.u|
+00000170 33 00 ff cc 72 f2 89 0e fe 7d 7a 07 f8 64 95 6f |3...r....}z..d.o|
+00000180 0b 3b 76 96 8f c1 d9 9f 6b 1a 10 28 d7 94 36 dc |.;v.....k..(..6.|
+00000190 87 de f2 95 a3 f6 15 44 13 2e 0d 88 aa 86 10 38 |.......D.......8|
+000001a0 ff 5f 58 a9 b8 e0 b9 4c fb a6 bb 1f f5 f6 25 4c |._X....L......%L|
+000001b0 d5 ab bb 62 70 82 7f 47 5e 05 99 aa 1c d4 12 be |...bp..G^.......|
+000001c0 77 2c 67 a3 5f 6c 9f 93 37 36 5f 96 34 8e 22 9d |w,g._l..76_.4.".|
+000001d0 a4 5e 4f 8c ce 54 e7 ea 7c 40 f5 9b 20 84 2e 96 |.^O..T..|@.. ...|
+000001e0 32 37 6b 65 cf e8 0d cb 3b 54 67 32 ed f6 49 b9 |27ke....;Tg2..I.|
+000001f0 d0 4f 36 e6 8a 1c df 35 ee 8a be 3f 8f 5a c9 35 |.O6....5...?.Z.5|
+00000200 3d 1b 7e 78 e4 0a d6 f4 6d 3e 48 dc 0d 4e 03 47 |=.~x....m>H..N.G|
+00000210 81 db 60 a9 fb 17 8c 39 5e 7d 77 07 21 13 3b 53 |..`....9^}w.!.;S|
+00000220 f2 50 bb c3 16 37 24 b8 ef 4a 45 ad 3e ce 05 6a |.P...7$..JE.>..j|
+00000230 25 fa 27 05 c8 f9 c5 d5 c3 b0 82 a8 0c ca ef 66 |%.'............f|
+00000240 58 a4 51 85 ee 94 2a 07 d9 a4 e5 1a b9 b8 9d a1 |X.Q...*.........|
+00000250 42 ae 3c 01 dc c2 96 84 a6 bd e4 e2 e6 37 f4 16 |B.<..........7..|
+00000260 51 62 9c ce 26 d5 fe ce 69 7a f5 dd f2 b9 7c d5 |Qb..&...iz....|.|
+00000270 9f 9d f6 ca d2 a3 3b 9d 73 99 72 38 3b be 3e 93 |......;.s.r8;.>.|
+00000280 d1 81 19 76 10 25 5b f7 3b b9 c3 21 b5 ef 1b 09 |...v.%[.;..!....|
+00000290 a5 97 76 a2 b6 4e a7 9e 9c b5 0a 9a a4 99 ec 5c |..v..N.........\|
+000002a0 02 fc 1a 83 b8 a2 f1 a5 16 0f 09 7a 21 2b 75 cd |...........z!+u.|
+000002b0 23 b5 cc 29 d5 09 3a 5e 88 9b 6b 4f 41 30 2a 42 |#..)..:^..kOA0*B|
+000002c0 03 98 56 2b 19 da e0 6f 5b f0 ee b9 a0 3d 98 12 |..V+...o[....=..|
+000002d0 41 af 96 ee 1c ae 55 84 b4 c5 98 f7 50 a7 62 cd |A.....U.....P.b.|
+000002e0 d7 99 4f be c8 65 fa 64 a3 2b bd b2 cc 9a 96 89 |..O..e.d.+......|
+000002f0 bb 9a 78 8f 60 5f 37 12 96 28 21 3d b5 0f 9c 3e |..x.`_7..(!=...>|
+00000300 ce 74 8b 9a 66 f0 ef af 38 1e 07 8e ca 6f 5a 35 |.t..f...8....oZ5|
+00000310 c9 87 71 17 03 03 00 99 c1 76 e9 d2 52 3f 6d 1b |..q......v..R?m.|
+00000320 ca eb 7d 24 2e c9 12 1b 44 f0 9c 06 95 26 d0 a3 |..}$....D....&..|
+00000330 04 e1 f1 8f e4 c0 83 91 e2 cf da 6c a1 b3 87 05 |...........l....|
+00000340 18 ae f1 7f 8d d3 43 9a f9 a8 9e 73 89 1a 61 2d |......C....s..a-|
+00000350 4f 2b 33 0b fd c0 12 0e d2 32 06 52 26 99 1d ce |O+3......2.R&...|
+00000360 49 11 a2 ec 23 ad 7f 22 1f 6e c6 12 21 f3 56 1c |I...#..".n..!.V.|
+00000370 fe d1 32 dd 1f b5 36 5d e3 78 fb 9c 3e 74 00 aa |..2...6].x..>t..|
+00000380 9d fd 92 f8 45 f9 1f e8 c3 4d 89 a8 91 d0 6c 2c |....E....M....l,|
+00000390 4f 82 52 f4 43 b0 1b fa 16 75 a4 78 f9 24 d1 3a |O.R.C....u.x.$.:|
+000003a0 1e 6b 97 6f 0e 3d bb 34 b3 0a 83 2f 56 88 b8 0e |.k.o.=.4.../V...|
+000003b0 90 17 03 03 00 35 cd f0 e5 f9 3f 62 e7 67 25 5f |.....5....?b.g%_|
+000003c0 4f 11 d9 d9 d0 e3 3b 9a a9 c0 27 1d d3 a4 06 1f |O.....;...'.....|
+000003d0 8d 61 b4 38 aa fe fd f8 6c 10 57 b6 7d 9c 92 96 |.a.8....l.W.}...|
+000003e0 c9 70 c2 67 a7 76 7d bb ab 0e 2d |.p.g.v}...-|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 7d 7c fa 64 ea |..........5}|.d.|
+00000010 ba 90 be e8 a7 0c 0c 48 10 fc 2d ac 5e dd 1c cf |.......H..-.^...|
+00000020 e8 d3 d9 98 3b c2 2b 80 93 44 22 85 bf cb ec c6 |....;.+..D".....|
+00000030 4a 13 6d 68 80 22 8b af aa f4 7c de 6b 28 fe ef |J.mh."....|.k(..|
+00000040 17 03 03 00 17 4e bd e5 fe 5c 6b 9c bb 48 b8 23 |.....N...\k..H.#|
+00000050 55 0f f7 21 25 cb 4c ae 74 b7 54 a2 17 03 03 00 |U..!%.L.t.T.....|
+00000060 13 c8 35 e9 be f6 74 09 23 55 ec 78 05 83 89 38 |..5...t.#U.x...8|
+00000070 ee 1c b3 3e |...>|
diff --git a/src/crypto/tls/testdata/Server-TLSv10-ECDHE-ECDSA-AES b/src/crypto/tls/testdata/Server-TLSv10-ECDHE-ECDSA-AES
new file mode 100644
index 0000000..c5d947c
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv10-ECDHE-ECDSA-AES
@@ -0,0 +1,79 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 51 01 00 00 4d 03 01 5e bf ff e7 c2 |....Q...M..^....|
+00000010 c1 98 4a a3 cf 5a e8 8d 8f 19 9e 85 48 5b 92 cc |..J..Z......H[..|
+00000020 7d 0c 14 1e 2e 50 5b d7 dd fe ef 00 00 04 c0 0a |}....P[.........|
+00000030 00 ff 01 00 00 20 00 0b 00 04 03 00 01 02 00 0a |..... ..........|
+00000040 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 16 |................|
+00000050 00 00 00 17 00 00 |......|
+>>> Flow 2 (server to client)
+00000000 16 03 01 00 3b 02 00 00 37 03 01 00 00 00 00 00 |....;...7.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 44 4f 57 4e 47 52 44 00 00 c0 0a 00 00 |...DOWNGRD......|
+00000030 0f ff 01 00 01 00 00 17 00 00 00 0b 00 02 01 00 |................|
+00000040 16 03 01 02 0e 0b 00 02 0a 00 02 07 00 02 04 30 |...............0|
+00000050 82 02 00 30 82 01 62 02 09 00 b8 bf 2d 47 a0 d2 |...0..b.....-G..|
+00000060 eb f4 30 09 06 07 2a 86 48 ce 3d 04 01 30 45 31 |..0...*.H.=..0E1|
+00000070 0b 30 09 06 03 55 04 06 13 02 41 55 31 13 30 11 |.0...U....AU1.0.|
+00000080 06 03 55 04 08 13 0a 53 6f 6d 65 2d 53 74 61 74 |..U....Some-Stat|
+00000090 65 31 21 30 1f 06 03 55 04 0a 13 18 49 6e 74 65 |e1!0...U....Inte|
+000000a0 72 6e 65 74 20 57 69 64 67 69 74 73 20 50 74 79 |rnet Widgits Pty|
+000000b0 20 4c 74 64 30 1e 17 0d 31 32 31 31 32 32 31 35 | Ltd0...12112215|
+000000c0 30 36 33 32 5a 17 0d 32 32 31 31 32 30 31 35 30 |0632Z..221120150|
+000000d0 36 33 32 5a 30 45 31 0b 30 09 06 03 55 04 06 13 |632Z0E1.0...U...|
+000000e0 02 41 55 31 13 30 11 06 03 55 04 08 13 0a 53 6f |.AU1.0...U....So|
+000000f0 6d 65 2d 53 74 61 74 65 31 21 30 1f 06 03 55 04 |me-State1!0...U.|
+00000100 0a 13 18 49 6e 74 65 72 6e 65 74 20 57 69 64 67 |...Internet Widg|
+00000110 69 74 73 20 50 74 79 20 4c 74 64 30 81 9b 30 10 |its Pty Ltd0..0.|
+00000120 06 07 2a 86 48 ce 3d 02 01 06 05 2b 81 04 00 23 |..*.H.=....+...#|
+00000130 03 81 86 00 04 00 c4 a1 ed be 98 f9 0b 48 73 36 |.............Hs6|
+00000140 7e c3 16 56 11 22 f2 3d 53 c3 3b 4d 21 3d cd 6b |~..V.".=S.;M!=.k|
+00000150 75 e6 f6 b0 dc 9a df 26 c1 bc b2 87 f0 72 32 7c |u......&.....r2||
+00000160 b3 64 2f 1c 90 bc ea 68 23 10 7e fe e3 25 c0 48 |.d/....h#.~..%.H|
+00000170 3a 69 e0 28 6d d3 37 00 ef 04 62 dd 0d a0 9c 70 |:i.(m.7...b....p|
+00000180 62 83 d8 81 d3 64 31 aa 9e 97 31 bd 96 b0 68 c0 |b....d1...1...h.|
+00000190 9b 23 de 76 64 3f 1a 5c 7f e9 12 0e 58 58 b6 5f |.#.vd?.\....XX._|
+000001a0 70 dd 9b d8 ea d5 d7 f5 d5 cc b9 b6 9f 30 66 5b |p............0f[|
+000001b0 66 9a 20 e2 27 e5 bf fe 3b 30 09 06 07 2a 86 48 |f. .'...;0...*.H|
+000001c0 ce 3d 04 01 03 81 8c 00 30 81 88 02 42 01 88 a2 |.=......0...B...|
+000001d0 4f eb e2 45 c5 48 7d 1b ac f5 ed 98 9d ae 47 70 |O..E.H}.......Gp|
+000001e0 c0 5e 1b b6 2f bd f1 b6 4d b7 61 40 d3 11 a2 ce |.^../...M.a@....|
+000001f0 ee 0b 7e 92 7e ff 76 9d c3 3b 7e a5 3f ce fa 10 |..~.~.v..;~.?...|
+00000200 e2 59 ec 47 2d 7c ac da 4e 97 0e 15 a0 6f d0 02 |.Y.G-|..N....o..|
+00000210 42 01 4d fc be 67 13 9c 2d 05 0e bd 3f a3 8c 25 |B.M..g..-...?..%|
+00000220 c1 33 13 83 0d 94 06 bb d4 37 7a f6 ec 7a c9 86 |.3.......7z..z..|
+00000230 2e dd d7 11 69 7f 85 7c 56 de fb 31 78 2b e4 c7 |....i..|V..1x+..|
+00000240 78 0d ae cb be 9e 4e 36 24 31 7b 6a 0f 39 95 12 |x.....N6$1{j.9..|
+00000250 07 8f 2a 16 03 01 00 b5 0c 00 00 b1 03 00 1d 20 |..*............ |
+00000260 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f bb 29 07 |/.}.G.bC.(.._.).|
+00000270 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 |0.........._X.;t|
+00000280 00 8b 30 81 88 02 42 00 c3 eb 60 b8 d3 af cb 2d |..0...B...`....-|
+00000290 4f ca 46 6d e4 fe 47 41 82 1e d4 14 0f 08 ab b6 |O.Fm..GA........|
+000002a0 b8 41 8b 46 f5 28 bb 87 28 73 a0 5c e9 ce f5 56 |.A.F.(..(s.\...V|
+000002b0 11 02 17 2c 39 b6 28 6c ec de 12 bf 22 91 3d 06 |...,9.(l....".=.|
+000002c0 ac 8e 0a 92 b1 46 69 86 44 02 42 01 fd 70 6e 63 |.....Fi.D.B..pnc|
+000002d0 1b 2a 21 47 9b 42 9c d4 4a 38 20 dd 94 05 c4 0f |.*!G.B..J8 .....|
+000002e0 5d b2 48 c8 17 90 01 4d 4f 7e 7a ef bb b2 5b 26 |].H....MO~z...[&|
+000002f0 7e e1 24 f5 80 93 69 72 3f cf bb 5d 52 ee ec b4 |~.$...ir?..]R...|
+00000300 cc 0c 96 1f 93 4c d6 a8 c7 b2 91 f5 6d 16 03 01 |.....L......m...|
+00000310 00 04 0e 00 00 00 |......|
+>>> Flow 3 (client to server)
+00000000 16 03 01 00 25 10 00 00 21 20 ec f2 2d ca 02 ce |....%...! ..-...|
+00000010 11 2d eb 26 d7 d9 fc b2 a7 2d 34 5b a9 3a 0b 2f |.-.&.....-4[.:./|
+00000020 5c 49 a9 69 1a 3a 83 90 ec 5f 14 03 01 00 01 01 |\I.i.:..._......|
+00000030 16 03 01 00 30 9f 06 c7 a7 a0 c3 a5 3d 60 6e fb |....0.......=`n.|
+00000040 c6 18 a4 d2 80 2e ad 8f cf 92 84 94 36 f8 81 28 |............6..(|
+00000050 c5 3f 37 e8 d6 e7 6d a3 f5 32 63 a0 ab 7a db 12 |.?7...m..2c..z..|
+00000060 17 e1 e4 33 d6 |...3.|
+>>> Flow 4 (server to client)
+00000000 14 03 01 00 01 01 16 03 01 00 30 18 29 35 d7 c5 |..........0.)5..|
+00000010 a2 31 3b 26 85 de 50 26 39 4d 16 22 58 a2 17 bd |.1;&..P&9M."X...|
+00000020 4b 73 33 8d dc 3f 92 20 f2 ca 22 00 f5 31 db a7 |Ks3..?. .."..1..|
+00000030 18 79 fc 71 87 68 a5 1d a6 db 33 17 03 01 00 20 |.y.q.h....3.... |
+00000040 0d be 57 e4 12 6d 2d 3a 33 24 a0 0c c4 9b 27 09 |..W..m-:3$....'.|
+00000050 85 e0 0e 42 04 79 21 9a bf 47 fa 0b 38 1a ce 8f |...B.y!..G..8...|
+00000060 17 03 01 00 30 6d 27 f1 9b cf 55 4d 65 48 38 1b |....0m'...UMeH8.|
+00000070 d9 dd 1d 5b 81 2f 10 a5 65 28 83 93 b3 b1 3a 72 |...[./..e(....:r|
+00000080 f0 15 9a e5 9f 21 80 f1 59 a5 0e f1 0c 2b d1 0c |.....!..Y....+..|
+00000090 d4 27 73 f3 7e 15 03 01 00 20 6f 08 27 3a d2 60 |.'s.~.... o.':.`|
+000000a0 c3 27 bc 73 55 bb 43 53 e2 e0 87 16 ca 8f 49 f0 |.'.sU.CS......I.|
+000000b0 88 a8 20 30 9d 42 86 d9 c3 36 |.. 0.B...6|
diff --git a/src/crypto/tls/testdata/Server-TLSv10-ExportKeyingMaterial b/src/crypto/tls/testdata/Server-TLSv10-ExportKeyingMaterial
new file mode 100644
index 0000000..b3d0f7d
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv10-ExportKeyingMaterial
@@ -0,0 +1,92 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 55 01 00 00 51 03 01 e0 8d 7b f2 8d |....U...Q....{..|
+00000010 45 9f c5 40 1b be 81 05 a1 83 82 c1 54 4a c7 1c |E..@........TJ..|
+00000020 f1 f8 d5 6c 7a ff 93 81 e2 a2 ba 00 00 04 c0 14 |...lz...........|
+00000030 00 ff 01 00 00 24 00 0b 00 04 03 00 01 02 00 0a |.....$..........|
+00000040 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 23 |...............#|
+00000050 00 00 00 16 00 00 00 17 00 00 |..........|
+>>> Flow 2 (server to client)
+00000000 16 03 01 00 3f 02 00 00 3b 03 01 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 44 4f 57 4e 47 52 44 00 00 c0 14 00 00 |...DOWNGRD......|
+00000030 13 00 23 00 00 ff 01 00 01 00 00 17 00 00 00 0b |..#.............|
+00000040 00 02 01 00 16 03 01 02 59 0b 00 02 55 00 02 52 |........Y...U..R|
+00000050 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 01 02 |..O0..K0........|
+00000060 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a |......?.[..0...*|
+00000070 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b 30 09 |.H........0.1.0.|
+00000080 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 03 55 |..U....Go1.0...U|
+00000090 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 |....Go Root0...1|
+000000a0 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d 32 35 |60101000000Z..25|
+000000b0 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 0b 30 |0101000000Z0.1.0|
+000000c0 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 06 03 |...U....Go1.0...|
+000000d0 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 2a 86 |U....Go0..0...*.|
+000000e0 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 |H............0..|
+000000f0 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc 06 28 |.....F}...'.H..(|
+00000100 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 |!.~...]..RE.z6G.|
+00000110 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb 4f 6d |...B[.....y.@.Om|
+00000120 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 |..+.....g....."8|
+00000130 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b |.J.ts+.4......t{|
+00000140 f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 |.X.la<..A..++$#w|
+00000150 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d 1e 24 |[.;.u]. T..c...$|
+00000160 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 62 f4 |....P....C...ub.|
+00000170 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 90 30 |..R.........0..0|
+00000180 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 |...U...........0|
+00000190 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 01 05 |...U.%..0...+...|
+000001a0 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 30 0c |......+.......0.|
+000001b0 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 06 03 |..U.......0.0...|
+000001c0 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e 49 a6 |U..........CC>I.|
+000001d0 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 04 14 |.m....`0...U.#..|
+000001e0 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 01 d5 |0...H.IM.~.1....|
+000001f0 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 10 82 |..n{0...U....0..|
+00000200 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 |.example.golang0|
+00000210 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 |...*.H..........|
+00000220 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 |...0.@+[P.a...SX|
+00000230 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a |...(.X..8....1Z.|
+00000240 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 38 92 |.f=C.-...... d8.|
+00000250 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 16 61 |$:....}.@ ._...a|
+00000260 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c |..v......\.....l|
+00000270 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 |..s..Cw.......@.|
+00000280 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 b3 3e |a.Lr+...F..M...>|
+00000290 c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 |...B...=.`.\!.;.|
+000002a0 fa e7 16 03 01 00 aa 0c 00 00 a6 03 00 1d 20 2f |.............. /|
+000002b0 e5 7d a3 47 cd 62 43 15 28 da ac 5f bb 29 07 30 |.}.G.bC.(.._.).0|
+000002c0 ff f6 84 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 00 |.........._X.;t.|
+000002d0 80 3d ff b7 ad d5 15 4f 10 6e 8a d2 ad 8a 6b 1b |.=.....O.n....k.|
+000002e0 9d 6c f2 92 99 c7 d7 d8 07 d5 c7 77 09 22 41 4f |.l.........w."AO|
+000002f0 7f ca 3e 8c 22 ba 2b f2 75 5f 47 c9 7e 0c 03 5d |..>.".+.u_G.~..]|
+00000300 1a 66 c3 c8 f3 76 f0 f6 fa 03 40 3a 9b e7 2b 35 |.f...v....@:..+5|
+00000310 bc c7 5e 62 a6 97 8a 1a 17 e3 13 4c 1f 88 39 2a |..^b.......L..9*|
+00000320 5b cc 9c 65 df 27 1e b3 26 d7 46 3e 76 a9 ae 71 |[..e.'..&.F>v..q|
+00000330 11 4d d6 10 b4 2e 30 37 a1 b4 ff 46 91 77 c7 4c |.M....07...F.w.L|
+00000340 f9 8e e3 96 88 d2 1e c5 9d fb a1 be c6 ef 5d f0 |..............].|
+00000350 52 16 03 01 00 04 0e 00 00 00 |R.........|
+>>> Flow 3 (client to server)
+00000000 16 03 01 00 25 10 00 00 21 20 01 39 8b 2b 21 99 |....%...! .9.+!.|
+00000010 fd fc b8 20 f1 51 97 c7 85 13 05 64 55 41 6b c4 |... .Q.....dUAk.|
+00000020 1a 5e d5 b2 7c 8b 31 08 0f 78 14 03 01 00 01 01 |.^..|.1..x......|
+00000030 16 03 01 00 30 d8 3b e6 9f f8 a8 b2 6b 8b fb 89 |....0.;.....k...|
+00000040 71 3b 55 cd c3 c9 78 3c 45 1b 8d 5f 70 4f bd 64 |q;U...x<E.._pO.d|
+00000050 a9 d1 c0 4d ce 34 e1 f9 d2 90 c9 49 b0 1f a3 76 |...M.4.....I...v|
+00000060 bd f4 78 d0 43 |..x.C|
+>>> Flow 4 (server to client)
+00000000 16 03 01 00 83 04 00 00 7f 00 00 00 00 00 79 00 |..............y.|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 |................|
+00000020 6d 2d 70 97 51 ed 14 ef 68 ca 42 c5 4c 71 8e 74 |m-p.Q...h.B.Lq.t|
+00000030 d4 83 d6 4a 5b 69 f8 af 61 3a 98 83 19 d5 7c 60 |...J[i..a:....|`|
+00000040 4a 1e f4 b7 26 b8 99 b5 45 6f a3 8d 97 63 5f 1b |J...&...Eo...c_.|
+00000050 ab f4 84 59 db ce 99 ce b8 6a 23 d5 15 49 38 16 |...Y.....j#..I8.|
+00000060 7e 51 5c e5 15 c0 58 7d c0 ee 59 1b e4 6e 1f c8 |~Q\...X}..Y..n..|
+00000070 fc d4 2c 33 ed 0a 2b e0 78 04 64 4b 56 e4 af 61 |..,3..+.x.dKV..a|
+00000080 c6 b5 7d f5 a0 86 9f e3 14 03 01 00 01 01 16 03 |..}.............|
+00000090 01 00 30 73 2b f0 16 d3 a8 02 b3 73 98 5e 4e a0 |..0s+......s.^N.|
+000000a0 ca 5b c4 50 fb 5a 92 11 43 97 e9 e3 16 9f 08 0a |.[.P.Z..C.......|
+000000b0 56 73 e6 44 67 70 aa 3d bb c1 36 c8 63 1c 2b 51 |Vs.Dgp.=..6.c.+Q|
+000000c0 1f 3b 81 17 03 01 00 20 4c 93 10 5c 01 e2 63 12 |.;..... L..\..c.|
+000000d0 97 6b e1 89 fb e7 14 cf ec 70 d1 fe 6f ea 8b 09 |.k.......p..o...|
+000000e0 63 5f 8c 8a 9e b5 ac b8 17 03 01 00 30 a1 ad dd |c_..........0...|
+000000f0 92 ac a8 6e 77 ed c2 ed 59 b6 a8 41 ad 45 59 8c |...nw...Y..A.EY.|
+00000100 4e 1d 16 36 57 e6 2f 47 3d 10 0f 36 04 00 b0 c1 |N..6W./G=..6....|
+00000110 a7 94 25 8e 77 1e 69 20 41 6c c0 9d 26 15 03 01 |..%.w.i Al..&...|
+00000120 00 20 c5 83 26 5d 20 cb 16 7e 27 63 d7 96 aa 96 |. ..&] ..~'c....|
+00000130 37 19 2a 7a 18 d4 85 08 25 32 85 d5 b5 e3 4e 9b |7.*z....%2....N.|
+00000140 98 f5 |..|
diff --git a/src/crypto/tls/testdata/Server-TLSv10-RSA-3DES b/src/crypto/tls/testdata/Server-TLSv10-RSA-3DES
new file mode 100644
index 0000000..e4853a4
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv10-RSA-3DES
@@ -0,0 +1,73 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 39 01 00 00 35 03 01 51 7a 48 8d de |....9...5..QzH..|
+00000010 0b 30 0f 9a 91 56 30 20 30 dd bd 74 3b e2 d7 db |.0...V0 0..t;...|
+00000020 46 3d bf 6f b6 ae 53 8a 7d 18 50 00 00 04 00 0a |F=.o..S.}.P.....|
+00000030 00 ff 01 00 00 08 00 16 00 00 00 17 00 00 |..............|
+>>> Flow 2 (server to client)
+00000000 16 03 01 00 35 02 00 00 31 03 01 00 00 00 00 00 |....5...1.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 44 4f 57 4e 47 52 44 00 00 00 0a 00 00 |...DOWNGRD......|
+00000030 09 ff 01 00 01 00 00 17 00 00 16 03 01 02 59 0b |..............Y.|
+00000040 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..|
+00000050 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.|
+00000060 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........|
+00000070 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1|
+00000080 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo|
+00000090 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000|
+000000a0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000|
+000000b0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go|
+000000c0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..|
+000000d0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........|
+000000e0 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...|
+000000f0 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R|
+00000100 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....|
+00000110 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.|
+00000120 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..|
+00000130 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.|
+00000140 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.|
+00000150 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C|
+00000160 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......|
+00000170 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......|
+00000180 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.|
+00000190 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...|
+000001a0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......|
+000001b0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........|
+000001c0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..|
+000001d0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~|
+000001e0 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.|
+000001f0 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g|
+00000200 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....|
+00000210 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.|
+00000220 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.|
+00000230 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....|
+00000240 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ |
+00000250 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\|
+00000260 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...|
+00000270 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.|
+00000280 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`|
+00000290 84 5c 21 d3 3b e9 fa e7 16 03 01 00 04 0e 00 00 |.\!.;...........|
+000002a0 00 |.|
+>>> Flow 3 (client to server)
+00000000 16 03 01 00 86 10 00 00 82 00 80 54 53 e6 48 5d |...........TS.H]|
+00000010 bb 47 19 7e ab 31 3b 4a c8 fb da 69 9d 74 b3 e1 |.G.~.1;J...i.t..|
+00000020 dc 8c ea 36 f7 a1 06 68 52 79 c3 08 be b9 5c 1a |...6...hRy....\.|
+00000030 80 cc 13 b8 7b b8 02 98 5e f8 50 47 a5 0d 37 dd |....{...^.PG..7.|
+00000040 86 c5 69 9c 1c 1c 91 39 ea 80 dc d1 87 d3 f8 f6 |..i....9........|
+00000050 84 c6 65 72 af 71 dc 98 56 9e bc e7 a9 9d 9b 31 |..er.q..V......1|
+00000060 d0 c3 54 28 05 86 91 e4 03 40 f7 2a cb 07 13 41 |..T(.....@.*...A|
+00000070 1e 30 0b b1 2d 52 ae 1f a1 6b a9 db c2 76 1d 4a |.0..-R...k...v.J|
+00000080 a6 81 ba 3c cb e9 3a 6b f3 70 ed 14 03 01 00 01 |...<..:k.p......|
+00000090 01 16 03 01 00 28 01 84 d8 e4 7a b1 11 3e 27 fb |.....(....z..>'.|
+000000a0 66 10 1a db 20 fb 9e e3 f1 a5 a7 86 2f fd c9 d2 |f... ......./...|
+000000b0 1c b8 a4 2b af 2b 66 fc ad 31 72 28 d7 1a |...+.+f..1r(..|
+>>> Flow 4 (server to client)
+00000000 14 03 01 00 01 01 16 03 01 00 28 67 3d c4 e9 a6 |..........(g=...|
+00000010 bb 99 57 90 eb fa 86 ee ab 00 08 61 2d c8 50 5b |..W........a-.P[|
+00000020 83 9c ce 83 60 7a 89 33 90 b7 f9 31 e9 37 04 3d |....`z.3...1.7.=|
+00000030 d6 01 44 17 03 01 00 18 0a 1c 6c 75 23 bc b2 e7 |..D.......lu#...|
+00000040 30 2d 61 57 d3 a6 a2 72 6a 7a 2d 8a 7b fd 45 67 |0-aW...rjz-.{.Eg|
+00000050 17 03 01 00 28 23 8b 77 dd a3 f2 b6 0e 59 40 3b |....(#.w.....Y@;|
+00000060 4e 3a 1b 0c 11 2f 99 00 b9 e1 2c 11 89 53 fb 23 |N:.../....,..S.#|
+00000070 fb 6c 60 71 db a8 43 a4 92 ad 68 24 e9 15 03 01 |.l`q..C...h$....|
+00000080 00 18 24 19 84 35 13 29 ed 3a f0 57 a9 e1 b6 e9 |..$..5.).:.W....|
+00000090 05 64 fe 46 c0 ca b1 88 12 a7 |.d.F......|
diff --git a/src/crypto/tls/testdata/Server-TLSv10-RSA-AES b/src/crypto/tls/testdata/Server-TLSv10-RSA-AES
new file mode 100644
index 0000000..f362a7a
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv10-RSA-AES
@@ -0,0 +1,76 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 39 01 00 00 35 03 01 96 f7 15 21 fc |....9...5.....!.|
+00000010 31 f5 cf cf e9 82 0f 84 db 34 a8 e4 3c e9 39 b4 |1........4..<.9.|
+00000020 90 af d7 47 2b b5 71 8a bb 26 b5 00 00 04 00 2f |...G+.q..&...../|
+00000030 00 ff 01 00 00 08 00 16 00 00 00 17 00 00 |..............|
+>>> Flow 2 (server to client)
+00000000 16 03 01 00 35 02 00 00 31 03 01 00 00 00 00 00 |....5...1.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 44 4f 57 4e 47 52 44 00 00 00 2f 00 00 |...DOWNGRD.../..|
+00000030 09 ff 01 00 01 00 00 17 00 00 16 03 01 02 59 0b |..............Y.|
+00000040 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..|
+00000050 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.|
+00000060 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........|
+00000070 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1|
+00000080 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo|
+00000090 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000|
+000000a0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000|
+000000b0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go|
+000000c0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..|
+000000d0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........|
+000000e0 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...|
+000000f0 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R|
+00000100 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....|
+00000110 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.|
+00000120 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..|
+00000130 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.|
+00000140 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.|
+00000150 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C|
+00000160 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......|
+00000170 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......|
+00000180 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.|
+00000190 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...|
+000001a0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......|
+000001b0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........|
+000001c0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..|
+000001d0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~|
+000001e0 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.|
+000001f0 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g|
+00000200 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....|
+00000210 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.|
+00000220 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.|
+00000230 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....|
+00000240 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ |
+00000250 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\|
+00000260 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...|
+00000270 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.|
+00000280 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`|
+00000290 84 5c 21 d3 3b e9 fa e7 16 03 01 00 04 0e 00 00 |.\!.;...........|
+000002a0 00 |.|
+>>> Flow 3 (client to server)
+00000000 16 03 01 00 86 10 00 00 82 00 80 47 20 04 47 3e |...........G .G>|
+00000010 d0 67 d1 d9 5d 17 eb 85 2c 3f 1c 4b 93 f9 ff 51 |.g..]...,?.K...Q|
+00000020 ca 61 eb 04 54 6d 49 97 02 67 fe 28 79 be 4d 37 |.a..TmI..g.(y.M7|
+00000030 f7 ba e8 e0 2b 90 31 fe 66 d8 04 ad bf fb 2c 05 |....+.1.f.....,.|
+00000040 7e 41 a0 5d 00 47 20 84 83 2c 39 7f 29 aa 72 72 |~A.].G ..,9.).rr|
+00000050 89 e3 c7 bb ea 07 d2 29 94 de 54 23 eb 9f ae fa |.......)..T#....|
+00000060 3b 9a 23 bd a8 43 11 ab b5 6c 8a ae c6 71 2c c4 |;.#..C...l...q,.|
+00000070 f6 4d 0d 19 8e f6 7e 44 d2 04 58 68 a7 bd 84 34 |.M....~D..Xh...4|
+00000080 5f e5 98 56 a5 1e 61 57 f2 f4 ea 14 03 01 00 01 |_..V..aW........|
+00000090 01 16 03 01 00 30 eb 07 c2 ed 41 24 ab 50 74 82 |.....0....A$.Pt.|
+000000a0 c4 83 28 2c b3 33 88 a1 c7 61 89 61 29 58 78 fc |..(,.3...a.a)Xx.|
+000000b0 b5 99 54 d2 c2 2b 14 e4 6b a9 9b b8 69 17 6c 53 |..T..+..k...i.lS|
+000000c0 dd dd d7 7b a5 a7 |...{..|
+>>> Flow 4 (server to client)
+00000000 14 03 01 00 01 01 16 03 01 00 30 17 39 24 df 39 |..........0.9$.9|
+00000010 2f b4 09 7b d8 76 fa c2 0a e2 68 f9 23 0c be 1b |/..{.v....h.#...|
+00000020 9d ba 91 16 2c f3 5b 6a 3d d3 63 12 35 76 91 38 |....,.[j=.c.5v.8|
+00000030 f3 a5 37 4a bc 65 f4 85 cb b8 65 17 03 01 00 20 |..7J.e....e.... |
+00000040 0c 59 ac 4f 44 97 46 bd d5 ae 98 74 9f 86 3e ef |.Y.OD.F....t..>.|
+00000050 b3 09 3c c4 0c 45 58 10 4f fd e0 be 86 ac 3e c8 |..<..EX.O.....>.|
+00000060 17 03 01 00 30 8c 76 1f 5a 4a 3b 98 4d 5c 0d c7 |....0.v.ZJ;.M\..|
+00000070 dc 55 df 70 ed 75 22 d2 a5 28 a7 4e 9f ed 83 3b |.U.p.u"..(.N...;|
+00000080 88 85 7d 1a 7e f9 6f e7 f3 26 e1 b1 7b 4e 52 a5 |..}.~.o..&..{NR.|
+00000090 29 55 a4 04 df 15 03 01 00 20 8b 10 5c 79 5e f8 |)U....... ..\y^.|
+000000a0 1d 41 1c b2 05 fd 58 5a 80 69 e5 ce db c3 ac a4 |.A....XZ.i......|
+000000b0 e6 95 1d 9d 32 e2 66 4b af 43 |....2.fK.C|
diff --git a/src/crypto/tls/testdata/Server-TLSv10-RSA-RC4 b/src/crypto/tls/testdata/Server-TLSv10-RSA-RC4
new file mode 100644
index 0000000..e07b8d8
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv10-RSA-RC4
@@ -0,0 +1,70 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 39 01 00 00 35 03 01 eb 78 34 78 f6 |....9...5...x4x.|
+00000010 8f 87 2f ee 5e da ee 37 5d 0a d5 79 d5 0e db b1 |../.^..7]..y....|
+00000020 b7 03 37 1f 2d ce 04 b9 2d 65 d7 00 00 04 00 05 |..7.-...-e......|
+00000030 00 ff 01 00 00 08 00 16 00 00 00 17 00 00 |..............|
+>>> Flow 2 (server to client)
+00000000 16 03 01 00 35 02 00 00 31 03 01 00 00 00 00 00 |....5...1.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 44 4f 57 4e 47 52 44 00 00 00 05 00 00 |...DOWNGRD......|
+00000030 09 ff 01 00 01 00 00 17 00 00 16 03 01 02 59 0b |..............Y.|
+00000040 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..|
+00000050 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.|
+00000060 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........|
+00000070 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1|
+00000080 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo|
+00000090 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000|
+000000a0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000|
+000000b0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go|
+000000c0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..|
+000000d0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........|
+000000e0 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...|
+000000f0 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R|
+00000100 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....|
+00000110 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.|
+00000120 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..|
+00000130 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.|
+00000140 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.|
+00000150 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C|
+00000160 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......|
+00000170 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......|
+00000180 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.|
+00000190 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...|
+000001a0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......|
+000001b0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........|
+000001c0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..|
+000001d0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~|
+000001e0 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.|
+000001f0 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g|
+00000200 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....|
+00000210 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.|
+00000220 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.|
+00000230 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....|
+00000240 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ |
+00000250 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\|
+00000260 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...|
+00000270 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.|
+00000280 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`|
+00000290 84 5c 21 d3 3b e9 fa e7 16 03 01 00 04 0e 00 00 |.\!.;...........|
+000002a0 00 |.|
+>>> Flow 3 (client to server)
+00000000 16 03 01 00 86 10 00 00 82 00 80 d4 db 61 0b 26 |.............a.&|
+00000010 06 af 94 37 9d fc 50 3f 50 4f 58 37 b9 b1 c2 d2 |...7..P?POX7....|
+00000020 92 2b f5 c9 fe 7f 3d f4 32 e3 ee ba 46 ea e5 36 |.+....=.2...F..6|
+00000030 9b fd c5 89 c9 14 45 e7 f7 ea 1a a9 63 c5 62 fb |......E.....c.b.|
+00000040 34 c4 80 1e 59 60 39 d9 ca 68 3f 3f 1a f9 6a 14 |4...Y`9..h??..j.|
+00000050 f7 c8 91 3b 7d eb cc b9 8c 42 f1 ef d8 0f cd 17 |...;}....B......|
+00000060 64 f3 b8 30 6e 50 d4 23 bb 26 78 c3 fe f0 c4 42 |d..0nP.#.&x....B|
+00000070 0a 89 90 fb 43 fe 7f 0f 06 82 e8 7f fb 42 dd 46 |....C........B.F|
+00000080 fc 38 6e d0 14 05 41 b8 05 6b e7 14 03 01 00 01 |.8n...A..k......|
+00000090 01 16 03 01 00 24 b4 bb 3e 8f 6b 91 43 c2 b9 16 |.....$..>.k.C...|
+000000a0 59 ba 7d f9 89 a4 89 ce 12 c8 76 b0 e3 8f 36 03 |Y.}.......v...6.|
+000000b0 f7 48 03 7e 4a fe e5 8e 88 91 |.H.~J.....|
+>>> Flow 4 (server to client)
+00000000 14 03 01 00 01 01 16 03 01 00 24 06 5d 9f 70 98 |..........$.].p.|
+00000010 8b 42 79 f1 ba 73 40 8e b3 f6 ff a1 45 57 c4 f3 |.By..s@.....EW..|
+00000020 6d 00 4e b5 52 f5 3d 08 b4 57 33 74 ab 6f 62 17 |m.N.R.=..W3t.ob.|
+00000030 03 01 00 21 6e 3a c7 a5 63 fb 81 78 10 9c 85 ab |...!n:..c..x....|
+00000040 3d 3b 50 3a 12 0b c2 0f f5 7e a2 d3 f7 82 3c 7f |=;P:.....~....<.|
+00000050 45 29 2c 1e eb 15 03 01 00 16 66 a4 bb 6d d1 fc |E),.......f..m..|
+00000060 36 b2 a9 e7 e5 7a da a1 37 f1 cf fa 8f 0c 73 f5 |6....z..7.....s.|
diff --git a/src/crypto/tls/testdata/Server-TLSv11-FallbackSCSV b/src/crypto/tls/testdata/Server-TLSv11-FallbackSCSV
new file mode 100644
index 0000000..7bd0341
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv11-FallbackSCSV
@@ -0,0 +1,11 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 77 01 00 00 73 03 02 0a 6b c9 55 9d |....w...s...k.U.|
+00000010 bf 4e 61 b2 0a c7 c6 96 9f eb 90 91 87 ca d3 d3 |.Na.............|
+00000020 62 dc b6 b4 db ea 41 fe 43 3e a3 00 00 14 c0 0a |b.....A.C>......|
+00000030 c0 14 00 39 c0 09 c0 13 00 33 00 35 00 2f 00 ff |...9.....3.5./..|
+00000040 56 00 01 00 00 36 00 00 00 0e 00 0c 00 00 09 31 |V....6.........1|
+00000050 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........|
+00000060 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................|
+00000070 00 23 00 00 00 16 00 00 00 17 00 00 |.#..........|
+>>> Flow 2 (server to client)
+00000000 15 03 02 00 02 02 56 |......V|
diff --git a/src/crypto/tls/testdata/Server-TLSv11-RSA-RC4 b/src/crypto/tls/testdata/Server-TLSv11-RSA-RC4
new file mode 100644
index 0000000..27062da
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv11-RSA-RC4
@@ -0,0 +1,70 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 39 01 00 00 35 03 02 ac 4f 36 f3 4c |....9...5...O6.L|
+00000010 64 ae 8d fc 50 a3 e1 e4 70 5d ba 8c de de c8 07 |d...P...p]......|
+00000020 70 24 8d bd c1 69 a3 0e ad 16 38 00 00 04 00 05 |p$...i....8.....|
+00000030 00 ff 01 00 00 08 00 16 00 00 00 17 00 00 |..............|
+>>> Flow 2 (server to client)
+00000000 16 03 02 00 35 02 00 00 31 03 02 00 00 00 00 00 |....5...1.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 44 4f 57 4e 47 52 44 00 00 00 05 00 00 |...DOWNGRD......|
+00000030 09 ff 01 00 01 00 00 17 00 00 16 03 02 02 59 0b |..............Y.|
+00000040 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..|
+00000050 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.|
+00000060 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........|
+00000070 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1|
+00000080 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo|
+00000090 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000|
+000000a0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000|
+000000b0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go|
+000000c0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..|
+000000d0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........|
+000000e0 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...|
+000000f0 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R|
+00000100 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....|
+00000110 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.|
+00000120 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..|
+00000130 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.|
+00000140 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.|
+00000150 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C|
+00000160 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......|
+00000170 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......|
+00000180 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.|
+00000190 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...|
+000001a0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......|
+000001b0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........|
+000001c0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..|
+000001d0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~|
+000001e0 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.|
+000001f0 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g|
+00000200 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....|
+00000210 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.|
+00000220 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.|
+00000230 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....|
+00000240 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ |
+00000250 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\|
+00000260 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...|
+00000270 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.|
+00000280 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`|
+00000290 84 5c 21 d3 3b e9 fa e7 16 03 02 00 04 0e 00 00 |.\!.;...........|
+000002a0 00 |.|
+>>> Flow 3 (client to server)
+00000000 16 03 02 00 86 10 00 00 82 00 80 49 c4 5f 04 e0 |...........I._..|
+00000010 63 96 72 bd c9 00 af 17 b1 59 b4 c7 40 a5 b7 b5 |c.r......Y..@...|
+00000020 68 79 d2 7b b0 2a e7 06 7e 97 ad da d8 3f cb f8 |hy.{.*..~....?..|
+00000030 7c b9 f1 9d be 49 7c 09 6a b0 25 49 9c 06 2a c3 ||....I|.j.%I..*.|
+00000040 d5 0a ae cc cc 08 31 5d 14 82 06 a7 57 fc 66 9c |......1]....W.f.|
+00000050 90 b7 be aa 15 46 2b aa ae fc 3a ce 3d 64 4e 80 |.....F+...:.=dN.|
+00000060 90 3f 77 c6 60 cd 6b dc 69 c1 92 a9 1e 8e 30 6a |.?w.`.k.i.....0j|
+00000070 34 a3 db 1a f5 a3 f9 ac 1c 07 4f be 38 d1 a5 61 |4.........O.8..a|
+00000080 e5 5f 84 99 f0 87 40 dc b2 cc 05 14 03 02 00 01 |._....@.........|
+00000090 01 16 03 02 00 24 eb d9 48 20 7b db 97 48 f2 c7 |.....$..H {..H..|
+000000a0 bb c1 ef fa 74 44 d8 a1 55 63 f3 d0 90 ef f2 0b |....tD..Uc......|
+000000b0 67 10 98 27 76 8a 70 78 0b df |g..'v.px..|
+>>> Flow 4 (server to client)
+00000000 14 03 02 00 01 01 16 03 02 00 24 41 50 b9 88 0e |..........$AP...|
+00000010 3f 27 36 f0 27 70 ca b8 bc 38 df e9 68 3e 29 cf |?'6.'p...8..h>).|
+00000020 80 b5 e8 59 bd 52 45 b7 0d fa a7 6d 77 a0 9e 17 |...Y.RE....mw...|
+00000030 03 02 00 21 94 2a 6a ca f0 b3 7e 1c d6 58 3f 64 |...!.*j...~..X?d|
+00000040 ef 62 35 72 aa c6 84 7b 19 c6 07 0e 04 63 c4 14 |.b5r...{.....c..|
+00000050 43 d8 73 ff 2f 15 03 02 00 16 5a 45 ba 51 95 c9 |C.s./.....ZE.Q..|
+00000060 53 2a a6 b1 61 35 db 0a 7b f9 8e a9 fb 18 87 b1 |S*..a5..{.......|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ALPN b/src/crypto/tls/testdata/Server-TLSv12-ALPN
new file mode 100644
index 0000000..ccd4a08
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-ALPN
@@ -0,0 +1,91 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 9d 01 00 00 99 03 03 f7 12 13 92 75 |...............u|
+00000010 34 ab f3 e8 a2 19 2d 3c 0c 8b 9e c3 e8 22 7e d8 |4.....-<....."~.|
+00000020 66 f9 08 88 70 9b cc 37 95 43 a7 00 00 04 cc a8 |f...p..7.C......|
+00000030 00 ff 01 00 00 6c 00 0b 00 04 03 00 01 02 00 0a |.....l..........|
+00000040 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 23 |...............#|
+00000050 00 00 00 10 00 10 00 0e 06 70 72 6f 74 6f 32 06 |.........proto2.|
+00000060 70 72 6f 74 6f 31 00 16 00 00 00 17 00 00 00 0d |proto1..........|
+00000070 00 30 00 2e 04 03 05 03 06 03 08 07 08 08 08 09 |.0..............|
+00000080 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................|
+00000090 03 03 02 03 03 01 02 01 03 02 02 02 04 02 05 02 |................|
+000000a0 06 02 |..|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 4c 02 00 00 48 03 03 00 00 00 00 00 |....L...H.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 cc a8 00 00 |...DOWNGRD......|
+00000030 20 00 23 00 00 ff 01 00 01 00 00 17 00 00 00 10 | .#.............|
+00000040 00 09 00 07 06 70 72 6f 74 6f 31 00 0b 00 02 01 |.....proto1.....|
+00000050 00 16 03 03 02 59 0b 00 02 55 00 02 52 00 02 4f |.....Y...U..R..O|
+00000060 30 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 |0..K0...........|
+00000070 e8 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 86 |...?.[..0...*.H.|
+00000080 f7 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 55 |.......0.1.0...U|
+00000090 04 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 13 |....Go1.0...U...|
+000000a0 07 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 31 |.Go Root0...1601|
+000000b0 30 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 30 |01000000Z..25010|
+000000c0 31 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 03 |1000000Z0.1.0...|
+000000d0 55 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 03 |U....Go1.0...U..|
+000000e0 13 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 f7 |..Go0..0...*.H..|
+000000f0 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 81 |..........0.....|
+00000100 00 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab 7e |..F}...'.H..(!.~|
+00000110 c4 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d 92 |...]..RE.z6G....|
+00000120 42 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd 2b |B[.....y.@.Om..+|
+00000130 13 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a 0b |.....g....."8.J.|
+00000140 74 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 9f |ts+.4......t{.X.|
+00000150 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c 3b |la<..A..++$#w[.;|
+00000160 bd 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 1d |.u]. T..c...$...|
+00000170 1a 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 52 |.P....C...ub...R|
+00000180 d7 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 03 |.........0..0...|
+00000190 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 03 |U...........0...|
+000001a0 55 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 03 |U.%..0...+......|
+000001b0 01 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 55 |...+.......0...U|
+000001c0 1d 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d 0e |.......0.0...U..|
+000001d0 04 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d b6 |........CC>I..m.|
+000001e0 80 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 80 |...`0...U.#..0..|
+000001f0 10 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab 6e |.H.IM.~.1......n|
+00000200 7b 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 78 |{0...U....0...ex|
+00000210 61 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 09 |ample.golang0...|
+00000220 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 9d |*.H.............|
+00000230 30 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed 83 |0.@+[P.a...SX...|
+00000240 28 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 3d |(.X..8....1Z..f=|
+00000250 43 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a 00 |C.-...... d8.$:.|
+00000260 bc cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 76 |...}.@ ._...a..v|
+00000270 fd 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed 73 |......\.....l..s|
+00000280 bb b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c |..Cw.......@.a.L|
+00000290 72 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd |r+...F..M...>...|
+000002a0 42 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 |B...=.`.\!.;....|
+000002b0 03 03 00 ac 0c 00 00 a8 03 00 1d 20 2f e5 7d a3 |........... /.}.|
+000002c0 47 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 |G.bC.(.._.).0...|
+000002d0 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 08 04 00 80 |......._X.;t....|
+000002e0 2a 3d 85 27 96 fe 41 e2 5a cc 39 dd 8a 8e 64 73 |*=.'..A.Z.9...ds|
+000002f0 ef 98 04 5c ac d2 8f 5e 55 b8 37 da 10 68 33 b8 |...\...^U.7..h3.|
+00000300 63 83 e1 c9 9a e6 3a e9 c9 20 cc 57 58 e2 ba bc |c.....:.. .WX...|
+00000310 e3 ac ab aa 08 e2 1e 6f 66 90 d7 66 c5 73 60 0d |.......of..f.s`.|
+00000320 19 4f eb 99 9d d1 b1 91 36 80 b9 20 aa f5 d9 c8 |.O......6.. ....|
+00000330 44 a7 99 c9 a6 4d 2c ff ca 4d 84 f2 a5 bf 02 c5 |D....M,..M......|
+00000340 61 77 7e 4a e6 7c dd bf 48 fc a6 53 fb c4 d3 dd |aw~J.|..H..S....|
+00000350 e6 20 b9 74 90 82 4a 3a 73 0a 81 74 07 a3 23 fe |. .t..J:s..t..#.|
+00000360 16 03 03 00 04 0e 00 00 00 |.........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 d1 bb f1 17 6c 41 |....%...! ....lA|
+00000010 8f 14 84 d2 98 99 30 0c 8a 00 4c 39 37 15 f5 be |......0...L97...|
+00000020 81 8d 08 e0 11 c1 f7 65 43 0b 14 03 03 00 01 01 |.......eC.......|
+00000030 16 03 03 00 20 ab 15 bb 47 30 42 c9 7d 45 f8 5d |.... ...G0B.}E.]|
+00000040 21 79 3b 4d 5e a9 99 f5 7d f3 4e 7e ba b9 9b 30 |!y;M^...}.N~...0|
+00000050 b6 14 4d ba f9 |..M..|
+>>> Flow 4 (server to client)
+00000000 16 03 03 00 83 04 00 00 7f 00 00 00 00 00 79 00 |..............y.|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 |................|
+00000020 6f 2d 7c 2b 51 ed 14 ef 68 ca 42 c5 4c f3 5c b9 |o-|+Q...h.B.L.\.|
+00000030 84 7d 30 9e 2f 9d 4d 0e 59 b4 28 fd 17 10 cd 1e |.}0./.M.Y.(.....|
+00000040 1c d3 2c 5e d9 dc db 26 d0 b9 00 4b 0a 13 54 90 |..,^...&...K..T.|
+00000050 f2 7b 68 75 6b 00 34 66 9e 43 29 06 16 49 38 16 |.{huk.4f.C)..I8.|
+00000060 7e 51 5c e5 15 c0 58 7d 52 0b 16 21 d8 2c e8 c8 |~Q\...X}R..!.,..|
+00000070 8e 3a f6 aa fa 21 45 4a 17 02 67 7d 93 1c 95 88 |.:...!EJ..g}....|
+00000080 36 a5 19 53 74 74 81 e1 14 03 03 00 01 01 16 03 |6..Stt..........|
+00000090 03 00 20 3d 66 04 37 0c 40 cc 20 2c 1c 16 ba 05 |.. =f.7.@. ,....|
+000000a0 d6 7b 40 04 27 40 6f cc d7 af 68 fb 32 49 6c 4f |.{@.'@o...h.2IlO|
+000000b0 f3 01 bf 17 03 03 00 1d 99 10 78 bc fa 7e 8a 86 |..........x..~..|
+000000c0 4c b8 e4 7c e2 79 70 eb ad 33 44 e1 ab 7a c9 ae |L..|.yp..3D..z..|
+000000d0 47 fe 39 50 d1 15 03 03 00 12 9e 9a be b0 55 c3 |G.9P..........U.|
+000000e0 3a 5f 5c e0 4b 8f 4f 81 52 d3 89 09 |:_\.K.O.R...|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ALPN-Fallback b/src/crypto/tls/testdata/Server-TLSv12-ALPN-Fallback
new file mode 100644
index 0000000..0702012
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-ALPN-Fallback
@@ -0,0 +1,90 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 a6 01 00 00 a2 03 03 ea e2 1b 90 0e |................|
+00000010 91 d5 9f b2 c6 ee 72 37 19 f5 14 cd ca a9 ca 03 |......r7........|
+00000020 98 c4 2e d4 85 05 4a a5 02 e1 4b 00 00 04 cc a8 |......J...K.....|
+00000030 00 ff 01 00 00 75 00 0b 00 04 03 00 01 02 00 0a |.....u..........|
+00000040 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 23 |...............#|
+00000050 00 00 00 10 00 19 00 17 06 70 72 6f 74 6f 33 08 |.........proto3.|
+00000060 68 74 74 70 2f 31 2e 31 06 70 72 6f 74 6f 34 00 |http/1.1.proto4.|
+00000070 16 00 00 00 17 00 00 00 0d 00 30 00 2e 04 03 05 |..........0.....|
+00000080 03 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 |................|
+00000090 05 08 06 04 01 05 01 06 01 03 03 02 03 03 01 02 |................|
+000000a0 01 03 02 02 02 04 02 05 02 06 02 |...........|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 3f 02 00 00 3b 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 44 4f 57 4e 47 52 44 01 00 cc a8 00 00 |...DOWNGRD......|
+00000030 13 00 23 00 00 ff 01 00 01 00 00 17 00 00 00 0b |..#.............|
+00000040 00 02 01 00 16 03 03 02 59 0b 00 02 55 00 02 52 |........Y...U..R|
+00000050 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 01 02 |..O0..K0........|
+00000060 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a |......?.[..0...*|
+00000070 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b 30 09 |.H........0.1.0.|
+00000080 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 03 55 |..U....Go1.0...U|
+00000090 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 |....Go Root0...1|
+000000a0 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d 32 35 |60101000000Z..25|
+000000b0 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 0b 30 |0101000000Z0.1.0|
+000000c0 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 06 03 |...U....Go1.0...|
+000000d0 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 2a 86 |U....Go0..0...*.|
+000000e0 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 |H............0..|
+000000f0 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc 06 28 |.....F}...'.H..(|
+00000100 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 |!.~...]..RE.z6G.|
+00000110 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb 4f 6d |...B[.....y.@.Om|
+00000120 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 |..+.....g....."8|
+00000130 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b |.J.ts+.4......t{|
+00000140 f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 |.X.la<..A..++$#w|
+00000150 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d 1e 24 |[.;.u]. T..c...$|
+00000160 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 62 f4 |....P....C...ub.|
+00000170 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 90 30 |..R.........0..0|
+00000180 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 |...U...........0|
+00000190 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 01 05 |...U.%..0...+...|
+000001a0 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 30 0c |......+.......0.|
+000001b0 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 06 03 |..U.......0.0...|
+000001c0 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e 49 a6 |U..........CC>I.|
+000001d0 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 04 14 |.m....`0...U.#..|
+000001e0 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 01 d5 |0...H.IM.~.1....|
+000001f0 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 10 82 |..n{0...U....0..|
+00000200 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 |.example.golang0|
+00000210 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 |...*.H..........|
+00000220 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 |...0.@+[P.a...SX|
+00000230 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a |...(.X..8....1Z.|
+00000240 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 38 92 |.f=C.-...... d8.|
+00000250 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 16 61 |$:....}.@ ._...a|
+00000260 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c |..v......\.....l|
+00000270 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 |..s..Cw.......@.|
+00000280 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 b3 3e |a.Lr+...F..M...>|
+00000290 c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 |...B...=.`.\!.;.|
+000002a0 fa e7 16 03 03 00 ac 0c 00 00 a8 03 00 1d 20 2f |.............. /|
+000002b0 e5 7d a3 47 cd 62 43 15 28 da ac 5f bb 29 07 30 |.}.G.bC.(.._.).0|
+000002c0 ff f6 84 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 08 |.........._X.;t.|
+000002d0 04 00 80 85 e9 a6 5c 79 bc db ed 97 fb 30 ca fd |......\y.....0..|
+000002e0 32 13 19 3f da 6f fd c1 11 74 fe e9 6f 60 ec 7e |2..?.o...t..o`.~|
+000002f0 48 7e 17 33 9b 8d 2a c2 82 e0 18 38 f3 0f 20 27 |H~.3..*....8.. '|
+00000300 81 0f c9 47 bf 5f 2b 2f 65 1c 6b e3 b7 72 85 46 |...G._+/e.k..r.F|
+00000310 5c 15 dc fd e6 be cf 50 51 62 f5 d9 17 e2 e8 bf |\......PQb......|
+00000320 08 7f 37 71 91 88 83 7f e3 90 66 66 c4 d8 60 25 |..7q......ff..`%|
+00000330 53 f7 9f 44 20 89 48 ff c2 3b 6d 21 e5 8c dc e5 |S..D .H..;m!....|
+00000340 42 ea d8 14 93 96 2f 53 24 66 e7 bb e7 2c 1f 92 |B...../S$f...,..|
+00000350 90 80 23 16 03 03 00 04 0e 00 00 00 |..#.........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 e8 d1 46 5e 70 b5 |....%...! ..F^p.|
+00000010 34 1c 6f cd be f0 86 24 2a d6 55 ae 97 de 52 0c |4.o....$*.U...R.|
+00000020 67 10 a0 02 ed ae f8 47 aa 52 14 03 03 00 01 01 |g......G.R......|
+00000030 16 03 03 00 20 52 cf 5d 07 bb bc e8 86 d4 f4 3e |.... R.].......>|
+00000040 49 51 a7 1d f5 df 10 c4 5a 77 37 ba 68 3d 4e c5 |IQ......Zw7.h=N.|
+00000050 11 ac 67 b7 e2 |..g..|
+>>> Flow 4 (server to client)
+00000000 16 03 03 00 83 04 00 00 7f 00 00 00 00 00 79 00 |..............y.|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 |................|
+00000020 6f 2d 7c 2b 51 ed 14 ef 68 ca 42 c5 4c 26 1d 23 |o-|+Q...h.B.L&.#|
+00000030 c4 90 54 85 8b 21 f5 0d e8 48 f2 5f 4e 6b f1 25 |..T..!...H._Nk.%|
+00000040 e8 46 8a e5 3c 09 57 df dd 37 a7 57 c5 a5 28 5a |.F..<.W..7.W..(Z|
+00000050 21 83 2a 98 4b a5 44 aa 5b cc 30 e9 62 49 38 16 |!.*.K.D.[.0.bI8.|
+00000060 7e 51 5c e5 15 c0 58 7d a4 aa c5 93 39 bb e2 b6 |~Q\...X}....9...|
+00000070 4f c4 3e 1e 03 dc 46 b1 f3 0d d2 61 6c 1e c5 e1 |O.>...F....al...|
+00000080 8f 18 2a 3c 85 83 c4 33 14 03 03 00 01 01 16 03 |..*<...3........|
+00000090 03 00 20 63 76 4f b3 77 4d 63 6c eb 73 f3 b2 ec |.. cvO.wMcl.s...|
+000000a0 b8 49 3e c5 81 d5 53 0c 96 77 2f 3f 52 d0 e1 5b |.I>...S..w/?R..[|
+000000b0 62 fa 0b 17 03 03 00 1d 2f 60 09 31 db e9 c5 23 |b......./`.1...#|
+000000c0 98 5c 46 23 a6 58 80 66 7d 50 84 f1 42 b8 65 65 |.\F#.X.f}P..B.ee|
+000000d0 77 2d d2 e4 be 15 03 03 00 12 b7 e8 e1 13 04 68 |w-.............h|
+000000e0 d5 21 c8 98 db 1b 1c 6e 4f b5 0b 9c |.!.....nO...|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch b/src/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch
new file mode 100644
index 0000000..2d8a2eb
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch
@@ -0,0 +1,14 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 9d 01 00 00 99 03 03 24 15 a8 f2 f5 |...........$....|
+00000010 53 02 78 f0 4c f7 82 3c 68 7d a0 b1 9a 0f 29 32 |S.x.L..<h}....)2|
+00000020 9c 38 cc e7 92 95 63 f2 30 53 46 00 00 04 cc a8 |.8....c.0SF.....|
+00000030 00 ff 01 00 00 6c 00 0b 00 04 03 00 01 02 00 0a |.....l..........|
+00000040 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 23 |...............#|
+00000050 00 00 00 10 00 10 00 0e 06 70 72 6f 74 6f 32 06 |.........proto2.|
+00000060 70 72 6f 74 6f 31 00 16 00 00 00 17 00 00 00 0d |proto1..........|
+00000070 00 30 00 2e 04 03 05 03 06 03 08 07 08 08 08 09 |.0..............|
+00000080 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................|
+00000090 03 03 02 03 03 01 02 01 03 02 02 02 04 02 05 02 |................|
+000000a0 06 02 |..|
+>>> Flow 2 (server to client)
+00000000 15 03 03 00 02 02 78 |......x|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ALPN-NotConfigured b/src/crypto/tls/testdata/Server-TLSv12-ALPN-NotConfigured
new file mode 100644
index 0000000..79f0748
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-ALPN-NotConfigured
@@ -0,0 +1,90 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 9d 01 00 00 99 03 03 19 26 ad 3f c0 |............&.?.|
+00000010 d6 a0 cc ac 9b 2a 91 d3 1a d5 96 78 5f 7c 3f e0 |.....*.....x_|?.|
+00000020 23 08 75 a1 ca cb aa da d7 c8 0b 00 00 04 cc a8 |#.u.............|
+00000030 00 ff 01 00 00 6c 00 0b 00 04 03 00 01 02 00 0a |.....l..........|
+00000040 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 23 |...............#|
+00000050 00 00 00 10 00 10 00 0e 06 70 72 6f 74 6f 32 06 |.........proto2.|
+00000060 70 72 6f 74 6f 31 00 16 00 00 00 17 00 00 00 0d |proto1..........|
+00000070 00 30 00 2e 04 03 05 03 06 03 08 07 08 08 08 09 |.0..............|
+00000080 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................|
+00000090 03 03 02 03 03 01 02 01 03 02 02 02 04 02 05 02 |................|
+000000a0 06 02 |..|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 3f 02 00 00 3b 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 44 4f 57 4e 47 52 44 01 00 cc a8 00 00 |...DOWNGRD......|
+00000030 13 00 23 00 00 ff 01 00 01 00 00 17 00 00 00 0b |..#.............|
+00000040 00 02 01 00 16 03 03 02 59 0b 00 02 55 00 02 52 |........Y...U..R|
+00000050 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 01 02 |..O0..K0........|
+00000060 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a |......?.[..0...*|
+00000070 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b 30 09 |.H........0.1.0.|
+00000080 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 03 55 |..U....Go1.0...U|
+00000090 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 |....Go Root0...1|
+000000a0 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d 32 35 |60101000000Z..25|
+000000b0 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 0b 30 |0101000000Z0.1.0|
+000000c0 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 06 03 |...U....Go1.0...|
+000000d0 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 2a 86 |U....Go0..0...*.|
+000000e0 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 |H............0..|
+000000f0 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc 06 28 |.....F}...'.H..(|
+00000100 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 |!.~...]..RE.z6G.|
+00000110 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb 4f 6d |...B[.....y.@.Om|
+00000120 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 |..+.....g....."8|
+00000130 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b |.J.ts+.4......t{|
+00000140 f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 |.X.la<..A..++$#w|
+00000150 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d 1e 24 |[.;.u]. T..c...$|
+00000160 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 62 f4 |....P....C...ub.|
+00000170 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 90 30 |..R.........0..0|
+00000180 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 |...U...........0|
+00000190 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 01 05 |...U.%..0...+...|
+000001a0 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 30 0c |......+.......0.|
+000001b0 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 06 03 |..U.......0.0...|
+000001c0 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e 49 a6 |U..........CC>I.|
+000001d0 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 04 14 |.m....`0...U.#..|
+000001e0 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 01 d5 |0...H.IM.~.1....|
+000001f0 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 10 82 |..n{0...U....0..|
+00000200 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 |.example.golang0|
+00000210 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 |...*.H..........|
+00000220 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 |...0.@+[P.a...SX|
+00000230 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a |...(.X..8....1Z.|
+00000240 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 38 92 |.f=C.-...... d8.|
+00000250 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 16 61 |$:....}.@ ._...a|
+00000260 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c |..v......\.....l|
+00000270 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 |..s..Cw.......@.|
+00000280 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 b3 3e |a.Lr+...F..M...>|
+00000290 c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 |...B...=.`.\!.;.|
+000002a0 fa e7 16 03 03 00 ac 0c 00 00 a8 03 00 1d 20 2f |.............. /|
+000002b0 e5 7d a3 47 cd 62 43 15 28 da ac 5f bb 29 07 30 |.}.G.bC.(.._.).0|
+000002c0 ff f6 84 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 08 |.........._X.;t.|
+000002d0 04 00 80 4f 9e 64 41 a6 8a 41 ab 9c c8 09 3e 94 |...O.dA..A....>.|
+000002e0 ee d2 9b ad 1b 3e a9 3c 7b 43 96 95 eb 4d b5 04 |.....>.<{C...M..|
+000002f0 1a 5f 0c b2 b3 a6 2c a4 e6 78 a8 b8 d5 6c 7f d0 |._....,..x...l..|
+00000300 16 e8 56 31 e0 4a 69 d3 6b 27 18 a3 4e f5 d1 6a |..V1.Ji.k'..N..j|
+00000310 36 15 b5 fc 4d 15 50 90 a0 30 b9 49 3d ac 8c 84 |6...M.P..0.I=...|
+00000320 d2 15 31 70 df e5 a6 97 d0 64 f7 1d 8a a1 87 4d |..1p.....d.....M|
+00000330 3c ee da 69 20 e4 31 67 ca f2 c0 09 ee 13 7c 78 |<..i .1g......|x|
+00000340 d6 c2 c0 39 e0 b8 00 52 a9 bf d0 99 e0 b0 66 70 |...9...R......fp|
+00000350 46 ae 62 16 03 03 00 04 0e 00 00 00 |F.b.........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 b0 1a 5b c3 55 5f |....%...! ..[.U_|
+00000010 0b b8 f3 69 ba 4f 49 93 05 0f b1 f1 d7 6b 6c 0c |...i.OI......kl.|
+00000020 98 d0 22 78 0c ad 15 6b 24 5b 14 03 03 00 01 01 |.."x...k$[......|
+00000030 16 03 03 00 20 9d aa 3f 17 b3 16 88 d5 44 3d 03 |.... ..?.....D=.|
+00000040 3c 3c 8d 92 f1 2f e4 38 cc 42 20 2f ef 6a 29 c6 |<<.../.8.B /.j).|
+00000050 5c ca 44 81 f6 |\.D..|
+>>> Flow 4 (server to client)
+00000000 16 03 03 00 83 04 00 00 7f 00 00 00 00 00 79 00 |..............y.|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 |................|
+00000020 6f 2d 7c 2b 51 ed 14 ef 68 ca 42 c5 4c 9a f3 2b |o-|+Q...h.B.L..+|
+00000030 7a 66 76 26 4f 73 12 14 ef a1 f4 8c c2 08 03 42 |zfv&Os.........B|
+00000040 4d d5 f9 d7 ab 31 78 51 f3 f4 94 49 5f 9d bf 23 |M....1xQ...I_..#|
+00000050 b2 11 7b ac 42 df 71 1a 37 db 64 99 a0 49 38 16 |..{.B.q.7.d..I8.|
+00000060 7e 51 5c e5 15 c0 58 7d 2d 89 ac 0d 05 31 27 ae |~Q\...X}-....1'.|
+00000070 85 ff 27 56 24 4c 26 b3 bc 6c f6 20 80 dd bd ba |..'V$L&..l. ....|
+00000080 a3 34 c2 32 a8 58 1b b9 14 03 03 00 01 01 16 03 |.4.2.X..........|
+00000090 03 00 20 74 e1 8a e6 a6 02 0d f7 e1 28 3a f4 c4 |.. t........(:..|
+000000a0 a6 8c 32 81 84 85 ec 58 6a 10 8a 6d c4 cc 10 3a |..2....Xj..m...:|
+000000b0 32 3e df 17 03 03 00 1d fd a8 94 23 3e 5d 96 b1 |2>.........#>]..|
+000000c0 68 a6 24 55 bf 29 08 93 c7 7b 9b 05 fc 0b 97 ff |h.$U.)...{......|
+000000d0 7c 93 b0 34 82 15 03 03 00 12 43 9f 44 e4 63 e7 ||..4......C.D.c.|
+000000e0 3c 30 a5 da 9f 58 ac 01 e4 e2 a7 30 |<0...X.....0|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndECDSAGiven b/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndECDSAGiven
new file mode 100644
index 0000000..41ed6c4
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndECDSAGiven
@@ -0,0 +1,126 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 6d 01 00 00 69 03 03 5e 92 9d 30 27 |....m...i..^..0'|
+00000010 23 da fa a0 07 30 03 c8 bd 60 f2 db e9 5e b3 fc |#....0...`...^..|
+00000020 65 d3 c5 e1 49 35 63 86 53 ec 87 00 00 04 00 2f |e...I5c.S....../|
+00000030 00 ff 01 00 00 3c 00 16 00 00 00 17 00 00 00 0d |.....<..........|
+00000040 00 30 00 2e 04 03 05 03 06 03 08 07 08 08 08 09 |.0..............|
+00000050 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................|
+00000060 03 03 02 03 03 01 02 01 03 02 02 02 04 02 05 02 |................|
+00000070 06 02 |..|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 35 02 00 00 31 03 03 00 00 00 00 00 |....5...1.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 2f 00 00 |...DOWNGRD.../..|
+00000030 09 ff 01 00 01 00 00 17 00 00 16 03 03 02 59 0b |..............Y.|
+00000040 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..|
+00000050 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.|
+00000060 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........|
+00000070 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1|
+00000080 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo|
+00000090 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000|
+000000a0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000|
+000000b0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go|
+000000c0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..|
+000000d0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........|
+000000e0 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...|
+000000f0 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R|
+00000100 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....|
+00000110 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.|
+00000120 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..|
+00000130 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.|
+00000140 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.|
+00000150 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C|
+00000160 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......|
+00000170 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......|
+00000180 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.|
+00000190 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...|
+000001a0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......|
+000001b0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........|
+000001c0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..|
+000001d0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~|
+000001e0 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.|
+000001f0 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g|
+00000200 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....|
+00000210 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.|
+00000220 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.|
+00000230 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....|
+00000240 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ |
+00000250 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\|
+00000260 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...|
+00000270 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.|
+00000280 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`|
+00000290 84 5c 21 d3 3b e9 fa e7 16 03 03 00 23 0d 00 00 |.\!.;.......#...|
+000002a0 1f 02 01 40 00 18 08 04 04 03 08 07 08 05 08 06 |...@............|
+000002b0 04 01 05 01 06 01 05 03 06 03 02 01 02 03 00 00 |................|
+000002c0 16 03 03 00 04 0e 00 00 00 |.........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 02 0a 0b 00 02 06 00 02 03 00 02 00 30 |...............0|
+00000010 82 01 fc 30 82 01 5e 02 09 00 9a 30 84 6c 26 35 |...0..^....0.l&5|
+00000020 d9 17 30 09 06 07 2a 86 48 ce 3d 04 01 30 45 31 |..0...*.H.=..0E1|
+00000030 0b 30 09 06 03 55 04 06 13 02 41 55 31 13 30 11 |.0...U....AU1.0.|
+00000040 06 03 55 04 08 13 0a 53 6f 6d 65 2d 53 74 61 74 |..U....Some-Stat|
+00000050 65 31 21 30 1f 06 03 55 04 0a 13 18 49 6e 74 65 |e1!0...U....Inte|
+00000060 72 6e 65 74 20 57 69 64 67 69 74 73 20 50 74 79 |rnet Widgits Pty|
+00000070 20 4c 74 64 30 1e 17 0d 31 32 31 31 31 34 31 33 | Ltd0...12111413|
+00000080 32 35 35 33 5a 17 0d 32 32 31 31 31 32 31 33 32 |2553Z..221112132|
+00000090 35 35 33 5a 30 41 31 0b 30 09 06 03 55 04 06 13 |553Z0A1.0...U...|
+000000a0 02 41 55 31 0c 30 0a 06 03 55 04 08 13 03 4e 53 |.AU1.0...U....NS|
+000000b0 57 31 10 30 0e 06 03 55 04 07 13 07 50 79 72 6d |W1.0...U....Pyrm|
+000000c0 6f 6e 74 31 12 30 10 06 03 55 04 03 13 09 4a 6f |ont1.0...U....Jo|
+000000d0 65 6c 20 53 69 6e 67 30 81 9b 30 10 06 07 2a 86 |el Sing0..0...*.|
+000000e0 48 ce 3d 02 01 06 05 2b 81 04 00 23 03 81 86 00 |H.=....+...#....|
+000000f0 04 00 95 8c 91 75 14 c0 5e c4 57 b4 d4 c3 6f 8d |.....u..^.W...o.|
+00000100 ae 68 1e dd 6f ce 86 e1 7e 6e b2 48 3e 81 e5 4e |.h..o...~n.H>..N|
+00000110 e2 c6 88 4b 64 dc f5 30 bb d3 ff 65 cc 5b f4 dd |...Kd..0...e.[..|
+00000120 b5 6a 3e 3e d0 1d de 47 c3 76 ad 19 f6 45 2c 8c |.j>>...G.v...E,.|
+00000130 bc d8 1d 01 4c 1f 70 90 46 76 48 8b 8f 83 cc 4a |....L.p.FvH....J|
+00000140 5c 8f 40 76 da e0 89 ec 1d 2b c4 4e 30 76 28 41 |\.@v.....+.N0v(A|
+00000150 b2 62 a8 fb 5b f1 f9 4e 7a 8d bd 09 b8 ae ea 8b |.b..[..Nz.......|
+00000160 18 27 4f 2e 70 fe 13 96 ba c3 d3 40 16 cd 65 4e |.'O.p......@..eN|
+00000170 ac 11 1e e6 f1 30 09 06 07 2a 86 48 ce 3d 04 01 |.....0...*.H.=..|
+00000180 03 81 8c 00 30 81 88 02 42 00 e0 14 c4 60 60 0b |....0...B....``.|
+00000190 72 68 b0 32 5d 61 4a 02 74 5c c2 81 b9 16 a8 3f |rh.2]aJ.t\.....?|
+000001a0 29 c8 36 c7 81 ff 6c b6 5b d9 70 f1 38 3b 50 48 |).6...l.[.p.8;PH|
+000001b0 28 94 cb 09 1a 52 f1 5d ee 8d f2 b9 f0 f0 da d9 |(....R.]........|
+000001c0 15 3a f9 bd 03 7a 87 a2 23 35 ec 02 42 01 a3 d4 |.:...z..#5..B...|
+000001d0 8a 78 35 1c 4a 9a 23 d2 0a be 2b 10 31 9d 9c 5f |.x5.J.#...+.1.._|
+000001e0 be e8 91 b3 da 1a f5 5d a3 23 f5 26 8b 45 70 8d |.......].#.&.Ep.|
+000001f0 65 62 9b 7e 01 99 3d 18 f6 10 9a 38 61 9b 2e 57 |eb.~..=....8a..W|
+00000200 e4 fa cc b1 8a ce e2 23 a0 87 f0 e1 67 51 eb 16 |.......#....gQ..|
+00000210 03 03 00 86 10 00 00 82 00 80 02 50 e4 cc a3 ad |...........P....|
+00000220 fb 33 24 a1 b3 0a 7c 0f 00 e6 1a 06 2b 9f 1e 1f |.3$...|.....+...|
+00000230 cc b8 b2 80 90 e7 86 20 32 40 06 ac 1b b0 41 b7 |....... 2@....A.|
+00000240 0d 9c 4c 41 90 01 0b 7a 7e b2 b2 46 39 dc 51 25 |..LA...z~..F9.Q%|
+00000250 98 e0 b9 ec 36 fc 08 64 f0 51 2a 41 e1 e5 61 3d |....6..d.Q*A..a=|
+00000260 fc 07 c1 9b 1f 6f 48 d4 1f 46 bf 14 e6 92 61 1a |.....oH..F....a.|
+00000270 bd 5f 25 1f 5e b1 3c ac c7 58 63 02 0d 3a e0 d6 |._%.^.<..Xc..:..|
+00000280 e9 39 fc ec 59 66 2e 91 b2 65 37 eb a8 b5 60 d9 |.9..Yf...e7...`.|
+00000290 49 05 9f 6f cc 71 79 bb f7 68 16 03 03 00 93 0f |I..o.qy..h......|
+000002a0 00 00 8f 04 03 00 8b 30 81 88 02 42 00 bd 6a 29 |.......0...B..j)|
+000002b0 21 06 1a e2 67 a1 7f 10 ab ca 3f 74 5a bc 2f 5d |!...g.....?tZ./]|
+000002c0 53 d0 59 90 f2 d0 b4 2d 75 47 67 0b 67 55 b6 4f |S.Y....-uGg.gU.O|
+000002d0 75 7d 32 d8 a7 25 c8 4c 90 0b 56 65 be 60 5d ee |u}2..%.L..Ve.`].|
+000002e0 f7 b3 80 79 26 e5 25 1d 17 cc d8 36 fc 39 02 42 |...y&.%....6.9.B|
+000002f0 01 c3 32 d6 f2 59 9e 10 c8 bf 7f 74 27 a1 00 df |..2..Y.....t'...|
+00000300 55 05 f0 b3 81 a1 6e 10 a6 fb 0b e4 1c 3f 62 02 |U.....n......?b.|
+00000310 c9 cc c2 4b 97 ad 0c 88 98 07 6c 98 6d db 9d 9f |...K......l.m...|
+00000320 68 a0 56 ab 5f f9 a2 21 33 86 64 53 de 37 ff 68 |h.V._..!3.dS.7.h|
+00000330 04 9d 14 03 03 00 01 01 16 03 03 00 40 85 14 34 |............@..4|
+00000340 d6 74 a9 d0 0b e9 1f 34 a9 e9 6c cf 5a ac 88 22 |.t.....4..l.Z.."|
+00000350 51 4d ae 16 05 dd 9e c1 36 5e e3 cf b1 5a b5 48 |QM......6^...Z.H|
+00000360 6c 24 b1 d6 fb 7f 03 6a 98 41 90 de 6d c7 b2 49 |l$.....j.A..m..I|
+00000370 d9 a3 c7 45 ff 18 7c f7 a4 cf 05 59 87 |...E..|....Y.|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....|
+00000010 00 00 00 00 00 00 00 00 00 00 00 63 1a 77 66 2a |...........c.wf*|
+00000020 49 3a b2 17 83 74 e1 d9 70 96 de 01 84 09 f4 88 |I:...t..p.......|
+00000030 c3 e7 3b 65 11 6f 13 32 b8 b4 f4 41 ca 6a d6 d7 |..;e.o.2...A.j..|
+00000040 51 a3 a1 f0 2d 5b b4 55 29 f9 d3 17 03 03 00 40 |Q...-[.U)......@|
+00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000060 d7 30 0f 03 89 22 4c 19 5f 06 a7 4b 95 59 91 52 |.0..."L._..K.Y.R|
+00000070 2a 65 ab 99 cb 71 99 8b 13 82 44 92 6b ff 59 07 |*e...q....D.k.Y.|
+00000080 28 ca 01 68 ab ad ba ee 6c 6a 19 0b e5 6d 82 24 |(..h....lj...m.$|
+00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
+000000a0 00 00 00 00 00 fc 07 f4 d4 bb 24 a3 f1 cf dc 3c |..........$....<|
+000000b0 ac 14 63 50 32 34 fd 73 c0 eb f2 78 7b 3b ea 58 |..cP24.s...x{;.X|
+000000c0 cc 3e ff 7f e5 |.>...|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndEd25519Given b/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndEd25519Given
new file mode 100644
index 0000000..f8cc960
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndEd25519Given
@@ -0,0 +1,109 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 6d 01 00 00 69 03 03 8a fe ad ad 75 |....m...i......u|
+00000010 e4 8c bf bf b7 b6 66 14 92 eb 84 85 9c c8 a7 66 |......f........f|
+00000020 04 2a d0 63 5e a6 bf 85 e9 4f 49 00 00 04 00 2f |.*.c^....OI..../|
+00000030 00 ff 01 00 00 3c 00 16 00 00 00 17 00 00 00 0d |.....<..........|
+00000040 00 30 00 2e 04 03 05 03 06 03 08 07 08 08 08 09 |.0..............|
+00000050 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................|
+00000060 03 03 02 03 03 01 02 01 03 02 02 02 04 02 05 02 |................|
+00000070 06 02 |..|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 35 02 00 00 31 03 03 00 00 00 00 00 |....5...1.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 2f 00 00 |...DOWNGRD.../..|
+00000030 09 ff 01 00 01 00 00 17 00 00 16 03 03 02 59 0b |..............Y.|
+00000040 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..|
+00000050 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.|
+00000060 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........|
+00000070 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1|
+00000080 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo|
+00000090 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000|
+000000a0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000|
+000000b0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go|
+000000c0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..|
+000000d0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........|
+000000e0 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...|
+000000f0 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R|
+00000100 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....|
+00000110 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.|
+00000120 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..|
+00000130 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.|
+00000140 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.|
+00000150 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C|
+00000160 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......|
+00000170 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......|
+00000180 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.|
+00000190 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...|
+000001a0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......|
+000001b0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........|
+000001c0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..|
+000001d0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~|
+000001e0 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.|
+000001f0 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g|
+00000200 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....|
+00000210 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.|
+00000220 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.|
+00000230 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....|
+00000240 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ |
+00000250 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\|
+00000260 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...|
+00000270 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.|
+00000280 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`|
+00000290 84 5c 21 d3 3b e9 fa e7 16 03 03 00 23 0d 00 00 |.\!.;.......#...|
+000002a0 1f 02 01 40 00 18 08 04 04 03 08 07 08 05 08 06 |...@............|
+000002b0 04 01 05 01 06 01 05 03 06 03 02 01 02 03 00 00 |................|
+000002c0 16 03 03 00 04 0e 00 00 00 |.........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 01 3c 0b 00 01 38 00 01 35 00 01 32 30 |....<...8..5..20|
+00000010 82 01 2e 30 81 e1 a0 03 02 01 02 02 10 17 d1 81 |...0............|
+00000020 93 be 2a 8c 21 20 10 25 15 e8 34 23 4f 30 05 06 |..*.! .%..4#O0..|
+00000030 03 2b 65 70 30 12 31 10 30 0e 06 03 55 04 0a 13 |.+ep0.1.0...U...|
+00000040 07 41 63 6d 65 20 43 6f 30 1e 17 0d 31 39 30 35 |.Acme Co0...1905|
+00000050 31 36 32 31 35 34 32 36 5a 17 0d 32 30 30 35 31 |16215426Z..20051|
+00000060 35 32 31 35 34 32 36 5a 30 12 31 10 30 0e 06 03 |5215426Z0.1.0...|
+00000070 55 04 0a 13 07 41 63 6d 65 20 43 6f 30 2a 30 05 |U....Acme Co0*0.|
+00000080 06 03 2b 65 70 03 21 00 0b e0 b5 60 b5 e2 79 30 |..+ep.!....`..y0|
+00000090 3d be e3 1e e0 50 b1 04 c8 6d c7 78 6c 69 2f c5 |=....P...m.xli/.|
+000000a0 14 ad 9a 63 6f 79 12 91 a3 4d 30 4b 30 0e 06 03 |...coy...M0K0...|
+000000b0 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 13 06 03 |U...........0...|
+000000c0 55 1d 25 04 0c 30 0a 06 08 2b 06 01 05 05 07 03 |U.%..0...+......|
+000000d0 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 |.0...U.......0.0|
+000000e0 16 06 03 55 1d 11 04 0f 30 0d 82 0b 65 78 61 6d |...U....0...exam|
+000000f0 70 6c 65 2e 63 6f 6d 30 05 06 03 2b 65 70 03 41 |ple.com0...+ep.A|
+00000100 00 fc 19 17 2a 94 a5 31 fa 29 c8 2e 7f 5b a0 5d |....*..1.)...[.]|
+00000110 8a 4e 34 40 39 d6 b3 10 dc 19 fe a0 22 71 b3 f5 |.N4@9......."q..|
+00000120 8f a1 58 0d cd f4 f1 85 24 bf e6 3d 14 df df ed |..X.....$..=....|
+00000130 0e e1 17 d8 11 a2 60 d0 8a 37 23 2a c2 46 aa 3a |......`..7#*.F.:|
+00000140 08 16 03 03 00 86 10 00 00 82 00 80 77 8b 9f 34 |............w..4|
+00000150 b4 db a7 0d 5b ed 1b 2f 4a 41 64 f5 ce 4a 00 7c |....[../JAd..J.||
+00000160 91 32 b3 cf 61 18 41 04 ae fa 3b 14 de 19 0e 64 |.2..a.A...;....d|
+00000170 f9 ec 75 a6 48 7e 28 57 26 f5 1c 75 1d 42 73 fc |..u.H~(W&..u.Bs.|
+00000180 11 51 2b ef e5 08 83 ac 17 ec 78 b8 5b 14 84 c9 |.Q+.......x.[...|
+00000190 bc 7f 22 fd 54 69 7a 82 36 c7 21 bc d6 04 c4 e7 |..".Tiz.6.!.....|
+000001a0 bc 48 c8 72 56 5d 1e 65 41 21 0a 26 85 a0 d8 c3 |.H.rV].eA!.&....|
+000001b0 50 f0 b6 07 25 ee 79 b8 f5 e6 17 85 d4 09 e7 d7 |P...%.y.........|
+000001c0 ab 8f 17 cb c2 13 a0 5a 50 cb e4 a7 16 03 03 00 |.......ZP.......|
+000001d0 48 0f 00 00 44 08 07 00 40 b7 24 50 46 db d4 8c |H...D...@.$PF...|
+000001e0 68 17 f5 5e 79 a9 80 8c 40 23 92 33 4e 1e cc ee |h..^y...@#.3N...|
+000001f0 d5 35 4d b8 2a 52 f0 7f 50 8e c6 d5 5f bc 08 35 |.5M.*R..P..._..5|
+00000200 a2 6d db cb 96 52 ec 92 c7 62 c7 59 ab d8 6f 9d |.m...R...b.Y..o.|
+00000210 d7 46 35 71 28 41 89 59 02 14 03 03 00 01 01 16 |.F5q(A.Y........|
+00000220 03 03 00 40 3e 12 44 bc c6 3d 88 71 ba d3 0c 26 |...@>.D..=.q...&|
+00000230 20 72 b0 7f 25 83 9f fd 77 c1 f5 1e 47 28 2e 60 | r..%...w...G(.`|
+00000240 53 e0 ac 52 e8 94 e4 87 90 3f af f3 a4 c0 d3 ba |S..R.....?......|
+00000250 fe b7 06 54 f7 13 33 36 47 8f 5e 45 22 84 18 3a |...T..36G.^E"..:|
+00000260 1f 14 21 85 |..!.|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....|
+00000010 00 00 00 00 00 00 00 00 00 00 00 d4 e6 b8 6f 53 |..............oS|
+00000020 6a d9 37 2b a4 95 9f 04 e5 99 2f f9 9a 16 fd a7 |j.7+....../.....|
+00000030 2d 39 d9 aa 7c 26 9e 44 4b 7f 8f d5 c6 24 4d ac |-9..|&.DK....$M.|
+00000040 13 ca 8a 45 1e 66 dc 9a bf 76 22 17 03 03 00 40 |...E.f...v"....@|
+00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000060 3f 5c 60 f8 22 7b aa 82 38 c4 4a 2e 07 50 cb 6c |?\`."{..8.J..P.l|
+00000070 3f 6f a9 39 bf 21 ce 7a 30 72 03 90 ec bc 9c 18 |?o.9.!.z0r......|
+00000080 1f a9 7f 82 3a d9 46 d9 d8 b8 77 65 e8 b3 e7 f5 |....:.F...we....|
+00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
+000000a0 00 00 00 00 00 6d 29 d4 87 0a b4 1d b4 9d f4 12 |.....m).........|
+000000b0 bc 3d a3 1b 79 21 85 0d e7 10 64 92 40 39 05 99 |.=..y!....d.@9..|
+000000c0 c8 a7 dd ef 0e |.....|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndGiven b/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndGiven
new file mode 100644
index 0000000..cc6450a
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndGiven
@@ -0,0 +1,125 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 6d 01 00 00 69 03 03 e9 31 0f d0 25 |....m...i...1..%|
+00000010 ef 25 a7 1a 9b 8c 4b a3 ca 2b a6 54 89 1c e1 68 |.%....K..+.T...h|
+00000020 6f b2 b2 60 6f 8a dc 87 24 8c 7b 00 00 04 00 2f |o..`o...$.{..../|
+00000030 00 ff 01 00 00 3c 00 16 00 00 00 17 00 00 00 0d |.....<..........|
+00000040 00 30 00 2e 04 03 05 03 06 03 08 07 08 08 08 09 |.0..............|
+00000050 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................|
+00000060 03 03 02 03 03 01 02 01 03 02 02 02 04 02 05 02 |................|
+00000070 06 02 |..|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 35 02 00 00 31 03 03 00 00 00 00 00 |....5...1.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 2f 00 00 |...DOWNGRD.../..|
+00000030 09 ff 01 00 01 00 00 17 00 00 16 03 03 02 59 0b |..............Y.|
+00000040 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..|
+00000050 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.|
+00000060 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........|
+00000070 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1|
+00000080 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo|
+00000090 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000|
+000000a0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000|
+000000b0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go|
+000000c0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..|
+000000d0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........|
+000000e0 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...|
+000000f0 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R|
+00000100 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....|
+00000110 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.|
+00000120 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..|
+00000130 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.|
+00000140 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.|
+00000150 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C|
+00000160 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......|
+00000170 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......|
+00000180 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.|
+00000190 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...|
+000001a0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......|
+000001b0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........|
+000001c0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..|
+000001d0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~|
+000001e0 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.|
+000001f0 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g|
+00000200 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....|
+00000210 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.|
+00000220 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.|
+00000230 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....|
+00000240 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ |
+00000250 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\|
+00000260 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...|
+00000270 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.|
+00000280 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`|
+00000290 84 5c 21 d3 3b e9 fa e7 16 03 03 00 23 0d 00 00 |.\!.;.......#...|
+000002a0 1f 02 01 40 00 18 08 04 04 03 08 07 08 05 08 06 |...@............|
+000002b0 04 01 05 01 06 01 05 03 06 03 02 01 02 03 00 00 |................|
+000002c0 16 03 03 00 04 0e 00 00 00 |.........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 01 fd 0b 00 01 f9 00 01 f6 00 01 f3 30 |...............0|
+00000010 82 01 ef 30 82 01 58 a0 03 02 01 02 02 10 5c 19 |...0..X.......\.|
+00000020 c1 89 65 83 55 6f dc 0b c9 b9 93 9f e9 bc 30 0d |..e.Uo........0.|
+00000030 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 12 31 |..*.H........0.1|
+00000040 10 30 0e 06 03 55 04 0a 13 07 41 63 6d 65 20 43 |.0...U....Acme C|
+00000050 6f 30 1e 17 0d 31 36 30 38 31 37 32 31 35 32 33 |o0...16081721523|
+00000060 31 5a 17 0d 31 37 30 38 31 37 32 31 35 32 33 31 |1Z..170817215231|
+00000070 5a 30 12 31 10 30 0e 06 03 55 04 0a 13 07 41 63 |Z0.1.0...U....Ac|
+00000080 6d 65 20 43 6f 30 81 9f 30 0d 06 09 2a 86 48 86 |me Co0..0...*.H.|
+00000090 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 |...........0....|
+000000a0 81 00 ba 6f aa 86 bd cf bf 9f f2 ef 5c 94 60 78 |...o........\.`x|
+000000b0 6f e8 13 f2 d1 96 6f cd d9 32 6e 22 37 ce 41 f9 |o.....o..2n"7.A.|
+000000c0 ca 5d 29 ac e1 27 da 61 a2 ee 81 cb 10 c7 df 34 |.])..'.a.......4|
+000000d0 58 95 86 e9 3d 19 e6 5c 27 73 60 c8 8d 78 02 f4 |X...=..\'s`..x..|
+000000e0 1d a4 98 09 a3 19 70 69 3c 25 62 66 2a ab 22 23 |......pi<%bf*."#|
+000000f0 c5 7b 85 38 4f 2e 09 73 32 a7 bd 3e 9b ad ca 84 |.{.8O..s2..>....|
+00000100 07 e6 0f 3a ff 77 c5 9d 41 85 00 8a b6 9b ee b0 |...:.w..A.......|
+00000110 a4 3f 2d 4c 4c e6 42 3e bb 51 c8 dd 48 54 f4 0c |.?-LL.B>.Q..HT..|
+00000120 8e 47 02 03 01 00 01 a3 46 30 44 30 0e 06 03 55 |.G......F0D0...U|
+00000130 1d 0f 01 01 ff 04 04 03 02 05 a0 30 13 06 03 55 |...........0...U|
+00000140 1d 25 04 0c 30 0a 06 08 2b 06 01 05 05 07 03 01 |.%..0...+.......|
+00000150 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 0f |0...U.......0.0.|
+00000160 06 03 55 1d 11 04 08 30 06 87 04 7f 00 00 01 30 |..U....0.......0|
+00000170 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 |...*.H..........|
+00000180 81 00 46 ab 44 a2 fb 28 54 f8 5a 67 f8 62 94 f1 |..F.D..(T.Zg.b..|
+00000190 9a b2 18 9e f2 b1 de 1d 7e 6f 76 95 a9 ba e7 5d |........~ov....]|
+000001a0 a8 16 6c 9c f7 09 d3 37 e4 4b 2b 36 7c 01 ad 41 |..l....7.K+6|..A|
+000001b0 d2 32 d8 c3 d2 93 f9 10 6b 8e 95 b9 2c 17 8a a3 |.2......k...,...|
+000001c0 44 48 bc 59 13 83 16 04 88 a4 81 5c 25 0d 98 0c |DH.Y.......\%...|
+000001d0 ac 11 b1 28 56 be 1d cd 61 62 84 09 bf d6 80 c6 |...(V...ab......|
+000001e0 45 8d 82 2c b4 d8 83 9b db c9 22 b7 2a 12 11 7b |E..,......".*..{|
+000001f0 fa 02 3b c1 c9 ff ea c9 9d a8 49 d3 95 d7 d5 0e |..;.......I.....|
+00000200 e5 35 16 03 03 00 86 10 00 00 82 00 80 29 51 da |.5...........)Q.|
+00000210 8e 5c 3e fb 44 8a 0f 97 42 23 8b e2 73 cc e2 90 |.\>.D...B#..s...|
+00000220 11 c4 98 01 e9 60 96 9e a9 96 30 c5 95 f8 56 0e |.....`....0...V.|
+00000230 4a 2e 77 e7 7e 23 b7 49 31 c4 87 c5 69 c6 ca 6f |J.w.~#.I1...i..o|
+00000240 ea 53 41 b4 2e 1e f6 0b 33 f5 e1 40 69 c0 91 6f |.SA.....3..@i..o|
+00000250 88 c1 68 c8 18 99 6e fe b3 5f 9b ee f1 4a 76 41 |..h...n.._...JvA|
+00000260 1f d1 05 f5 39 76 61 e6 a6 ea 75 0e 50 32 a1 19 |....9va...u.P2..|
+00000270 20 6a 4c 5d 62 6e 2a 6e af f9 9c 38 b6 3a bc 86 | jL]bn*n...8.:..|
+00000280 eb ac 6d d3 b5 48 30 11 4d 98 2e 61 34 16 03 03 |..m..H0.M..a4...|
+00000290 00 88 0f 00 00 84 08 04 00 80 82 ed 3f da b5 50 |............?..P|
+000002a0 d2 50 51 14 cf ee f7 b9 7b a9 0c 77 2f 88 42 0a |.PQ.....{..w/.B.|
+000002b0 34 a9 5d e7 32 26 3a 28 87 49 fb c4 83 31 68 c6 |4.].2&:(.I...1h.|
+000002c0 0d 32 d4 31 0a d1 d6 1e 6f 7f 89 93 bf b7 7c c7 |.2.1....o.....|.|
+000002d0 95 f8 c3 69 d8 58 4e e4 76 07 36 84 b7 c3 e7 22 |...i.XN.v.6...."|
+000002e0 01 4c 59 ae 89 95 bb e0 07 e0 31 6a e2 95 4c d4 |.LY.......1j..L.|
+000002f0 01 54 9d 27 82 60 31 13 39 07 47 c2 0c 08 5c d4 |.T.'.`1.9.G...\.|
+00000300 03 5a 6f d7 89 a0 67 5e 2d a0 11 03 bf 0e 35 d8 |.Zo...g^-.....5.|
+00000310 d0 78 2f 1e d8 15 47 ce c9 d3 14 03 03 00 01 01 |.x/...G.........|
+00000320 16 03 03 00 40 d0 0a 0e 93 dd 9a 51 4f a9 7f 5f |....@......QO.._|
+00000330 93 a6 60 a6 f2 10 f1 bd bd ae 13 5d 11 b7 0d 1a |..`........]....|
+00000340 3d 1e f3 0c b7 53 7c 10 ed fa 8c d7 3f 20 ec f2 |=....S|.....? ..|
+00000350 7d e9 15 87 3d d3 05 21 3a bc a5 54 fa 40 3b 53 |}...=..!:..T.@;S|
+00000360 41 7c ea c6 28 |A|..(|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....|
+00000010 00 00 00 00 00 00 00 00 00 00 00 a8 8e 30 08 f0 |.............0..|
+00000020 87 7b 13 31 99 6d 7e 9a 9b 03 d3 6f 84 d8 d9 31 |.{.1.m~....o...1|
+00000030 2b d2 aa d4 0e ae 6e 72 03 ac e7 7e 5c 22 cc ac |+.....nr...~\"..|
+00000040 33 b5 df 04 b2 4a 2b 6f bb a1 6f 17 03 03 00 40 |3....J+o..o....@|
+00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000060 50 9c 81 04 9b 1d 61 8a 30 9c 18 68 c7 e1 c9 f3 |P.....a.0..h....|
+00000070 70 f0 1b b6 4a dd fc c7 e3 e3 20 e2 4d 6f 9f bf |p...J..... .Mo..|
+00000080 17 b0 5e 5b 45 73 29 1e d4 30 b4 03 ca 8e 69 63 |..^[Es)..0....ic|
+00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
+000000a0 00 00 00 00 00 28 ca 6a 4c 1b 3c 11 61 ce b2 58 |.....(.jL.<.a..X|
+000000b0 94 e7 e4 7d c5 ce 51 03 c4 ae b5 4c 33 0b 3c 95 |...}..Q....L3.<.|
+000000c0 ec b1 65 ea da |..e..|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndPKCS1v15Given b/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndPKCS1v15Given
new file mode 100644
index 0000000..875fe1b
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndPKCS1v15Given
@@ -0,0 +1,125 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 6d 01 00 00 69 03 03 dc f3 c6 52 a4 |....m...i.....R.|
+00000010 9a 9c 53 e0 5a 3c cc 4c 4f 09 32 7f f1 7c 86 6b |..S.Z<.LO.2..|.k|
+00000020 75 59 68 a5 81 72 45 46 fb 94 a8 00 00 04 00 2f |uYh..rEF......./|
+00000030 00 ff 01 00 00 3c 00 16 00 00 00 17 00 00 00 0d |.....<..........|
+00000040 00 30 00 2e 04 03 05 03 06 03 08 07 08 08 08 09 |.0..............|
+00000050 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................|
+00000060 03 03 02 03 03 01 02 01 03 02 02 02 04 02 05 02 |................|
+00000070 06 02 |..|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 35 02 00 00 31 03 03 00 00 00 00 00 |....5...1.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 2f 00 00 |...DOWNGRD.../..|
+00000030 09 ff 01 00 01 00 00 17 00 00 16 03 03 02 59 0b |..............Y.|
+00000040 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..|
+00000050 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.|
+00000060 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........|
+00000070 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1|
+00000080 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo|
+00000090 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000|
+000000a0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000|
+000000b0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go|
+000000c0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..|
+000000d0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........|
+000000e0 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...|
+000000f0 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R|
+00000100 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....|
+00000110 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.|
+00000120 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..|
+00000130 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.|
+00000140 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.|
+00000150 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C|
+00000160 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......|
+00000170 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......|
+00000180 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.|
+00000190 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...|
+000001a0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......|
+000001b0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........|
+000001c0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..|
+000001d0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~|
+000001e0 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.|
+000001f0 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g|
+00000200 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....|
+00000210 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.|
+00000220 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.|
+00000230 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....|
+00000240 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ |
+00000250 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\|
+00000260 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...|
+00000270 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.|
+00000280 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`|
+00000290 84 5c 21 d3 3b e9 fa e7 16 03 03 00 23 0d 00 00 |.\!.;.......#...|
+000002a0 1f 02 01 40 00 18 08 04 04 03 08 07 08 05 08 06 |...@............|
+000002b0 04 01 05 01 06 01 05 03 06 03 02 01 02 03 00 00 |................|
+000002c0 16 03 03 00 04 0e 00 00 00 |.........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 01 fd 0b 00 01 f9 00 01 f6 00 01 f3 30 |...............0|
+00000010 82 01 ef 30 82 01 58 a0 03 02 01 02 02 10 5c 19 |...0..X.......\.|
+00000020 c1 89 65 83 55 6f dc 0b c9 b9 93 9f e9 bc 30 0d |..e.Uo........0.|
+00000030 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 12 31 |..*.H........0.1|
+00000040 10 30 0e 06 03 55 04 0a 13 07 41 63 6d 65 20 43 |.0...U....Acme C|
+00000050 6f 30 1e 17 0d 31 36 30 38 31 37 32 31 35 32 33 |o0...16081721523|
+00000060 31 5a 17 0d 31 37 30 38 31 37 32 31 35 32 33 31 |1Z..170817215231|
+00000070 5a 30 12 31 10 30 0e 06 03 55 04 0a 13 07 41 63 |Z0.1.0...U....Ac|
+00000080 6d 65 20 43 6f 30 81 9f 30 0d 06 09 2a 86 48 86 |me Co0..0...*.H.|
+00000090 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 |...........0....|
+000000a0 81 00 ba 6f aa 86 bd cf bf 9f f2 ef 5c 94 60 78 |...o........\.`x|
+000000b0 6f e8 13 f2 d1 96 6f cd d9 32 6e 22 37 ce 41 f9 |o.....o..2n"7.A.|
+000000c0 ca 5d 29 ac e1 27 da 61 a2 ee 81 cb 10 c7 df 34 |.])..'.a.......4|
+000000d0 58 95 86 e9 3d 19 e6 5c 27 73 60 c8 8d 78 02 f4 |X...=..\'s`..x..|
+000000e0 1d a4 98 09 a3 19 70 69 3c 25 62 66 2a ab 22 23 |......pi<%bf*."#|
+000000f0 c5 7b 85 38 4f 2e 09 73 32 a7 bd 3e 9b ad ca 84 |.{.8O..s2..>....|
+00000100 07 e6 0f 3a ff 77 c5 9d 41 85 00 8a b6 9b ee b0 |...:.w..A.......|
+00000110 a4 3f 2d 4c 4c e6 42 3e bb 51 c8 dd 48 54 f4 0c |.?-LL.B>.Q..HT..|
+00000120 8e 47 02 03 01 00 01 a3 46 30 44 30 0e 06 03 55 |.G......F0D0...U|
+00000130 1d 0f 01 01 ff 04 04 03 02 05 a0 30 13 06 03 55 |...........0...U|
+00000140 1d 25 04 0c 30 0a 06 08 2b 06 01 05 05 07 03 01 |.%..0...+.......|
+00000150 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 0f |0...U.......0.0.|
+00000160 06 03 55 1d 11 04 08 30 06 87 04 7f 00 00 01 30 |..U....0.......0|
+00000170 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 |...*.H..........|
+00000180 81 00 46 ab 44 a2 fb 28 54 f8 5a 67 f8 62 94 f1 |..F.D..(T.Zg.b..|
+00000190 9a b2 18 9e f2 b1 de 1d 7e 6f 76 95 a9 ba e7 5d |........~ov....]|
+000001a0 a8 16 6c 9c f7 09 d3 37 e4 4b 2b 36 7c 01 ad 41 |..l....7.K+6|..A|
+000001b0 d2 32 d8 c3 d2 93 f9 10 6b 8e 95 b9 2c 17 8a a3 |.2......k...,...|
+000001c0 44 48 bc 59 13 83 16 04 88 a4 81 5c 25 0d 98 0c |DH.Y.......\%...|
+000001d0 ac 11 b1 28 56 be 1d cd 61 62 84 09 bf d6 80 c6 |...(V...ab......|
+000001e0 45 8d 82 2c b4 d8 83 9b db c9 22 b7 2a 12 11 7b |E..,......".*..{|
+000001f0 fa 02 3b c1 c9 ff ea c9 9d a8 49 d3 95 d7 d5 0e |..;.......I.....|
+00000200 e5 35 16 03 03 00 86 10 00 00 82 00 80 b5 77 6b |.5............wk|
+00000210 fa 10 fb df 48 8f e7 51 b4 cb 14 c5 48 bd 63 d6 |....H..Q....H.c.|
+00000220 0e 19 d0 81 a8 5a d7 b5 43 84 35 85 37 b7 8d 2e |.....Z..C.5.7...|
+00000230 c7 c8 70 4c f4 45 bf be 17 86 e7 40 1d 6f 88 2a |..pL.E.....@.o.*|
+00000240 91 b5 aa aa 34 f7 9a f3 96 e4 dd 51 15 88 be f1 |....4......Q....|
+00000250 80 a9 6f 94 ed c7 5d 28 66 b4 37 e8 22 4f 42 c3 |..o...](f.7."OB.|
+00000260 b5 f0 2f dd 57 dc 8d e5 5a c0 9d fa ce 3c 7a 2d |../.W...Z....<z-|
+00000270 1d 45 9b fc 7b ba e7 11 eb 16 ae 68 bd b4 94 14 |.E..{......h....|
+00000280 3a a2 4d 0d e0 cd 53 a9 f1 07 d6 4a 41 16 03 03 |:.M...S....JA...|
+00000290 00 88 0f 00 00 84 04 01 00 80 78 60 7e 91 f5 47 |..........x`~..G|
+000002a0 15 61 85 70 cf b3 16 6e 45 4c 8b 42 2a 66 7e b6 |.a.p...nEL.B*f~.|
+000002b0 76 4f 26 6b b5 d7 e1 68 c2 2e bf b9 71 f2 30 7f |vO&k...h....q.0.|
+000002c0 e4 50 56 1e 0e 64 cf 05 5c 57 be 84 ce ac 8e 04 |.PV..d..\W......|
+000002d0 44 f8 c5 2a 55 ab c5 50 84 c4 b0 73 c7 73 46 80 |D..*U..P...s.sF.|
+000002e0 bd 33 0f bc 90 2f af 50 5a 21 a7 ec 01 6b f2 ae |.3.../.PZ!...k..|
+000002f0 84 bf 08 cb 7b 3a ca cb 76 bb e3 d7 e1 8e ee e2 |....{:..v.......|
+00000300 88 25 b0 9b 68 74 ff 48 5f 48 e0 8e bd 04 d0 85 |.%..ht.H_H......|
+00000310 ea 58 93 0c c4 27 01 38 5b c5 14 03 03 00 01 01 |.X...'.8[.......|
+00000320 16 03 03 00 40 9a 93 f3 2f 40 10 df 03 f1 90 8f |....@.../@......|
+00000330 41 4a 76 77 44 7c 00 13 c0 2b a2 86 b3 4e 09 93 |AJvwD|...+...N..|
+00000340 01 e4 3a d4 53 ae a1 4c 07 56 18 3c ec 7f 98 a6 |..:.S..L.V.<....|
+00000350 04 7b 15 23 e4 e1 75 15 ec 33 1d 09 04 e8 04 1a |.{.#..u..3......|
+00000360 e1 51 0c 78 99 |.Q.x.|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....|
+00000010 00 00 00 00 00 00 00 00 00 00 00 a2 b0 ad 7e 71 |..............~q|
+00000020 0c 2c db df 4c b1 4f 19 e6 00 4f 11 ff 5e 4a c5 |.,..L.O...O..^J.|
+00000030 c2 9d 8c 6c 03 50 12 3d 81 ec 44 5a 75 ba 2d 48 |...l.P.=..DZu.-H|
+00000040 7a 74 c3 a3 68 5a 26 ee 7e f5 a2 17 03 03 00 40 |zt..hZ&.~......@|
+00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000060 ad 1b 16 8e 39 99 64 7c c5 49 24 83 c4 4e f6 86 |....9.d|.I$..N..|
+00000070 6b 5d 68 ae f4 0b 58 23 83 eb ab 01 52 4d 07 a1 |k]h...X#....RM..|
+00000080 59 00 e8 dc a5 a1 6f 76 e2 e9 f2 e1 21 58 6b a0 |Y.....ov....!Xk.|
+00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
+000000a0 00 00 00 00 00 3c 6e a7 81 36 d0 8c 99 d8 f3 55 |.....<n..6.....U|
+000000b0 02 2e 1a 48 2d 5c 46 6e ff f2 17 f2 d4 60 b5 9e |...H-\Fn.....`..|
+000000c0 33 54 50 0d 6d |3TP.m|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedNotGiven b/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedNotGiven
new file mode 100644
index 0000000..7c2c59d
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedNotGiven
@@ -0,0 +1,85 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 6d 01 00 00 69 03 03 ac ea d9 49 98 |....m...i.....I.|
+00000010 9a 0c 7c 86 64 7c 73 72 6d 79 3f 7b e9 11 8b 1d |..|.d|srmy?{....|
+00000020 79 95 f5 f5 23 9f b2 f1 9c f4 b5 00 00 04 00 2f |y...#........../|
+00000030 00 ff 01 00 00 3c 00 16 00 00 00 17 00 00 00 0d |.....<..........|
+00000040 00 30 00 2e 04 03 05 03 06 03 08 07 08 08 08 09 |.0..............|
+00000050 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................|
+00000060 03 03 02 03 03 01 02 01 03 02 02 02 04 02 05 02 |................|
+00000070 06 02 |..|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 35 02 00 00 31 03 03 00 00 00 00 00 |....5...1.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 2f 00 00 |...DOWNGRD.../..|
+00000030 09 ff 01 00 01 00 00 17 00 00 16 03 03 02 59 0b |..............Y.|
+00000040 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..|
+00000050 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.|
+00000060 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........|
+00000070 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1|
+00000080 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo|
+00000090 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000|
+000000a0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000|
+000000b0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go|
+000000c0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..|
+000000d0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........|
+000000e0 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...|
+000000f0 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R|
+00000100 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....|
+00000110 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.|
+00000120 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..|
+00000130 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.|
+00000140 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.|
+00000150 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C|
+00000160 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......|
+00000170 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......|
+00000180 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.|
+00000190 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...|
+000001a0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......|
+000001b0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........|
+000001c0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..|
+000001d0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~|
+000001e0 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.|
+000001f0 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g|
+00000200 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....|
+00000210 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.|
+00000220 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.|
+00000230 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....|
+00000240 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ |
+00000250 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\|
+00000260 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...|
+00000270 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.|
+00000280 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`|
+00000290 84 5c 21 d3 3b e9 fa e7 16 03 03 00 23 0d 00 00 |.\!.;.......#...|
+000002a0 1f 02 01 40 00 18 08 04 04 03 08 07 08 05 08 06 |...@............|
+000002b0 04 01 05 01 06 01 05 03 06 03 02 01 02 03 00 00 |................|
+000002c0 16 03 03 00 04 0e 00 00 00 |.........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 07 0b 00 00 03 00 00 00 16 03 03 00 |................|
+00000010 86 10 00 00 82 00 80 2e 37 44 fb d7 1d 2f 3d a5 |........7D.../=.|
+00000020 1b 43 cf f4 1c cf 9d 95 fa be 9f 9d 96 8a 27 5d |.C............']|
+00000030 7b be 19 10 bd 5e 9a 3e 49 49 d2 af 85 07 70 f8 |{....^.>II....p.|
+00000040 c8 4f 69 02 ff 4e 9d ee f4 0d 4d 54 a1 aa 61 a3 |.Oi..N....MT..a.|
+00000050 e0 cc db a7 2c 46 80 6e eb 10 fb cd 2e 3b c5 50 |....,F.n.....;.P|
+00000060 2b a5 d9 a0 bf 01 d2 f8 d8 51 2b ad 40 6f c6 6f |+........Q+.@o.o|
+00000070 0e 30 53 27 73 89 b7 1b c1 28 ff ff 18 4c fa 6f |.0S's....(...L.o|
+00000080 fa 5f 16 b3 38 36 9f f4 07 74 ca bb bb c2 3f aa |._..86...t....?.|
+00000090 0d e7 42 24 fb f8 4c 14 03 03 00 01 01 16 03 03 |..B$..L.........|
+000000a0 00 40 19 02 9e 3a ce b9 38 40 ce d6 3b 87 b2 f6 |.@...:..8@..;...|
+000000b0 1b 7d ee 76 62 f8 6e 04 80 8f cb 1b f7 1e 1d a6 |.}.vb.n.........|
+000000c0 50 8a 59 b1 ad 7d c5 9d 2f 2d 14 56 2e e5 3b b3 |P.Y..}../-.V..;.|
+000000d0 db da 7e 37 10 97 71 91 d3 7b 93 f6 64 a4 d7 8b |..~7..q..{..d...|
+000000e0 d2 f0 |..|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....|
+00000010 00 00 00 00 00 00 00 00 00 00 00 46 c8 31 06 11 |...........F.1..|
+00000020 01 8e df b0 e7 cc 16 d3 97 2e a2 68 e7 a4 d1 0f |...........h....|
+00000030 91 71 dd ba db 97 20 45 60 c2 47 c7 ee 56 c4 68 |.q.... E`.G..V.h|
+00000040 a4 b1 05 09 e2 68 4d 54 fa ff 01 17 03 03 00 40 |.....hMT.......@|
+00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000060 79 bf ad 63 e3 11 2b d0 41 0e 24 85 92 c4 9b b5 |y..c..+.A.$.....|
+00000070 b2 d3 2e fc aa 46 84 85 a7 37 90 fc f0 2b 5a 7e |.....F...7...+Z~|
+00000080 28 9f 2e 57 1d 8f c3 ca eb 40 32 79 af 4b b8 28 |(..W.....@2y.K.(|
+00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
+000000a0 00 00 00 00 00 8b 6c 27 b8 ff f9 ea ca 68 75 54 |......l'.....huT|
+000000b0 bf bf a7 f4 b1 58 a5 b3 31 01 4d c7 85 58 31 d4 |.....X..1.M..X1.|
+000000c0 e7 da 7e 77 68 |..~wh|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ECDHE-ECDSA-AES b/src/crypto/tls/testdata/Server-TLSv12-ECDHE-ECDSA-AES
new file mode 100644
index 0000000..697b810
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-ECDHE-ECDSA-AES
@@ -0,0 +1,84 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 85 01 00 00 81 03 03 83 21 a6 e4 ea |............!...|
+00000010 e9 7b 3a 7c 72 28 ee 68 c5 c7 fa f1 98 ed 4a be |.{:|r(.h......J.|
+00000020 b8 42 13 fb d3 ab 63 16 d2 74 c8 00 00 04 c0 0a |.B....c..t......|
+00000030 00 ff 01 00 00 54 00 0b 00 04 03 00 01 02 00 0a |.....T..........|
+00000040 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 16 |................|
+00000050 00 00 00 17 00 00 00 0d 00 30 00 2e 04 03 05 03 |.........0......|
+00000060 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................|
+00000070 08 06 04 01 05 01 06 01 03 03 02 03 03 01 02 01 |................|
+00000080 03 02 02 02 04 02 05 02 06 02 |..........|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 3b 02 00 00 37 03 03 00 00 00 00 00 |....;...7.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 c0 0a 00 00 |...DOWNGRD......|
+00000030 0f ff 01 00 01 00 00 17 00 00 00 0b 00 02 01 00 |................|
+00000040 16 03 03 02 0e 0b 00 02 0a 00 02 07 00 02 04 30 |...............0|
+00000050 82 02 00 30 82 01 62 02 09 00 b8 bf 2d 47 a0 d2 |...0..b.....-G..|
+00000060 eb f4 30 09 06 07 2a 86 48 ce 3d 04 01 30 45 31 |..0...*.H.=..0E1|
+00000070 0b 30 09 06 03 55 04 06 13 02 41 55 31 13 30 11 |.0...U....AU1.0.|
+00000080 06 03 55 04 08 13 0a 53 6f 6d 65 2d 53 74 61 74 |..U....Some-Stat|
+00000090 65 31 21 30 1f 06 03 55 04 0a 13 18 49 6e 74 65 |e1!0...U....Inte|
+000000a0 72 6e 65 74 20 57 69 64 67 69 74 73 20 50 74 79 |rnet Widgits Pty|
+000000b0 20 4c 74 64 30 1e 17 0d 31 32 31 31 32 32 31 35 | Ltd0...12112215|
+000000c0 30 36 33 32 5a 17 0d 32 32 31 31 32 30 31 35 30 |0632Z..221120150|
+000000d0 36 33 32 5a 30 45 31 0b 30 09 06 03 55 04 06 13 |632Z0E1.0...U...|
+000000e0 02 41 55 31 13 30 11 06 03 55 04 08 13 0a 53 6f |.AU1.0...U....So|
+000000f0 6d 65 2d 53 74 61 74 65 31 21 30 1f 06 03 55 04 |me-State1!0...U.|
+00000100 0a 13 18 49 6e 74 65 72 6e 65 74 20 57 69 64 67 |...Internet Widg|
+00000110 69 74 73 20 50 74 79 20 4c 74 64 30 81 9b 30 10 |its Pty Ltd0..0.|
+00000120 06 07 2a 86 48 ce 3d 02 01 06 05 2b 81 04 00 23 |..*.H.=....+...#|
+00000130 03 81 86 00 04 00 c4 a1 ed be 98 f9 0b 48 73 36 |.............Hs6|
+00000140 7e c3 16 56 11 22 f2 3d 53 c3 3b 4d 21 3d cd 6b |~..V.".=S.;M!=.k|
+00000150 75 e6 f6 b0 dc 9a df 26 c1 bc b2 87 f0 72 32 7c |u......&.....r2||
+00000160 b3 64 2f 1c 90 bc ea 68 23 10 7e fe e3 25 c0 48 |.d/....h#.~..%.H|
+00000170 3a 69 e0 28 6d d3 37 00 ef 04 62 dd 0d a0 9c 70 |:i.(m.7...b....p|
+00000180 62 83 d8 81 d3 64 31 aa 9e 97 31 bd 96 b0 68 c0 |b....d1...1...h.|
+00000190 9b 23 de 76 64 3f 1a 5c 7f e9 12 0e 58 58 b6 5f |.#.vd?.\....XX._|
+000001a0 70 dd 9b d8 ea d5 d7 f5 d5 cc b9 b6 9f 30 66 5b |p............0f[|
+000001b0 66 9a 20 e2 27 e5 bf fe 3b 30 09 06 07 2a 86 48 |f. .'...;0...*.H|
+000001c0 ce 3d 04 01 03 81 8c 00 30 81 88 02 42 01 88 a2 |.=......0...B...|
+000001d0 4f eb e2 45 c5 48 7d 1b ac f5 ed 98 9d ae 47 70 |O..E.H}.......Gp|
+000001e0 c0 5e 1b b6 2f bd f1 b6 4d b7 61 40 d3 11 a2 ce |.^../...M.a@....|
+000001f0 ee 0b 7e 92 7e ff 76 9d c3 3b 7e a5 3f ce fa 10 |..~.~.v..;~.?...|
+00000200 e2 59 ec 47 2d 7c ac da 4e 97 0e 15 a0 6f d0 02 |.Y.G-|..N....o..|
+00000210 42 01 4d fc be 67 13 9c 2d 05 0e bd 3f a3 8c 25 |B.M..g..-...?..%|
+00000220 c1 33 13 83 0d 94 06 bb d4 37 7a f6 ec 7a c9 86 |.3.......7z..z..|
+00000230 2e dd d7 11 69 7f 85 7c 56 de fb 31 78 2b e4 c7 |....i..|V..1x+..|
+00000240 78 0d ae cb be 9e 4e 36 24 31 7b 6a 0f 39 95 12 |x.....N6$1{j.9..|
+00000250 07 8f 2a 16 03 03 00 b7 0c 00 00 b3 03 00 1d 20 |..*............ |
+00000260 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f bb 29 07 |/.}.G.bC.(.._.).|
+00000270 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 |0.........._X.;t|
+00000280 04 03 00 8b 30 81 88 02 42 00 b9 39 44 59 12 77 |....0...B..9DY.w|
+00000290 8d e2 79 25 01 d1 6a 05 3d 53 ea f3 91 d6 c5 09 |..y%..j.=S......|
+000002a0 24 bd 0c ad 24 cc 1c a7 fb 03 eb 0a 0d f4 30 96 |$...$.........0.|
+000002b0 8d 28 a1 b3 64 ba 30 27 95 29 23 22 91 62 c3 1f |.(..d.0'.)#".b..|
+000002c0 51 aa c8 be 17 85 31 8e f5 40 3e 02 42 00 ee a1 |Q.....1..@>.B...|
+000002d0 64 14 a1 52 b3 e5 54 c9 24 53 94 5a 43 d8 4f 79 |d..R..T.$S.ZC.Oy|
+000002e0 69 4b a8 51 ee de b3 b0 f7 1a 57 a3 28 72 d2 13 |iK.Q......W.(r..|
+000002f0 a6 d3 17 0b c4 45 34 7f 10 3b 81 cb 0c 8d 51 b6 |.....E4..;....Q.|
+00000300 0b 86 21 d0 ee 1d 7e 73 6b ea 77 8c 66 dc 65 16 |..!...~sk.w.f.e.|
+00000310 03 03 00 04 0e 00 00 00 |........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 ed 3e ba a7 43 53 |....%...! .>..CS|
+00000010 5e e4 60 aa 31 3f e1 69 60 32 25 3d fd 8b 32 da |^.`.1?.i`2%=..2.|
+00000020 f2 c5 db c7 02 e6 4d d0 de 15 14 03 03 00 01 01 |......M.........|
+00000030 16 03 03 00 40 ee 28 f2 27 82 24 9d 17 d1 48 7a |....@.(.'.$...Hz|
+00000040 74 2d dd 16 18 b7 70 97 2f 2b 91 47 eb c2 1d ae |t-....p./+.G....|
+00000050 3f 48 52 cd ff e7 9e 0b 35 ad 1f 60 5e 07 b1 5e |?HR.....5..`^..^|
+00000060 1c ba 6a 85 bb 6b 30 94 41 8a 59 81 cf 37 5f 26 |..j..k0.A.Y..7_&|
+00000070 b1 52 36 5f df |.R6_.|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....|
+00000010 00 00 00 00 00 00 00 00 00 00 00 f5 05 5a a6 22 |.............Z."|
+00000020 90 4e 8d d9 f1 55 c4 78 f2 ec 9d 97 cd fe af ae |.N...U.x........|
+00000030 b7 62 00 67 2e b2 d9 1e 0c a3 c8 6a bf d2 3c 42 |.b.g.......j..<B|
+00000040 c4 0a d1 08 36 64 8e bd 0a 2f a2 17 03 03 00 40 |....6d.../.....@|
+00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000060 ef 16 5e cb e7 c4 2d a8 76 77 da 18 91 bd cb 78 |..^...-.vw.....x|
+00000070 76 c5 5d 70 e5 ba 57 2a 1f 2b 11 3f 18 18 e6 1b |v.]p..W*.+.?....|
+00000080 36 78 c9 f1 5e 71 f1 71 f1 01 31 e6 37 fa 76 92 |6x..^q.q..1.7.v.|
+00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
+000000a0 00 00 00 00 00 13 3e 42 a5 61 84 ae 49 8b b9 91 |......>B.a..I...|
+000000b0 c2 a3 76 74 1e 4f 53 0a fc 71 de 0d d2 44 c8 ac |..vt.OS..q...D..|
+000000c0 2e 09 27 e6 ad |..'..|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-Ed25519 b/src/crypto/tls/testdata/Server-TLSv12-Ed25519
new file mode 100644
index 0000000..42bb154
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-Ed25519
@@ -0,0 +1,58 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 85 01 00 00 81 03 03 f3 04 e3 e7 a2 |................|
+00000010 39 79 b2 9e 94 35 cf c3 a8 54 77 ab 96 72 b6 40 |9y...5...Tw..r.@|
+00000020 de 59 6b cf d4 f5 f4 2c fd 7d f6 00 00 04 cc a9 |.Yk....,.}......|
+00000030 00 ff 01 00 00 54 00 0b 00 04 03 00 01 02 00 0a |.....T..........|
+00000040 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 16 |................|
+00000050 00 00 00 17 00 00 00 0d 00 30 00 2e 04 03 05 03 |.........0......|
+00000060 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................|
+00000070 08 06 04 01 05 01 06 01 03 03 02 03 03 01 02 01 |................|
+00000080 03 02 02 02 04 02 05 02 06 02 |..........|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 3b 02 00 00 37 03 03 00 00 00 00 00 |....;...7.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 cc a9 00 00 |...DOWNGRD......|
+00000030 0f ff 01 00 01 00 00 17 00 00 00 0b 00 02 01 00 |................|
+00000040 16 03 03 01 3c 0b 00 01 38 00 01 35 00 01 32 30 |....<...8..5..20|
+00000050 82 01 2e 30 81 e1 a0 03 02 01 02 02 10 0f 43 1c |...0..........C.|
+00000060 42 57 93 94 1d e9 87 e4 f1 ad 15 00 5d 30 05 06 |BW..........]0..|
+00000070 03 2b 65 70 30 12 31 10 30 0e 06 03 55 04 0a 13 |.+ep0.1.0...U...|
+00000080 07 41 63 6d 65 20 43 6f 30 1e 17 0d 31 39 30 35 |.Acme Co0...1905|
+00000090 31 36 32 31 33 38 30 31 5a 17 0d 32 30 30 35 31 |16213801Z..20051|
+000000a0 35 32 31 33 38 30 31 5a 30 12 31 10 30 0e 06 03 |5213801Z0.1.0...|
+000000b0 55 04 0a 13 07 41 63 6d 65 20 43 6f 30 2a 30 05 |U....Acme Co0*0.|
+000000c0 06 03 2b 65 70 03 21 00 3f e2 15 2e e6 e3 ef 3f |..+ep.!.?......?|
+000000d0 4e 85 4a 75 77 a3 64 9e ed e0 bf 84 2c cc 92 26 |N.Juw.d.....,..&|
+000000e0 8f fa 6f 34 83 aa ec 8f a3 4d 30 4b 30 0e 06 03 |..o4.....M0K0...|
+000000f0 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 13 06 03 |U...........0...|
+00000100 55 1d 25 04 0c 30 0a 06 08 2b 06 01 05 05 07 03 |U.%..0...+......|
+00000110 01 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 |.0...U.......0.0|
+00000120 16 06 03 55 1d 11 04 0f 30 0d 82 0b 65 78 61 6d |...U....0...exam|
+00000130 70 6c 65 2e 63 6f 6d 30 05 06 03 2b 65 70 03 41 |ple.com0...+ep.A|
+00000140 00 63 44 ed 9c c4 be 53 24 53 9f d2 10 8d 9f e8 |.cD....S$S......|
+00000150 21 08 90 95 39 e5 0d c1 55 ff 2c 16 b7 1d fc ab |!...9...U.,.....|
+00000160 7d 4d d4 e0 93 13 d0 a9 42 e0 b6 6b fe 5d 67 48 |}M......B..k.]gH|
+00000170 d7 9f 50 bc 6c cd 4b 03 83 7c f2 08 58 cd ac cf |..P.l.K..|..X...|
+00000180 0c 16 03 03 00 6c 0c 00 00 68 03 00 1d 20 2f e5 |.....l...h... /.|
+00000190 7d a3 47 cd 62 43 15 28 da ac 5f bb 29 07 30 ff |}.G.bC.(.._.).0.|
+000001a0 f6 84 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 08 07 |........._X.;t..|
+000001b0 00 40 a2 12 66 be 81 b1 24 93 f2 e1 60 9f c4 13 |.@..f...$...`...|
+000001c0 04 3f 39 77 8f fe e4 33 5b f7 9d 84 f5 0f 96 aa |.?9w...3[.......|
+000001d0 a0 d6 9d da ae b2 eb 76 64 02 82 58 d4 bc 5a 44 |.......vd..X..ZD|
+000001e0 b9 5a f5 33 57 fa a6 9c d5 05 84 9a 19 0b 65 37 |.Z.3W.........e7|
+000001f0 bc 05 16 03 03 00 04 0e 00 00 00 |...........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 95 58 05 04 03 27 |....%...! .X...'|
+00000010 5e 14 d4 41 5a 3b eb d3 13 ad d4 16 fb 43 bf d6 |^..AZ;.......C..|
+00000020 7c 0a 1e a9 6c f9 72 84 47 1a 14 03 03 00 01 01 ||...l.r.G.......|
+00000030 16 03 03 00 20 06 f8 af f4 38 35 de 88 74 d6 cc |.... ....85..t..|
+00000040 a8 fa 2c ee a4 88 42 5c 4a aa 62 49 dc 32 da 15 |..,...B\J.bI.2..|
+00000050 1d 9c 5a b8 59 |..Z.Y|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 20 3a 16 00 b6 c5 |.......... :....|
+00000010 76 1f 39 6b 17 2d 2f 34 83 c2 fd 1b 57 c4 0c 02 |v.9k.-/4....W...|
+00000020 18 16 6c d2 92 69 63 9b 32 33 e0 17 03 03 00 1d |..l..ic.23......|
+00000030 04 97 df f0 2c 4b 3d 69 99 36 eb 0b 11 56 97 ab |....,K=i.6...V..|
+00000040 98 5d d9 d4 6f 93 92 5c cc f6 7e 77 40 15 03 03 |.]..o..\..~w@...|
+00000050 00 12 58 cf 6e 90 04 6b ae 4f cf 6b 71 15 80 22 |..X.n..k.O.kq.."|
+00000060 f5 80 fa df |....|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ExportKeyingMaterial b/src/crypto/tls/testdata/Server-TLSv12-ExportKeyingMaterial
new file mode 100644
index 0000000..ff8d635
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-ExportKeyingMaterial
@@ -0,0 +1,96 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 89 01 00 00 85 03 03 ad 13 87 9e b3 |................|
+00000010 c7 71 bb bf be e3 b9 80 3f 17 bf 41 37 95 22 e6 |.q......?..A7.".|
+00000020 f2 98 a9 15 62 1d 65 06 69 ea 53 00 00 04 c0 14 |....b.e.i.S.....|
+00000030 00 ff 01 00 00 58 00 0b 00 04 03 00 01 02 00 0a |.....X..........|
+00000040 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 23 |...............#|
+00000050 00 00 00 16 00 00 00 17 00 00 00 0d 00 30 00 2e |.............0..|
+00000060 04 03 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b |................|
+00000070 08 04 08 05 08 06 04 01 05 01 06 01 03 03 02 03 |................|
+00000080 03 01 02 01 03 02 02 02 04 02 05 02 06 02 |..............|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 3f 02 00 00 3b 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 44 4f 57 4e 47 52 44 01 00 c0 14 00 00 |...DOWNGRD......|
+00000030 13 00 23 00 00 ff 01 00 01 00 00 17 00 00 00 0b |..#.............|
+00000040 00 02 01 00 16 03 03 02 59 0b 00 02 55 00 02 52 |........Y...U..R|
+00000050 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 01 02 |..O0..K0........|
+00000060 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a |......?.[..0...*|
+00000070 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b 30 09 |.H........0.1.0.|
+00000080 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 03 55 |..U....Go1.0...U|
+00000090 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 |....Go Root0...1|
+000000a0 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d 32 35 |60101000000Z..25|
+000000b0 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 0b 30 |0101000000Z0.1.0|
+000000c0 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 06 03 |...U....Go1.0...|
+000000d0 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 2a 86 |U....Go0..0...*.|
+000000e0 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 89 |H............0..|
+000000f0 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc 06 28 |.....F}...'.H..(|
+00000100 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 |!.~...]..RE.z6G.|
+00000110 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb 4f 6d |...B[.....y.@.Om|
+00000120 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 |..+.....g....."8|
+00000130 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b |.J.ts+.4......t{|
+00000140 f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 |.X.la<..A..++$#w|
+00000150 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d 1e 24 |[.;.u]. T..c...$|
+00000160 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 62 f4 |....P....C...ub.|
+00000170 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 90 30 |..R.........0..0|
+00000180 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 |...U...........0|
+00000190 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 01 05 |...U.%..0...+...|
+000001a0 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 30 0c |......+.......0.|
+000001b0 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 06 03 |..U.......0.0...|
+000001c0 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e 49 a6 |U..........CC>I.|
+000001d0 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 04 14 |.m....`0...U.#..|
+000001e0 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 01 d5 |0...H.IM.~.1....|
+000001f0 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 10 82 |..n{0...U....0..|
+00000200 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 |.example.golang0|
+00000210 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 03 81 |...*.H..........|
+00000220 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 |...0.@+[P.a...SX|
+00000230 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a |...(.X..8....1Z.|
+00000240 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 38 92 |.f=C.-...... d8.|
+00000250 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 16 61 |$:....}.@ ._...a|
+00000260 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c |..v......\.....l|
+00000270 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 |..s..Cw.......@.|
+00000280 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 b3 3e |a.Lr+...F..M...>|
+00000290 c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 |...B...=.`.\!.;.|
+000002a0 fa e7 16 03 03 00 ac 0c 00 00 a8 03 00 1d 20 2f |.............. /|
+000002b0 e5 7d a3 47 cd 62 43 15 28 da ac 5f bb 29 07 30 |.}.G.bC.(.._.).0|
+000002c0 ff f6 84 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 08 |.........._X.;t.|
+000002d0 04 00 80 41 24 c2 f9 e8 40 21 47 3c ab 8e 99 5e |...A$...@!G<...^|
+000002e0 0e 08 27 86 6c 29 ae 36 ed 21 18 23 67 cc f7 d5 |..'.l).6.!.#g...|
+000002f0 3f e2 2c 48 2f 3d 47 e5 af d5 61 86 0f 91 69 30 |?.,H/=G...a...i0|
+00000300 cf 84 56 f2 d3 c1 9a a3 a1 a2 c8 ef 4d 33 de 12 |..V.........M3..|
+00000310 d6 46 55 5b c6 6a 65 a5 36 b5 51 5b db 04 25 aa |.FU[.je.6.Q[..%.|
+00000320 1c af a0 b0 2d ee db 00 c5 ad 1b 94 d3 90 11 86 |....-...........|
+00000330 10 83 35 41 65 9e a4 2c a9 ee 37 ac d4 cc 05 76 |..5Ae..,..7....v|
+00000340 92 59 f9 51 68 79 6d 9e 5f eb 80 47 3a 7c e0 74 |.Y.Qhym._..G:|.t|
+00000350 ac f5 36 16 03 03 00 04 0e 00 00 00 |..6.........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 d2 ed 26 ce 1f 5d |....%...! ..&..]|
+00000010 50 b8 f4 19 fc 63 e2 b6 3d 7d 39 54 c2 c1 61 a9 |P....c..=}9T..a.|
+00000020 2a 82 d8 e3 a9 2f 22 8c b2 18 14 03 03 00 01 01 |*..../".........|
+00000030 16 03 03 00 40 82 78 f0 1e e6 03 20 67 66 4e d6 |....@.x.... gfN.|
+00000040 93 25 69 9e 38 c6 dd 17 92 02 18 7f 5f 9c 9c f0 |.%i.8......._...|
+00000050 a3 f7 45 d3 ba 82 e3 01 38 e5 4f cf 8b 0e 77 6e |..E.....8.O...wn|
+00000060 91 99 83 e0 f1 3d e8 a1 39 d4 ea b3 2e 1c 67 59 |.....=..9.....gY|
+00000070 c5 5d 83 30 dc |.].0.|
+>>> Flow 4 (server to client)
+00000000 16 03 03 00 83 04 00 00 7f 00 00 00 00 00 79 00 |..............y.|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 |................|
+00000020 6f 2d 70 97 51 ed 14 ef 68 ca 42 c5 4c ff 6b a2 |o-p.Q...h.B.L.k.|
+00000030 3e f9 07 a9 91 ad 0d c7 23 bd 7f 04 cf 4d a0 eb |>.......#....M..|
+00000040 58 e0 e1 37 73 d3 cc 4b e2 7f 6d 3a 2e 47 b5 b4 |X..7s..K..m:.G..|
+00000050 60 dd e6 9a ea 30 1e 6e 7a e7 8e 84 ca 49 38 16 |`....0.nz....I8.|
+00000060 7e 51 5c e5 15 c0 58 7d a2 ba e2 ca 90 24 11 ea |~Q\...X}.....$..|
+00000070 53 9c 7d cb 47 13 91 cf f6 05 f0 2f db 57 1a 40 |S.}.G....../.W.@|
+00000080 57 b0 d4 97 8e 23 7e f5 14 03 03 00 01 01 16 03 |W....#~.........|
+00000090 03 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 |..@.............|
+000000a0 00 00 00 72 43 0e f2 f3 bb e8 6d 3b f2 ff 96 53 |...rC.....m;...S|
+000000b0 12 36 07 e0 f0 17 35 e7 52 87 a3 12 7b 53 d4 83 |.6....5.R...{S..|
+000000c0 cc d2 d3 06 4b e2 3a fc 38 4f a7 75 d8 3c 6a a4 |....K.:.8O.u.<j.|
+000000d0 b7 5f e8 17 03 03 00 40 00 00 00 00 00 00 00 00 |._.....@........|
+000000e0 00 00 00 00 00 00 00 00 7d b5 ce 35 23 2a ba 64 |........}..5#*.d|
+000000f0 0d 4e cc 9d 53 37 84 1d 6d c5 b0 ae a6 64 76 82 |.N..S7..m....dv.|
+00000100 4d 80 97 1e 16 5f 0a 85 72 be 27 41 a3 e0 45 35 |M...._..r.'A..E5|
+00000110 6e d4 c0 41 e5 99 8c 19 15 03 03 00 30 00 00 00 |n..A........0...|
+00000120 00 00 00 00 00 00 00 00 00 00 00 00 00 c9 f3 4e |...............N|
+00000130 91 b6 c2 c0 a5 cf 21 6b ed 58 d9 cf 9c 9b ff 0a |......!k.X......|
+00000140 6c 62 73 de f8 c3 39 22 2e d3 c6 45 9d |lbs...9"...E.|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-IssueTicket b/src/crypto/tls/testdata/Server-TLSv12-IssueTicket
new file mode 100644
index 0000000..ee29358
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-IssueTicket
@@ -0,0 +1,90 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 71 01 00 00 6d 03 03 bf f8 80 5d 1b |....q...m.....].|
+00000010 ea 95 cb 32 3b 8f ff 5e f9 4d 58 7d dc a4 50 cc |...2;..^.MX}..P.|
+00000020 68 4d 40 98 11 af f3 e4 d7 31 43 00 00 04 00 2f |hM@......1C..../|
+00000030 00 ff 01 00 00 40 00 23 00 00 00 16 00 00 00 17 |.....@.#........|
+00000040 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 08 07 |.....0..........|
+00000050 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 |................|
+00000060 05 01 06 01 03 03 02 03 03 01 02 01 03 02 02 02 |................|
+00000070 04 02 05 02 06 02 |......|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 39 02 00 00 35 03 03 00 00 00 00 00 |....9...5.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 2f 00 00 |...DOWNGRD.../..|
+00000030 0d 00 23 00 00 ff 01 00 01 00 00 17 00 00 16 03 |..#.............|
+00000040 03 02 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 |..Y...U..R..O0..|
+00000050 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d |K0..............|
+00000060 3f e2 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 |?.[..0...*.H....|
+00000070 01 0b 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 |....0.1.0...U...|
+00000080 02 47 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f |.Go1.0...U....Go|
+00000090 20 52 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 | Root0...1601010|
+000000a0 30 30 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 |00000Z..25010100|
+000000b0 30 30 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a |0000Z0.1.0...U..|
+000000c0 13 02 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 |..Go1.0...U....G|
+000000d0 6f 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 |o0..0...*.H.....|
+000000e0 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 |.......0.......F|
+000000f0 7d 93 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 |}...'.H..(!.~...|
+00000100 5d fe 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 |]..RE.z6G....B[.|
+00000110 81 c0 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 |....y.@.Om..+...|
+00000120 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b |..g....."8.J.ts+|
+00000130 c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c |.4......t{.X.la<|
+00000140 c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d |..A..++$#w[.;.u]|
+00000150 ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b |. T..c...$....P.|
+00000160 aa b6 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 |...C...ub...R...|
+00000170 01 00 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f |......0..0...U..|
+00000180 01 01 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 |.........0...U.%|
+00000190 04 16 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 |..0...+.........|
+000001a0 2b 06 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 |+.......0...U...|
+000001b0 01 ff 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 |....0.0...U.....|
+000001c0 10 9f 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f |.....CC>I..m....|
+000001d0 60 30 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 |`0...U.#..0...H.|
+000001e0 49 4d 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 |IM.~.1......n{0.|
+000001f0 06 03 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 |..U....0...examp|
+00000200 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 |le.golang0...*.H|
+00000210 86 f7 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 |.............0.@|
+00000220 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 |+[P.a...SX...(.X|
+00000230 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d |..8....1Z..f=C.-|
+00000240 d9 0b f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c |...... d8.$:....|
+00000250 7d b7 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 |}.@ ._...a..v...|
+00000260 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 |...\.....l..s..C|
+00000270 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d |w.......@.a.Lr+.|
+00000280 ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db |..F..M...>...B..|
+00000290 fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 |.=.`.\!.;.......|
+000002a0 04 0e 00 00 00 |.....|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 86 10 00 00 82 00 80 35 d7 dd 48 68 |...........5..Hh|
+00000010 17 8c 9b 02 75 0c 6b 76 17 0a e1 f8 06 c0 d7 1d |....u.kv........|
+00000020 bf a5 97 d2 59 0f c9 90 4a f0 6f 40 dc e7 30 c4 |....Y...J.o@..0.|
+00000030 75 ab 74 9c 32 48 a4 84 3c 40 a0 bd 03 aa 09 2b |u.t.2H..<@.....+|
+00000040 b2 4c 80 82 17 b8 3d 27 16 9a b7 90 66 f2 10 4e |.L....='....f..N|
+00000050 41 7e 78 24 de 27 91 f9 e9 bc bf 15 3a 35 1b ae |A~x$.'......:5..|
+00000060 28 9e e1 09 f0 7a 4d 66 7e de d1 43 bf f5 e4 09 |(....zMf~..C....|
+00000070 a7 21 cb 0e 1d 59 6d a0 a6 41 44 58 f4 ab ac 6a |.!...Ym..ADX...j|
+00000080 98 db 25 e3 57 ee 94 87 85 51 ea 14 03 03 00 01 |..%.W....Q......|
+00000090 01 16 03 03 00 40 c9 64 79 e7 15 1d 30 15 95 89 |.....@.dy...0...|
+000000a0 b1 9b 12 42 69 4b 22 20 54 5a aa b6 71 02 1c 3f |...BiK" TZ..q..?|
+000000b0 7c b5 66 07 b5 1f 55 96 3f ce 47 1f 66 52 d8 6b ||.f...U.?.G.fR.k|
+000000c0 65 71 c0 4e 0b 7e 55 e0 f5 af 42 29 af 2b 1d 0e |eq.N.~U...B).+..|
+000000d0 e6 96 cd 7b fc d3 |...{..|
+>>> Flow 4 (server to client)
+00000000 16 03 03 00 83 04 00 00 7f 00 00 00 00 00 79 00 |..............y.|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 |................|
+00000020 6f 2d b0 ac 51 ed 14 ef 68 ca 42 c5 4c 85 f6 26 |o-..Q...h.B.L..&|
+00000030 0d a4 ad a8 f5 14 64 4f b9 c3 fb 1e 55 c1 1f c7 |......dO....U...|
+00000040 31 57 72 68 db 03 37 a8 c9 07 f4 ca 62 6c 5c f3 |1Wrh..7.....bl\.|
+00000050 8b 5a 3d 76 dd 63 ea 68 61 6b a1 2d 95 49 38 16 |.Z=v.c.hak.-.I8.|
+00000060 7e 51 5c e5 15 c0 58 7d c5 67 4a 6f 64 b6 79 1a |~Q\...X}.gJod.y.|
+00000070 41 9b b1 33 15 38 74 92 5c a5 48 c3 f2 94 bb 33 |A..3.8t.\.H....3|
+00000080 ec af cf d7 e7 c9 3e 35 14 03 03 00 01 01 16 03 |......>5........|
+00000090 03 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 |..@.............|
+000000a0 00 00 00 19 51 7c 1c a3 80 34 e1 81 30 3f f9 a4 |....Q|...4..0?..|
+000000b0 a0 97 97 fd 94 fb ab e8 80 48 25 7b 83 ca 38 61 |.........H%{..8a|
+000000c0 34 95 d0 52 6f 09 ad 4f 74 35 c5 3d e8 bb aa 5d |4..Ro..Ot5.=...]|
+000000d0 d0 fc 85 17 03 03 00 40 00 00 00 00 00 00 00 00 |.......@........|
+000000e0 00 00 00 00 00 00 00 00 e7 19 f9 fd 10 7c 17 04 |.............|..|
+000000f0 2d ce 5f a6 41 33 3d 05 b0 29 91 ff a0 a5 76 52 |-._.A3=..)....vR|
+00000100 e1 b9 ba 6a ca d3 79 60 11 ac 43 b5 30 f7 15 dc |...j..y`..C.0...|
+00000110 6f b1 d2 b2 00 85 43 40 15 03 03 00 30 00 00 00 |o.....C@....0...|
+00000120 00 00 00 00 00 00 00 00 00 00 00 00 00 19 99 8a |................|
+00000130 4c 18 e0 03 cc 27 7a be 2c e5 d2 16 95 f6 a4 6e |L....'z.,......n|
+00000140 11 d3 1d f4 01 52 2b fc 98 04 b1 0b 31 |.....R+.....1|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-IssueTicketPreDisable b/src/crypto/tls/testdata/Server-TLSv12-IssueTicketPreDisable
new file mode 100644
index 0000000..20ce3c3
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-IssueTicketPreDisable
@@ -0,0 +1,90 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 71 01 00 00 6d 03 03 a1 ba 69 29 39 |....q...m....i)9|
+00000010 b5 fc c7 90 90 54 35 be 5a ad 4a e2 b2 3d b9 01 |.....T5.Z.J..=..|
+00000020 f0 48 fd 77 b5 9e bc 89 f5 d4 df 00 00 04 00 2f |.H.w.........../|
+00000030 00 ff 01 00 00 40 00 23 00 00 00 16 00 00 00 17 |.....@.#........|
+00000040 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 08 07 |.....0..........|
+00000050 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 |................|
+00000060 05 01 06 01 03 03 02 03 03 01 02 01 03 02 02 02 |................|
+00000070 04 02 05 02 06 02 |......|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 39 02 00 00 35 03 03 00 00 00 00 00 |....9...5.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 2f 00 00 |...DOWNGRD.../..|
+00000030 0d 00 23 00 00 ff 01 00 01 00 00 17 00 00 16 03 |..#.............|
+00000040 03 02 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 |..Y...U..R..O0..|
+00000050 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d |K0..............|
+00000060 3f e2 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 |?.[..0...*.H....|
+00000070 01 0b 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 |....0.1.0...U...|
+00000080 02 47 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f |.Go1.0...U....Go|
+00000090 20 52 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 | Root0...1601010|
+000000a0 30 30 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 |00000Z..25010100|
+000000b0 30 30 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a |0000Z0.1.0...U..|
+000000c0 13 02 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 |..Go1.0...U....G|
+000000d0 6f 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 |o0..0...*.H.....|
+000000e0 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 |.......0.......F|
+000000f0 7d 93 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 |}...'.H..(!.~...|
+00000100 5d fe 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 |]..RE.z6G....B[.|
+00000110 81 c0 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 |....y.@.Om..+...|
+00000120 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b |..g....."8.J.ts+|
+00000130 c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c |.4......t{.X.la<|
+00000140 c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d |..A..++$#w[.;.u]|
+00000150 ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b |. T..c...$....P.|
+00000160 aa b6 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 |...C...ub...R...|
+00000170 01 00 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f |......0..0...U..|
+00000180 01 01 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 |.........0...U.%|
+00000190 04 16 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 |..0...+.........|
+000001a0 2b 06 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 |+.......0...U...|
+000001b0 01 ff 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 |....0.0...U.....|
+000001c0 10 9f 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f |.....CC>I..m....|
+000001d0 60 30 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 |`0...U.#..0...H.|
+000001e0 49 4d 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 |IM.~.1......n{0.|
+000001f0 06 03 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 |..U....0...examp|
+00000200 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 |le.golang0...*.H|
+00000210 86 f7 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 |.............0.@|
+00000220 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 |+[P.a...SX...(.X|
+00000230 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d |..8....1Z..f=C.-|
+00000240 d9 0b f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c |...... d8.$:....|
+00000250 7d b7 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 |}.@ ._...a..v...|
+00000260 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 |...\.....l..s..C|
+00000270 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d |w.......@.a.Lr+.|
+00000280 ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db |..F..M...>...B..|
+00000290 fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 |.=.`.\!.;.......|
+000002a0 04 0e 00 00 00 |.....|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 86 10 00 00 82 00 80 cc 4e 62 e0 bf |............Nb..|
+00000010 21 65 dc f2 57 fb fe 6e e4 cc de b4 1f aa af 52 |!e..W..n.......R|
+00000020 a4 e0 0e 1b fa 8b 23 4b d9 e2 4b 62 6a 26 80 f7 |......#K..Kbj&..|
+00000030 15 82 ba 44 4a 18 b8 97 ca a1 79 4b 11 59 90 7d |...DJ.....yK.Y.}|
+00000040 ea 89 7c f9 6b 5f 29 c7 ca 32 bf 3b 53 b2 bb bb |..|.k_)..2.;S...|
+00000050 77 0a 5c 1f c2 d8 20 cf 59 19 4e a0 ff ef ca ca |w.\... .Y.N.....|
+00000060 25 39 ac c7 64 b9 e8 68 09 f2 49 96 8e 49 c7 4c |%9..d..h..I..I.L|
+00000070 cd ff 28 6f d8 0d d3 7a ae 7a 51 9e 04 70 8a 59 |..(o...z.zQ..p.Y|
+00000080 8c 05 61 c9 2b bd e1 05 5a 12 63 14 03 03 00 01 |..a.+...Z.c.....|
+00000090 01 16 03 03 00 40 ac 30 bb 83 2f e2 a1 98 a3 c5 |.....@.0../.....|
+000000a0 9c e3 55 36 70 a0 10 fc 53 7e 2d ae f1 02 d7 04 |..U6p...S~-.....|
+000000b0 1f 4e 5d ed 33 29 99 04 54 8e 51 74 d5 2a 73 21 |.N].3)..T.Qt.*s!|
+000000c0 4f bf 8b 0c 04 b2 f2 d4 3e a7 f6 ee 8b fb 3a 0b |O.......>.....:.|
+000000d0 86 27 7c a7 bb 32 |.'|..2|
+>>> Flow 4 (server to client)
+00000000 16 03 03 00 83 04 00 00 7f 00 00 00 00 00 79 00 |..............y.|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 |................|
+00000020 6f 2d b0 ac 51 ed 14 ef 68 ca 42 c5 4c fa 53 68 |o-..Q...h.B.L.Sh|
+00000030 d9 20 e9 d9 c1 9c 90 3b f2 e6 57 af 04 e5 db 6b |. .....;..W....k|
+00000040 36 0b b5 b8 e2 a5 a4 bf 52 31 80 32 b9 da d9 32 |6.......R1.2...2|
+00000050 36 e7 31 d3 22 78 12 ae 7a 80 ac fa 6d 49 38 16 |6.1."x..z...mI8.|
+00000060 7e 51 5c e5 15 c0 58 7d d6 77 d5 17 1b d9 a8 74 |~Q\...X}.w.....t|
+00000070 be 93 25 54 84 a7 1a 93 1f 20 a4 49 eb 26 e7 8e |..%T..... .I.&..|
+00000080 d3 0f cf 9c 75 cc 6f 36 14 03 03 00 01 01 16 03 |....u.o6........|
+00000090 03 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 |..@.............|
+000000a0 00 00 00 eb f1 52 79 ff b8 6c 9c 23 f3 22 bc 96 |.....Ry..l.#."..|
+000000b0 2a bc e7 73 05 32 4b 2e e4 5e 31 97 62 86 cc 12 |*..s.2K..^1.b...|
+000000c0 ae 22 77 92 37 5d 82 41 57 48 aa f4 0a f3 94 30 |."w.7].AWH.....0|
+000000d0 5d 06 7b 17 03 03 00 40 00 00 00 00 00 00 00 00 |].{....@........|
+000000e0 00 00 00 00 00 00 00 00 8f 8d a7 06 a7 d6 52 5a |..............RZ|
+000000f0 b9 66 5e ef e3 8d 1d 91 d0 6d 30 29 92 4e 6a 81 |.f^......m0).Nj.|
+00000100 f4 77 97 06 de a8 c8 d1 4c 6b 15 07 1f 9b 59 6d |.w......Lk....Ym|
+00000110 cb 4f 23 20 58 aa 22 21 15 03 03 00 30 00 00 00 |.O# X."!....0...|
+00000120 00 00 00 00 00 00 00 00 00 00 00 00 00 06 55 3d |..............U=|
+00000130 42 f5 12 b2 66 aa af 00 91 5e b8 31 ae 19 0e 35 |B...f....^.1...5|
+00000140 a2 d7 a6 e7 0c 3c 2b 95 62 69 d7 a0 81 |.....<+.bi...|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-P256 b/src/crypto/tls/testdata/Server-TLSv12-P256
new file mode 100644
index 0000000..349857e
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-P256
@@ -0,0 +1,84 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 7d 01 00 00 79 03 03 26 b5 ad b7 ec |....}...y..&....|
+00000010 e9 2f d5 cc 9e c2 f6 6f dd ab c5 4b 2c 74 48 a5 |./.....o...K,tH.|
+00000020 9c c5 21 41 fd 32 91 04 8f 1b 6c 00 00 04 cc a8 |..!A.2....l.....|
+00000030 00 ff 01 00 00 4c 00 0b 00 04 03 00 01 02 00 0a |.....L..........|
+00000040 00 04 00 02 00 17 00 16 00 00 00 17 00 00 00 0d |................|
+00000050 00 30 00 2e 04 03 05 03 06 03 08 07 08 08 08 09 |.0..............|
+00000060 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................|
+00000070 03 03 02 03 03 01 02 01 03 02 02 02 04 02 05 02 |................|
+00000080 06 02 |..|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 3b 02 00 00 37 03 03 00 00 00 00 00 |....;...7.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 cc a8 00 00 |...DOWNGRD......|
+00000030 0f ff 01 00 01 00 00 17 00 00 00 0b 00 02 01 00 |................|
+00000040 16 03 03 02 59 0b 00 02 55 00 02 52 00 02 4f 30 |....Y...U..R..O0|
+00000050 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 |..K0............|
+00000060 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 86 f7 |..?.[..0...*.H..|
+00000070 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 55 04 |......0.1.0...U.|
+00000080 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 13 07 |...Go1.0...U....|
+00000090 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 31 30 |Go Root0...16010|
+000000a0 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 30 31 |1000000Z..250101|
+000000b0 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 03 55 |000000Z0.1.0...U|
+000000c0 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 03 13 |....Go1.0...U...|
+000000d0 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d |.Go0..0...*.H...|
+000000e0 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 |.........0......|
+000000f0 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab 7e c4 |.F}...'.H..(!.~.|
+00000100 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d 92 42 |..]..RE.z6G....B|
+00000110 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 |[.....y.@.Om..+.|
+00000120 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 |....g....."8.J.t|
+00000130 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c |s+.4......t{.X.l|
+00000140 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd |a<..A..++$#w[.;.|
+00000150 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a |u]. T..c...$....|
+00000160 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 |P....C...ub...R.|
+00000170 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 03 55 |........0..0...U|
+00000180 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 03 55 |...........0...U|
+00000190 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 03 01 |.%..0...+.......|
+000001a0 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 55 1d |..+.......0...U.|
+000001b0 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d 0e 04 |......0.0...U...|
+000001c0 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d b6 80 |.......CC>I..m..|
+000001d0 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 80 10 |..`0...U.#..0...|
+000001e0 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b |H.IM.~.1......n{|
+000001f0 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 78 61 |0...U....0...exa|
+00000200 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a |mple.golang0...*|
+00000210 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 9d 30 |.H.............0|
+00000220 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed 83 28 |.@+[P.a...SX...(|
+00000230 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 |.X..8....1Z..f=C|
+00000240 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a 00 bc |.-...... d8.$:..|
+00000250 cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 76 fd |..}.@ ._...a..v.|
+00000260 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb |.....\.....l..s.|
+00000270 b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 |.Cw.......@.a.Lr|
+00000280 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 |+...F..M...>...B|
+00000290 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 |...=.`.\!.;.....|
+000002a0 03 00 cd 0c 00 00 c9 03 00 17 41 04 1e 18 37 ef |..........A...7.|
+000002b0 0d 19 51 88 35 75 71 b5 e5 54 5b 12 2e 8f 09 67 |..Q.5uq..T[....g|
+000002c0 fd a7 24 20 3e b2 56 1c ce 97 28 5e f8 2b 2d 4f |..$ >.V...(^.+-O|
+000002d0 9e f1 07 9f 6c 4b 5b 83 56 e2 32 42 e9 58 b6 d7 |....lK[.V.2B.X..|
+000002e0 49 a6 b5 68 1a 41 03 56 6b dc 5a 89 08 04 00 80 |I..h.A.Vk.Z.....|
+000002f0 ca 2e 5d 9c 99 56 e6 7a 60 e2 b6 65 09 2e 4f ee |..]..V.z`..e..O.|
+00000300 5d 7f d0 c0 f6 01 fe 62 13 12 14 dd 4d c9 eb e5 |]......b....M...|
+00000310 ee 27 ab 56 77 d1 0b 65 83 96 e5 72 ea 9a 78 85 |.'.Vw..e...r..x.|
+00000320 07 e6 86 bf 58 84 a8 4d 08 4a 56 14 a6 7f 0c 5a |....X..M.JV....Z|
+00000330 68 3c 6a 9e 0e 2a 70 6a 4f 58 96 45 f2 14 11 45 |h<j..*pjOX.E...E|
+00000340 49 fc b1 0b 13 ff e8 f9 40 71 fb b6 05 ef 88 32 |I.......@q.....2|
+00000350 06 19 e0 e9 9d 97 20 e2 78 0b 4b 4c 71 4a 08 ee |...... .x.KLqJ..|
+00000360 31 27 ef dd d0 5b d9 32 88 76 51 38 03 00 ba 67 |1'...[.2.vQ8...g|
+00000370 16 03 03 00 04 0e 00 00 00 |.........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 46 10 00 00 42 41 04 1c 05 a2 39 1b |....F...BA....9.|
+00000010 b9 e6 ef 38 6d 6f fe 95 0e ef 8d 8a 1b 70 10 b6 |...8mo.......p..|
+00000020 fc 0e 5f ee 0f 6e 08 b6 2d 4f 26 b1 5a af be f8 |.._..n..-O&.Z...|
+00000030 77 72 e4 19 5d a3 91 c6 0c 72 a3 19 9f 20 4f 6e |wr..]....r... On|
+00000040 75 91 ef 62 4f 1a aa 29 b2 75 6f 14 03 03 00 01 |u..bO..).uo.....|
+00000050 01 16 03 03 00 20 44 af 52 7b ff ca cf 30 ce 71 |..... D.R{...0.q|
+00000060 94 6d 90 2b 6d f3 0e a6 5d 60 15 29 b2 03 81 59 |.m.+m...]`.)...Y|
+00000070 ec 37 a1 cf a5 79 |.7...y|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 20 af 15 24 30 06 |.......... ..$0.|
+00000010 dd 4c 8b 8a 87 e1 f5 24 ac 36 bc 43 8d 89 20 19 |.L.....$.6.C.. .|
+00000020 04 d2 9c 14 c4 af 24 30 bf ef 1e 17 03 03 00 1d |......$0........|
+00000030 82 3b 55 e7 67 fe 89 bf 5b c1 7e d6 98 94 36 1f |.;U.g...[.~...6.|
+00000040 74 f3 34 2b cb 95 48 ed 4d 33 64 b9 ce 15 03 03 |t.4+..H.M3d.....|
+00000050 00 12 ca bf 01 54 b4 c3 b4 f8 04 87 6d 75 ef 8c |.....T......mu..|
+00000060 c7 9d 1b 1c |....|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-RSA-3DES b/src/crypto/tls/testdata/Server-TLSv12-RSA-3DES
new file mode 100644
index 0000000..0298d49
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-RSA-3DES
@@ -0,0 +1,78 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 6d 01 00 00 69 03 03 6c 16 54 e2 20 |....m...i..l.T. |
+00000010 da ff dc 37 ae f5 5d e2 77 32 fe 7b 7a cc 31 1f |...7..].w2.{z.1.|
+00000020 f5 49 6e 75 89 27 b0 aa 67 e7 99 00 00 04 00 0a |.Inu.'..g.......|
+00000030 00 ff 01 00 00 3c 00 16 00 00 00 17 00 00 00 0d |.....<..........|
+00000040 00 30 00 2e 04 03 05 03 06 03 08 07 08 08 08 09 |.0..............|
+00000050 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................|
+00000060 03 03 02 03 03 01 02 01 03 02 02 02 04 02 05 02 |................|
+00000070 06 02 |..|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 35 02 00 00 31 03 03 00 00 00 00 00 |....5...1.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 0a 00 00 |...DOWNGRD......|
+00000030 09 ff 01 00 01 00 00 17 00 00 16 03 03 02 59 0b |..............Y.|
+00000040 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..|
+00000050 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.|
+00000060 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........|
+00000070 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1|
+00000080 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo|
+00000090 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000|
+000000a0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000|
+000000b0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go|
+000000c0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..|
+000000d0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........|
+000000e0 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...|
+000000f0 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R|
+00000100 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....|
+00000110 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.|
+00000120 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..|
+00000130 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.|
+00000140 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.|
+00000150 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C|
+00000160 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......|
+00000170 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......|
+00000180 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.|
+00000190 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...|
+000001a0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......|
+000001b0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........|
+000001c0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..|
+000001d0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~|
+000001e0 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.|
+000001f0 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g|
+00000200 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....|
+00000210 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.|
+00000220 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.|
+00000230 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....|
+00000240 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ |
+00000250 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\|
+00000260 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...|
+00000270 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.|
+00000280 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`|
+00000290 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e 00 00 |.\!.;...........|
+000002a0 00 |.|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 86 10 00 00 82 00 80 bc bb c4 2a df |..............*.|
+00000010 56 75 8b 3e e1 cd 12 f8 58 29 4d 4d ab f0 12 0c |Vu.>....X)MM....|
+00000020 d7 20 3b cb d5 68 5e c1 a4 03 89 f7 d4 f4 ee c9 |. ;..h^.........|
+00000030 38 8e bb 42 de e4 fb c6 9f df db 7f af 6c ae b5 |8..B.........l..|
+00000040 6a 99 70 3c 1e 88 38 22 aa 1e 81 51 1e 7d 36 31 |j.p<..8"...Q.}61|
+00000050 4e d2 a9 08 c0 bc 11 d8 27 41 26 75 f3 35 74 74 |N.......'A&u.5tt|
+00000060 ef 50 0e 2b bd da 41 ed 81 56 b9 e4 13 74 e9 80 |.P.+..A..V...t..|
+00000070 9f a2 90 d1 fd 85 26 02 f3 aa 75 53 d9 58 bc 2f |......&...uS.X./|
+00000080 3b e5 60 cb f8 ac e6 32 6e 5f 80 14 03 03 00 01 |;.`....2n_......|
+00000090 01 16 03 03 00 30 8c e6 a6 6a 76 aa 84 32 0c 6b |.....0...jv..2.k|
+000000a0 17 41 9d 56 46 46 5c 34 a1 37 d5 7f e6 ab 55 de |.A.VFF\4.7....U.|
+000000b0 70 54 69 0a 6d 18 1c 14 87 ee 73 8b f9 57 37 2f |pTi.m.....s..W7/|
+000000c0 2e bb 07 4c f1 a9 |...L..|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 30 00 00 00 00 00 |..........0.....|
+00000010 00 00 00 49 b9 2a 89 cb 6e 15 d4 a6 f7 24 a5 3a |...I.*..n....$.:|
+00000020 da f3 5b ac ff 43 a2 a6 5b 27 36 9c 6d 55 ba c8 |..[..C..['6.mU..|
+00000030 f4 77 f7 44 8c bc a7 5e 3f c6 59 17 03 03 00 30 |.w.D...^?.Y....0|
+00000040 00 00 00 00 00 00 00 00 44 44 d7 76 36 88 a6 84 |........DD.v6...|
+00000050 02 27 40 d6 d1 bb a5 20 41 d5 06 66 3a 56 05 94 |.'@.... A..f:V..|
+00000060 41 97 fc 85 95 70 28 85 7a 7a ce 43 71 5d ad a8 |A....p(.zz.Cq]..|
+00000070 15 03 03 00 20 00 00 00 00 00 00 00 00 8e 63 57 |.... .........cW|
+00000080 61 6d c1 0b ca ea 89 9e b4 9e 6d fb 9f 3b 2a fc |am........m..;*.|
+00000090 a0 56 d1 21 5d |.V.!]|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-RSA-AES b/src/crypto/tls/testdata/Server-TLSv12-RSA-AES
new file mode 100644
index 0000000..68a1cb1
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-RSA-AES
@@ -0,0 +1,82 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 6d 01 00 00 69 03 03 0a b6 18 8a 8f |....m...i.......|
+00000010 90 e2 fb ee cd e3 d5 62 53 17 45 bd b3 7f 53 4d |.......bS.E...SM|
+00000020 4e 06 62 66 25 60 b1 3f 96 b0 21 00 00 04 00 2f |N.bf%`.?..!..../|
+00000030 00 ff 01 00 00 3c 00 16 00 00 00 17 00 00 00 0d |.....<..........|
+00000040 00 30 00 2e 04 03 05 03 06 03 08 07 08 08 08 09 |.0..............|
+00000050 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................|
+00000060 03 03 02 03 03 01 02 01 03 02 02 02 04 02 05 02 |................|
+00000070 06 02 |..|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 35 02 00 00 31 03 03 00 00 00 00 00 |....5...1.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 2f 00 00 |...DOWNGRD.../..|
+00000030 09 ff 01 00 01 00 00 17 00 00 16 03 03 02 59 0b |..............Y.|
+00000040 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..|
+00000050 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.|
+00000060 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........|
+00000070 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1|
+00000080 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo|
+00000090 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000|
+000000a0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000|
+000000b0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go|
+000000c0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..|
+000000d0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........|
+000000e0 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...|
+000000f0 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R|
+00000100 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....|
+00000110 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.|
+00000120 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..|
+00000130 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.|
+00000140 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.|
+00000150 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C|
+00000160 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......|
+00000170 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......|
+00000180 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.|
+00000190 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...|
+000001a0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......|
+000001b0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........|
+000001c0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..|
+000001d0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~|
+000001e0 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.|
+000001f0 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g|
+00000200 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....|
+00000210 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.|
+00000220 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.|
+00000230 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....|
+00000240 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ |
+00000250 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\|
+00000260 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...|
+00000270 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.|
+00000280 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`|
+00000290 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e 00 00 |.\!.;...........|
+000002a0 00 |.|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 86 10 00 00 82 00 80 19 dc d4 4c b0 |..............L.|
+00000010 5c 30 24 b8 fd e1 cd 4e af bc c3 f5 78 12 8c 51 |\0$....N....x..Q|
+00000020 a9 a9 ab fd 87 72 a4 bc 0c fc 87 5e 1d af 67 02 |.....r.....^..g.|
+00000030 13 c5 c2 8c 00 5f 33 d1 86 43 50 b3 3a 1d b8 69 |....._3..CP.:..i|
+00000040 b1 2f ce 82 cd 8d 31 0d 15 c1 fb af b3 47 64 57 |./....1......GdW|
+00000050 38 24 33 46 03 d5 ba 33 36 a0 eb de 21 2b ae 64 |8$3F...36...!+.d|
+00000060 cc 0c 43 fe a3 7b 34 a1 d2 de d5 85 ec ac c7 0d |..C..{4.........|
+00000070 04 ec 63 62 ab fe 86 ba e9 ee 31 2c 09 84 13 6a |..cb......1,...j|
+00000080 10 bc 0f 71 93 9d e8 c4 e3 f6 a9 14 03 03 00 01 |...q............|
+00000090 01 16 03 03 00 40 b7 75 28 6e 6b 9a 60 8f fc 5b |.....@.u(nk.`..[|
+000000a0 91 0a 16 54 ec b1 4b 55 b8 b2 5c 53 48 92 aa dc |...T..KU..\SH...|
+000000b0 55 64 2c b0 dc 77 b4 6f 7a a9 23 9c 44 8b 74 64 |Ud,..w.oz.#.D.td|
+000000c0 c5 28 ea c7 8d 97 9b c8 a3 ec 11 d7 93 81 08 20 |.(............. |
+000000d0 9c 2f 79 32 92 45 |./y2.E|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....|
+00000010 00 00 00 00 00 00 00 00 00 00 00 92 50 e8 02 a0 |............P...|
+00000020 14 d6 03 5d db bb 29 21 09 a3 71 08 54 f3 5e 7c |...]..)!..q.T.^||
+00000030 9a 64 18 f3 4f 64 84 4d b7 e9 82 a8 2c 3b 46 70 |.d..Od.M....,;Fp|
+00000040 cb cb de b5 e3 c3 12 d5 7b 6f 08 17 03 03 00 40 |........{o.....@|
+00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000060 4f 4f fe dd e5 b1 38 6b b1 2f 5d 23 8b b2 34 b1 |OO....8k./]#..4.|
+00000070 c6 9f 8d 32 83 5f b5 36 0b df a6 aa 3f 90 30 b7 |...2._.6....?.0.|
+00000080 1d 66 26 89 29 ab 71 dc 00 14 d6 8e 7e 47 bd ee |.f&.).q.....~G..|
+00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
+000000a0 00 00 00 00 00 e3 72 e5 7c 8c c6 f5 72 ba 37 52 |......r.|...r.7R|
+000000b0 be 38 a0 a2 62 71 d9 f6 a2 9e b5 4a af 0f 13 3e |.8..bq.....J...>|
+000000c0 3c 85 ab ea eb |<....|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-RSA-AES-GCM b/src/crypto/tls/testdata/Server-TLSv12-RSA-AES-GCM
new file mode 100644
index 0000000..8d8c3b4
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-RSA-AES-GCM
@@ -0,0 +1,81 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 85 01 00 00 81 03 03 6e 70 d5 90 98 |...........np...|
+00000010 0a 70 40 22 4f 31 e8 7d a0 81 bd 22 e8 4e 97 8b |.p@"O1.}...".N..|
+00000020 4d bb 3d d1 d6 2f 09 b9 bd 2f 43 00 00 04 c0 2f |M.=../.../C..../|
+00000030 00 ff 01 00 00 54 00 0b 00 04 03 00 01 02 00 0a |.....T..........|
+00000040 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 16 |................|
+00000050 00 00 00 17 00 00 00 0d 00 30 00 2e 04 03 05 03 |.........0......|
+00000060 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................|
+00000070 08 06 04 01 05 01 06 01 03 03 02 03 03 01 02 01 |................|
+00000080 03 02 02 02 04 02 05 02 06 02 |..........|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 3b 02 00 00 37 03 03 00 00 00 00 00 |....;...7.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 c0 2f 00 00 |...DOWNGRD.../..|
+00000030 0f ff 01 00 01 00 00 17 00 00 00 0b 00 02 01 00 |................|
+00000040 16 03 03 02 59 0b 00 02 55 00 02 52 00 02 4f 30 |....Y...U..R..O0|
+00000050 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 |..K0............|
+00000060 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 86 f7 |..?.[..0...*.H..|
+00000070 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 55 04 |......0.1.0...U.|
+00000080 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 13 07 |...Go1.0...U....|
+00000090 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 31 30 |Go Root0...16010|
+000000a0 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 30 31 |1000000Z..250101|
+000000b0 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 03 55 |000000Z0.1.0...U|
+000000c0 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 03 13 |....Go1.0...U...|
+000000d0 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d |.Go0..0...*.H...|
+000000e0 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 |.........0......|
+000000f0 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab 7e c4 |.F}...'.H..(!.~.|
+00000100 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d 92 42 |..]..RE.z6G....B|
+00000110 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 |[.....y.@.Om..+.|
+00000120 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 |....g....."8.J.t|
+00000130 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c |s+.4......t{.X.l|
+00000140 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd |a<..A..++$#w[.;.|
+00000150 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a |u]. T..c...$....|
+00000160 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 |P....C...ub...R.|
+00000170 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 03 55 |........0..0...U|
+00000180 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 03 55 |...........0...U|
+00000190 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 03 01 |.%..0...+.......|
+000001a0 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 55 1d |..+.......0...U.|
+000001b0 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d 0e 04 |......0.0...U...|
+000001c0 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d b6 80 |.......CC>I..m..|
+000001d0 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 80 10 |..`0...U.#..0...|
+000001e0 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b |H.IM.~.1......n{|
+000001f0 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 78 61 |0...U....0...exa|
+00000200 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a |mple.golang0...*|
+00000210 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 9d 30 |.H.............0|
+00000220 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed 83 28 |.@+[P.a...SX...(|
+00000230 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 |.X..8....1Z..f=C|
+00000240 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a 00 bc |.-...... d8.$:..|
+00000250 cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 76 fd |..}.@ ._...a..v.|
+00000260 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb |.....\.....l..s.|
+00000270 b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 |.Cw.......@.a.Lr|
+00000280 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 |+...F..M...>...B|
+00000290 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 |...=.`.\!.;.....|
+000002a0 03 00 ac 0c 00 00 a8 03 00 1d 20 2f e5 7d a3 47 |.......... /.}.G|
+000002b0 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af |.bC.(.._.).0....|
+000002c0 c4 cf c2 ed 90 99 5f 58 cb 3b 74 08 04 00 80 49 |......_X.;t....I|
+000002d0 51 c7 81 cd e1 9f 67 83 76 7e 51 19 83 2a 34 47 |Q.....g.v~Q..*4G|
+000002e0 5a e8 6d 13 dd e5 44 eb 1a 20 42 ac d3 65 e8 2e |Z.m...D.. B..e..|
+000002f0 8d c5 79 56 e6 5e 26 00 9b 2a 80 16 d8 2e af 42 |..yV.^&..*.....B|
+00000300 35 b7 0f f8 6a 41 87 b6 c5 6a 37 6e bc 17 5e a4 |5...jA...j7n..^.|
+00000310 1f ba 93 33 98 92 92 2e 76 7b 49 55 8d 37 c2 c3 |...3....v{IU.7..|
+00000320 d5 65 4a 73 84 28 6c 0a 4b 26 62 61 fa 46 0f 47 |.eJs.(l.K&ba.F.G|
+00000330 d5 e5 99 05 57 23 76 6d c9 7b 0d 8d ff 91 98 eb |....W#vm.{......|
+00000340 17 96 c0 00 a6 88 3c be 03 5b db e7 a5 84 ae 16 |......<..[......|
+00000350 03 03 00 04 0e 00 00 00 |........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 7d 0c 38 84 cd 0b |....%...! }.8...|
+00000010 d1 65 02 f7 ab 8b 8b 4e 8f 05 a5 ea 7a 32 db 1b |.e.....N....z2..|
+00000020 e7 42 5b 2b 83 95 2b e1 aa 30 14 03 03 00 01 01 |.B[+..+..0......|
+00000030 16 03 03 00 28 7d f6 5b 8f 2e 17 84 50 23 db ad |....(}.[....P#..|
+00000040 47 84 59 ba e8 d7 ab c5 28 dc 06 51 aa 9c 7a d0 |G.Y.....(..Q..z.|
+00000050 6e ae 27 90 e9 aa 92 9e 83 6f 4e eb 6a |n.'......oN.j|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 28 00 00 00 00 00 |..........(.....|
+00000010 00 00 00 a5 ec 31 bb 01 5d a3 15 01 22 88 0e f1 |.....1..]..."...|
+00000020 2a 21 18 47 10 64 3d f0 d0 fb f8 fd 27 ed 34 88 |*!.G.d=.....'.4.|
+00000030 c1 b5 b3 17 03 03 00 25 00 00 00 00 00 00 00 01 |.......%........|
+00000040 e4 3c 6a db 2b a9 59 64 d1 3f 4b a0 98 37 52 03 |.<j.+.Yd.?K..7R.|
+00000050 b7 b1 6e 98 ed c0 da e4 75 63 27 64 c4 15 03 03 |..n.....uc'd....|
+00000060 00 1a 00 00 00 00 00 00 00 02 84 a5 21 7b b0 77 |............!{.w|
+00000070 83 03 52 57 79 1f 5c ec 75 da 49 89 |..RWy.\.u.I.|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-RSA-AES256-GCM-SHA384 b/src/crypto/tls/testdata/Server-TLSv12-RSA-AES256-GCM-SHA384
new file mode 100644
index 0000000..e1b8f7e
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-RSA-AES256-GCM-SHA384
@@ -0,0 +1,81 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 85 01 00 00 81 03 03 0f 5a 3f b1 98 |............Z?..|
+00000010 d1 40 d3 93 3a cf 86 50 56 51 7a b4 1d f5 c8 53 |.@..:..PVQz....S|
+00000020 74 9e 5b c3 27 a3 7d fe a3 4a 73 00 00 04 c0 30 |t.[.'.}..Js....0|
+00000030 00 ff 01 00 00 54 00 0b 00 04 03 00 01 02 00 0a |.....T..........|
+00000040 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 16 |................|
+00000050 00 00 00 17 00 00 00 0d 00 30 00 2e 04 03 05 03 |.........0......|
+00000060 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................|
+00000070 08 06 04 01 05 01 06 01 03 03 02 03 03 01 02 01 |................|
+00000080 03 02 02 02 04 02 05 02 06 02 |..........|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 3b 02 00 00 37 03 03 00 00 00 00 00 |....;...7.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 c0 30 00 00 |...DOWNGRD...0..|
+00000030 0f ff 01 00 01 00 00 17 00 00 00 0b 00 02 01 00 |................|
+00000040 16 03 03 02 59 0b 00 02 55 00 02 52 00 02 4f 30 |....Y...U..R..O0|
+00000050 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 |..K0............|
+00000060 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 86 f7 |..?.[..0...*.H..|
+00000070 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 55 04 |......0.1.0...U.|
+00000080 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 13 07 |...Go1.0...U....|
+00000090 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 31 30 |Go Root0...16010|
+000000a0 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 30 31 |1000000Z..250101|
+000000b0 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 03 55 |000000Z0.1.0...U|
+000000c0 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 03 13 |....Go1.0...U...|
+000000d0 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d |.Go0..0...*.H...|
+000000e0 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 |.........0......|
+000000f0 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab 7e c4 |.F}...'.H..(!.~.|
+00000100 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d 92 42 |..]..RE.z6G....B|
+00000110 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 |[.....y.@.Om..+.|
+00000120 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 |....g....."8.J.t|
+00000130 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c |s+.4......t{.X.l|
+00000140 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd |a<..A..++$#w[.;.|
+00000150 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a |u]. T..c...$....|
+00000160 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 |P....C...ub...R.|
+00000170 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 03 55 |........0..0...U|
+00000180 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 03 55 |...........0...U|
+00000190 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 03 01 |.%..0...+.......|
+000001a0 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 55 1d |..+.......0...U.|
+000001b0 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d 0e 04 |......0.0...U...|
+000001c0 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d b6 80 |.......CC>I..m..|
+000001d0 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 80 10 |..`0...U.#..0...|
+000001e0 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b |H.IM.~.1......n{|
+000001f0 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 78 61 |0...U....0...exa|
+00000200 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a |mple.golang0...*|
+00000210 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 9d 30 |.H.............0|
+00000220 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed 83 28 |.@+[P.a...SX...(|
+00000230 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 |.X..8....1Z..f=C|
+00000240 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a 00 bc |.-...... d8.$:..|
+00000250 cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 76 fd |..}.@ ._...a..v.|
+00000260 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb |.....\.....l..s.|
+00000270 b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 |.Cw.......@.a.Lr|
+00000280 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 |+...F..M...>...B|
+00000290 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 |...=.`.\!.;.....|
+000002a0 03 00 ac 0c 00 00 a8 03 00 1d 20 2f e5 7d a3 47 |.......... /.}.G|
+000002b0 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af |.bC.(.._.).0....|
+000002c0 c4 cf c2 ed 90 99 5f 58 cb 3b 74 08 04 00 80 da |......_X.;t.....|
+000002d0 4d 5e f1 10 1f ed 70 d1 88 7a 22 79 6e 5c c9 4c |M^....p..z"yn\.L|
+000002e0 e3 e7 a2 bd f4 3d f4 75 dc a3 85 5e f1 af 55 6f |.....=.u...^..Uo|
+000002f0 e3 36 21 c6 8a 44 e9 58 29 89 32 4d 14 90 9d 1b |.6!..D.X).2M....|
+00000300 bd 0e fa c3 eb 40 5d 05 5d ba 58 55 3e f9 30 b8 |.....@].].XU>.0.|
+00000310 8f 56 35 71 12 33 92 0e 14 f9 90 2c ee 36 03 50 |.V5q.3.....,.6.P|
+00000320 1c f6 76 a7 99 3e fd bb 5f 21 96 c5 56 1e ed 28 |..v..>.._!..V..(|
+00000330 00 0b cd ac cd 70 1a 7e 2d 2d 7d 1d 76 7d e6 89 |.....p.~--}.v}..|
+00000340 ba 35 dc e1 9f 48 39 ff 9e a9 48 77 8e d3 71 16 |.5...H9...Hw..q.|
+00000350 03 03 00 04 0e 00 00 00 |........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 80 4d 7d 95 1c e0 |....%...! .M}...|
+00000010 d5 c1 f6 6d 43 92 08 23 82 cb 30 e0 d7 15 d8 51 |...mC..#..0....Q|
+00000020 14 2f 8a 1c 3a 07 be d9 96 54 14 03 03 00 01 01 |./..:....T......|
+00000030 16 03 03 00 28 00 a6 4e 03 ff 76 94 d4 b8 c6 c5 |....(..N..v.....|
+00000040 7d 4d 2b 7e 5d 4f 5c b8 5a 78 46 c9 0f ce 57 7f |}M+~]O\.ZxF...W.|
+00000050 02 a0 1a 83 b1 92 3f 96 ce 8a 00 8f 30 |......?.....0|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 28 00 00 00 00 00 |..........(.....|
+00000010 00 00 00 2f ec 4b c3 a6 99 1f ab 91 62 01 d5 e6 |.../.K......b...|
+00000020 93 23 20 7e b8 61 be 90 a0 10 e3 f1 8a 82 f9 bc |.# ~.a..........|
+00000030 27 fe 65 17 03 03 00 25 00 00 00 00 00 00 00 01 |'.e....%........|
+00000040 54 bd d1 e8 02 9a ab fa 2f d1 19 e9 45 81 05 d1 |T......./...E...|
+00000050 ba d2 d7 77 54 88 cc fe 14 b3 3b d1 28 15 03 03 |...wT.....;.(...|
+00000060 00 1a 00 00 00 00 00 00 00 02 de 3f 93 32 6e f5 |...........?.2n.|
+00000070 07 60 ed 65 6f 81 62 90 52 f6 4a a2 |.`.eo.b.R.J.|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-RSA-RC4 b/src/crypto/tls/testdata/Server-TLSv12-RSA-RC4
new file mode 100644
index 0000000..30b00f6
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-RSA-RC4
@@ -0,0 +1,74 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 6d 01 00 00 69 03 03 dd 92 e1 75 15 |....m...i.....u.|
+00000010 1d 9f 00 c5 2b 8a 14 86 aa 93 7c c0 32 2a 29 14 |....+.....|.2*).|
+00000020 38 75 ce 62 a7 df c1 4a eb 1e 0c 00 00 04 00 05 |8u.b...J........|
+00000030 00 ff 01 00 00 3c 00 16 00 00 00 17 00 00 00 0d |.....<..........|
+00000040 00 30 00 2e 04 03 05 03 06 03 08 07 08 08 08 09 |.0..............|
+00000050 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................|
+00000060 03 03 02 03 03 01 02 01 03 02 02 02 04 02 05 02 |................|
+00000070 06 02 |..|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 35 02 00 00 31 03 03 00 00 00 00 00 |....5...1.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 05 00 00 |...DOWNGRD......|
+00000030 09 ff 01 00 01 00 00 17 00 00 16 03 03 02 59 0b |..............Y.|
+00000040 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..|
+00000050 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.|
+00000060 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........|
+00000070 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1|
+00000080 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo|
+00000090 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000|
+000000a0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000|
+000000b0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go|
+000000c0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..|
+000000d0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........|
+000000e0 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...|
+000000f0 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R|
+00000100 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....|
+00000110 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.|
+00000120 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..|
+00000130 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.|
+00000140 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.|
+00000150 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C|
+00000160 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......|
+00000170 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......|
+00000180 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.|
+00000190 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...|
+000001a0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......|
+000001b0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........|
+000001c0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..|
+000001d0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~|
+000001e0 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.|
+000001f0 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g|
+00000200 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....|
+00000210 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.|
+00000220 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.|
+00000230 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....|
+00000240 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ |
+00000250 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\|
+00000260 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...|
+00000270 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.|
+00000280 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`|
+00000290 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e 00 00 |.\!.;...........|
+000002a0 00 |.|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 86 10 00 00 82 00 80 8d bb 5a 48 87 |.............ZH.|
+00000010 95 ca 2d eb a8 47 de 35 4d 70 3e 89 a1 ce c5 8d |..-..G.5Mp>.....|
+00000020 02 95 f6 ac e6 2f 1f ae c5 4a 82 08 22 d5 89 0b |...../...J.."...|
+00000030 c1 0e be 18 39 d0 e9 e5 ed 87 92 6e 61 3f 68 e5 |....9......na?h.|
+00000040 ed 1d a5 cc 43 d1 42 28 be 4d 31 11 27 f7 dd 25 |....C.B(.M1.'..%|
+00000050 58 b7 fc 76 bb 7c 06 d8 c2 69 0a 87 2b 54 bf 4e |X..v.|...i..+T.N|
+00000060 8a fa 54 db 78 d4 98 51 21 e4 32 28 49 31 51 c0 |..T.x..Q!.2(I1Q.|
+00000070 a8 7e f0 97 d9 f3 f7 18 d7 a9 74 79 4d 2f 3f df |.~........tyM/?.|
+00000080 b1 25 88 9e 15 cf 94 42 15 68 65 14 03 03 00 01 |.%.....B.he.....|
+00000090 01 16 03 03 00 24 cb ac 7c 7c 16 02 a9 08 c3 53 |.....$..||.....S|
+000000a0 b8 0e ee 24 fa 51 e0 ce 37 40 e7 f2 ab 93 3d 81 |...$.Q..7@....=.|
+000000b0 58 49 96 0e e7 54 43 67 42 1b |XI...TCgB.|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 24 e4 2f 5e 7f 6f |..........$./^.o|
+00000010 46 22 85 a0 2d 5a fd 36 0b 9f eb 26 80 89 1d 7e |F"..-Z.6...&...~|
+00000020 ca 57 a7 f5 5d 54 1c e4 85 77 f5 28 54 a5 15 17 |.W..]T...w.(T...|
+00000030 03 03 00 21 84 a2 f5 c9 e4 df b4 31 8a cf 04 77 |...!.......1...w|
+00000040 22 ab 93 9a ae d2 45 d0 d1 7d 42 11 92 b6 b5 1c |".....E..}B.....|
+00000050 ac 60 0b d1 9e 15 03 03 00 16 ed f3 12 75 df bc |.`...........u..|
+00000060 32 e6 c3 fa 74 7a 32 c6 d7 21 67 0a df be b1 15 |2...tz2..!g.....|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-RSA-RSAPKCS1v15 b/src/crypto/tls/testdata/Server-TLSv12-RSA-RSAPKCS1v15
new file mode 100644
index 0000000..1c7bcea
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-RSA-RSAPKCS1v15
@@ -0,0 +1,77 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 59 01 00 00 55 03 03 01 3d 46 ff b5 |....Y...U...=F..|
+00000010 47 eb 03 bd 9b 27 66 92 92 db 11 f9 58 1d 21 ba |G....'f.....X.!.|
+00000020 b9 51 90 81 d0 8f 7e 3c cd 7b b8 00 00 04 cc a8 |.Q....~<.{......|
+00000030 00 ff 01 00 00 28 00 0b 00 04 03 00 01 02 00 0a |.....(..........|
+00000040 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 16 |................|
+00000050 00 00 00 17 00 00 00 0d 00 04 00 02 04 01 |..............|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 3b 02 00 00 37 03 03 00 00 00 00 00 |....;...7.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 cc a8 00 00 |...DOWNGRD......|
+00000030 0f ff 01 00 01 00 00 17 00 00 00 0b 00 02 01 00 |................|
+00000040 16 03 03 02 59 0b 00 02 55 00 02 52 00 02 4f 30 |....Y...U..R..O0|
+00000050 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 |..K0............|
+00000060 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 86 f7 |..?.[..0...*.H..|
+00000070 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 55 04 |......0.1.0...U.|
+00000080 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 13 07 |...Go1.0...U....|
+00000090 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 31 30 |Go Root0...16010|
+000000a0 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 30 31 |1000000Z..250101|
+000000b0 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 03 55 |000000Z0.1.0...U|
+000000c0 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 03 13 |....Go1.0...U...|
+000000d0 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d |.Go0..0...*.H...|
+000000e0 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 |.........0......|
+000000f0 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab 7e c4 |.F}...'.H..(!.~.|
+00000100 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d 92 42 |..]..RE.z6G....B|
+00000110 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 |[.....y.@.Om..+.|
+00000120 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 |....g....."8.J.t|
+00000130 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c |s+.4......t{.X.l|
+00000140 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd |a<..A..++$#w[.;.|
+00000150 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a |u]. T..c...$....|
+00000160 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 |P....C...ub...R.|
+00000170 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 03 55 |........0..0...U|
+00000180 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 03 55 |...........0...U|
+00000190 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 03 01 |.%..0...+.......|
+000001a0 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 55 1d |..+.......0...U.|
+000001b0 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d 0e 04 |......0.0...U...|
+000001c0 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d b6 80 |.......CC>I..m..|
+000001d0 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 80 10 |..`0...U.#..0...|
+000001e0 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b |H.IM.~.1......n{|
+000001f0 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 78 61 |0...U....0...exa|
+00000200 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a |mple.golang0...*|
+00000210 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 9d 30 |.H.............0|
+00000220 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed 83 28 |.@+[P.a...SX...(|
+00000230 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 |.X..8....1Z..f=C|
+00000240 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a 00 bc |.-...... d8.$:..|
+00000250 cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 76 fd |..}.@ ._...a..v.|
+00000260 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb |.....\.....l..s.|
+00000270 b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 |.Cw.......@.a.Lr|
+00000280 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 |+...F..M...>...B|
+00000290 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 |...=.`.\!.;.....|
+000002a0 03 00 ac 0c 00 00 a8 03 00 1d 20 2f e5 7d a3 47 |.......... /.}.G|
+000002b0 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af |.bC.(.._.).0....|
+000002c0 c4 cf c2 ed 90 99 5f 58 cb 3b 74 04 01 00 80 21 |......_X.;t....!|
+000002d0 b5 82 7e 5a 7d 93 55 15 db e1 eb cc 62 8d f8 45 |..~Z}.U.....b..E|
+000002e0 2f e0 5d 57 51 08 80 86 b6 43 85 0f be f7 49 ca |/.]WQ....C....I.|
+000002f0 97 f2 f1 20 51 e6 29 8d c6 88 91 e3 60 8c 88 69 |... Q.).....`..i|
+00000300 73 9b 38 70 ad 2f 5b 44 62 05 05 20 28 92 57 f9 |s.8p./[Db.. (.W.|
+00000310 51 6e 6b 8c b7 3f c3 6e a3 53 b9 bd 02 bd 69 ae |Qnk..?.n.S....i.|
+00000320 ee 5f 96 57 7b a2 02 86 70 33 6b e7 ad 03 25 13 |._.W{...p3k...%.|
+00000330 10 f8 d7 cb 2e 33 b2 1f 53 64 77 d1 e5 8a 32 bc |.....3..Sdw...2.|
+00000340 e0 bc 65 9d 94 de fb 9a d5 66 00 7a 79 dc da 16 |..e......f.zy...|
+00000350 03 03 00 04 0e 00 00 00 |........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 6d d3 b6 6a f0 ac |....%...! m..j..|
+00000010 40 6e e8 73 db a2 04 41 6a 7f c1 cc ae 13 44 e1 |@n.s...Aj.....D.|
+00000020 1c f4 5a 59 1b 88 4b a8 89 61 14 03 03 00 01 01 |..ZY..K..a......|
+00000030 16 03 03 00 20 5f 09 a4 44 8e a8 6d 09 14 32 05 |.... _..D..m..2.|
+00000040 ce ae f9 ad ad a2 d9 45 77 be e2 2c bd 97 22 1a |.......Ew..,..".|
+00000050 7d 3b 54 db 82 |};T..|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 20 54 52 24 a8 3a |.......... TR$.:|
+00000010 e3 45 a2 49 1c c5 10 62 6e d1 32 fe 70 0f 32 e0 |.E.I...bn.2.p.2.|
+00000020 fc 95 22 81 32 38 ab f2 0a ba 6c 17 03 03 00 1d |..".28....l.....|
+00000030 b7 a9 2a a5 ad e5 9e 39 cc a9 bc 81 ef a1 67 e1 |..*....9......g.|
+00000040 85 08 9f f4 e7 04 c8 0b 0d fd 5c ec 94 15 03 03 |..........\.....|
+00000050 00 12 d7 18 99 08 6c 98 dc 05 20 19 cd dd f2 29 |......l... ....)|
+00000060 14 3c cf 31 |.<.1|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-RSA-RSAPSS b/src/crypto/tls/testdata/Server-TLSv12-RSA-RSAPSS
new file mode 100644
index 0000000..46ee1aa
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-RSA-RSAPSS
@@ -0,0 +1,77 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 5b 01 00 00 57 03 03 ee 47 d0 cd 83 |....[...W...G...|
+00000010 ff 1e f3 45 81 2e 59 6a 84 da c9 29 bd b0 8b f5 |...E..Yj...)....|
+00000020 3c 47 58 b0 94 59 33 9a f6 00 2d 00 00 04 cc a8 |<GX..Y3...-.....|
+00000030 00 ff 01 00 00 2a 00 0b 00 04 03 00 01 02 00 0a |.....*..........|
+00000040 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 16 |................|
+00000050 00 00 00 17 00 00 00 0d 00 06 00 04 08 06 08 04 |................|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 3b 02 00 00 37 03 03 00 00 00 00 00 |....;...7.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 cc a8 00 00 |...DOWNGRD......|
+00000030 0f ff 01 00 01 00 00 17 00 00 00 0b 00 02 01 00 |................|
+00000040 16 03 03 02 59 0b 00 02 55 00 02 52 00 02 4f 30 |....Y...U..R..O0|
+00000050 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 |..K0............|
+00000060 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 86 f7 |..?.[..0...*.H..|
+00000070 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 55 04 |......0.1.0...U.|
+00000080 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 13 07 |...Go1.0...U....|
+00000090 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 31 30 |Go Root0...16010|
+000000a0 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 30 31 |1000000Z..250101|
+000000b0 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 03 55 |000000Z0.1.0...U|
+000000c0 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 03 13 |....Go1.0...U...|
+000000d0 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d |.Go0..0...*.H...|
+000000e0 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 |.........0......|
+000000f0 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab 7e c4 |.F}...'.H..(!.~.|
+00000100 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d 92 42 |..]..RE.z6G....B|
+00000110 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 |[.....y.@.Om..+.|
+00000120 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 |....g....."8.J.t|
+00000130 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c |s+.4......t{.X.l|
+00000140 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd |a<..A..++$#w[.;.|
+00000150 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a |u]. T..c...$....|
+00000160 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 |P....C...ub...R.|
+00000170 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 03 55 |........0..0...U|
+00000180 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 03 55 |...........0...U|
+00000190 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 03 01 |.%..0...+.......|
+000001a0 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 55 1d |..+.......0...U.|
+000001b0 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d 0e 04 |......0.0...U...|
+000001c0 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d b6 80 |.......CC>I..m..|
+000001d0 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 80 10 |..`0...U.#..0...|
+000001e0 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b |H.IM.~.1......n{|
+000001f0 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 78 61 |0...U....0...exa|
+00000200 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a |mple.golang0...*|
+00000210 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 9d 30 |.H.............0|
+00000220 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed 83 28 |.@+[P.a...SX...(|
+00000230 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 |.X..8....1Z..f=C|
+00000240 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a 00 bc |.-...... d8.$:..|
+00000250 cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 76 fd |..}.@ ._...a..v.|
+00000260 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb |.....\.....l..s.|
+00000270 b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 |.Cw.......@.a.Lr|
+00000280 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 |+...F..M...>...B|
+00000290 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 |...=.`.\!.;.....|
+000002a0 03 00 ac 0c 00 00 a8 03 00 1d 20 2f e5 7d a3 47 |.......... /.}.G|
+000002b0 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af |.bC.(.._.).0....|
+000002c0 c4 cf c2 ed 90 99 5f 58 cb 3b 74 08 04 00 80 95 |......_X.;t.....|
+000002d0 e0 3f 63 8b d7 e0 51 5a eb ea 5e de ce da 62 02 |.?c...QZ..^...b.|
+000002e0 7d 7d 42 7f 9f db 53 a2 a9 e5 be b4 32 47 65 9a |}}B...S.....2Ge.|
+000002f0 cc d6 9f ee 4c bc 28 7d 27 00 69 e2 fa fd fa 65 |....L.(}'.i....e|
+00000300 a0 3d c1 00 85 a9 28 8c d1 9b 6d 49 2f 84 17 b0 |.=....(...mI/...|
+00000310 59 cd ac 79 a8 6d cc 8a a0 05 e9 ca e8 df 14 2d |Y..y.m.........-|
+00000320 a0 59 a3 75 a6 c6 ec 91 37 e1 e6 dc 6d d8 74 96 |.Y.u....7...m.t.|
+00000330 95 bc ff 11 ca fe 91 4a d6 9e d7 73 5f bd 28 6a |.......J...s_.(j|
+00000340 23 6d c5 2b ee 25 17 6c e1 50 c1 f9 42 7e 3c 16 |#m.+.%.l.P..B~<.|
+00000350 03 03 00 04 0e 00 00 00 |........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 51 de e0 c4 a5 8f |....%...! Q.....|
+00000010 ee 05 c5 d5 a2 ce 9c 4a 19 6d 14 cb 61 88 a6 fe |.......J.m..a...|
+00000020 38 24 b6 4e d7 f0 c5 27 97 32 14 03 03 00 01 01 |8$.N...'.2......|
+00000030 16 03 03 00 20 0e 14 d4 f5 c2 10 a1 80 b3 b4 90 |.... ...........|
+00000040 17 43 1f 22 69 78 00 bb 87 c3 78 23 8e 03 8f c4 |.C."ix....x#....|
+00000050 28 1c f8 42 e6 |(..B.|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 20 6f a9 ff 13 fb |.......... o....|
+00000010 85 fa e4 fc cd ca 74 59 21 cd 3c fd 73 43 a2 48 |......tY!.<.sC.H|
+00000020 f5 cf cd f7 9b 24 1d db 8a 52 a6 17 03 03 00 1d |.....$...R......|
+00000030 63 25 92 b2 0c f7 d1 92 83 95 3c 13 ee 78 4c c1 |c%........<..xL.|
+00000040 60 66 60 ed 8e 86 5b 1d 2d 1b a5 ab 38 15 03 03 |`f`...[.-...8...|
+00000050 00 12 d5 3c b4 59 87 f5 45 fc 68 9b 03 7e 5b 97 |...<.Y..E.h..~[.|
+00000060 c1 83 13 33 |...3|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-Resume b/src/crypto/tls/testdata/Server-TLSv12-Resume
new file mode 100644
index 0000000..cd0a124
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-Resume
@@ -0,0 +1,54 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 01 0a 01 00 01 06 03 03 2d b6 ca ea 39 |...........-...9|
+00000010 59 17 86 df 90 2f 73 e0 a0 5c 6e 28 09 78 69 d6 |Y..../s..\n(.xi.|
+00000020 30 06 b7 7b 17 a9 79 30 2a d8 57 20 c5 5c ed 86 |0..{..y0*.W .\..|
+00000030 15 f4 3b c8 d2 5f 7a 80 2a 6a cd 40 c2 da 6f a8 |..;.._z.*j.@..o.|
+00000040 cd d7 e7 bf 48 bd fb a1 e9 4b 9b a9 00 04 00 2f |....H....K...../|
+00000050 00 ff 01 00 00 b9 00 23 00 79 00 00 00 00 00 00 |.......#.y......|
+00000060 00 00 00 00 00 00 00 00 00 00 94 6f 2d b0 ac 51 |...........o-..Q|
+00000070 ed 14 ef 68 ca 42 c5 4c 85 f6 26 0d a4 ad a8 f5 |...h.B.L..&.....|
+00000080 14 64 4f b9 c3 fb 1e 55 c1 1f c7 31 57 72 68 db |.dO....U...1Wrh.|
+00000090 03 37 a8 c9 07 f4 ca 62 6c 5c f3 8b 5a 3d 76 dd |.7.....bl\..Z=v.|
+000000a0 63 ea 68 61 6b a1 2d 95 49 38 16 7e 51 5c e5 15 |c.hak.-.I8.~Q\..|
+000000b0 c0 58 7d c5 67 4a 6f 64 b6 79 1a 41 9b b1 33 15 |.X}.gJod.y.A..3.|
+000000c0 38 74 92 5c a5 48 c3 f2 94 bb 33 ec af cf d7 e7 |8t.\.H....3.....|
+000000d0 c9 3e 35 00 16 00 00 00 17 00 00 00 0d 00 30 00 |.>5...........0.|
+000000e0 2e 04 03 05 03 06 03 08 07 08 08 08 09 08 0a 08 |................|
+000000f0 0b 08 04 08 05 08 06 04 01 05 01 06 01 03 03 02 |................|
+00000100 03 03 01 02 01 03 02 02 02 04 02 05 02 06 02 |...............|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 59 02 00 00 55 03 03 00 00 00 00 00 |....Y...U.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 44 4f 57 4e 47 52 44 01 20 c5 5c ed 86 |...DOWNGRD. .\..|
+00000030 15 f4 3b c8 d2 5f 7a 80 2a 6a cd 40 c2 da 6f a8 |..;.._z.*j.@..o.|
+00000040 cd d7 e7 bf 48 bd fb a1 e9 4b 9b a9 00 2f 00 00 |....H....K.../..|
+00000050 0d 00 23 00 00 ff 01 00 01 00 00 17 00 00 16 03 |..#.............|
+00000060 03 00 83 04 00 00 7f 00 00 00 00 00 79 00 00 00 |............y...|
+00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 94 6f 2d |..............o-|
+00000080 b0 ac 51 ed 14 ef 68 ca 42 c5 4c 85 f6 26 0d a4 |..Q...h.B.L..&..|
+00000090 ad a8 f5 14 64 4f b9 c3 fb 1e 55 c1 1f c7 31 57 |....dO....U...1W|
+000000a0 72 68 db 03 37 a8 c9 07 f4 ca 62 6c 5c f3 8b 5a |rh..7.....bl\..Z|
+000000b0 3d 76 dd 63 ea 68 61 6b a1 2d 95 49 38 16 7e 51 |=v.c.hak.-.I8.~Q|
+000000c0 5c e5 15 c0 58 7d c5 67 4a 6f 64 b6 79 1a 41 9b |\...X}.gJod.y.A.|
+000000d0 b1 33 15 38 74 92 5c a5 48 c3 f2 94 bb 33 ec af |.3.8t.\.H....3..|
+000000e0 cf d7 e7 c9 3e 35 14 03 03 00 01 01 16 03 03 00 |....>5..........|
+000000f0 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |@...............|
+00000100 00 47 68 3a 66 5b d6 ed b7 60 a9 fb e8 37 d6 9d |.Gh:f[...`...7..|
+00000110 a6 b9 4d d5 f3 9f 0f c6 3c 21 6e d5 80 08 a8 34 |..M.....<!n....4|
+00000120 34 da a3 1f b0 20 28 e4 2f 2b 6b c6 3e dc ac 6b |4.... (./+k.>..k|
+00000130 40 |@|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 16 03 03 00 40 46 34 b3 97 54 |..........@F4..T|
+00000010 20 5b 95 f3 22 f8 a1 89 c8 95 93 ba 7b a4 a8 8f | [..".......{...|
+00000020 46 a8 d6 c1 b3 ac f0 e0 49 3d 8d e4 1c ac b8 a4 |F.......I=......|
+00000030 01 21 5e d8 f0 f5 10 10 f7 de 8b 33 9d 94 cf f6 |.!^........3....|
+00000040 f2 9b 39 22 5c e6 c0 5e b4 1d cd |..9"\..^...|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 40 00 00 00 00 00 00 00 00 00 00 00 |....@...........|
+00000010 00 00 00 00 00 5c bc 45 06 2e d3 7b 30 99 a6 af |.....\.E...{0...|
+00000020 64 0e 63 93 73 6f 0a e7 a4 1d ac 94 25 11 a5 63 |d.c.so......%..c|
+00000030 8d b2 44 aa 98 44 f8 b5 51 ea 2c fb 26 99 f6 a4 |..D..D..Q.,.&...|
+00000040 2c f8 15 c3 90 15 03 03 00 30 00 00 00 00 00 00 |,........0......|
+00000050 00 00 00 00 00 00 00 00 00 00 c6 58 8e 7c 97 de |...........X.|..|
+00000060 3b b8 39 cd 7b 1d 67 77 27 da 93 39 52 a7 81 9b |;.9.{.gw'..9R...|
+00000070 ab 5a bc e9 00 1a 64 3a ca f5 |.Z....d:..|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ResumeDisabled b/src/crypto/tls/testdata/Server-TLSv12-ResumeDisabled
new file mode 100644
index 0000000..9110f54
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-ResumeDisabled
@@ -0,0 +1,91 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 01 06 01 00 01 02 03 03 dc 6d 25 a7 37 |............m%.7|
+00000010 5a 18 ef e8 ba a7 4b cb 25 8b 5a 61 bd fd 99 56 |Z.....K.%.Za...V|
+00000020 a8 7f 10 26 f7 f4 e9 3e 16 89 ce 20 ac c3 35 13 |...&...>... ..5.|
+00000030 d1 28 31 15 15 2d 6b e9 50 20 07 2c c5 48 6c 21 |.(1..-k.P .,.Hl!|
+00000040 78 bf c9 7c c4 39 e7 2e 0a ed 71 21 00 04 00 2f |x..|.9....q!.../|
+00000050 00 ff 01 00 00 b5 00 23 00 75 00 00 00 00 00 00 |.......#.u......|
+00000060 00 00 00 00 00 00 00 00 00 00 94 6f 2d b0 ac 51 |...........o-..Q|
+00000070 ed 14 ef 68 ca 42 c5 4c 22 21 0e 9f b0 e7 07 47 |...h.B.L"!.....G|
+00000080 1d 09 01 ee 9b 67 49 2f 06 cb 51 1b d9 33 b3 ff |.....gI/..Q..3..|
+00000090 30 6c d4 a3 d6 6b 49 aa f8 2e 20 35 79 5a 76 91 |0l...kI... 5yZv.|
+000000a0 46 71 26 91 22 4f 32 50 49 38 16 7f 51 5c e5 47 |Fq&."O2PI8..Q\.G|
+000000b0 26 64 f4 0c dd 12 66 59 0d 8f 92 07 ab ff 68 01 |&d....fY......h.|
+000000c0 0d d5 54 06 2d 08 b1 09 a1 3c ff f9 bc 78 03 00 |..T.-....<...x..|
+000000d0 16 00 00 00 17 00 00 00 0d 00 30 00 2e 04 03 05 |..........0.....|
+000000e0 03 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 |................|
+000000f0 05 08 06 04 01 05 01 06 01 03 03 02 03 03 01 02 |................|
+00000100 01 03 02 02 02 04 02 05 02 06 02 |...........|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 35 02 00 00 31 03 03 00 00 00 00 00 |....5...1.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 2f 00 00 |...DOWNGRD.../..|
+00000030 09 ff 01 00 01 00 00 17 00 00 16 03 03 02 59 0b |..............Y.|
+00000040 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..|
+00000050 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.|
+00000060 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........|
+00000070 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1|
+00000080 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo|
+00000090 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000|
+000000a0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000|
+000000b0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go|
+000000c0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..|
+000000d0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........|
+000000e0 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...|
+000000f0 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R|
+00000100 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....|
+00000110 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.|
+00000120 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..|
+00000130 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.|
+00000140 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.|
+00000150 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C|
+00000160 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......|
+00000170 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......|
+00000180 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.|
+00000190 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...|
+000001a0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......|
+000001b0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........|
+000001c0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..|
+000001d0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~|
+000001e0 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.|
+000001f0 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g|
+00000200 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....|
+00000210 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.|
+00000220 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.|
+00000230 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....|
+00000240 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ |
+00000250 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\|
+00000260 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...|
+00000270 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.|
+00000280 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`|
+00000290 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e 00 00 |.\!.;...........|
+000002a0 00 |.|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 86 10 00 00 82 00 80 c0 3f 68 b7 3f |............?h.?|
+00000010 6c 1f de 6b 2d 67 9e 1b 13 13 ad 67 d8 0f b2 b1 |l..k-g.....g....|
+00000020 95 17 e7 0b e1 ba 6f 93 20 43 aa c7 a4 02 8e 38 |......o. C.....8|
+00000030 01 6b 53 55 33 6e 82 ea 70 d7 e2 a6 bd be 57 2d |.kSU3n..p.....W-|
+00000040 85 1c 4a 28 30 42 34 e6 f9 38 9c 59 ed 1c fc ff |..J(0B4..8.Y....|
+00000050 19 0f 1d 71 f1 4b 2a 7a b1 c6 d9 11 a5 5e ca 1c |...q.K*z.....^..|
+00000060 14 70 71 4c 3a c8 8d ca d9 4b 57 f8 76 2c 8f 89 |.pqL:....KW.v,..|
+00000070 84 41 96 fb 37 2d 17 a9 28 c8 c6 47 1b fb 3d 42 |.A..7-..(..G..=B|
+00000080 64 12 8f c7 e7 36 35 bf ce df d7 14 03 03 00 01 |d....65.........|
+00000090 01 16 03 03 00 40 47 f9 4a d1 3b af 27 48 8a 15 |.....@G.J.;.'H..|
+000000a0 c1 61 61 41 cc c3 4f 1d 9c 86 42 a9 17 1d e3 68 |.aaA..O...B....h|
+000000b0 84 1f ae b7 9f 4b 70 be 72 0b 2c 48 88 ea ff 43 |.....Kp.r.,H...C|
+000000c0 37 01 cc 37 c0 2d e9 da 8b 94 ef ed f9 02 95 a9 |7..7.-..........|
+000000d0 bf 63 0f 6a 7c c0 |.c.j|.|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....|
+00000010 00 00 00 00 00 00 00 00 00 00 00 4a bf f1 2b 6a |...........J..+j|
+00000020 af e5 b9 51 69 38 3e a3 47 bf 0b 67 83 15 e0 91 |...Qi8>.G..g....|
+00000030 c6 b3 cb fc 24 05 31 b7 51 3d fa bb 08 9a f9 f8 |....$.1.Q=......|
+00000040 89 2a f1 5a b1 a8 1a ed aa 63 00 17 03 03 00 40 |.*.Z.....c.....@|
+00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000060 80 37 dc f6 b1 a2 80 91 0e c9 71 c6 1c 1e 45 14 |.7........q...E.|
+00000070 50 cd 39 85 73 8a f5 90 75 28 05 ab 69 ae 1a bd |P.9.s...u(..i...|
+00000080 b9 ee 39 e8 3f 2d 73 4d 21 fa 2e 05 b4 a1 02 64 |..9.?-sM!......d|
+00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
+000000a0 00 00 00 00 00 14 1e f7 64 d8 47 a6 93 aa 03 aa |........d.G.....|
+000000b0 7c f3 a2 fb b8 6f cf f2 0d e4 2d d1 d6 67 f3 6b ||....o....-..g.k|
+000000c0 ef e3 5d dc 5b |..].[|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-SNI b/src/crypto/tls/testdata/Server-TLSv12-SNI
new file mode 100644
index 0000000..c3dc1b6
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-SNI
@@ -0,0 +1,83 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 81 01 00 00 7d 03 03 cc a1 7b c4 56 |........}....{.V|
+00000010 9f 65 31 01 b0 23 09 18 10 50 7c 1e 14 7b b5 dd |.e1..#...P|..{..|
+00000020 d4 70 07 3e 0b 19 19 31 6b f7 4d 00 00 04 00 2f |.p.>...1k.M..../|
+00000030 00 ff 01 00 00 50 00 00 00 10 00 0e 00 00 0b 73 |.....P.........s|
+00000040 6e 69 74 65 73 74 2e 63 6f 6d 00 16 00 00 00 17 |nitest.com......|
+00000050 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 08 07 |.....0..........|
+00000060 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 |................|
+00000070 05 01 06 01 03 03 02 03 03 01 02 01 03 02 02 02 |................|
+00000080 04 02 05 02 06 02 |......|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 35 02 00 00 31 03 03 00 00 00 00 00 |....5...1.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 2f 00 00 |...DOWNGRD.../..|
+00000030 09 ff 01 00 01 00 00 17 00 00 16 03 03 02 59 0b |..............Y.|
+00000040 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..|
+00000050 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.|
+00000060 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........|
+00000070 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1|
+00000080 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo|
+00000090 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000|
+000000a0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000|
+000000b0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go|
+000000c0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..|
+000000d0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........|
+000000e0 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...|
+000000f0 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R|
+00000100 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....|
+00000110 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.|
+00000120 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..|
+00000130 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.|
+00000140 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.|
+00000150 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C|
+00000160 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......|
+00000170 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......|
+00000180 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.|
+00000190 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...|
+000001a0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......|
+000001b0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........|
+000001c0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..|
+000001d0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~|
+000001e0 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.|
+000001f0 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g|
+00000200 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....|
+00000210 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.|
+00000220 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.|
+00000230 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....|
+00000240 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ |
+00000250 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\|
+00000260 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...|
+00000270 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.|
+00000280 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`|
+00000290 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e 00 00 |.\!.;...........|
+000002a0 00 |.|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 86 10 00 00 82 00 80 04 36 4c 25 96 |............6L%.|
+00000010 b0 1a 33 80 88 98 4f 2a c8 93 24 81 0a 78 6c 85 |..3...O*..$..xl.|
+00000020 06 4d f1 cf 25 18 e0 f0 61 50 c5 45 c1 24 1b b3 |.M..%...aP.E.$..|
+00000030 d6 3c d3 49 a6 40 81 2c bb ef 49 76 c0 10 4c ad |.<.I.@.,..Iv..L.|
+00000040 2e 7d 4d f4 0b 96 bc 1c eb 3d 1d 7d 18 25 34 14 |.}M......=.}.%4.|
+00000050 ed 76 f2 a1 17 aa 87 1b ef ff 11 93 a7 44 0c 33 |.v...........D.3|
+00000060 86 27 38 3d 5d 3f bb f1 8d a9 f5 44 28 d1 28 41 |.'8=]?.....D(.(A|
+00000070 bb b7 9a fb 83 81 91 92 4e 7d 71 55 43 ed 42 12 |........N}qUC.B.|
+00000080 86 5f de 02 13 1f c4 63 08 87 db 14 03 03 00 01 |._.....c........|
+00000090 01 16 03 03 00 40 32 01 5f a2 e1 08 cf 6b ce 11 |.....@2._....k..|
+000000a0 db 82 94 c5 f1 12 9a ac 68 dc f9 c8 2c 00 a5 dd |........h...,...|
+000000b0 6b 49 c8 8b b7 9f e3 90 27 a5 c2 45 fc 75 e5 ac |kI......'..E.u..|
+000000c0 77 0c 80 bd 43 41 d4 00 c0 fb 8d 08 a6 f4 f7 63 |w...CA.........c|
+000000d0 07 01 09 06 e5 fc |......|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....|
+00000010 00 00 00 00 00 00 00 00 00 00 00 6d 31 fe 01 3d |...........m1..=|
+00000020 2a c3 97 67 9f 08 f8 c9 ce 57 5c 4a e6 da 17 f2 |*..g.....W\J....|
+00000030 f8 47 2b d9 9d 7e af 59 b8 a9 23 9d 7e d5 ed 77 |.G+..~.Y..#.~..w|
+00000040 3b cd d4 b7 76 5b 6f 6d 09 bd 0c 17 03 03 00 40 |;...v[om.......@|
+00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000060 d2 8c 47 46 36 47 fa d8 f8 1c b4 fc f6 fd fb 4b |..GF6G.........K|
+00000070 79 e1 a3 39 df ac 6c 94 61 dd 20 1a e7 c0 4c 9c |y..9..l.a. ...L.|
+00000080 45 69 69 cf 73 cb b1 6c fc 71 49 de 41 ca 4d 4f |Eii.s..l.qI.A.MO|
+00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
+000000a0 00 00 00 00 00 d1 66 64 ce 59 eb 23 13 e9 92 28 |......fd.Y.#...(|
+000000b0 a4 2a 7a b0 e1 79 ce 92 34 77 6e b3 8d d3 bb e6 |.*z..y..4wn.....|
+000000c0 ad 90 e8 a2 1a |.....|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-SNI-GetCertificate b/src/crypto/tls/testdata/Server-TLSv12-SNI-GetCertificate
new file mode 100644
index 0000000..474ab1a
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-SNI-GetCertificate
@@ -0,0 +1,83 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 81 01 00 00 7d 03 03 02 34 82 a7 1a |........}...4...|
+00000010 fe 81 b0 1c 2e df cc 04 2d f7 22 39 34 95 c7 c1 |........-."94...|
+00000020 b2 92 a2 d2 aa ca 57 0f 9c be b4 00 00 04 00 2f |......W......../|
+00000030 00 ff 01 00 00 50 00 00 00 10 00 0e 00 00 0b 73 |.....P.........s|
+00000040 6e 69 74 65 73 74 2e 63 6f 6d 00 16 00 00 00 17 |nitest.com......|
+00000050 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 08 07 |.....0..........|
+00000060 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 |................|
+00000070 05 01 06 01 03 03 02 03 03 01 02 01 03 02 02 02 |................|
+00000080 04 02 05 02 06 02 |......|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 35 02 00 00 31 03 03 00 00 00 00 00 |....5...1.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 2f 00 00 |...DOWNGRD.../..|
+00000030 09 ff 01 00 01 00 00 17 00 00 16 03 03 02 59 0b |..............Y.|
+00000040 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..|
+00000050 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.|
+00000060 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........|
+00000070 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1|
+00000080 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo|
+00000090 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000|
+000000a0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000|
+000000b0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go|
+000000c0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..|
+000000d0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........|
+000000e0 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...|
+000000f0 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R|
+00000100 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....|
+00000110 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.|
+00000120 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..|
+00000130 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.|
+00000140 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.|
+00000150 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C|
+00000160 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......|
+00000170 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......|
+00000180 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.|
+00000190 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...|
+000001a0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......|
+000001b0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........|
+000001c0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..|
+000001d0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~|
+000001e0 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.|
+000001f0 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g|
+00000200 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....|
+00000210 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.|
+00000220 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.|
+00000230 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....|
+00000240 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ |
+00000250 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\|
+00000260 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...|
+00000270 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.|
+00000280 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`|
+00000290 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e 00 00 |.\!.;...........|
+000002a0 00 |.|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 86 10 00 00 82 00 80 d9 90 3c 11 be |.............<..|
+00000010 f3 48 de f0 8f 9e 12 ca e0 ab 86 e0 7e e7 8b ea |.H..........~...|
+00000020 1a 76 3e 65 8d 7a d6 1c 72 2a f7 1e aa 0a 12 8f |.v>e.z..r*......|
+00000030 54 ac 33 95 9d 00 a9 a6 94 54 7b 6a d9 e3 f4 67 |T.3......T{j...g|
+00000040 a6 d3 b1 c1 5d 86 51 aa 63 67 6b 6e cb 3b 5e 59 |....].Q.cgkn.;^Y|
+00000050 02 c2 57 fd 37 39 1b 73 9a 61 b0 78 de e8 cc f8 |..W.79.s.a.x....|
+00000060 b3 01 11 e5 e9 31 85 4d fe 60 d4 12 70 71 64 45 |.....1.M.`..pqdE|
+00000070 e8 7d fb be 5b 82 c0 c4 e1 57 09 2c f2 d7 a3 79 |.}..[....W.,...y|
+00000080 1c 40 08 e1 e6 cd e2 3e e7 55 da 14 03 03 00 01 |.@.....>.U......|
+00000090 01 16 03 03 00 40 29 9e b7 cf 5e 7c e9 40 91 5f |.....@)...^|.@._|
+000000a0 b6 12 d4 42 ec 6a bc 03 d9 fa e4 d8 bf c7 2c c5 |...B.j........,.|
+000000b0 52 74 17 77 b1 aa 13 87 f0 81 da 0d ca 7f d9 ca |Rt.w............|
+000000c0 18 46 55 62 3f 90 21 60 fa 85 8c 80 6b 23 45 e7 |.FUb?.!`....k#E.|
+000000d0 0b 6e 8c e2 c3 f6 |.n....|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....|
+00000010 00 00 00 00 00 00 00 00 00 00 00 ee 8d 0f cd 15 |................|
+00000020 db b4 cd 25 27 b6 7e 9b 82 91 2f 01 e1 4f f9 0c |...%'.~.../..O..|
+00000030 68 4c bf 26 2b 4b 49 f5 0a 67 8a 4f 12 35 37 75 |hL.&+KI..g.O.57u|
+00000040 16 fe cc 26 35 66 60 8c ed 42 40 17 03 03 00 40 |...&5f`..B@....@|
+00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000060 f5 7a ee 53 aa 85 bb 81 c4 57 68 12 f1 40 4c 20 |.z.S.....Wh..@L |
+00000070 2a ff fc 6c dd 73 65 fc 41 e6 5b 96 6b 35 2f 8a |*..l.se.A.[.k5/.|
+00000080 62 49 4a da f4 df 93 a0 ab e1 12 4d 8d 34 2c 6a |bIJ........M.4,j|
+00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
+000000a0 00 00 00 00 00 1c 08 e5 52 29 79 d6 15 07 10 44 |........R)y....D|
+000000b0 95 07 07 cb 3b 2b 37 2f e3 dc 17 f9 27 b6 5d 44 |....;+7/....'.]D|
+000000c0 d0 30 4b 2e 21 |.0K.!|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-SNI-GetCertificateNotFound b/src/crypto/tls/testdata/Server-TLSv12-SNI-GetCertificateNotFound
new file mode 100644
index 0000000..0c06ce9
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-SNI-GetCertificateNotFound
@@ -0,0 +1,83 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 81 01 00 00 7d 03 03 77 e7 c3 97 fa |........}..w....|
+00000010 59 80 de d1 f5 9f ce e5 a5 38 60 2c 30 b2 64 5b |Y........8`,0.d[|
+00000020 6c 0a 56 49 1d 6f 19 57 5a ac 05 00 00 04 00 2f |l.VI.o.WZ....../|
+00000030 00 ff 01 00 00 50 00 00 00 10 00 0e 00 00 0b 73 |.....P.........s|
+00000040 6e 69 74 65 73 74 2e 63 6f 6d 00 16 00 00 00 17 |nitest.com......|
+00000050 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 08 07 |.....0..........|
+00000060 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 |................|
+00000070 05 01 06 01 03 03 02 03 03 01 02 01 03 02 02 02 |................|
+00000080 04 02 05 02 06 02 |......|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 35 02 00 00 31 03 03 00 00 00 00 00 |....5...1.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 00 2f 00 00 |...DOWNGRD.../..|
+00000030 09 ff 01 00 01 00 00 17 00 00 16 03 03 02 59 0b |..............Y.|
+00000040 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 01 |..U..R..O0..K0..|
+00000050 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b ea |............?.[.|
+00000060 a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |.0...*.H........|
+00000070 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 |0.1.0...U....Go1|
+00000080 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f 6f |.0...U....Go Roo|
+00000090 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 30 |t0...16010100000|
+000000a0 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 30 |0Z..250101000000|
+000000b0 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |Z0.1.0...U....Go|
+000000c0 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 9f |1.0...U....Go0..|
+000000d0 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 |0...*.H.........|
+000000e0 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e 12 |...0.......F}...|
+000000f0 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 |'.H..(!.~...]..R|
+00000100 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be 97 |E.z6G....B[.....|
+00000110 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 |y.@.Om..+.....g.|
+00000120 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 |...."8.J.ts+.4..|
+00000130 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 |....t{.X.la<..A.|
+00000140 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 cf |.++$#w[.;.u]. T.|
+00000150 a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 |.c...$....P....C|
+00000160 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 a3 |...ub...R.......|
+00000170 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff 04 |..0..0...U......|
+00000180 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 14 |.....0...U.%..0.|
+00000190 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 05 |..+.........+...|
+000001a0 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 02 |....0...U.......|
+000001b0 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 16 |0.0...U.........|
+000001c0 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 |.CC>I..m....`0..|
+000001d0 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 7e |.U.#..0...H.IM.~|
+000001e0 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 1d |.1......n{0...U.|
+000001f0 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e 67 |...0...example.g|
+00000200 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d 01 |olang0...*.H....|
+00000210 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 |.........0.@+[P.|
+00000220 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 |a...SX...(.X..8.|
+00000230 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 |...1Z..f=C.-....|
+00000240 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 20 |.. d8.$:....}.@ |
+00000250 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c |._...a..v......\|
+00000260 ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c |.....l..s..Cw...|
+00000270 f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 06 |....@.a.Lr+...F.|
+00000280 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 |.M...>...B...=.`|
+00000290 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e 00 00 |.\!.;...........|
+000002a0 00 |.|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 86 10 00 00 82 00 80 67 0c a0 f8 da |...........g....|
+00000010 2e d9 9e 9d ef c8 9b 77 f5 fe 25 32 74 49 1d a7 |.......w..%2tI..|
+00000020 7d 69 37 2a 94 07 5a 15 e8 f1 1d 36 25 ae 32 e4 |}i7*..Z....6%.2.|
+00000030 9c f5 35 fb 54 81 f2 19 4f 8d 6b 64 1a b2 a2 2e |..5.T...O.kd....|
+00000040 c4 cb 5b 73 9d 46 97 01 33 d3 b8 a9 18 39 2c ad |..[s.F..3....9,.|
+00000050 f2 eb 6b 02 38 44 f8 cf ae ac a6 e6 54 92 29 ae |..k.8D......T.).|
+00000060 a6 8a 4e 82 99 f3 77 8c b6 3a a1 5c 4f 25 3b 7f |..N...w..:.\O%;.|
+00000070 39 2f cd 51 dc e3 fc 7c 5a 5a 33 e4 af 43 d0 d3 |9/.Q...|ZZ3..C..|
+00000080 eb 3b 86 71 af 92 53 6e 02 b9 59 14 03 03 00 01 |.;.q..Sn..Y.....|
+00000090 01 16 03 03 00 40 8b e4 6f d3 88 e7 6a e9 aa f2 |.....@..o...j...|
+000000a0 4f 67 69 80 bc f1 78 ca a9 f9 29 ce 44 93 81 46 |Ogi...x...).D..F|
+000000b0 0e 18 d1 2a 14 8b 3b b5 15 e4 b5 2a bb 88 d4 80 |...*..;....*....|
+000000c0 7b 2f 03 c7 83 7c 61 24 29 fe dd bc 49 8a b1 88 |{/...|a$)...I...|
+000000d0 41 ac 8a 12 f8 d6 |A.....|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....|
+00000010 00 00 00 00 00 00 00 00 00 00 00 e7 d3 34 46 88 |.............4F.|
+00000020 0e 7f ae 5b d6 e5 70 d2 7d 99 25 1b 27 89 8a a4 |...[..p.}.%.'...|
+00000030 02 03 01 a4 e1 d6 72 af c3 5a 55 f7 56 69 60 91 |......r..ZU.Vi`.|
+00000040 49 29 68 36 99 e5 09 ac 7a e3 4f 17 03 03 00 40 |I)h6....z.O....@|
+00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000060 71 d0 36 7d 2c 3b 40 e3 a9 3f c1 d0 5e 3a ee d2 |q.6},;@..?..^:..|
+00000070 4d 0d b7 f4 83 3e 75 e0 ed 8a fc b2 9b ed 98 a8 |M....>u.........|
+00000080 ec 49 65 83 53 e0 79 52 03 2b 78 8a 64 3e 4c 5e |.Ie.S.yR.+x.d>L^|
+00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
+000000a0 00 00 00 00 00 76 38 c3 3d 86 d8 58 f2 16 48 94 |.....v8.=..X..H.|
+000000b0 46 65 ea 80 46 74 fe 66 7c 72 99 30 b3 05 08 14 |Fe..Ft.f|r.0....|
+000000c0 19 e3 ee 6f cf |...o.|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-X25519 b/src/crypto/tls/testdata/Server-TLSv12-X25519
new file mode 100644
index 0000000..09f321e
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-X25519
@@ -0,0 +1,80 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 7d 01 00 00 79 03 03 dc 04 e9 5b d1 |....}...y.....[.|
+00000010 6b d9 b9 5e f7 4c 01 7e 58 4a 99 d9 90 c8 a2 7b |k..^.L.~XJ.....{|
+00000020 f4 55 08 68 9b 42 34 6a 14 6c 01 00 00 04 cc a8 |.U.h.B4j.l......|
+00000030 00 ff 01 00 00 4c 00 0b 00 04 03 00 01 02 00 0a |.....L..........|
+00000040 00 04 00 02 00 1d 00 16 00 00 00 17 00 00 00 0d |................|
+00000050 00 30 00 2e 04 03 05 03 06 03 08 07 08 08 08 09 |.0..............|
+00000060 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................|
+00000070 03 03 02 03 03 01 02 01 03 02 02 02 04 02 05 02 |................|
+00000080 06 02 |..|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 3b 02 00 00 37 03 03 00 00 00 00 00 |....;...7.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 44 4f 57 4e 47 52 44 01 00 cc a8 00 00 |...DOWNGRD......|
+00000030 0f ff 01 00 01 00 00 17 00 00 00 0b 00 02 01 00 |................|
+00000040 16 03 03 02 59 0b 00 02 55 00 02 52 00 02 4f 30 |....Y...U..R..O0|
+00000050 82 02 4b 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 |..K0............|
+00000060 f0 9d 3f e2 5b ea a6 30 0d 06 09 2a 86 48 86 f7 |..?.[..0...*.H..|
+00000070 0d 01 01 0b 05 00 30 1f 31 0b 30 09 06 03 55 04 |......0.1.0...U.|
+00000080 0a 13 02 47 6f 31 10 30 0e 06 03 55 04 03 13 07 |...Go1.0...U....|
+00000090 47 6f 20 52 6f 6f 74 30 1e 17 0d 31 36 30 31 30 |Go Root0...16010|
+000000a0 31 30 30 30 30 30 30 5a 17 0d 32 35 30 31 30 31 |1000000Z..250101|
+000000b0 30 30 30 30 30 30 5a 30 1a 31 0b 30 09 06 03 55 |000000Z0.1.0...U|
+000000c0 04 0a 13 02 47 6f 31 0b 30 09 06 03 55 04 03 13 |....Go1.0...U...|
+000000d0 02 47 6f 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d |.Go0..0...*.H...|
+000000e0 01 01 01 05 00 03 81 8d 00 30 81 89 02 81 81 00 |.........0......|
+000000f0 db 46 7d 93 2e 12 27 06 48 bc 06 28 21 ab 7e c4 |.F}...'.H..(!.~.|
+00000100 b6 a2 5d fe 1e 52 45 88 7a 36 47 a5 08 0d 92 42 |..]..RE.z6G....B|
+00000110 5b c2 81 c0 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 |[.....y.@.Om..+.|
+00000120 8b c2 a5 2e 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 |....g....."8.J.t|
+00000130 73 2b c2 34 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c |s+.4......t{.X.l|
+00000140 61 3c c0 b0 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd |a<..A..++$#w[.;.|
+00000150 75 5d ce 20 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a |u]. T..c...$....|
+00000160 50 8b aa b6 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 |P....C...ub...R.|
+00000170 02 03 01 00 01 a3 81 93 30 81 90 30 0e 06 03 55 |........0..0...U|
+00000180 1d 0f 01 01 ff 04 04 03 02 05 a0 30 1d 06 03 55 |...........0...U|
+00000190 1d 25 04 16 30 14 06 08 2b 06 01 05 05 07 03 01 |.%..0...+.......|
+000001a0 06 08 2b 06 01 05 05 07 03 02 30 0c 06 03 55 1d |..+.......0...U.|
+000001b0 13 01 01 ff 04 02 30 00 30 19 06 03 55 1d 0e 04 |......0.0...U...|
+000001c0 12 04 10 9f 91 16 1f 43 43 3e 49 a6 de 6d b6 80 |.......CC>I..m..|
+000001d0 d7 9f 60 30 1b 06 03 55 1d 23 04 14 30 12 80 10 |..`0...U.#..0...|
+000001e0 48 13 49 4d 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b |H.IM.~.1......n{|
+000001f0 30 19 06 03 55 1d 11 04 12 30 10 82 0e 65 78 61 |0...U....0...exa|
+00000200 6d 70 6c 65 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a |mple.golang0...*|
+00000210 86 48 86 f7 0d 01 01 0b 05 00 03 81 81 00 9d 30 |.H.............0|
+00000220 cc 40 2b 5b 50 a0 61 cb ba e5 53 58 e1 ed 83 28 |.@+[P.a...SX...(|
+00000230 a9 58 1a a9 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 |.X..8....1Z..f=C|
+00000240 d3 2d d9 0b f2 97 df d3 20 64 38 92 24 3a 00 bc |.-...... d8.$:..|
+00000250 cf 9c 7d b7 40 20 01 5f aa d3 16 61 09 a2 76 fd |..}.@ ._...a..v.|
+00000260 13 c3 cc e1 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb |.....\.....l..s.|
+00000270 b3 43 77 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 |.Cw.......@.a.Lr|
+00000280 2b 9d ae db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 |+...F..M...>...B|
+00000290 d4 db fe 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 |...=.`.\!.;.....|
+000002a0 03 00 ac 0c 00 00 a8 03 00 1d 20 2f e5 7d a3 47 |.......... /.}.G|
+000002b0 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af |.bC.(.._.).0....|
+000002c0 c4 cf c2 ed 90 99 5f 58 cb 3b 74 08 04 00 80 27 |......_X.;t....'|
+000002d0 d6 32 9d 2d 17 61 04 13 02 29 ad c2 af f7 ac 7b |.2.-.a...).....{|
+000002e0 65 1c 6b cd 1d 7d 05 d7 b9 55 82 1b 23 92 6b b5 |e.k..}...U..#.k.|
+000002f0 a2 d6 65 d7 42 6f a3 b6 2a f0 ac a4 6c dd f3 11 |..e.Bo..*...l...|
+00000300 a0 20 ee 45 42 33 fc 45 d1 9e d7 bb 75 0e d1 bd |. .EB3.E....u...|
+00000310 cd 8f 64 35 85 79 88 9b 63 1e 8c 08 1b fd 19 5e |..d5.y..c......^|
+00000320 a9 ac 06 79 1e 4a 95 fa cd 60 86 e3 10 e4 d0 39 |...y.J...`.....9|
+00000330 0c a0 0b 6f 6f 55 a4 7d 65 d4 41 ee 60 62 42 a8 |...ooU.}e.A.`bB.|
+00000340 5e 22 55 48 3c 54 53 f0 28 e1 7f 67 4f f0 1f 16 |^"UH<TS.(..gO...|
+00000350 03 03 00 04 0e 00 00 00 |........|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 35 e6 c9 e2 76 cf |....%...! 5...v.|
+00000010 36 af dc 27 30 6b eb f4 ae 62 f1 f4 40 81 04 d2 |6..'0k...b..@...|
+00000020 f1 c7 d5 af 7d 64 ef 64 d0 58 14 03 03 00 01 01 |....}d.d.X......|
+00000030 16 03 03 00 20 5b 64 ec 49 29 26 ba 8c ed 85 fb |.... [d.I)&.....|
+00000040 3e 09 c4 66 bb 60 4e d7 b1 69 73 5a 67 51 77 20 |>..f.`N..isZgQw |
+00000050 5b 14 1f c0 69 |[...i|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 20 74 49 81 b6 d3 |.......... tI...|
+00000010 79 68 0d 78 47 7a 97 a7 cd 3b 2c 24 a3 42 83 18 |yh.xGz...;,$.B..|
+00000020 e4 0c c3 da 4a 1c ff 7b 5d 4c 08 17 03 03 00 1d |....J..{]L......|
+00000030 c2 8a f4 f2 de db 53 69 79 61 c9 30 7b ae 74 cc |......Siya.0{.t.|
+00000040 eb 37 b7 e8 19 cb e6 5f 49 7f 3d a0 37 15 03 03 |.7....._I.=.7...|
+00000050 00 12 99 68 9b 76 f6 66 52 55 fc 8e 4f 17 56 a7 |...h.v.fRU..O.V.|
+00000060 33 0b db 05 |3...|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-AES128-SHA256 b/src/crypto/tls/testdata/Server-TLSv13-AES128-SHA256
new file mode 100644
index 0000000..465d5f9
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-AES128-SHA256
@@ -0,0 +1,97 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 ca 01 00 00 c6 03 03 8e 4c 3b 7c dc |............L;|.|
+00000010 d6 2d c0 19 de dd 85 01 ce 5a 48 3e 63 ab 4a 21 |.-.......ZH>c.J!|
+00000020 9c 0e 23 4f 41 99 43 bd 78 5b 82 20 90 e6 4e 23 |..#OA.C.x[. ..N#|
+00000030 34 72 2a ad 9a cf 95 20 20 f0 e9 cf 7a 4a 57 65 |4r*.... ...zJWe|
+00000040 87 09 c7 76 79 25 9c 3e 16 22 4c c5 00 04 13 01 |...vy%.>."L.....|
+00000050 00 ff 01 00 00 79 00 0b 00 04 03 00 01 02 00 0a |.....y..........|
+00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 16 |................|
+00000070 00 00 00 17 00 00 00 0d 00 1e 00 1c 04 03 05 03 |................|
+00000080 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................|
+00000090 08 06 04 01 05 01 06 01 00 2b 00 03 02 03 04 00 |.........+......|
+000000a0 2d 00 02 01 01 00 33 00 26 00 24 00 1d 00 20 74 |-.....3.&.$... t|
+000000b0 47 39 80 c0 36 61 58 c4 16 58 d5 e1 9f 60 ca a8 |G9..6aX..X...`..|
+000000c0 f8 ef 86 40 65 2d 5b 5d 4b cc 37 1d 66 15 66 |...@e-[]K.7.f.f|
+>>> 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 90 e6 4e 23 |........... ..N#|
+00000030 34 72 2a ad 9a cf 95 20 20 f0 e9 cf 7a 4a 57 65 |4r*.... ...zJWe|
+00000040 87 09 c7 76 79 25 9c 3e 16 22 4c c5 13 01 00 00 |...vy%.>."L.....|
+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 e2 d2 17 5f 12 74 |............._.t|
+00000090 c1 79 bc 63 27 63 e7 52 05 50 f5 13 16 ea 3e 9e |.y.c'c.R.P....>.|
+000000a0 19 17 03 03 02 6d dd 67 27 89 03 8e f4 db 9b 65 |.....m.g'......e|
+000000b0 bc ff 5e 8a 9b a2 20 3c 4d ee b2 98 e3 52 94 b1 |..^... <M....R..|
+000000c0 ab b2 6c 96 31 08 29 d8 f8 f3 a6 86 42 1e 82 42 |..l.1.).....B..B|
+000000d0 79 ad 44 de da 44 ac c6 c8 ae 0f ce 8c f5 03 1a |y.D..D..........|
+000000e0 26 78 0e 92 e4 0b 81 84 ce 89 f1 a6 ee b1 c1 62 |&x.............b|
+000000f0 92 79 69 2b b6 4b 1f 2d 81 9c 06 1e f2 c5 0a 21 |.yi+.K.-.......!|
+00000100 5c f8 1f 3a 8d 0c dd 04 2b fb 96 0c e5 ed a9 9c |\..:....+.......|
+00000110 34 42 fb 31 89 04 09 a5 9f ed ec cd ba 88 d7 de |4B.1............|
+00000120 ae bb 96 1a fd 49 c7 6b 1f 9e 5a 2b 12 26 91 3b |.....I.k..Z+.&.;|
+00000130 17 5a 32 d1 7e 60 4a 55 de ed 39 0d 6b e2 ed a8 |.Z2.~`JU..9.k...|
+00000140 21 bc 3f 94 3d bf aa b9 84 5a 76 21 27 e7 9e 7a |!.?.=....Zv!'..z|
+00000150 f0 93 8b e3 3f a5 00 af 8d 62 b6 c8 ef 69 cf 99 |....?....b...i..|
+00000160 0e 94 90 29 e4 ed 8b d5 06 c6 1e ea f0 a1 08 48 |...)...........H|
+00000170 4a 6a cf 9b 6c 8a b7 41 ad 58 ea fe 90 43 94 77 |Jj..l..A.X...C.w|
+00000180 b0 80 c9 26 79 a3 5d 89 ef 93 10 f1 37 43 07 e2 |...&y.].....7C..|
+00000190 c3 af 1f 6c 46 d8 3b c6 54 c1 d4 72 ad 15 a1 b9 |...lF.;.T..r....|
+000001a0 4f 72 74 f0 ed 62 3b 83 75 ab 12 5c 87 df 8e b8 |Ort..b;.u..\....|
+000001b0 79 af c3 f8 e0 fb f6 b7 ab ec 67 3e ec 05 a1 69 |y.........g>...i|
+000001c0 69 d5 56 45 b2 3b 5f 24 42 b9 4f 43 ec 0d 0d 6c |i.VE.;_$B.OC...l|
+000001d0 0e 44 10 e6 45 e1 a2 11 27 e6 70 a8 d3 a4 2e a1 |.D..E...'.p.....|
+000001e0 43 d6 a5 46 79 d1 e8 37 07 c0 29 68 fa ab dc 67 |C..Fy..7..)h...g|
+000001f0 91 94 04 28 aa 12 01 3f c7 4f d6 a8 93 99 53 5e |...(...?.O....S^|
+00000200 0b 5f ff 83 a0 14 47 23 e6 5e 3c a0 e4 47 28 74 |._....G#.^<..G(t|
+00000210 20 a4 cc 28 03 41 62 5a 27 eb 22 33 ba ac e2 63 | ..(.AbZ'."3...c|
+00000220 c7 a6 09 c7 87 70 45 1a 8b df 96 89 bc 3f 14 0d |.....pE......?..|
+00000230 28 5a 67 a1 d4 30 a3 c3 3a 4b 1f 0e a7 7d 40 cd |(Zg..0..:K...}@.|
+00000240 0e 59 12 2d be 40 ea c1 cb fc b0 d3 42 72 56 4b |.Y.-.@......BrVK|
+00000250 7a a8 e8 70 d6 07 e0 0a 69 ad e6 0b e9 da b7 27 |z..p....i......'|
+00000260 57 e6 aa d3 0d 46 86 93 c0 ce e6 1a b8 8f bb 95 |W....F..........|
+00000270 09 58 e7 51 96 53 4e 71 70 bf 34 7a b0 e9 a8 e7 |.X.Q.SNqp.4z....|
+00000280 51 0f 0c 68 f1 9f 17 28 53 d4 ac 7a 9f 06 cc ce |Q..h...(S..z....|
+00000290 36 81 e7 bf f2 85 b5 5b 4e 23 84 70 67 d5 45 a3 |6......[N#.pg.E.|
+000002a0 3a df f2 26 7c 93 d0 47 f9 0d 87 21 a0 e3 05 a3 |:..&|..G...!....|
+000002b0 ed 7b 99 7d 56 1f 43 77 4e fb db 7d 63 70 a0 fb |.{.}V.CwN..}cp..|
+000002c0 bf 41 d7 48 a8 ae b1 70 1e 99 ae 2b e5 1c 7b 4d |.A.H...p...+..{M|
+000002d0 a8 a6 86 39 83 d4 63 32 56 57 44 4c 44 2e 77 22 |...9..c2VWDLD.w"|
+000002e0 7b e4 33 3a 40 df f1 7e 21 8a 8d da 72 dd 6f 29 |{.3:@..~!...r.o)|
+000002f0 5a de 90 0c a2 76 e0 73 7a 82 d3 26 88 e1 f7 c5 |Z....v.sz..&....|
+00000300 69 c2 04 9b 98 4b 49 7f e3 ac 18 90 85 4f ec c7 |i....KI......O..|
+00000310 29 67 b7 17 03 03 00 99 1c 83 e0 03 3a 6e 3e 08 |)g..........:n>.|
+00000320 e5 33 26 ca 22 a7 01 d9 8c fa f8 75 74 4a 34 a9 |.3&."......utJ4.|
+00000330 12 f7 0a fd 49 2e ef 7d 07 97 59 d7 5a 69 b2 cb |....I..}..Y.Zi..|
+00000340 07 a4 5e 5d 52 f5 4b 50 b3 df 46 fd 3e 86 fe 07 |..^]R.KP..F.>...|
+00000350 98 94 ad cd 2b a2 11 03 1c 1b 13 03 ba 13 68 e4 |....+.........h.|
+00000360 45 5a 70 41 92 a1 67 65 a3 23 4b 81 47 3b 18 a4 |EZpA..ge.#K.G;..|
+00000370 6e 8f 62 e1 2b ee 5f 77 35 e2 07 f7 c9 39 ec 9f |n.b.+._w5....9..|
+00000380 e5 dc b6 e9 64 b9 83 50 02 3f e6 2f ba 3e f6 97 |....d..P.?./.>..|
+00000390 0b 75 9d e2 d6 ac 86 89 a2 ce 99 29 7b 11 de 6a |.u.........){..j|
+000003a0 23 da 7c 84 ec d3 71 f4 fd 6b 5c 0a c0 25 3e c0 |#.|...q..k\..%>.|
+000003b0 11 17 03 03 00 35 39 bb d8 45 80 5d 07 86 99 65 |.....59..E.]...e|
+000003c0 7c 85 6f 3a 08 e2 a4 fa 2e be 23 63 51 64 71 7c ||.o:......#cQdq||
+000003d0 d7 5d 87 31 91 53 6e 77 7d ea d1 66 fd b7 a9 0e |.].1.Snw}..f....|
+000003e0 c9 da dc ba b7 d9 5f 0f 33 fd 52 17 03 03 00 8b |......_.3.R.....|
+000003f0 99 86 2a e1 93 87 40 c9 6e 9d 27 7d dd a0 03 a2 |..*...@.n.'}....|
+00000400 65 cb c2 63 33 59 2f 4a a7 01 56 94 28 e4 ec c7 |e..c3Y/J..V.(...|
+00000410 8f 62 ed 71 c1 80 b9 f8 55 07 0b ab 2a bd f8 68 |.b.q....U...*..h|
+00000420 7d 90 a9 98 36 5b d8 f3 00 22 d9 a9 76 30 ef cd |}...6[..."..v0..|
+00000430 3f 42 68 af 70 5b 12 c8 9d f8 00 01 3d 02 82 44 |?Bh.p[......=..D|
+00000440 2d a6 2e dc 3b b4 42 5c c6 01 c4 fb a3 32 86 10 |-...;.B\.....2..|
+00000450 d8 25 ab 87 24 d7 38 7f dd b8 5f f9 5e 47 a9 57 |.%..$.8..._.^G.W|
+00000460 cc 48 fb 0f 74 4a db 4f db 92 21 be 08 7c 53 6f |.H..tJ.O..!..|So|
+00000470 89 3f 68 77 cd 02 a7 aa 9c 9d b5 |.?hw.......|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 1d f1 fe e2 c3 |..........5.....|
+00000010 4e 95 57 0b 7e d6 32 45 6b 9c ed 89 c2 69 62 70 |N.W.~.2Ek....ibp|
+00000020 79 0f a8 42 72 94 05 ad f5 fe a5 83 4b 56 80 41 |y..Br.......KV.A|
+00000030 2c 58 e0 e2 00 70 de c1 39 c8 fa c4 bb 89 57 aa |,X...p..9.....W.|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e a3 8a 39 2d 93 5d d3 ce cd 5a 31 |.......9-.]...Z1|
+00000010 19 21 b8 b5 6f 3e 58 7a 0c 09 9b a8 4b 23 3d 3d |.!..o>Xz....K#==|
+00000020 d7 73 7a 17 03 03 00 13 d1 a5 7c 5e 2e fa 6b 86 |.sz.......|^..k.|
+00000030 f9 36 3c 8d 2b 5b 7e 58 db c8 0d |.6<.+[~X...|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-AES256-SHA384 b/src/crypto/tls/testdata/Server-TLSv13-AES256-SHA384
new file mode 100644
index 0000000..64310a1
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-AES256-SHA384
@@ -0,0 +1,100 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 ca 01 00 00 c6 03 03 c4 ac 32 36 24 |.............26$|
+00000010 08 b0 6c 1d 1e 58 7e b3 3d 52 35 29 85 52 3a b3 |..l..X~.=R5).R:.|
+00000020 32 a2 71 86 4b 33 5d bb b8 b8 ac 20 77 6d 45 2f |2.q.K3].... wmE/|
+00000030 a3 fe 59 3f 9b cf 4e 60 55 84 f7 99 c2 f5 7e 1e |..Y?..N`U.....~.|
+00000040 6f 0a 4d fe bf 13 e8 95 80 a7 7d c6 00 04 13 02 |o.M.......}.....|
+00000050 00 ff 01 00 00 79 00 0b 00 04 03 00 01 02 00 0a |.....y..........|
+00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 16 |................|
+00000070 00 00 00 17 00 00 00 0d 00 1e 00 1c 04 03 05 03 |................|
+00000080 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................|
+00000090 08 06 04 01 05 01 06 01 00 2b 00 03 02 03 04 00 |.........+......|
+000000a0 2d 00 02 01 01 00 33 00 26 00 24 00 1d 00 20 8f |-.....3.&.$... .|
+000000b0 5a 28 ca 6a 1b 42 2f 1a 53 8f cc 4f 88 b3 0c ad |Z(.j.B/.S..O....|
+000000c0 35 59 c5 10 46 ef a4 5f 1e d4 63 69 93 4f 15 |5Y..F.._..ci.O.|
+>>> 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 77 6d 45 2f |........... wmE/|
+00000030 a3 fe 59 3f 9b cf 4e 60 55 84 f7 99 c2 f5 7e 1e |..Y?..N`U.....~.|
+00000040 6f 0a 4d fe bf 13 e8 95 80 a7 7d c6 13 02 00 00 |o.M.......}.....|
+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 e4 b2 43 7d 15 fc |............C}..|
+00000090 ae 58 44 9d 0d 82 a4 1c 21 c4 3f 86 fb 4b 6b d1 |.XD.....!.?..Kk.|
+000000a0 96 17 03 03 02 6d 03 84 7a 2c 7e d8 c8 ca 31 07 |.....m..z,~...1.|
+000000b0 fc 2c 47 5b e4 c1 e1 5f 1a c9 a0 45 4e 9a 3d 63 |.,G[..._...EN.=c|
+000000c0 11 3b 26 d7 05 e3 6c 36 c3 49 46 c3 73 4e ee 97 |.;&...l6.IF.sN..|
+000000d0 dc 4e 09 f4 22 0f 34 05 e1 84 d5 ed 76 a1 4e ba |.N..".4.....v.N.|
+000000e0 7c d7 9c 9d 16 ae 96 0f 62 41 64 80 ed fc 4c 1e ||.......bAd...L.|
+000000f0 75 a4 5a fe bf 7c 95 6f 81 ef bb e9 9c 69 63 df |u.Z..|.o.....ic.|
+00000100 b0 07 d1 4f 1e 96 9e c9 a4 09 d6 79 f2 33 58 eb |...O.......y.3X.|
+00000110 78 a5 a7 29 27 58 1b 99 79 79 e3 1d 61 6e fd 7b |x..)'X..yy..an.{|
+00000120 c8 7f c6 07 3a f5 23 d6 4d 7a 74 af 53 f6 b1 63 |....:.#.Mzt.S..c|
+00000130 2f eb 51 65 b5 91 ac af 4b bf 9e 98 90 8a ae 02 |/.Qe....K.......|
+00000140 86 35 78 66 13 2c de 95 5b e1 d8 78 18 bf 65 8f |.5xf.,..[..x..e.|
+00000150 a2 30 ae e7 fa aa ac bc 44 72 03 f5 86 b1 1b c2 |.0......Dr......|
+00000160 d5 61 dc 4d 74 47 73 67 f1 43 11 1a 95 6f e3 88 |.a.MtGsg.C...o..|
+00000170 51 9a 4b c7 bd dc 36 8f 5d de 56 4c 8d 30 8d ec |Q.K...6.].VL.0..|
+00000180 08 0b 90 be c8 dc df 7d 6e e7 85 c9 ab dd be a9 |.......}n.......|
+00000190 57 c4 6a 76 36 bb a8 4b e2 be d1 28 67 3b a9 0c |W.jv6..K...(g;..|
+000001a0 a1 78 2e e4 af f4 51 a3 f5 8c b3 8d c8 7c 8e e7 |.x....Q......|..|
+000001b0 d2 7f 38 91 04 42 f4 e9 ae e2 3a 3d 37 10 78 f3 |..8..B....:=7.x.|
+000001c0 2d 9c 9f f7 4f 49 f0 45 bd 1e 8d 7d e3 84 b9 9a |-...OI.E...}....|
+000001d0 75 40 fb 2b 4f 71 2d b7 bd 1a 6e 4a 7a b4 53 f8 |u@.+Oq-...nJz.S.|
+000001e0 d7 c9 6e d9 f6 7b de fa f0 12 5d fc c0 71 1a bf |..n..{....]..q..|
+000001f0 76 d8 c4 ad c5 f7 e2 79 55 79 40 e5 55 ee bc dc |v......yUy@.U...|
+00000200 42 06 97 89 da 2d a7 e9 26 e4 82 e1 63 5f e2 ee |B....-..&...c_..|
+00000210 1a 37 6d 65 bf d7 5f 2e 86 a5 a8 4d b2 e1 31 2f |.7me.._....M..1/|
+00000220 8b c5 0b 88 03 bf 1f 37 8c 96 ec 54 4f 75 9b f9 |.......7...TOu..|
+00000230 00 98 96 e6 db c1 24 94 6a d1 dd f7 9b d2 2e 24 |......$.j......$|
+00000240 82 c7 34 5a f6 aa 36 5b b7 63 11 b2 1d 15 a6 48 |..4Z..6[.c.....H|
+00000250 74 5c a7 70 a9 c4 fc 14 67 51 7e 16 7c 90 5b 64 |t\.p....gQ~.|.[d|
+00000260 ff 49 02 f6 4d 7a c2 f9 d7 1d 47 4b de bf ae ca |.I..Mz....GK....|
+00000270 03 56 84 31 01 37 80 85 79 fb d8 f4 72 9f 98 a3 |.V.1.7..y...r...|
+00000280 44 d4 52 f8 af 8c 98 d8 66 69 f7 71 58 db 42 fa |D.R.....fi.qX.B.|
+00000290 d7 c9 05 d1 9d 7a df 9f a9 b1 12 53 d2 70 fa ca |.....z.....S.p..|
+000002a0 7e a6 de 8d ed 08 69 b2 34 45 3a a5 ba 1d 2e d8 |~.....i.4E:.....|
+000002b0 d5 ee ee 60 16 18 cc e1 db aa e6 1b 19 5a ec e6 |...`.........Z..|
+000002c0 b8 ec 51 46 99 6d 1e 83 9b 9d 44 a7 85 5a 10 23 |..QF.m....D..Z.#|
+000002d0 74 a3 b6 09 b5 d7 2a 12 6a e2 2a da 5d 87 d9 fe |t.....*.j.*.]...|
+000002e0 b6 c7 8f c8 03 27 b0 6e 98 57 6f e4 d5 8b 88 5d |.....'.n.Wo....]|
+000002f0 0a b3 c4 a1 ae df 89 53 af d5 8e 59 97 2d 65 c0 |.......S...Y.-e.|
+00000300 52 e8 5f 8a 37 3f 8b ef 77 fc 93 0c b5 50 3b 94 |R._.7?..w....P;.|
+00000310 13 1b 3b 17 03 03 00 99 3e e8 05 5a 69 dc 0c 90 |..;.....>..Zi...|
+00000320 a3 17 35 ea 27 2b da 64 44 72 30 5b 9c a5 6b 1b |..5.'+.dDr0[..k.|
+00000330 c2 a8 af 38 c3 43 52 14 fd ec a8 8b c9 ab 6b 67 |...8.CR.......kg|
+00000340 32 84 f9 b4 e1 89 08 8f 6a c2 2a 17 b9 f5 92 c8 |2.......j.*.....|
+00000350 3a 97 62 98 b8 93 94 5d a1 6b 05 17 56 5d 6e b5 |:.b....].k..V]n.|
+00000360 d3 72 a6 06 77 b2 45 fe 2d 37 10 7e b8 16 16 f4 |.r..w.E.-7.~....|
+00000370 70 86 56 a4 be 52 54 3e 90 7d 47 66 23 35 e9 a2 |p.V..RT>.}Gf#5..|
+00000380 e9 4f 86 e2 a7 b9 20 b6 c8 9f 19 08 6b 73 93 86 |.O.... .....ks..|
+00000390 d7 8d 1a 9a 00 6b cf fb cb 32 5d 36 91 4f 39 e2 |.....k...2]6.O9.|
+000003a0 f5 0d fa 37 3d b8 c6 86 cb 57 71 a8 c6 f8 74 cb |...7=....Wq...t.|
+000003b0 c0 17 03 03 00 45 67 fe 1b 83 1a bf ac 3b ee 0f |.....Eg......;..|
+000003c0 31 35 da 42 6c e3 3f 14 63 4a f3 5b 5b 02 76 c8 |15.Bl.?.cJ.[[.v.|
+000003d0 21 84 7e 11 42 e3 8c e7 b6 7c 1d ba 41 ec dd 68 |!.~.B....|..A..h|
+000003e0 73 4a 1b c5 bc 11 fa 22 33 9b 51 7d f0 27 88 4a |sJ....."3.Q}.'.J|
+000003f0 1b bf e8 a9 3f f5 2f 9a 05 ce 07 17 03 03 00 9b |....?./.........|
+00000400 da 09 d0 83 a3 24 92 94 b7 9f 34 10 7b 1c b9 e4 |.....$....4.{...|
+00000410 ca 56 c9 8f 71 03 99 0b c5 ea 6d 50 6d 75 dd 7b |.V..q.....mPmu.{|
+00000420 28 4d 5c 6e 32 83 61 36 68 0b 64 ac b7 6b ec bb |(M\n2.a6h.d..k..|
+00000430 22 72 56 4b 6a 58 98 a2 62 9c 15 28 fa a8 38 a3 |"rVKjX..b..(..8.|
+00000440 63 b7 8b d4 3d 63 3f 64 34 45 e2 f1 ad e6 3e 66 |c...=c?d4E....>f|
+00000450 8e 45 5f 3e ca fc 5e a8 40 17 a9 ac c6 52 e4 4e |.E_>..^.@....R.N|
+00000460 14 15 0b a1 00 db 8c a2 dd 41 35 74 1f f4 06 ac |.........A5t....|
+00000470 72 8c 86 1f a9 de 6d 1c 24 6d 2d 37 f2 dd 1a f9 |r.....m.$m-7....|
+00000480 60 0d 48 fc 8e a3 97 5a 9b 6b 99 13 77 4c f8 bf |`.H....Z.k..wL..|
+00000490 b3 e5 db 07 31 3d b9 a9 56 9f c2 |....1=..V..|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 45 2a e9 8b e0 d6 |..........E*....|
+00000010 52 b2 a9 01 20 d1 48 61 5e 6a c3 cf 79 14 f3 c0 |R... .Ha^j..y...|
+00000020 8e 1f 76 2b 16 d5 53 c8 ae a8 a5 7b 14 aa 8c 4b |..v+..S....{...K|
+00000030 5d 76 e6 dd 5b b9 1f 87 39 62 f6 e5 72 13 1e d0 |]v..[...9b..r...|
+00000040 48 06 f5 d9 ce b8 4d 32 42 49 f1 dd 52 96 e5 68 |H.....M2BI..R..h|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e 97 3a d5 e2 f1 22 da d5 0a 3a 2c |......:..."...:,|
+00000010 c1 c0 53 ff 44 bd 06 02 02 eb b6 91 c5 b3 d7 c7 |..S.D...........|
+00000020 c2 6e 56 17 03 03 00 13 af c2 91 94 6e db 5e 62 |.nV.........n.^b|
+00000030 9a 1e 40 e4 50 a1 b4 9c 16 45 be |..@.P....E.|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-ALPN b/src/crypto/tls/testdata/Server-TLSv13-ALPN
new file mode 100644
index 0000000..7537272
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-ALPN
@@ -0,0 +1,100 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 e2 01 00 00 de 03 03 35 09 24 92 91 |...........5.$..|
+00000010 f9 de f8 f0 68 a2 6d f2 e6 2a df de f1 7c c4 44 |....h.m..*...|.D|
+00000020 7b 22 14 03 29 2a f2 1b 6c a2 0e 20 e4 bc 0e 83 |{"..)*..l.. ....|
+00000030 35 d7 c1 4c ea 8f ba 77 32 ae c9 44 b0 51 16 05 |5..L...w2..D.Q..|
+00000040 06 03 6b c9 23 06 42 26 80 25 6d 67 00 04 13 03 |..k.#.B&.%mg....|
+00000050 00 ff 01 00 00 91 00 0b 00 04 03 00 01 02 00 0a |................|
+00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 23 |...............#|
+00000070 00 00 00 10 00 10 00 0e 06 70 72 6f 74 6f 32 06 |.........proto2.|
+00000080 70 72 6f 74 6f 31 00 16 00 00 00 17 00 00 00 0d |proto1..........|
+00000090 00 1e 00 1c 04 03 05 03 06 03 08 07 08 08 08 09 |................|
+000000a0 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................|
+000000b0 00 2b 00 03 02 03 04 00 2d 00 02 01 01 00 33 00 |.+......-.....3.|
+000000c0 26 00 24 00 1d 00 20 59 cf 4e a0 d2 89 c8 fd 8b |&.$... Y.N......|
+000000d0 22 e8 ce 43 a4 b4 2b b3 9f 12 46 c0 21 2a 10 55 |"..C..+...F.!*.U|
+000000e0 fd a7 6f 65 04 51 21 |..oe.Q!|
+>>> 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 e4 bc 0e 83 |........... ....|
+00000030 35 d7 c1 4c ea 8f ba 77 32 ae c9 44 b0 51 16 05 |5..L...w2..D.Q..|
+00000040 06 03 6b c9 23 06 42 26 80 25 6d 67 13 03 00 00 |..k.#.B&.%mg....|
+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 24 7a a5 d4 28 fe 61 |.........$z..(.a|
+00000090 12 68 43 19 5a 01 88 e7 ae 24 e4 6f d3 c6 e7 13 |.hC.Z....$.o....|
+000000a0 32 aa 80 56 e2 1b 8c bb 5f ee 33 5f 86 8e 17 03 |2..V...._.3_....|
+000000b0 03 02 6d ee 98 f9 eb 4c 74 7f 2b 73 22 7e 79 e7 |..m....Lt.+s"~y.|
+000000c0 ed ed 93 f5 0b 68 0b 5a 14 79 45 83 9a b7 ea e7 |.....h.Z.yE.....|
+000000d0 9b 89 21 97 c4 dc cd 89 e7 27 44 d9 5c de a2 79 |..!......'D.\..y|
+000000e0 5c bb 9b f1 4a fc 3e 04 64 b4 70 cc 30 a3 3a bc |\...J.>.d.p.0.:.|
+000000f0 4c d3 4d 90 b8 1c cf 3f ad 63 12 a6 b7 df 6a a5 |L.M....?.c....j.|
+00000100 03 1f a6 96 d5 94 ea fd fc a3 95 2b 38 cb 25 47 |...........+8.%G|
+00000110 63 d4 42 10 2c 91 d3 d9 12 79 e2 ba 3e 0b 82 09 |c.B.,....y..>...|
+00000120 c6 02 ee 55 14 17 73 3e 11 17 e9 d7 b5 9c d2 b7 |...U..s>........|
+00000130 d7 2f f0 23 51 a1 d3 71 68 9d 4c 01 98 a9 07 e0 |./.#Q..qh.L.....|
+00000140 b0 fd f8 74 0c bc eb 5e 57 1d 48 65 ac 80 d4 f4 |...t...^W.He....|
+00000150 4e 56 1d 89 ce ab 21 5e 5f a0 5c ed a3 e7 07 5d |NV....!^_.\....]|
+00000160 c3 d9 9d 31 62 e0 91 2b c6 e2 5c f6 69 2a 06 b8 |...1b..+..\.i*..|
+00000170 e1 24 92 39 7b 06 58 72 a1 84 87 c4 e9 53 83 12 |.$.9{.Xr.....S..|
+00000180 2a 03 24 6a 9d 84 55 30 04 15 7b 68 88 46 75 6e |*.$j..U0..{h.Fun|
+00000190 3f 0a f7 e8 9f 64 04 32 b7 5e 8c 64 82 ec 6d 9b |?....d.2.^.d..m.|
+000001a0 e0 41 33 69 e4 75 51 d9 e3 ba 7a 9e 7b 8f b7 3e |.A3i.uQ...z.{..>|
+000001b0 bc 30 3a 55 10 81 ec 1f f9 c1 77 30 3d 7e 3f b5 |.0:U......w0=~?.|
+000001c0 db 44 a5 54 d1 b3 81 64 20 5d 8d 31 48 19 5a 2f |.D.T...d ].1H.Z/|
+000001d0 4a b9 b2 31 b8 56 f4 9c 9d ac 35 5d 54 55 0b 09 |J..1.V....5]TU..|
+000001e0 e0 10 13 47 b1 ad 3f 9b 62 39 84 4e 49 99 d0 38 |...G..?.b9.NI..8|
+000001f0 fe 7d 8b f2 a5 50 ab 62 54 85 7f 70 ae 51 13 6a |.}...P.bT..p.Q.j|
+00000200 7a 5d eb cd c6 e2 29 47 a6 e0 a2 b1 46 da bc 7c |z]....)G....F..||
+00000210 38 8b 45 a7 07 c1 f4 e6 fe f0 83 24 fa 87 d1 17 |8.E........$....|
+00000220 d1 6b 0d 6f 96 2a 28 35 81 5c 78 6e a8 16 f9 0a |.k.o.*(5.\xn....|
+00000230 71 47 72 5d 21 ad b9 93 63 16 b9 58 e6 22 66 86 |qGr]!...c..X."f.|
+00000240 b5 43 c0 91 c9 cd 70 8e f9 c0 38 c9 4d 04 fa 39 |.C....p...8.M..9|
+00000250 e1 02 46 59 85 67 38 35 ce 84 ec b9 34 50 84 03 |..FY.g85....4P..|
+00000260 82 12 75 ee 4a c5 db 61 d1 31 2e c5 62 88 cb 10 |..u.J..a.1..b...|
+00000270 c9 bc 65 7b cd df d5 0a 56 75 81 a0 a8 f0 ee 54 |..e{....Vu.....T|
+00000280 f5 b3 c8 36 13 c7 6d 95 4a 72 61 d9 98 c4 08 dc |...6..m.Jra.....|
+00000290 7f 35 de 4c 5b aa 6f 7d 6d f2 e0 e2 46 1f 5d 72 |.5.L[.o}m...F.]r|
+000002a0 a5 c1 ee 5e af 34 44 8b 07 90 9a 2f d3 3e cf 8d |...^.4D..../.>..|
+000002b0 69 54 19 ae 3e c2 89 55 5e 0b 98 e1 24 c5 6b 88 |iT..>..U^...$.k.|
+000002c0 2e 67 83 9e cc 97 b0 06 58 7d 5f 82 55 21 d3 79 |.g......X}_.U!.y|
+000002d0 04 d8 2e 59 08 67 78 70 ee bc 9b 26 12 50 da 5a |...Y.gxp...&.P.Z|
+000002e0 40 66 45 b8 36 16 50 5b 93 15 a9 a8 c0 85 34 ee |@fE.6.P[......4.|
+000002f0 d2 ee 4e 7d 66 28 f6 65 5c 88 3c b1 de e9 de 8b |..N}f(.e\.<.....|
+00000300 e8 b2 51 d7 f0 51 69 fd fe f1 8c 57 df 3f d5 40 |..Q..Qi....W.?.@|
+00000310 e8 54 a0 b2 59 e1 75 27 fc fd b7 41 d9 ad 49 5e |.T..Y.u'...A..I^|
+00000320 17 03 03 00 99 2c 47 73 11 39 91 57 05 d0 f6 0f |.....,Gs.9.W....|
+00000330 8c 6c f2 66 a0 d1 cd 3f 80 3c bb f3 27 78 83 64 |.l.f...?.<..'x.d|
+00000340 4d 33 de b8 f5 8b 27 a9 1f 8b 75 9f b2 c6 d7 08 |M3....'...u.....|
+00000350 13 8e 73 a6 81 0e 71 fd 7b 33 87 c2 23 6f bc ad |..s...q.{3..#o..|
+00000360 9b e6 60 91 12 3f 74 de 8f 7c 49 9f 0a 74 cc e0 |..`..?t..|I..t..|
+00000370 68 e3 50 cc ca 2f a2 30 a9 32 31 ec 92 5f 4d d1 |h.P../.0.21.._M.|
+00000380 39 f1 4d f6 2d 21 3c 54 33 38 a2 46 c0 7a 55 8c |9.M.-!<T38.F.zU.|
+00000390 7f 7e 88 00 21 9c c9 53 fe 30 01 42 7c d8 e8 5b |.~..!..S.0.B|..[|
+000003a0 46 c3 28 73 7f ab 84 aa 83 f1 2e 51 eb 0d 90 ec |F.(s.......Q....|
+000003b0 fa 96 3c 79 9d 8f ce 59 57 15 94 18 3f 53 17 03 |..<y...YW...?S..|
+000003c0 03 00 35 dd 46 07 33 0d 1e 78 18 5a f6 45 43 ae |..5.F.3..x.Z.EC.|
+000003d0 61 ed 97 94 eb 67 82 cf 43 3f cb e7 23 68 fb cc |a....g..C?..#h..|
+000003e0 a3 c1 91 74 2f cc fc 49 44 a8 7b 7b 17 44 6a d5 |...t/..ID.{{.Dj.|
+000003f0 4e 0c a7 21 ff 01 fc 2f 17 03 03 00 8b 59 58 d0 |N..!.../.....YX.|
+00000400 30 c0 e9 18 f6 de 1c fa 95 a9 1a 3a d4 f9 ed 28 |0..........:...(|
+00000410 bd 81 0c 68 82 17 a0 c5 55 5e 96 58 29 c7 50 25 |...h....U^.X).P%|
+00000420 8b 62 b3 2f 63 27 3c b4 03 83 78 e5 30 7b 03 6a |.b./c'<...x.0{.j|
+00000430 aa 2e 0b 61 bc cf 36 84 7c 72 4e 4c 52 d7 a7 b6 |...a..6.|rNLR...|
+00000440 93 7b 52 09 a9 13 dc 96 61 2e c3 88 37 8f a7 ae |.{R.....a...7...|
+00000450 eb 9f f3 fd 05 fb f1 71 bd 73 a3 4a 53 72 51 60 |.......q.s.JSrQ`|
+00000460 eb 06 3f 37 52 e7 d4 4b 06 f1 37 46 f9 bf 87 9c |..?7R..K..7F....|
+00000470 d8 c7 be ad 7d 8d 12 54 93 d3 43 15 af f8 c6 8d |....}..T..C.....|
+00000480 c5 5d b0 74 bc 4c 70 44 |.].t.LpD|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 de e1 cc 43 bc |..........5...C.|
+00000010 ae b2 a6 66 68 d4 c4 b9 18 72 1f 26 f7 03 c9 6e |...fh....r.&...n|
+00000020 9b 12 0e ff 65 ff f5 5f 84 6c fb 99 be e6 b3 07 |....e.._.l......|
+00000030 db ea d2 33 cc 7e 8c eb 42 db db fd e8 21 62 b0 |...3.~..B....!b.|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e 1e 5c 6b 1e dd ea a2 1d bd 6e 66 |......\k......nf|
+00000010 0b 99 e0 91 0b c1 3e 9b 49 e7 40 0d a7 7a bb 31 |......>.I.@..z.1|
+00000020 4c 5c c2 17 03 03 00 13 a5 98 a7 8a 05 a7 bb 60 |L\.............`|
+00000030 11 aa b3 05 f6 cd 8b 16 3d 97 3e |........=.>|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-ALPN-Fallback b/src/crypto/tls/testdata/Server-TLSv13-ALPN-Fallback
new file mode 100644
index 0000000..d4a054d
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-ALPN-Fallback
@@ -0,0 +1,99 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 eb 01 00 00 e7 03 03 ca 9d 80 22 cc |..............".|
+00000010 77 d9 f2 87 3f a8 93 a1 13 6f a0 f5 4e d0 1b fe |w...?....o..N...|
+00000020 cc 04 c0 7c 8d 7d 2e 5c c2 6d 69 20 1e 1f 96 97 |...|.}.\.mi ....|
+00000030 82 97 85 5b fd c1 59 cb a5 2a 91 c1 b5 88 06 6c |...[..Y..*.....l|
+00000040 b0 ed 5c 41 78 cc f6 3c 28 d9 29 2b 00 04 13 03 |..\Ax..<(.)+....|
+00000050 00 ff 01 00 00 9a 00 0b 00 04 03 00 01 02 00 0a |................|
+00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 23 |...............#|
+00000070 00 00 00 10 00 19 00 17 06 70 72 6f 74 6f 33 08 |.........proto3.|
+00000080 68 74 74 70 2f 31 2e 31 06 70 72 6f 74 6f 34 00 |http/1.1.proto4.|
+00000090 16 00 00 00 17 00 00 00 0d 00 1e 00 1c 04 03 05 |................|
+000000a0 03 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 |................|
+000000b0 05 08 06 04 01 05 01 06 01 00 2b 00 03 02 03 04 |..........+.....|
+000000c0 00 2d 00 02 01 01 00 33 00 26 00 24 00 1d 00 20 |.-.....3.&.$... |
+000000d0 c1 26 2b f3 64 5e 41 1a 11 9c 1d 4b 09 bd f4 98 |.&+.d^A....K....|
+000000e0 b4 7d 06 bb 88 97 5c ef 01 24 0b 3d 9e ed 91 0f |.}....\..$.=....|
+>>> 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 1e 1f 96 97 |........... ....|
+00000030 82 97 85 5b fd c1 59 cb a5 2a 91 c1 b5 88 06 6c |...[..Y..*.....l|
+00000040 b0 ed 5c 41 78 cc f6 3c 28 d9 29 2b 13 03 00 00 |..\Ax..<(.)+....|
+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 ca 84 74 0d 35 9d |............t.5.|
+00000090 80 3d d8 95 cb f2 12 f1 10 6b f6 91 12 ab 37 ea |.=.......k....7.|
+000000a0 a2 17 03 03 02 6d 1e 6b ca 76 70 67 ce 22 70 8c |.....m.k.vpg."p.|
+000000b0 ab 4d 33 a8 2e 93 77 2c 2f b1 7a e3 42 ca 83 e2 |.M3...w,/.z.B...|
+000000c0 e5 c9 45 dc 97 d3 85 64 e8 07 13 c8 55 7c cd bf |..E....d....U|..|
+000000d0 20 d1 3b 43 a7 13 a1 f6 66 0e 98 e7 23 18 cf 38 | .;C....f...#..8|
+000000e0 d3 92 d7 29 30 44 fa dc 81 1d e3 04 ca b0 b3 08 |...)0D..........|
+000000f0 d4 a4 64 18 f4 4f 06 ca ca a0 bb 90 38 6d 09 21 |..d..O......8m.!|
+00000100 42 c1 a0 c4 51 90 78 61 b1 55 eb 63 8d 65 73 47 |B...Q.xa.U.c.esG|
+00000110 7c 6d f5 7f c6 dc 55 a1 a3 a4 16 6b 2d 62 d2 8d ||m....U....k-b..|
+00000120 1f 96 8f 84 96 a6 94 f0 a0 9e 03 04 67 a2 e9 e3 |............g...|
+00000130 38 0c cd f3 af 45 77 65 33 06 e7 aa cf a0 e6 01 |8....Ewe3.......|
+00000140 a7 5f 62 95 32 18 b9 58 03 db 9c ca c7 50 80 cf |._b.2..X.....P..|
+00000150 15 1c b0 7e 97 30 bb e2 bf d5 67 f4 e1 87 1e 07 |...~.0....g.....|
+00000160 71 2f f5 31 7e 7e 05 8a cb a1 98 83 de de aa 87 |q/.1~~..........|
+00000170 b9 d2 4a 5e 4c 27 04 15 6b 3a 21 02 28 2c 3a 76 |..J^L'..k:!.(,:v|
+00000180 64 1f b0 f3 45 1e 2a fc 97 3f 0e 18 c8 00 a2 0b |d...E.*..?......|
+00000190 51 4a 8f 1d d7 a6 d7 b9 64 11 bc ed 74 c9 90 bd |QJ......d...t...|
+000001a0 a3 27 b3 c0 95 ea 49 88 af de 76 d9 82 67 01 0f |.'....I...v..g..|
+000001b0 60 f1 f7 84 7e 56 46 65 c7 42 cc fb 99 25 a3 77 |`...~VFe.B...%.w|
+000001c0 c5 8c 02 87 4e d4 78 17 0d 16 f1 00 de f9 d5 0b |....N.x.........|
+000001d0 36 28 f5 27 59 4b fd ba 38 cb 3c 53 3d 02 3b 77 |6(.'YK..8.<S=.;w|
+000001e0 b6 f1 e8 0d 87 58 f9 5b ac 87 53 ba e7 1c 0c 1b |.....X.[..S.....|
+000001f0 be e1 43 a6 8f 0d ab a7 3e e6 ed cb 66 c1 06 49 |..C.....>...f..I|
+00000200 9a cd 52 91 5e bc 1f a5 c6 78 2c d0 a4 67 14 3f |..R.^....x,..g.?|
+00000210 94 2a 9c 9f 47 ee fa c7 50 ca 00 c2 30 69 d9 ca |.*..G...P...0i..|
+00000220 30 b7 ac f4 3b d9 91 d7 33 40 87 de d9 a2 7f 77 |0...;...3@.....w|
+00000230 5b b0 57 ca 10 03 ec 3b 95 e9 c2 de 50 f1 28 7a |[.W....;....P.(z|
+00000240 49 c1 be ef 6d 99 ea 98 47 8b af 51 d0 fb 0a d0 |I...m...G..Q....|
+00000250 b5 b2 ad e3 69 ba fc 34 c7 aa 04 8b d5 fc 17 54 |....i..4.......T|
+00000260 e1 51 f0 26 32 21 71 90 0e 30 10 f6 68 6f 53 b7 |.Q.&2!q..0..hoS.|
+00000270 b6 d8 1c 13 0a c9 fb 9e 46 13 22 4c 7c 93 18 ed |........F."L|...|
+00000280 b8 72 69 56 00 ab df ec f5 4c 32 60 0e a4 a3 b0 |.riV.....L2`....|
+00000290 b3 12 5c 61 26 1c aa b2 c2 68 64 65 cc 01 57 c9 |..\a&....hde..W.|
+000002a0 70 18 f7 db 2c 0d 24 b3 68 3a 08 db 07 ff 3c f5 |p...,.$.h:....<.|
+000002b0 2e 9a 1e d1 9c 62 4d 6d 4b 48 37 dd 62 0b 2b ab |.....bMmKH7.b.+.|
+000002c0 49 a1 0f 7e 1b 6f 4e 43 69 63 3d 8e ce 51 f9 32 |I..~.oNCic=..Q.2|
+000002d0 4e f4 21 97 f5 16 e4 2b 0b f3 6f 5d 15 7e 68 dd |N.!....+..o].~h.|
+000002e0 c6 5b 5f ac 56 42 99 76 28 38 d2 8b ed 0e c6 a4 |.[_.VB.v(8......|
+000002f0 69 d3 f1 c4 a9 d6 7a d2 00 ac ad ff 9c d2 8d 1e |i.....z.........|
+00000300 46 88 64 24 51 78 2a a8 4a ea a4 fa 28 3b 70 3a |F.d$Qx*.J...(;p:|
+00000310 75 8b 9d 17 03 03 00 99 22 d3 e9 8f ae 4e 5e 17 |u......."....N^.|
+00000320 3e 86 54 cd fd 66 68 c6 fe 73 ac 19 98 c1 a1 66 |>.T..fh..s.....f|
+00000330 4f 7a 4f 5e 0b c5 a1 43 74 d4 c2 0a ce 45 05 2f |OzO^...Ct....E./|
+00000340 5f f1 1b 50 eb 08 8f 36 30 f0 78 e9 1d c1 e5 b0 |_..P...60.x.....|
+00000350 cf 27 14 ed 67 ed 12 7e f1 4c 10 e8 ff 6f 13 7d |.'..g..~.L...o.}|
+00000360 0f a8 c3 b6 19 22 9a 68 9b ab 6d 77 09 f5 56 de |.....".h..mw..V.|
+00000370 84 23 d6 ed 38 62 06 4b 05 9b 59 39 2f 09 65 70 |.#..8b.K..Y9/.ep|
+00000380 9e 9c f9 fe a2 e4 db 1e c0 12 d2 ee 41 77 b3 05 |............Aw..|
+00000390 a1 c3 bb 41 70 0e dd f7 0d ca 41 58 12 9e 4f 23 |...Ap.....AX..O#|
+000003a0 2e 72 00 9b 19 70 78 54 b4 27 69 16 15 e8 6f d4 |.r...pxT.'i...o.|
+000003b0 e7 17 03 03 00 35 ad df 36 e1 d4 a4 04 8e fa 1a |.....5..6.......|
+000003c0 77 da e7 99 62 e9 8f a0 27 af a6 ba 7f 47 49 47 |w...b...'....GIG|
+000003d0 aa a3 bd bb cd 32 f6 e6 90 77 95 34 e5 72 f0 f9 |.....2...w.4.r..|
+000003e0 75 8c cf 25 5b bc 2a b0 98 be fb 17 03 03 00 8b |u..%[.*.........|
+000003f0 e9 20 f8 90 78 d5 78 11 c3 bb 5c 41 f0 cd 51 3e |. ..x.x...\A..Q>|
+00000400 a1 20 bb 72 98 e3 d1 fe 9d 61 ae a4 8f 71 57 6c |. .r.....a...qWl|
+00000410 e7 68 de 63 95 ed 46 00 f4 8f cd 59 c7 97 7f 98 |.h.c..F....Y....|
+00000420 61 f3 68 18 18 1e 94 16 f7 f2 de 73 81 3d a5 7e |a.h........s.=.~|
+00000430 12 68 65 70 6f ca bd 2b 92 f8 7c ec 88 2c 3f c0 |.hepo..+..|..,?.|
+00000440 76 52 cc e3 38 e0 ce 0b dc 35 ef 87 cf ea 4b 2b |vR..8....5....K+|
+00000450 53 88 52 3f f6 e1 d7 ea 5f a2 d9 4f a7 03 ac c1 |S.R?...._..O....|
+00000460 7d ab 95 ce a5 f5 00 53 f6 6d ab 7e 07 88 51 9b |}......S.m.~..Q.|
+00000470 2c e9 e9 ac 1b f9 17 ac 33 17 00 |,.......3..|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 52 13 5e 7a c8 |..........5R.^z.|
+00000010 3e b6 e1 8e 59 c9 cf 54 0b c8 c2 17 ab 76 0d 3d |>...Y..T.....v.=|
+00000020 ec 5c 76 2c 21 21 f3 1e a7 25 ba 67 97 8a 8f de |.\v,!!...%.g....|
+00000030 03 7d 1a bc 0a 9e c7 e7 02 52 cf d4 80 3e 80 7e |.}.......R...>.~|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e 77 f7 66 ab db 08 5c e5 9d 7f a3 |.....w.f...\....|
+00000010 f7 37 24 70 e7 7c d2 44 25 de 3d c3 71 18 aa 24 |.7$p.|.D%.=.q..$|
+00000020 9b 9d 18 17 03 03 00 13 e3 6e e2 8a d9 ae 0f c3 |.........n......|
+00000030 ad 90 03 90 40 be 42 fe 4e ad d2 |....@.B.N..|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-ALPN-NoMatch b/src/crypto/tls/testdata/Server-TLSv13-ALPN-NoMatch
new file mode 100644
index 0000000..a8b3d80
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-ALPN-NoMatch
@@ -0,0 +1,18 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 e2 01 00 00 de 03 03 3d ae 42 d4 d3 |...........=.B..|
+00000010 a9 75 5b a6 8f 9f 47 6f fe e7 3d 3e 5c d8 35 01 |.u[...Go..=>\.5.|
+00000020 c9 25 fd 94 e4 ac 7e b4 e1 4e 0f 20 56 29 44 cd |.%....~..N. V)D.|
+00000030 7f 99 7b a6 9a 4d d4 3c e8 01 00 93 e5 e0 a8 7b |..{..M.<.......{|
+00000040 81 13 85 e9 2e 4e 12 a2 b9 d4 7d 8e 00 04 13 03 |.....N....}.....|
+00000050 00 ff 01 00 00 91 00 0b 00 04 03 00 01 02 00 0a |................|
+00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 23 |...............#|
+00000070 00 00 00 10 00 10 00 0e 06 70 72 6f 74 6f 32 06 |.........proto2.|
+00000080 70 72 6f 74 6f 31 00 16 00 00 00 17 00 00 00 0d |proto1..........|
+00000090 00 1e 00 1c 04 03 05 03 06 03 08 07 08 08 08 09 |................|
+000000a0 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................|
+000000b0 00 2b 00 03 02 03 04 00 2d 00 02 01 01 00 33 00 |.+......-.....3.|
+000000c0 26 00 24 00 1d 00 20 3c 8b f2 09 ad ff 96 76 0f |&.$... <......v.|
+000000d0 9b 05 eb c8 5a 48 68 be a6 6e dd f6 f5 7d 56 89 |....ZHh..n...}V.|
+000000e0 ff 37 75 13 b1 1b 01 |.7u....|
+>>> Flow 2 (server to client)
+00000000 15 03 03 00 02 02 78 |......x|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-ALPN-NotConfigured b/src/crypto/tls/testdata/Server-TLSv13-ALPN-NotConfigured
new file mode 100644
index 0000000..c4bd035
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-ALPN-NotConfigured
@@ -0,0 +1,99 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 e2 01 00 00 de 03 03 1f f5 b0 88 a0 |................|
+00000010 fd 0e cd 4d 25 21 88 bf 07 16 95 49 6a 78 2d 70 |...M%!.....Ijx-p|
+00000020 25 f7 06 36 f2 98 4c 23 16 41 a5 20 87 60 d3 78 |%..6..L#.A. .`.x|
+00000030 c7 ab 8b f9 2b 2c 21 1e f4 5b 25 bc 81 53 18 5c |....+,!..[%..S.\|
+00000040 3b 7e dd 3e 7b c4 ee d1 f8 9d bf 7a 00 04 13 03 |;~.>{......z....|
+00000050 00 ff 01 00 00 91 00 0b 00 04 03 00 01 02 00 0a |................|
+00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 23 |...............#|
+00000070 00 00 00 10 00 10 00 0e 06 70 72 6f 74 6f 32 06 |.........proto2.|
+00000080 70 72 6f 74 6f 31 00 16 00 00 00 17 00 00 00 0d |proto1..........|
+00000090 00 1e 00 1c 04 03 05 03 06 03 08 07 08 08 08 09 |................|
+000000a0 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................|
+000000b0 00 2b 00 03 02 03 04 00 2d 00 02 01 01 00 33 00 |.+......-.....3.|
+000000c0 26 00 24 00 1d 00 20 5f 8f fa 0f 94 46 78 3d a9 |&.$... _....Fx=.|
+000000d0 7d d8 2b 65 f6 c1 55 6b fd aa 4b 65 23 7b ad 13 |}.+e..Uk..Ke#{..|
+000000e0 88 06 ce 54 f1 77 63 |...T.wc|
+>>> 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 87 60 d3 78 |........... .`.x|
+00000030 c7 ab 8b f9 2b 2c 21 1e f4 5b 25 bc 81 53 18 5c |....+,!..[%..S.\|
+00000040 3b 7e dd 3e 7b c4 ee d1 f8 9d bf 7a 13 03 00 00 |;~.>{......z....|
+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 30 cc 27 0f 8c cd |..........0.'...|
+00000090 77 85 98 61 e4 19 19 63 ac 5b 55 37 c2 73 6d f6 |w..a...c.[U7.sm.|
+000000a0 a1 17 03 03 02 6d 5f 60 9f d3 fc 5e 57 fb b6 35 |.....m_`...^W..5|
+000000b0 99 3c a7 65 6f eb b5 89 5a 3c be e1 a5 c7 af 14 |.<.eo...Z<......|
+000000c0 67 d4 0c 87 d4 dd c9 28 1c 5c 89 c6 55 68 e0 b3 |g......(.\..Uh..|
+000000d0 42 d8 e4 4f 64 df 26 4a a2 14 eb 34 69 9f 8d 8e |B..Od.&J...4i...|
+000000e0 fc 21 db 17 93 37 7d d4 57 bb 76 4d 1e 70 9f 58 |.!...7}.W.vM.p.X|
+000000f0 f3 ae 12 71 aa 4b 30 e3 86 92 32 c6 55 12 08 42 |...q.K0...2.U..B|
+00000100 bf 6a 6a f9 79 b9 50 37 11 15 a4 b3 c8 a8 16 da |.jj.y.P7........|
+00000110 e9 62 ed 3d 80 da 38 22 c6 c3 fd 1c b2 d2 8c 74 |.b.=..8".......t|
+00000120 23 39 70 67 b0 34 25 24 eb 72 e2 c1 63 d6 48 09 |#9pg.4%$.r..c.H.|
+00000130 ee d7 5e 15 2b 78 64 97 c8 d0 6b 2a 1c b6 d8 12 |..^.+xd...k*....|
+00000140 9e 9a b5 dc 24 51 5a 38 a1 4c 9c df 74 3f 63 f0 |....$QZ8.L..t?c.|
+00000150 d2 45 49 58 5c 3c 42 f2 56 fd bc 0e c1 d6 8b 7d |.EIX\<B.V......}|
+00000160 31 bf af c7 a2 91 8a c7 e2 ef 3d fe 66 5b 29 97 |1.........=.f[).|
+00000170 40 7e 84 2e 83 2b 41 48 69 72 02 75 49 74 77 18 |@~...+AHir.uItw.|
+00000180 af a9 ef 22 66 f2 2f 37 79 e7 10 6d 22 e9 81 86 |..."f./7y..m"...|
+00000190 c1 55 28 7d a1 1f 80 dc c8 f1 00 d7 21 c9 ff 69 |.U(}........!..i|
+000001a0 8c f0 b3 48 c4 8b 97 6a bf fc 24 ad d2 23 f5 6b |...H...j..$..#.k|
+000001b0 4d c8 96 d6 85 91 7b c6 21 79 2f e5 59 32 7d e7 |M.....{.!y/.Y2}.|
+000001c0 7b 77 46 c7 f8 6d 6e 8c 4f c8 47 84 0c f4 9d 81 |{wF..mn.O.G.....|
+000001d0 be 2e 38 c6 79 43 d1 ca 78 81 40 1a a3 0e bc fd |..8.yC..x.@.....|
+000001e0 42 2d de 55 33 48 50 6a 5b 47 b6 cb ea 6c e6 e9 |B-.U3HPj[G...l..|
+000001f0 ab 11 10 34 c3 4e 61 e1 dd a8 8d 8b c3 af 18 13 |...4.Na.........|
+00000200 2c 17 02 c9 7d 21 74 12 e1 9b a7 1e 95 8f 3a 6f |,...}!t.......:o|
+00000210 60 75 f6 e9 f8 87 e5 15 de 33 ba 01 50 28 5c 2d |`u.......3..P(\-|
+00000220 cf 74 64 c5 c8 36 48 2a f6 32 12 96 07 2f 2d 20 |.td..6H*.2.../- |
+00000230 97 cb c1 c9 8f d1 27 f0 90 66 70 1c 45 20 c9 99 |......'..fp.E ..|
+00000240 5c 9c 44 2d a2 93 5c 4c 48 7a 6b 0c 2e a7 b9 21 |\.D-..\LHzk....!|
+00000250 1b 86 94 41 2c 53 72 0b 91 55 2b 6a b2 8f 67 f9 |...A,Sr..U+j..g.|
+00000260 2a 17 84 6f b0 f6 5e 0d 57 ad ca 1d 85 77 a7 03 |*..o..^.W....w..|
+00000270 c4 ea 62 b3 63 34 59 81 a4 90 b7 f7 39 61 8e e2 |..b.c4Y.....9a..|
+00000280 79 9c bd 71 49 7a 0c 34 2b a7 4a f4 65 f0 14 96 |y..qIz.4+.J.e...|
+00000290 4a fa 5f d6 03 eb 9e 40 04 4b 45 1c 58 a6 f7 04 |J._....@.KE.X...|
+000002a0 25 27 d3 7d 7b 28 0c 43 8b cd dd 8b 5b 19 6c 21 |%'.}{(.C....[.l!|
+000002b0 c1 03 9d 75 2e 7d 83 c8 f1 ad dc fd 96 75 6f 56 |...u.}.......uoV|
+000002c0 3d 9f e9 e3 52 ff d4 b0 55 c1 43 d9 74 b1 c7 f8 |=...R...U.C.t...|
+000002d0 99 91 e5 b7 b1 28 64 64 d8 7a de 35 64 7d 75 d6 |.....(dd.z.5d}u.|
+000002e0 7f 4b 56 63 9b fb c3 6f f1 00 e6 f2 0a 7f 06 47 |.KVc...o.......G|
+000002f0 3c b9 dc 5f 2d b2 ef ca 2b 51 de a1 db 09 5d ec |<.._-...+Q....].|
+00000300 80 c3 85 36 09 b4 61 6a 21 c2 68 bb 31 6b f6 14 |...6..aj!.h.1k..|
+00000310 5c 18 73 17 03 03 00 99 0b 3b ee 6c 6e c6 5f fd |\.s......;.ln._.|
+00000320 33 e5 38 52 86 25 8f 76 93 db 62 77 2f 28 7a 19 |3.8R.%.v..bw/(z.|
+00000330 d1 78 ed 1a a4 e3 aa 13 b7 c4 24 d1 f9 f6 77 85 |.x........$...w.|
+00000340 a6 bd cf 21 3a 95 4d 70 3d 3e 40 3b 23 17 da b4 |...!:.Mp=>@;#...|
+00000350 b0 1d b7 bb 4f 90 8c 73 5a d2 f5 5b 4a 74 b0 25 |....O..sZ..[Jt.%|
+00000360 eb a8 7e a0 9d 1a e4 4e bf 4f 55 b8 9d 93 cf 5b |..~....N.OU....[|
+00000370 a4 22 3d 3b d5 8f 23 de 41 70 47 d8 3b 82 6b ba |."=;..#.ApG.;.k.|
+00000380 26 f2 a2 e9 45 8e a9 72 1e 37 2e 0d a9 4b 54 b2 |&...E..r.7...KT.|
+00000390 6f 8f ec 04 97 86 b4 e4 4c cc f1 ed c9 e1 61 b1 |o.......L.....a.|
+000003a0 f8 a2 d7 fc a5 1a 8c 44 95 16 fc e3 25 b1 a9 d6 |.......D....%...|
+000003b0 21 17 03 03 00 35 fa ad 27 32 8d 61 3a 32 36 ef |!....5..'2.a:26.|
+000003c0 ea ff 4e 95 cd a6 83 19 e2 72 85 44 33 b2 c0 45 |..N......r.D3..E|
+000003d0 f0 34 92 ca 5a a2 14 4c 6c a3 95 bd fe 3b f8 fd |.4..Z..Ll....;..|
+000003e0 e1 11 9b f6 8f 4f c6 ae 05 31 55 17 03 03 00 8b |.....O...1U.....|
+000003f0 8a a3 df b3 a0 68 8a e1 4f db c6 2a 8e df dc b6 |.....h..O..*....|
+00000400 07 b5 c4 c7 34 7f d8 e9 3f 88 0f 15 14 01 50 bc |....4...?.....P.|
+00000410 64 05 8d 91 fa 24 1e 0e cf db 11 8c 46 58 6e f1 |d....$......FXn.|
+00000420 09 68 14 9a 89 e0 6b ef ac 90 27 69 2b 01 6c 2e |.h....k...'i+.l.|
+00000430 6d e9 26 9f b1 ff b8 6c 8b 33 bb e8 42 54 85 c9 |m.&....l.3..BT..|
+00000440 14 d5 89 48 50 a6 8d be dd b8 96 f1 45 4f 90 08 |...HP.......EO..|
+00000450 da cf 1f 75 33 85 d9 be 8e a5 4a c5 be a9 a3 16 |...u3.....J.....|
+00000460 f6 37 02 79 ea c3 e5 10 ed ff d5 f2 3d 46 7b ed |.7.y........=F{.|
+00000470 bf be 36 a2 8a 00 9f 30 02 54 71 |..6....0.Tq|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 b6 3d e7 c7 a8 |..........5.=...|
+00000010 2d c2 a7 8b cc 13 db 7d c2 75 18 f9 86 20 2b f0 |-......}.u... +.|
+00000020 e1 5d 11 b1 2d df 0c 12 a7 c5 3a 28 97 6e f8 f0 |.]..-.....:(.n..|
+00000030 7f c0 81 72 68 a5 41 68 59 ef da 3e 2f ef 97 45 |...rh.AhY..>/..E|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e fd 53 e4 87 a2 41 38 98 a6 d8 fa |......S...A8....|
+00000010 7b 65 66 98 37 a6 4a 06 6b 25 11 66 ed 9c 00 22 |{ef.7.J.k%.f..."|
+00000020 83 6e f5 17 03 03 00 13 fc bb b9 93 79 3c 94 6c |.n..........y<.l|
+00000030 1d 48 d9 5c 3e 51 86 fb 2a 0d d8 |.H.\>Q..*..|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-CHACHA20-SHA256 b/src/crypto/tls/testdata/Server-TLSv13-CHACHA20-SHA256
new file mode 100644
index 0000000..1357ed4
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-CHACHA20-SHA256
@@ -0,0 +1,97 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 ca 01 00 00 c6 03 03 c4 32 0e 10 66 |............2..f|
+00000010 40 b2 cd 10 90 69 42 31 34 21 b1 a4 0e 15 f9 1e |@....iB14!......|
+00000020 cd 2b 1d 1a 9a a5 4c 27 87 aa ba 20 6a f8 a9 57 |.+....L'... j..W|
+00000030 72 d6 5b 81 86 e7 df a0 9c a3 f4 21 30 c9 68 f3 |r.[........!0.h.|
+00000040 81 7c 2a 3a c6 fe 97 d7 40 c9 41 79 00 04 13 03 |.|*:....@.Ay....|
+00000050 00 ff 01 00 00 79 00 0b 00 04 03 00 01 02 00 0a |.....y..........|
+00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 16 |................|
+00000070 00 00 00 17 00 00 00 0d 00 1e 00 1c 04 03 05 03 |................|
+00000080 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................|
+00000090 08 06 04 01 05 01 06 01 00 2b 00 03 02 03 04 00 |.........+......|
+000000a0 2d 00 02 01 01 00 33 00 26 00 24 00 1d 00 20 89 |-.....3.&.$... .|
+000000b0 77 64 a7 d7 9f 30 4d 07 5c 4c f5 3b 67 a3 f2 e3 |wd...0M.\L.;g...|
+000000c0 55 bb bb 9f 2e 18 26 04 b2 1a a2 64 c5 39 67 |U.....&....d.9g|
+>>> 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 6a f8 a9 57 |........... j..W|
+00000030 72 d6 5b 81 86 e7 df a0 9c a3 f4 21 30 c9 68 f3 |r.[........!0.h.|
+00000040 81 7c 2a 3a c6 fe 97 d7 40 c9 41 79 13 03 00 00 |.|*:....@.Ay....|
+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 db 02 44 4c 7e 06 |............DL~.|
+00000090 95 c7 f2 f7 8f f7 80 96 d0 11 b7 d7 d6 9e 40 3b |..............@;|
+000000a0 0f 17 03 03 02 6d 63 90 e6 9e e7 fd 52 34 74 8f |.....mc.....R4t.|
+000000b0 e5 db e8 90 49 90 89 8a c3 7f 33 a0 c7 91 2a 3f |....I.....3...*?|
+000000c0 c5 1f 0c 00 58 9f 5e d7 01 35 24 92 a7 66 db 0e |....X.^..5$..f..|
+000000d0 fd d3 6c ff 58 61 56 39 b3 9b 05 d2 a1 9f ab f1 |..l.XaV9........|
+000000e0 29 ce b0 c6 37 c5 56 8d 0b 2a bd 0c 04 a3 c8 4e |)...7.V..*.....N|
+000000f0 61 08 44 4b b7 f1 12 60 a9 f6 e7 02 14 e7 d4 1a |a.DK...`........|
+00000100 cf e6 4d ce 11 7c e3 7b 44 95 6d fa 8e b2 3b f4 |..M..|.{D.m...;.|
+00000110 bb 8e fa ed be ec fb f4 1d d0 12 56 d3 64 c8 cd |...........V.d..|
+00000120 58 e0 e0 df c1 f2 c7 b5 7a 6c 23 ff d1 78 b7 76 |X.......zl#..x.v|
+00000130 a5 96 66 5c 4e 49 5a 8e fd 9d 74 dc e7 f0 99 f8 |..f\NIZ...t.....|
+00000140 d5 95 7a 5b ba b6 ab 87 90 a5 35 19 bf 99 2c 04 |..z[......5...,.|
+00000150 93 61 e3 9b 5c 06 48 38 f0 25 8a be 30 cd 43 c0 |.a..\.H8.%..0.C.|
+00000160 10 c9 1d 51 3e 93 5f 6c 02 1c 38 fe 78 44 1a ea |...Q>._l..8.xD..|
+00000170 99 a4 ef 7d 03 ce 71 95 d7 1d e1 b3 b8 e2 20 99 |...}..q....... .|
+00000180 aa 30 0f c1 75 a7 0d 39 98 12 96 27 c6 39 b8 57 |.0..u..9...'.9.W|
+00000190 6e ab 79 c7 91 c2 56 9d b3 e1 cb 17 6a cc 42 47 |n.y...V.....j.BG|
+000001a0 fc a4 52 10 ab cd 4b 1f 65 3e 35 61 ed 38 99 7b |..R...K.e>5a.8.{|
+000001b0 a7 79 02 f2 16 cb 85 fb 85 f8 86 56 40 6b ee 2f |.y.........V@k./|
+000001c0 38 c6 4f 9c 25 14 b6 e4 5f 5c cc 73 ef 69 f3 5a |8.O.%..._\.s.i.Z|
+000001d0 c6 ef 0d 65 e8 d4 f8 c6 0c 5b 09 88 4d 09 e7 50 |...e.....[..M..P|
+000001e0 86 d0 2d 6c 8c 99 d0 d9 6a 24 77 97 47 59 9d ce |..-l....j$w.GY..|
+000001f0 b9 a5 34 99 f6 0b 08 9a 7e 79 8d 84 8e c2 ae ac |..4.....~y......|
+00000200 ca b3 af 5d 7d 96 d2 99 3b da ee ec 36 b3 ad 71 |...]}...;...6..q|
+00000210 89 17 de 52 71 75 99 ca e7 02 c2 ab ae da 5b 22 |...Rqu........["|
+00000220 a7 88 0c ae c5 c0 b0 1f 3c cd da fa e7 8b 39 46 |........<.....9F|
+00000230 84 c0 1a 33 29 ed 90 0e 5b 32 86 96 9f 97 69 66 |...3)...[2....if|
+00000240 90 08 0e 0e 84 4d 43 55 c1 be 08 20 85 fc 9d 7a |.....MCU... ...z|
+00000250 a6 df e8 31 b0 35 c3 69 b6 14 b2 ec 6c 7d ad ae |...1.5.i....l}..|
+00000260 2b b4 c0 5a d1 07 a7 45 17 93 d6 a5 50 d0 e4 cc |+..Z...E....P...|
+00000270 97 85 5d 06 21 62 e2 95 d7 b5 a5 a9 08 cf 34 f4 |..].!b........4.|
+00000280 ae cc 17 e4 0e 4e 5a 13 b1 73 03 45 b9 29 b5 45 |.....NZ..s.E.).E|
+00000290 77 a1 4b 2f 8f c5 72 41 dc ab f9 b7 f3 72 28 f4 |w.K/..rA.....r(.|
+000002a0 cb 08 07 0a 20 7c 8b 26 70 92 7b 7b b9 99 61 0a |.... |.&p.{{..a.|
+000002b0 63 17 e2 96 86 0a 6a 56 a1 90 1f 5e 50 bb 7f 72 |c.....jV...^P..r|
+000002c0 73 58 f4 25 c8 18 ec a5 b1 86 cd 96 77 57 91 67 |sX.%........wW.g|
+000002d0 76 e1 7a bf 1b 40 62 a0 58 d7 e8 2c 4c 86 7b ed |v.z..@b.X..,L.{.|
+000002e0 7f 3f 43 38 88 97 f7 a1 5f 22 0c a0 4a a4 b3 b9 |.?C8...._"..J...|
+000002f0 11 2c 31 f3 98 f0 21 42 fb 42 a7 9e 38 ce 58 5f |.,1...!B.B..8.X_|
+00000300 bc d0 a5 43 07 d2 e1 4b 5f 5c fd 56 da 99 63 2a |...C...K_\.V..c*|
+00000310 0d 7f 46 17 03 03 00 99 bf be 5f 82 e4 2b d8 9f |..F......._..+..|
+00000320 cf ab 68 b0 3d a4 a0 c7 c3 41 dd e5 46 cf 7b 55 |..h.=....A..F.{U|
+00000330 c7 6d 76 e4 62 60 c5 ae d3 a0 f0 44 8c 88 de 05 |.mv.b`.....D....|
+00000340 5e 5e 03 61 fe 66 22 31 cf f5 75 b6 97 51 36 79 |^^.a.f"1..u..Q6y|
+00000350 f0 b7 d1 7f e6 1a fa 04 73 23 ad 66 f8 6c 47 a7 |........s#.f.lG.|
+00000360 cc 0b 96 c4 a7 a8 e8 4c 91 bc c9 32 30 ec db 2e |.......L...20...|
+00000370 73 68 00 5b c3 83 17 60 51 b1 03 8d c3 f9 e1 e8 |sh.[...`Q.......|
+00000380 f7 e7 a8 f4 94 b7 4f c1 bf aa 50 49 61 b1 11 0a |......O...PIa...|
+00000390 78 24 cc 16 3b e5 10 72 95 df e4 a3 5d 2c ff ad |x$..;..r....],..|
+000003a0 bd 50 04 93 3c 3c 48 28 0b e3 d9 d3 db 4d 4a 8f |.P..<<H(.....MJ.|
+000003b0 62 17 03 03 00 35 b2 f4 32 f5 f9 b9 f3 cc 15 d5 |b....5..2.......|
+000003c0 d7 85 83 e7 37 5f ac 10 4f 2f 43 59 0b a6 4b 9c |....7_..O/CY..K.|
+000003d0 2b e8 c3 87 fa 3f 4d b5 54 75 93 ab 2f 4c 72 03 |+....?M.Tu../Lr.|
+000003e0 6f 8f f4 ac 43 d1 4c dc 62 b7 6d 17 03 03 00 8b |o...C.L.b.m.....|
+000003f0 89 17 54 55 04 e9 55 45 a3 82 7e e9 7c 2e 28 6b |..TU..UE..~.|.(k|
+00000400 28 a7 82 f1 e7 db cd 3e ac 6e d8 d0 0b 0e 52 73 |(......>.n....Rs|
+00000410 b0 01 2c 04 8e 7b 70 c3 36 85 a4 44 aa 15 63 d6 |..,..{p.6..D..c.|
+00000420 7d f4 81 86 3c 1e ad d3 b3 2c ea 33 bf 0e 71 68 |}...<....,.3..qh|
+00000430 4a 1a 3a 98 bb 21 d4 75 6c 0d d2 30 b4 b3 86 5d |J.:..!.ul..0...]|
+00000440 90 ab 49 dc 18 4f 08 10 8b 23 8d bd 61 68 75 ee |..I..O...#..ahu.|
+00000450 87 62 54 2d 2d 1e c0 39 5c eb 32 40 7a da 4d 2f |.bT--..9\.2@z.M/|
+00000460 83 f9 e8 1f 71 d7 79 99 24 8a b7 13 25 64 a6 ae |....q.y.$...%d..|
+00000470 29 e2 48 6f f7 52 cf a4 aa c2 70 |).Ho.R....p|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 5e e5 2f e4 ed |..........5^./..|
+00000010 87 c3 26 01 1a d0 4d c7 95 16 76 be 17 a3 f4 1f |..&...M...v.....|
+00000020 57 27 f6 19 62 30 7e f0 47 6e 11 7f ce 85 54 9a |W'..b0~.Gn....T.|
+00000030 1e 86 9a c6 10 5e 38 3c 0a de d1 4e 7e f1 9d 0f |.....^8<...N~...|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e 1f a0 f2 e5 47 62 54 e2 07 3d e2 |.........GbT..=.|
+00000010 42 8a be ec e0 92 4e ae 1e 7a 75 6f 8d c0 65 73 |B.....N..zuo..es|
+00000020 b5 eb bc 17 03 03 00 13 89 03 04 f9 42 a9 6d cf |............B.m.|
+00000030 68 67 f4 ca e0 87 f9 ef d4 42 6a |hg.......Bj|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndECDSAGiven b/src/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndECDSAGiven
new file mode 100644
index 0000000..a957c26
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndECDSAGiven
@@ -0,0 +1,180 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 ca 01 00 00 c6 03 03 cd 87 c0 5e 7c |..............^||
+00000010 7b d7 c6 77 d9 21 6f 46 00 07 88 61 18 8c b9 d4 |{..w.!oF...a....|
+00000020 ad 25 6a 9d 7e 54 cc 70 52 7c 0f 20 67 9b dd 18 |.%j.~T.pR|. g...|
+00000030 84 bb 23 7d 53 10 b9 6c 01 ef 30 6f 79 7d 64 5c |..#}S..l..0oy}d\|
+00000040 79 3e c1 11 8f 75 cf 83 02 d3 e8 d9 00 04 13 01 |y>...u..........|
+00000050 00 ff 01 00 00 79 00 0b 00 04 03 00 01 02 00 0a |.....y..........|
+00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 16 |................|
+00000070 00 00 00 17 00 00 00 0d 00 1e 00 1c 04 03 05 03 |................|
+00000080 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................|
+00000090 08 06 04 01 05 01 06 01 00 2b 00 03 02 03 04 00 |.........+......|
+000000a0 2d 00 02 01 01 00 33 00 26 00 24 00 1d 00 20 d7 |-.....3.&.$... .|
+000000b0 18 8a c1 a5 4d cb 7c f2 7d e4 cf 7a c6 92 28 ee |....M.|.}..z..(.|
+000000c0 a6 b4 79 65 bf 2b fb 71 2e a5 2a 58 da 6f 5e |..ye.+.q..*X.o^|
+>>> 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 67 9b dd 18 |........... g...|
+00000030 84 bb 23 7d 53 10 b9 6c 01 ef 30 6f 79 7d 64 5c |..#}S..l..0oy}d\|
+00000040 79 3e c1 11 8f 75 cf 83 02 d3 e8 d9 13 01 00 00 |y>...u..........|
+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 4d 4b 33 12 cb ed |..........MK3...|
+00000090 f7 a2 55 e7 a6 ab 5b b1 55 16 30 c3 ee e1 5c 14 |..U...[.U.0...\.|
+000000a0 b8 17 03 03 00 3e 30 04 2a e5 e8 b8 f3 25 9b a9 |.....>0.*....%..|
+000000b0 92 e6 eb d9 fb b6 62 64 e2 de 9d c0 48 68 b3 d7 |......bd....Hh..|
+000000c0 0f 8b ad 21 69 c7 f0 d7 96 ff 6a 24 2f 01 c9 e7 |...!i.....j$/...|
+000000d0 e9 06 4b 93 94 67 97 44 46 c4 69 2f 0e aa e0 9b |..K..g.DF.i/....|
+000000e0 8d 19 f2 2c 17 03 03 02 6d a1 fb 2b 5f 10 e9 62 |...,....m..+_..b|
+000000f0 8b ad c1 33 58 f6 a7 89 78 a6 dd 64 ff c2 c7 57 |...3X...x..d...W|
+00000100 80 9f 59 be 2d bd f5 b9 8a 6b d9 22 1c fe 10 ea |..Y.-....k."....|
+00000110 c4 a5 3e 45 d9 d7 12 cf 48 d5 26 18 49 50 80 69 |..>E....H.&.IP.i|
+00000120 44 28 03 3b b6 f8 0a 0e b4 cb 5e 5b 57 0f c0 2f |D(.;......^[W../|
+00000130 59 4f 13 e3 9c 02 18 b1 ce 94 78 05 18 64 73 c6 |YO........x..ds.|
+00000140 05 89 d1 54 37 18 ea 09 61 08 c5 6a 54 f6 48 44 |...T7...a..jT.HD|
+00000150 40 63 6a 53 b9 41 5f 4f 8e 05 e7 31 7b 08 d0 67 |@cjS.A_O...1{..g|
+00000160 8e bf 56 c4 56 0a 82 b2 74 6a 89 dd b4 f7 3c 0b |..V.V...tj....<.|
+00000170 3c fd 21 1f 00 72 1d 4f be b1 50 44 9a 14 67 7d |<.!..r.O..PD..g}|
+00000180 a9 93 30 a2 4e ea 61 c9 fd 44 de 5c 88 36 59 a2 |..0.N.a..D.\.6Y.|
+00000190 e3 63 b1 9c ea dd 47 0a ca 63 9e 50 9d ca 57 12 |.c....G..c.P..W.|
+000001a0 05 9b fc f1 26 a2 5e 18 9b 32 00 38 1f ce a6 58 |....&.^..2.8...X|
+000001b0 58 0f 61 e2 44 c2 89 34 cc f4 fd 9a dc 1a 67 a6 |X.a.D..4......g.|
+000001c0 e8 b1 fc 9f dc bd 0b 21 01 49 0d 9b e1 40 00 f6 |.......!.I...@..|
+000001d0 33 1a 57 c5 84 c1 98 3d 7f 53 d3 4d 2e 04 5e 40 |3.W....=.S.M..^@|
+000001e0 7d 38 80 66 bc c5 40 d9 14 f6 83 26 82 9b c8 14 |}8.f..@....&....|
+000001f0 61 aa 6c 1c a1 53 81 f8 b0 7f 06 92 5c af be 57 |a.l..S......\..W|
+00000200 1a 54 97 02 27 31 1f 58 52 cf 39 2f 82 26 ae 6c |.T..'1.XR.9/.&.l|
+00000210 86 d9 46 cd 38 16 e2 67 62 82 2e 53 7a 86 15 30 |..F.8..gb..Sz..0|
+00000220 08 0c a7 e2 85 18 55 79 16 44 4d 50 9e b5 e7 e1 |......Uy.DMP....|
+00000230 2c 1e 1d eb e1 83 f3 9e d0 7b 45 b8 1e 51 d9 79 |,........{E..Q.y|
+00000240 91 7a b8 90 bc 18 94 69 ad 94 08 e5 23 de 2b fa |.z.....i....#.+.|
+00000250 8d ef 23 4c 40 df e1 43 0d 71 51 ef 88 a9 bb 89 |..#L@..C.qQ.....|
+00000260 59 87 9c db e1 d4 31 94 a7 f5 af 7d 51 be e9 d0 |Y.....1....}Q...|
+00000270 f2 49 12 72 47 65 a0 5b 7d 9f 91 85 f7 e8 d6 90 |.I.rGe.[}.......|
+00000280 b3 4d f3 5d 6a 51 96 a9 81 84 72 95 47 e8 0a f5 |.M.]jQ....r.G...|
+00000290 8d d6 2a 64 c2 34 1b d8 f0 f9 62 0c be 17 12 9b |..*d.4....b.....|
+000002a0 40 a2 c3 8a eb 30 20 04 e4 69 a3 27 90 a6 1a 4f |@....0 ..i.'...O|
+000002b0 3f 95 65 e6 9e c7 ad 03 e1 d2 34 d2 84 d5 f6 8c |?.e.......4.....|
+000002c0 1e 8a aa e4 75 c0 7f 1d 79 4e 70 10 4e 18 9c eb |....u...yNp.N...|
+000002d0 17 76 0c 66 6c 82 72 41 83 98 fc 41 41 4a 07 03 |.v.fl.rA...AAJ..|
+000002e0 a6 16 51 0d 60 96 43 0a 97 27 72 42 31 70 6b 02 |..Q.`.C..'rB1pk.|
+000002f0 e4 58 b0 15 4f 2e a3 5a ed dc 82 99 82 47 d5 6c |.X..O..Z.....G.l|
+00000300 4b b4 68 70 f5 a3 31 36 52 8d af ab d1 ac f6 28 |K.hp..16R......(|
+00000310 2e 18 bc 4f 1b 7c a8 ad c3 1f 2f 70 a6 c4 39 c6 |...O.|..../p..9.|
+00000320 ae 0f 2e b7 58 c9 c0 2a 4b 34 c2 42 12 e3 5d ed |....X..*K4.B..].|
+00000330 d1 ac e1 f1 14 66 d4 09 1c a0 99 82 d3 04 13 2a |.....f.........*|
+00000340 a4 20 c4 e7 38 1e 0a 02 4e 96 02 71 9d f6 f7 86 |. ..8...N..q....|
+00000350 f7 30 1a 5d 65 4f 17 03 03 00 99 3f 3d 4a 91 ae |.0.]eO.....?=J..|
+00000360 0f 80 52 0f 1c d1 a2 75 83 e5 08 d8 1f 9d c8 24 |..R....u.......$|
+00000370 fc 85 ba 76 1f 9e 1e 35 a3 dd 45 83 8e b9 55 a6 |...v...5..E...U.|
+00000380 3b 26 ae 82 4f 1f 2e 8f e5 25 fb d6 22 0f 55 d6 |;&..O....%..".U.|
+00000390 ac fa 93 6d d1 d3 7c 41 af c0 15 5c 8b e1 64 c1 |...m..|A...\..d.|
+000003a0 3f a2 c8 9e 48 f5 63 61 3a df 13 6e f4 e3 60 9d |?...H.ca:..n..`.|
+000003b0 bc 52 bd b7 94 e9 4b 7a 65 97 28 ac 39 6a 77 a7 |.R....Kze.(.9jw.|
+000003c0 86 1d b4 6b e4 15 c4 bd 2b 41 b6 06 ac ff b5 9f |...k....+A......|
+000003d0 17 47 b4 a7 1d 69 8b 6e 82 eb f7 39 03 95 10 dd |.G...i.n...9....|
+000003e0 18 78 50 58 c8 78 80 ae 45 dc 54 0f 33 cb 4a d2 |.xPX.x..E.T.3.J.|
+000003f0 90 00 12 d4 17 03 03 00 35 76 fa bf ab 3f c3 3d |........5v...?.=|
+00000400 dd 78 65 cc 35 1e 24 35 4f 7d 3c e4 bb 73 d8 19 |.xe.5.$5O}<..s..|
+00000410 56 94 f4 ce ad bc 1d 6a fb 1b 75 01 93 36 2b 44 |V......j..u..6+D|
+00000420 3a 3c a3 9b 7c 57 6f 98 24 a3 64 b1 13 47 |:<..|Wo.$.d..G|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 02 1e e0 29 6d d1 38 |............)m.8|
+00000010 a6 03 d7 fc 2b df a4 a4 d0 ae 87 01 b8 82 5d eb |....+.........].|
+00000020 3c 25 3e a1 33 89 b5 05 eb bc 02 0f ad 84 f0 2b |<%>.3..........+|
+00000030 5f 14 af 0d f8 f1 08 e3 ca c1 8e ad 4b a5 a0 09 |_...........K...|
+00000040 b8 a0 4f bf e4 0f 93 a9 4a 35 35 26 22 d7 04 03 |..O.....J55&"...|
+00000050 70 95 4f 80 df d4 47 5b 21 14 27 d6 17 ea 32 6e |p.O...G[!.'...2n|
+00000060 ea 3a ca 31 7c f2 d1 46 a2 ef 47 b9 16 d6 18 d5 |.:.1|..F..G.....|
+00000070 17 35 71 9d 14 37 63 cd e1 c6 ff 3d ec a5 d8 53 |.5q..7c....=...S|
+00000080 48 d5 d8 0b 75 39 c1 d2 66 ad 97 4e 5f eb c3 c7 |H...u9..f..N_...|
+00000090 e0 77 95 fd 16 84 e2 a3 6a f2 a8 88 5e 4c 86 be |.w......j...^L..|
+000000a0 81 a5 f2 6b 12 86 63 f1 4f a6 8d 63 7c 07 0f 8d |...k..c.O..c|...|
+000000b0 53 d5 d4 00 c7 b7 2a ef b2 1d 07 4e 43 d6 25 35 |S.....*....NC.%5|
+000000c0 c9 b1 fa 91 d1 f7 87 c6 98 c7 e7 c2 c3 7d 42 09 |.............}B.|
+000000d0 e5 3c 50 83 1b 20 ef ec e4 ac 2e f2 3e 03 73 52 |.<P.. ......>.sR|
+000000e0 2e 1d 20 cf e2 8d 15 c3 c7 a6 2f 68 b5 8e 5f bc |.. ......./h.._.|
+000000f0 c5 73 61 ff 52 3c b0 7b 47 82 47 a0 73 f8 1c ab |.sa.R<.{G.G.s...|
+00000100 4d ea 15 fa 94 e0 7f 70 c1 c8 9c 55 f0 96 38 42 |M......p...U..8B|
+00000110 76 d4 26 6d a7 73 11 59 43 19 2f 49 70 a9 18 1c |v.&m.s.YC./Ip...|
+00000120 12 9e ee d3 eb ca 1c c0 3b e1 99 e3 c2 25 de 39 |........;....%.9|
+00000130 1a 15 e0 d7 20 9d 1b 95 74 8c ee 96 7b 5e de 13 |.... ...t...{^..|
+00000140 99 56 54 a2 31 7b e9 96 02 9e 86 7b 15 9d c6 3e |.VT.1{.....{...>|
+00000150 24 a5 19 e5 8e de 85 97 05 68 4f 39 d1 49 05 c9 |$........hO9.I..|
+00000160 7a 54 90 29 e7 93 ec 8e 6f cc 73 73 82 7d 72 8d |zT.)....o.ss.}r.|
+00000170 4a 85 29 7f a5 53 13 26 16 b2 fa c3 ce 1f 8b ae |J.)..S.&........|
+00000180 e6 60 8c 2d b0 64 66 d4 29 7c b5 2d 1d 11 c5 09 |.`.-.df.)|.-....|
+00000190 bb a5 44 c6 c8 af e6 f1 d5 f8 d9 45 97 64 7f 03 |..D........E.d..|
+000001a0 02 f7 f5 9f cb 31 1e 89 e4 5d a0 e9 34 db be 28 |.....1...]..4..(|
+000001b0 51 15 68 54 01 7c e5 1d b4 05 d2 d6 24 ca 10 69 |Q.hT.|......$..i|
+000001c0 31 bf 8b 7a ee d9 bf e1 2a d4 7c c8 e8 79 ca dd |1..z....*.|..y..|
+000001d0 0f 73 09 c8 cf 97 28 78 04 5b 04 51 44 c4 5f d1 |.s....(x.[.QD._.|
+000001e0 dc da 4f f5 d9 5c 9c b1 ea f8 1b f7 43 90 c0 c0 |..O..\......C...|
+000001f0 fd 82 56 e3 71 15 18 5e 7e 5c 61 5e b3 80 c1 1c |..V.q..^~\a^....|
+00000200 22 92 32 67 23 f6 3b 74 e4 20 4e 1f fb f8 89 55 |".2g#.;t. N....U|
+00000210 e7 3c 18 30 24 77 7c 33 5c 89 91 60 65 14 06 9e |.<.0$w|3\..`e...|
+00000220 e2 6d f0 07 84 4b b4 14 e8 17 03 03 00 a3 a7 e1 |.m...K..........|
+00000230 f7 26 48 56 da 6d ef a5 f4 5f 19 52 37 9e e7 6d |.&HV.m..._.R7..m|
+00000240 28 07 70 ee 1e de 85 2b 7a 2d bf eb 48 06 f5 d4 |(.p....+z-..H...|
+00000250 ea 4d 83 86 59 d4 14 4f 46 bc 17 89 f1 f5 37 0e |.M..Y..OF.....7.|
+00000260 84 60 6e ba 73 d7 c1 bc 6f d7 aa cf f0 36 96 a2 |.`n.s...o....6..|
+00000270 83 60 81 6f 48 6c 9d 87 e5 b6 5e 77 ab c5 e3 cb |.`.oHl....^w....|
+00000280 8e 55 94 dc 94 f3 8a ce cb f7 b4 d5 33 55 df 88 |.U..........3U..|
+00000290 22 44 04 ee 4e f5 30 e7 30 94 dc 95 2d 97 2c e4 |"D..N.0.0...-.,.|
+000002a0 34 58 4d 38 9e 25 61 96 c1 37 66 34 2b be ee e6 |4XM8.%a..7f4+...|
+000002b0 ee 39 73 89 a3 aa 1b 0a 5a bf 44 23 4e 19 5c c4 |.9s.....Z.D#N.\.|
+000002c0 3f 27 47 5c 40 67 6c 50 b8 3f 7c c9 97 f0 55 02 |?'G\@glP.?|...U.|
+000002d0 16 17 03 03 00 35 82 8b 0d 4e 87 3c c6 bc 41 8b |.....5...N.<..A.|
+000002e0 ec ab 71 9d 57 7b e6 22 e4 87 82 61 5d f8 69 31 |..q.W{."...a].i1|
+000002f0 8a 2c be 2c d8 4d 2f dc 9a 91 31 7a ab d8 a4 0e |.,.,.M/...1z....|
+00000300 ba cb fc ef 17 a4 7c 87 ca 13 bb 17 03 03 00 13 |......|.........|
+00000310 3b d0 da 9f d4 be fa 59 7a 30 8b 7e 8e a0 99 c0 |;......Yz0.~....|
+00000320 c2 36 f3 |.6.|
+>>> Flow 4 (server to client)
+00000000 17 03 03 02 90 a2 a0 e4 83 63 ad 8d d5 45 25 dc |.........c...E%.|
+00000010 41 02 31 28 8d b0 87 85 66 b8 9c 36 f3 1f 97 87 |A.1(....f..6....|
+00000020 8c c9 e6 b4 67 1e 42 ab 84 c4 eb 0a 41 b1 0f 50 |....g.B.....A..P|
+00000030 25 c3 7e 69 20 cf 8a d0 56 79 61 e3 e1 5b cc a4 |%.~i ...Vya..[..|
+00000040 24 5a c7 2d 3b 17 33 92 59 6c 7e 29 a9 a2 2c 73 |$Z.-;.3.Yl~)..,s|
+00000050 3e b1 65 32 3d 6a 2b 61 5d 76 c4 66 0e 4f f1 da |>.e2=j+a]v.f.O..|
+00000060 dd d3 7e 29 3d f5 42 99 9e 04 60 a4 9a a1 c0 f7 |..~)=.B...`.....|
+00000070 54 4e d5 58 73 85 02 83 38 ba 4e 93 9a 69 68 07 |TN.Xs...8.N..ih.|
+00000080 71 c9 a7 e4 83 51 4c 11 21 26 b2 dd ad 4b 2a ef |q....QL.!&...K*.|
+00000090 23 9b b0 f6 d6 96 9f 99 1f 69 fe 35 28 86 49 bc |#........i.5(.I.|
+000000a0 ec 97 11 4d 4e b7 c1 c2 da 6c ae c7 40 b9 2a 1f |...MN....l..@.*.|
+000000b0 ff 9d 9d ea 90 b9 61 6f 76 ae fe 55 70 f6 ee 54 |......aov..Up..T|
+000000c0 54 62 6d 19 9a fc 40 16 e5 c2 e2 3e d1 68 c6 09 |Tbm...@....>.h..|
+000000d0 be 54 64 25 8a a0 2b e6 b3 14 7e 74 17 91 f0 de |.Td%..+...~t....|
+000000e0 87 e8 3c 3e 58 8d 1b b2 4e 2d 7d c1 f8 aa 16 ca |..<>X...N-}.....|
+000000f0 2a 3e 8f aa 52 14 e4 f2 2a b9 6e 62 46 ab ed 3a |*>..R...*.nbF..:|
+00000100 ff a1 51 53 92 7a 78 c4 ed 9d fd 1f b4 62 2e e7 |..QS.zx......b..|
+00000110 cc 9d 09 fa 06 2e 9e 55 e5 98 9e b8 be e9 12 94 |.......U........|
+00000120 33 58 6b be 71 a1 4f f8 a0 83 85 f8 7e b4 28 a7 |3Xk.q.O.....~.(.|
+00000130 ee 1b ac 3c 46 b6 ac 60 af 5d cc b0 a8 2c 3f 95 |...<F..`.]...,?.|
+00000140 75 2a 73 ac 02 7e d8 04 21 fc 68 d7 6f 1d 31 40 |u*s..~..!.h.o.1@|
+00000150 43 81 26 b7 00 5f 77 d9 21 7b b4 7c cd 9f 89 69 |C.&.._w.!{.|...i|
+00000160 ef 11 0c 60 db 22 94 98 eb 10 d9 0c 0e 29 c2 d9 |...`.".......)..|
+00000170 74 8d 71 25 b8 5a c1 13 d6 f6 01 58 6d 71 31 7c |t.q%.Z.....Xmq1||
+00000180 66 e8 e5 36 06 b3 e4 51 0c b1 43 88 bf 2b 54 d7 |f..6...Q..C..+T.|
+00000190 52 79 3d 07 a9 c2 e5 97 cc 79 87 b1 c7 8b 30 7b |Ry=......y....0{|
+000001a0 b1 fe 90 58 35 a1 dc 18 8a fa cc df 63 2b 72 57 |...X5.......c+rW|
+000001b0 14 e1 12 4c bc d7 ba c2 e5 f7 4c 40 d6 34 ea 11 |...L......L@.4..|
+000001c0 8f be 3d 7a 34 11 c1 1a ad f8 2e 89 94 8a 3a ce |..=z4.........:.|
+000001d0 e5 8f e8 bc 77 71 38 8c 3c 6e 29 a3 1a 14 9d 3d |....wq8.<n)....=|
+000001e0 a3 28 46 32 38 f0 14 74 ff 9b 99 71 65 ab ef c8 |.(F28..t...qe...|
+000001f0 67 ab 47 91 61 d1 af cf 7d 96 89 d5 57 17 96 d3 |g.G.a...}...W...|
+00000200 30 d5 fb 74 3b b8 df 77 98 7b 04 3e a1 a8 5a f1 |0..t;..w.{.>..Z.|
+00000210 6b 5c d2 4d b2 20 35 63 9e 83 c0 7e 83 60 46 57 |k\.M. 5c...~.`FW|
+00000220 c0 80 0d d7 b9 9f 14 c0 58 2d 48 2a cc 8c 1d 32 |........X-H*...2|
+00000230 2c 34 ec 10 f2 34 b4 28 e1 0e 83 38 c4 2e 5a 09 |,4...4.(...8..Z.|
+00000240 ff e6 3f d3 9a 32 8e 33 9e 31 18 e5 1d 6b 97 12 |..?..2.3.1...k..|
+00000250 9b 93 84 86 62 8a 0a 8a ab 8d 37 68 af a1 ec 8e |....b.....7h....|
+00000260 38 c8 47 ef 10 f8 64 7c e1 13 0a 33 eb c2 4b bf |8.G...d|...3..K.|
+00000270 47 49 6d 93 3c c9 44 aa 74 67 a9 93 dd de 66 47 |GIm.<.D.tg....fG|
+00000280 1e b3 55 47 b1 16 88 68 82 24 d6 b8 81 b0 5a b6 |..UG...h.$....Z.|
+00000290 27 7a f8 0b 5c 17 03 03 00 1e a5 9b 8c d2 3e 96 |'z..\.........>.|
+000002a0 f3 49 7a ed d9 fc 33 62 15 12 43 76 11 f9 dc fc |.Iz...3b..Cv....|
+000002b0 ea d2 d7 87 22 6f 9e 3d 17 03 03 00 13 e1 30 4e |...."o.=......0N|
+000002c0 4c 1d 02 78 57 a5 ee 8f 1c 5f 19 f0 57 3a 8d 7e |L..xW...._..W:.~|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndEd25519Given b/src/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndEd25519Given
new file mode 100644
index 0000000..6943bf6
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndEd25519Given
@@ -0,0 +1,149 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 ca 01 00 00 c6 03 03 e4 83 a9 75 06 |..............u.|
+00000010 0f 8b c9 35 1e 62 89 7f a8 df 7c 93 b6 f0 8f 94 |...5.b....|.....|
+00000020 ea 31 dc 66 11 66 bd 77 33 54 bf 20 38 77 15 8d |.1.f.f.w3T. 8w..|
+00000030 b4 21 50 72 6f 95 61 6c 15 b8 35 c9 92 10 72 99 |.!Pro.al..5...r.|
+00000040 bc 41 03 53 7c 5e 7b b3 a4 2e b4 19 00 04 13 01 |.A.S|^{.........|
+00000050 00 ff 01 00 00 79 00 0b 00 04 03 00 01 02 00 0a |.....y..........|
+00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 16 |................|
+00000070 00 00 00 17 00 00 00 0d 00 1e 00 1c 04 03 05 03 |................|
+00000080 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................|
+00000090 08 06 04 01 05 01 06 01 00 2b 00 03 02 03 04 00 |.........+......|
+000000a0 2d 00 02 01 01 00 33 00 26 00 24 00 1d 00 20 8e |-.....3.&.$... .|
+000000b0 cf 32 24 aa f2 36 c7 41 50 66 dd 57 ce 97 72 8d |.2$..6.APf.W..r.|
+000000c0 f3 b6 7d a0 a4 5e 5d fe be bb ce 32 9f 03 75 |..}..^]....2..u|
+>>> 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 38 77 15 8d |........... 8w..|
+00000030 b4 21 50 72 6f 95 61 6c 15 b8 35 c9 92 10 72 99 |.!Pro.al..5...r.|
+00000040 bc 41 03 53 7c 5e 7b b3 a4 2e b4 19 13 01 00 00 |.A.S|^{.........|
+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 3b ca 9a d3 b7 99 |..........;.....|
+00000090 d7 d8 c9 f9 96 b8 70 69 3b 22 42 0f c4 72 de 7c |......pi;"B..r.||
+000000a0 05 17 03 03 00 3e 38 d7 00 60 b9 ce 17 31 26 9f |.....>8..`...1&.|
+000000b0 db ef e2 b1 99 55 c8 f9 f3 a0 81 19 12 a7 63 85 |.....U........c.|
+000000c0 5a 26 2d d1 1c ad 5d ae d6 4b 66 93 62 d7 fe 08 |Z&-...]..Kf.b...|
+000000d0 40 e9 fa 16 8b 89 f8 04 e8 33 67 20 2b 21 91 a0 |@........3g +!..|
+000000e0 c6 0a 87 ff 17 03 03 02 6d 79 97 6c 2f f6 01 7b |........my.l/..{|
+000000f0 3a 49 0e 1a 00 96 10 fd 7f 77 db 76 b2 d4 e4 68 |:I.......w.v...h|
+00000100 46 4e 4f 3c 64 54 ca 27 9a 5c 78 98 f4 96 a4 fe |FNO<dT.'.\x.....|
+00000110 29 e5 44 cb 6d 3e bd ce 89 15 c6 75 d8 28 00 da |).D.m>.....u.(..|
+00000120 ff d8 ec 27 2c f2 4c e5 a0 6e 88 ce 67 6e 35 f4 |...',.L..n..gn5.|
+00000130 e5 d5 96 2d 40 af fa 88 12 8a 48 24 2c f9 82 f5 |...-@.....H$,...|
+00000140 cb a4 6e 95 a6 53 bc 79 f7 6a ef 66 77 bc 46 f0 |..n..S.y.j.fw.F.|
+00000150 1b 0d 6b 5c 76 82 15 c4 d0 1c dd ec cc ce 09 93 |..k\v...........|
+00000160 ce 21 55 9b d8 8a 11 1b 0c 24 fa 9e 5f 29 4a f1 |.!U......$.._)J.|
+00000170 2a 2e ad c0 6d 6d 46 06 5b c9 75 b3 3e 32 45 67 |*...mmF.[.u.>2Eg|
+00000180 05 26 cc d8 a8 4a a9 b1 67 71 a6 82 1c dc f0 15 |.&...J..gq......|
+00000190 6d 25 f5 6e be a2 5f 45 39 dc d1 2e df fa e1 e9 |m%.n.._E9.......|
+000001a0 48 ca 7a 78 fa 0e 53 d1 5c 8f c2 40 91 d5 fa 40 |H.zx..S.\..@...@|
+000001b0 7e a1 52 23 c8 56 1f 31 17 91 5c 38 bb 54 56 f3 |~.R#.V.1..\8.TV.|
+000001c0 1e 14 90 43 b7 ef fd 56 b5 ae 13 90 97 dc 60 15 |...C...V......`.|
+000001d0 67 72 fc c2 0a 32 90 be ec de 69 16 d3 1b 22 2c |gr...2....i...",|
+000001e0 25 9f 91 27 a7 6d 8c a4 de 02 fd 0e da bf ca 71 |%..'.m.........q|
+000001f0 77 9b 56 b8 07 e8 80 00 9b d9 36 1c 09 4f 9f 54 |w.V.......6..O.T|
+00000200 76 d5 76 f4 9a 03 94 bb 9e 93 f0 b5 3c a1 71 ec |v.v.........<.q.|
+00000210 b3 83 3a 06 b4 46 97 bf ef bb f0 26 94 4e b0 08 |..:..F.....&.N..|
+00000220 3b ec 81 20 66 92 11 85 a0 c2 90 fd c5 bc ae 39 |;.. f..........9|
+00000230 2c 87 ec e4 5d 59 ee b4 e9 0d f7 2a e0 3b 2a 94 |,...]Y.....*.;*.|
+00000240 1a 79 2f e8 5c 88 d3 61 2e 47 c0 f3 c4 01 84 a9 |.y/.\..a.G......|
+00000250 cf f6 36 13 cb 4b 0b f7 9a 14 f1 d5 0e 10 80 fd |..6..K..........|
+00000260 11 79 20 20 ae 56 5e de 58 53 19 38 26 e2 ac bc |.y .V^.XS.8&...|
+00000270 0c 40 38 8b f9 67 62 4c 42 7d 18 4f 27 e9 53 96 |.@8..gbLB}.O'.S.|
+00000280 78 4b fa 44 fe c2 c3 d9 99 f2 2c 59 2b 2b 2c 88 |xK.D......,Y++,.|
+00000290 5b dc a8 98 3d 17 14 09 70 ce e4 02 8b 3c 5d 94 |[...=...p....<].|
+000002a0 44 ac ba 57 2d a9 bf b8 70 e9 b8 a8 c3 b8 90 da |D..W-...p.......|
+000002b0 ec b1 b4 57 d6 e3 0f 41 82 bb 21 4a 57 dc ac 4b |...W...A..!JW..K|
+000002c0 89 34 75 fc c4 56 6b 70 3d 83 2b fa be c8 2b cd |.4u..Vkp=.+...+.|
+000002d0 f8 4f 9f 9e 9a 0e d2 d0 46 cd 21 a5 f7 07 a6 2a |.O......F.!....*|
+000002e0 85 7b 30 92 78 a2 da a5 1d 1c 1c 54 63 4b 66 b2 |.{0.x......TcKf.|
+000002f0 f1 a7 c4 43 57 97 7f 28 37 e7 15 62 9b 1c f5 90 |...CW..(7..b....|
+00000300 0c 19 36 1a c1 48 48 e5 7d 56 93 3c 13 e3 cd 6a |..6..HH.}V.<...j|
+00000310 aa aa ba d5 24 95 c7 df 9c a9 76 6c 07 bf 09 2d |....$.....vl...-|
+00000320 4b 7b 55 94 37 ec d4 69 ce ab 0f 48 37 74 37 99 |K{U.7..i...H7t7.|
+00000330 83 0d 60 8a 73 56 fb e2 9e 0c 39 0e 23 bf 68 b2 |..`.sV....9.#.h.|
+00000340 92 51 12 bc cf 1b af 9d 7c fe 77 14 c8 66 4a 6f |.Q......|.w..fJo|
+00000350 91 06 55 6a 11 61 17 03 03 00 99 c2 bf 26 a6 fa |..Uj.a.......&..|
+00000360 67 16 a3 b9 1f 36 f8 4f 5d 59 b1 be 43 3a 70 01 |g....6.O]Y..C:p.|
+00000370 c0 3a 4b c5 20 b1 22 49 04 22 bb 7f 5f f4 bb f8 |.:K. ."I.".._...|
+00000380 35 03 0e dc ba ce de 2a 25 ea 96 dd 3d 64 34 90 |5......*%...=d4.|
+00000390 30 f8 34 22 bb e4 94 00 bb b3 ea 3c d2 87 90 9a |0.4".......<....|
+000003a0 86 76 6b b7 e3 78 fc 35 10 50 ce b6 c0 71 52 ae |.vk..x.5.P...qR.|
+000003b0 a5 f7 bf 8c 5e 5d c1 96 c7 92 6f f0 04 87 d9 a8 |....^]....o.....|
+000003c0 72 f4 9e ed 6d ab 28 42 7c c8 60 39 81 66 74 a1 |r...m.(B|.`9.ft.|
+000003d0 79 79 6a 59 02 29 b8 14 12 34 a7 96 8f e0 c1 d6 |yyjY.)...4......|
+000003e0 4e da e2 63 22 c1 60 b1 87 64 d3 80 b9 c4 df 9a |N..c".`..d......|
+000003f0 5f 2c 22 91 17 03 03 00 35 9a 62 4d a2 ba 27 31 |_,".....5.bM..'1|
+00000400 fc 8e 23 cc 5f f0 5c 8c 9b c1 b0 ae 7b b8 fa e2 |..#._.\.....{...|
+00000410 f3 af 6c 6c ac 86 1e e1 2b 9f 14 a1 f3 5f b5 f9 |..ll....+...._..|
+00000420 76 b6 dd 73 f5 6a 08 29 f1 29 9e 79 87 aa |v..s.j.).).y..|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 01 50 ef 68 27 d6 ec |..........P.h'..|
+00000010 76 00 e1 c6 ed 3c f6 a1 83 b4 4b 26 28 ba 0f d6 |v....<....K&(...|
+00000020 2a fd f0 4a 10 8f 9c ed 84 3f 0a 0e 5b 77 e2 7d |*..J.....?..[w.}|
+00000030 1e 03 2a 76 5b 2b 87 78 ad bd 45 8b 03 b3 8d e7 |..*v[+.x..E.....|
+00000040 b7 66 ca 5e 36 f8 53 87 90 3c 1a 33 46 1d 32 4f |.f.^6.S..<.3F.2O|
+00000050 f1 90 fb 36 da 96 1c 1a db 9f 9b e6 9f 85 f8 13 |...6............|
+00000060 7d e1 ab e1 ca c6 05 df 15 ea af dd 55 58 c7 5f |}...........UX._|
+00000070 de 62 1b 93 60 a4 fc 39 0a ef 95 bc 0c ca 8f 84 |.b..`..9........|
+00000080 98 0a 6d 5b fd c6 0c ad 02 7f 0c f8 b4 be fe 5a |..m[...........Z|
+00000090 fb 22 00 08 09 5d c7 47 76 89 e5 06 d1 90 5b e6 |."...].Gv.....[.|
+000000a0 63 64 06 28 37 d9 1b e9 0d 27 45 f7 72 30 d7 f2 |cd.(7....'E.r0..|
+000000b0 db 8e bf 95 97 29 43 e7 16 bf a0 59 9c fa d9 59 |.....)C....Y...Y|
+000000c0 a0 a6 9b 1f b5 74 80 87 d0 61 2f d5 a5 ac dd b2 |.....t...a/.....|
+000000d0 8d 27 fc e6 68 eb 07 b3 3d 97 a9 93 5b 35 99 e9 |.'..h...=...[5..|
+000000e0 ba 99 fe 49 d6 39 1a 0a 38 98 cd 47 b9 67 9b 9a |...I.9..8..G.g..|
+000000f0 77 65 45 f8 48 fb d3 1c 0f a2 2e af e0 29 68 bc |weE.H........)h.|
+00000100 81 24 3b 9b 36 0a ef 51 75 ff 61 6a d4 6c 59 42 |.$;.6..Qu.aj.lYB|
+00000110 54 31 47 e9 02 9e 58 33 9e 89 65 b6 65 db b2 81 |T1G...X3..e.e...|
+00000120 bd c1 f4 0a 34 eb f3 26 f5 8d 36 6d da 78 e6 88 |....4..&..6m.x..|
+00000130 00 8f 92 24 dc 76 e3 95 dc 13 b5 92 91 ee c0 82 |...$.v..........|
+00000140 cb 63 85 b6 59 67 dc 14 2e 2d 58 8e 56 7e 7c db |.c..Yg...-X.V~|.|
+00000150 2f 54 01 ed 17 8d 9a 97 22 39 7f 17 03 03 00 59 |/T......"9.....Y|
+00000160 a1 f2 0d 19 e7 d8 a8 6d cd ea f6 82 ee 5d 0a 55 |.......m.....].U|
+00000170 22 61 11 21 f7 b0 1d 86 a8 4d c2 e2 9b ac bb 87 |"a.!.....M......|
+00000180 a2 82 67 ee 78 76 9b e0 c0 00 85 bf 1e 2b ab e6 |..g.xv.......+..|
+00000190 f1 43 79 69 a0 3d 04 b7 d9 7f 31 c7 7a b7 4f 5c |.Cyi.=....1.z.O\|
+000001a0 9f 62 84 dc f4 6d a1 ce 3d ff 24 88 15 10 4a e6 |.b...m..=.$...J.|
+000001b0 5c 12 68 08 3c 55 a2 a9 d7 17 03 03 00 35 f4 d9 |\.h.<U.......5..|
+000001c0 9f 41 70 39 d4 88 2a 0b 43 c3 78 0f c2 42 48 b8 |.Ap9..*.C.x..BH.|
+000001d0 e5 26 ad e3 72 40 66 d7 a0 5e 5e 0c 6a af 1a 47 |.&..r@f..^^.j..G|
+000001e0 c6 5f 25 ce c9 13 77 60 8f 6e a7 9f bc e3 f9 58 |._%...w`.n.....X|
+000001f0 9c 12 cc |...|
+>>> Flow 4 (server to client)
+00000000 17 03 03 01 c2 80 69 97 9a 20 30 2a 1c f4 31 f9 |......i.. 0*..1.|
+00000010 0f cf f7 79 c0 01 e1 f3 35 f5 16 a0 33 d6 eb 21 |...y....5...3..!|
+00000020 44 db bc c6 c4 91 6b a6 75 da ca d3 63 78 47 8b |D.....k.u...cxG.|
+00000030 96 e5 6f 63 2c 77 c0 33 29 d8 3e ee bf 8e 6b d4 |..oc,w.3).>...k.|
+00000040 de f7 1b 0e e6 ae ce cd 17 0d 24 77 10 3d e4 89 |..........$w.=..|
+00000050 06 07 a3 77 68 ac 20 ec 0b ae 47 41 3b 80 4e 95 |...wh. ...GA;.N.|
+00000060 02 aa 13 36 19 03 06 1c 47 b3 f7 f0 4b 6d 5a c6 |...6....G...KmZ.|
+00000070 42 14 95 03 20 c7 46 96 42 d3 18 5a 40 bd a1 03 |B... .F.B..Z@...|
+00000080 b6 d2 8b f9 ff 2d d1 b1 3c 8a 34 af 23 64 31 7d |.....-..<.4.#d1}|
+00000090 46 47 21 b4 82 16 df a2 a4 0f 96 03 4b 38 3d 5d |FG!.........K8=]|
+000000a0 d0 d1 78 d1 6e 6a a2 95 c0 a7 e6 ee 07 eb 77 68 |..x.nj........wh|
+000000b0 35 78 72 3e df d9 4b e9 1b ab 34 99 2d fe 52 99 |5xr>..K...4.-.R.|
+000000c0 6e 57 63 13 39 ae 5e ce b6 43 21 07 fd fe b7 6d |nWc.9.^..C!....m|
+000000d0 8f 72 a4 f8 7e 0a 56 60 61 d5 5a d4 01 b3 47 8e |.r..~.V`a.Z...G.|
+000000e0 f0 48 cd 85 61 a3 d2 d1 eb ba 04 39 6b 5e 5f fc |.H..a......9k^_.|
+000000f0 e3 90 c1 cb 3f 40 30 00 5c 94 df bf 5b 89 6d ab |....?@0.\...[.m.|
+00000100 15 1e 72 50 ac 56 ee 16 7d 84 4c e6 0c 89 68 fa |..rP.V..}.L...h.|
+00000110 d5 8d 5f 09 85 25 5f 8c 70 df 0b b7 94 15 40 20 |.._..%_.p.....@ |
+00000120 b1 ff 41 50 5d 9f c6 8a 9b 7f 40 6f dc bd 4f 54 |..AP].....@o..OT|
+00000130 d8 1f e6 f1 44 00 11 97 45 ca 80 bc 15 eb 93 01 |....D...E.......|
+00000140 dd 54 c6 75 7e 08 b9 38 f5 4d 97 c5 50 56 97 3c |.T.u~..8.M..PV.<|
+00000150 3c 72 9a 33 7c 68 b1 73 2b 38 c7 b8 a8 3c 5d af |<r.3|h.s+8...<].|
+00000160 a6 3e 12 ef d1 c1 99 36 10 02 af 0c 5b 16 16 7a |.>.....6....[..z|
+00000170 f5 74 8d ac a4 0f 38 34 ee cd 08 50 e0 33 b0 e1 |.t....84...P.3..|
+00000180 52 e1 5d f2 7d c6 7b 64 c7 46 f6 9e d0 a2 cf 89 |R.].}.{d.F......|
+00000190 3c c9 ab 2f fb 8a f3 ba 78 e9 4c c5 2d 62 32 6b |<../....x.L.-b2k|
+000001a0 50 4c a0 7e d3 bb 2a 66 57 99 38 69 e8 77 ef 18 |PL.~..*fW.8i.w..|
+000001b0 24 af b3 cb e5 c0 37 a2 97 f6 00 d4 68 8a 71 af |$.....7.....h.q.|
+000001c0 24 a4 ab 19 07 3b c0 17 03 03 00 1e 60 b4 fc 15 |$....;......`...|
+000001d0 f9 9c b1 a1 60 1a ba f5 1b b9 c1 33 f1 8b e5 c0 |....`......3....|
+000001e0 48 77 4f 11 42 21 ad 8c d2 d6 17 03 03 00 13 5c |HwO.B!.........\|
+000001f0 db 07 5e 65 40 58 74 a4 7f ab 5f cc f0 9a 91 0c |..^e@Xt..._.....|
+00000200 17 3d |.=|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndGiven b/src/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndGiven
new file mode 100644
index 0000000..8ba88eb
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndGiven
@@ -0,0 +1,177 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 ca 01 00 00 c6 03 03 56 2e 3c 64 35 |...........V.<d5|
+00000010 b8 7d db 8a 3c f0 93 73 0f 64 8d 84 da b6 59 37 |.}..<..s.d....Y7|
+00000020 22 99 3f 69 16 56 16 39 a2 a9 58 20 7c d3 26 20 |".?i.V.9..X |.& |
+00000030 a0 dc e9 7a 07 71 02 2d 3b 27 85 16 fb 6e 26 e5 |...z.q.-;'...n&.|
+00000040 c3 67 e5 0b bd e5 50 8f bd 39 6f 2c 00 04 13 01 |.g....P..9o,....|
+00000050 00 ff 01 00 00 79 00 0b 00 04 03 00 01 02 00 0a |.....y..........|
+00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 16 |................|
+00000070 00 00 00 17 00 00 00 0d 00 1e 00 1c 04 03 05 03 |................|
+00000080 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................|
+00000090 08 06 04 01 05 01 06 01 00 2b 00 03 02 03 04 00 |.........+......|
+000000a0 2d 00 02 01 01 00 33 00 26 00 24 00 1d 00 20 f6 |-.....3.&.$... .|
+000000b0 96 06 42 18 9d ae a6 49 01 d1 a5 d3 ee c7 5a ed |..B....I......Z.|
+000000c0 26 20 c7 d5 e8 3c 58 21 1b 17 28 ea f9 e3 45 |& ...<X!..(...E|
+>>> 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 7c d3 26 20 |........... |.& |
+00000030 a0 dc e9 7a 07 71 02 2d 3b 27 85 16 fb 6e 26 e5 |...z.q.-;'...n&.|
+00000040 c3 67 e5 0b bd e5 50 8f bd 39 6f 2c 13 01 00 00 |.g....P..9o,....|
+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 43 8e 41 a4 04 13 |..........C.A...|
+00000090 01 08 9f 6e 1a fd 00 68 38 5c 93 d9 9a f7 1e 36 |...n...h8\.....6|
+000000a0 ea 17 03 03 00 3e 9f ae 80 ef f4 20 66 e7 44 fc |.....>..... f.D.|
+000000b0 4d a4 3f 0e dc bb 33 47 0f 13 96 fa 03 07 d6 6f |M.?...3G.......o|
+000000c0 cc 9f 3c fd 01 f5 87 d9 ec c9 d0 fc dd bf c8 5c |..<............\|
+000000d0 0b 3d aa a7 c6 1d 90 18 d9 a1 1a a0 a1 ea 49 32 |.=............I2|
+000000e0 9e 45 86 f7 17 03 03 02 6d 61 29 fe 45 7e 5c b3 |.E......ma).E~\.|
+000000f0 8a 73 f2 65 c1 90 4e 93 0d 84 b2 bd e4 46 93 c2 |.s.e..N......F..|
+00000100 52 3f 07 38 e7 23 db 25 5e 71 98 a9 7d fd e9 ef |R?.8.#.%^q..}...|
+00000110 3f 2c d8 9c ae 41 c4 d3 c7 9e d5 6e f0 0c 33 78 |?,...A.....n..3x|
+00000120 98 cf bf 22 3d 1f d0 f3 c8 a2 34 e8 ce 5e 0d 37 |..."=.....4..^.7|
+00000130 52 e2 b8 e3 50 ea 35 3e e5 59 a0 6d ed 9e 09 36 |R...P.5>.Y.m...6|
+00000140 59 20 33 08 a9 41 f4 72 aa 2d 0c b5 d6 96 d9 04 |Y 3..A.r.-......|
+00000150 1a f1 d8 45 ed 67 ab f9 15 fa 25 ef 6d 87 72 ad |...E.g....%.m.r.|
+00000160 f0 06 59 a5 8e 61 80 8b 28 f9 a0 df 5b b2 a2 3a |..Y..a..(...[..:|
+00000170 1c 91 43 18 f4 a2 f3 4e db dc 24 1b c3 0e 77 22 |..C....N..$...w"|
+00000180 83 ae 88 9f 8e 8d 48 38 f4 60 51 42 fa f2 a4 de |......H8.`QB....|
+00000190 33 78 35 d0 b6 01 3d 7a f5 54 68 51 fd 0e 4c 9b |3x5...=z.ThQ..L.|
+000001a0 92 7c a5 01 96 52 7e de 38 b9 b0 ee 60 1e aa eb |.|...R~.8...`...|
+000001b0 8c e6 b4 f4 7c 35 d2 0b 9b 83 94 ac ac ce 7e 58 |....|5........~X|
+000001c0 51 6e c3 ae 3b cd f5 85 8a 1e 43 78 19 ee dc a1 |Qn..;.....Cx....|
+000001d0 a3 d0 93 24 0d 3b 6a 4b cd dc 78 9c 0b 2f bc 41 |...$.;jK..x../.A|
+000001e0 46 2f 64 3c 23 95 04 8b 60 75 bf 4d 45 3b e4 1e |F/d<#...`u.ME;..|
+000001f0 9c 5b 1a 46 bb f3 4d a9 1b 59 33 b4 40 78 bd ff |.[.F..M..Y3.@x..|
+00000200 30 7d d4 cc 5e 83 03 de 8d a3 a6 27 b4 bc 12 6e |0}..^......'...n|
+00000210 5e f2 88 e8 b6 60 f3 01 e8 4a 53 c7 a9 fc a1 cc |^....`...JS.....|
+00000220 27 45 c1 06 90 38 9a fb 1b 2a 9e ed 9e f6 19 85 |'E...8...*......|
+00000230 dd f7 8a 7f 95 08 3a 25 c0 5b 63 96 44 71 c2 16 |......:%.[c.Dq..|
+00000240 9c e1 10 69 e5 6a 5c 4a e8 2a ed 6f bd de f5 98 |...i.j\J.*.o....|
+00000250 c0 a0 c5 54 7c cc 06 11 b2 54 1a c3 b4 46 c2 b4 |...T|....T...F..|
+00000260 97 d8 9c 7d f1 f3 d4 6f 3c a0 ef 18 c5 a6 e9 13 |...}...o<.......|
+00000270 e9 f4 9d bf 9b 25 a2 da c6 ba 7a 6d 91 fd 41 a4 |.....%....zm..A.|
+00000280 e8 88 e3 79 2c 99 df 4d 21 48 89 57 5a bf 2a 2d |...y,..M!H.WZ.*-|
+00000290 72 4e 1e 3a e8 c9 82 7b c0 ff 6b 7c e8 8f 41 bf |rN.:...{..k|..A.|
+000002a0 83 19 9e 96 d1 3f 2b 60 8f 7f 0b f8 6c 70 82 dd |.....?+`....lp..|
+000002b0 34 da 91 62 17 20 e9 99 2e e2 a9 9a 9d fd 5d f8 |4..b. ........].|
+000002c0 a5 c0 ac e8 a3 df 11 b5 df 2c bd e1 e8 0f 7e 0a |.........,....~.|
+000002d0 f2 47 4c 92 33 7b 6b 49 e5 30 31 8b 2e 16 81 3e |.GL.3{kI.01....>|
+000002e0 79 25 f7 d7 d2 8f 5e e6 e3 2d ed 0d e1 08 97 13 |y%....^..-......|
+000002f0 f3 ce 7d b1 36 0d 7c b0 4f 23 6b 12 ef 3a a4 8b |..}.6.|.O#k..:..|
+00000300 b5 d0 c9 ee 48 77 70 28 61 ff ad 49 f6 48 4c 37 |....Hwp(a..I.HL7|
+00000310 7b 00 c4 01 5d 8b 54 bc 44 5c 5f 98 6f 7d 84 84 |{...].T.D\_.o}..|
+00000320 c8 d0 55 88 f9 17 f6 02 f1 84 b6 3c 1a 03 e8 7b |..U........<...{|
+00000330 b9 4e 24 c6 d8 0a f6 8c b9 49 c6 10 38 53 e1 10 |.N$......I..8S..|
+00000340 8f 91 cd 39 9a 3a e8 c7 10 f3 c3 91 84 3c 8c a6 |...9.:.......<..|
+00000350 55 ab f4 f5 ab e7 17 03 03 00 99 e5 40 f6 35 34 |U...........@.54|
+00000360 2d 42 3e 7f e1 51 26 56 50 4e 60 b0 2f 65 e3 cd |-B>..Q&VPN`./e..|
+00000370 c7 08 0e 96 77 08 c7 f6 4f e6 70 90 bc 80 95 e7 |....w...O.p.....|
+00000380 b2 df 98 83 94 4d 9e 5c 8a af d3 45 da e9 d7 fa |.....M.\...E....|
+00000390 d8 d2 60 f8 b1 06 d9 27 64 45 4d e8 d3 07 8a bb |..`....'dEM.....|
+000003a0 72 7a c6 71 00 7e 8b b0 2b 7d d0 f7 ab 1a bf d2 |rz.q.~..+}......|
+000003b0 50 be a9 3a 0c 68 b8 48 9a 91 ee db 26 4d d3 66 |P..:.h.H....&M.f|
+000003c0 5b 00 ef c3 cc b8 f2 4e 1e 51 c7 9b 34 3c e3 01 |[......N.Q..4<..|
+000003d0 7f 75 4e 41 e4 56 34 ec 14 92 0f 1e 6d dd 51 9a |.uNA.V4.....m.Q.|
+000003e0 e0 8b 33 54 df 77 1f ff d3 72 67 4c 62 16 b7 f8 |..3T.w...rgLb...|
+000003f0 4f 8f f8 ee 17 03 03 00 35 b7 83 d2 27 a3 15 f2 |O.......5...'...|
+00000400 75 55 aa 06 8c 5f c4 fa 0f 43 88 c9 c5 e3 c7 36 |uU..._...C.....6|
+00000410 40 6b 35 0b 7e 60 a1 1e 48 ef 46 2c d6 e4 48 80 |@k5.~`..H.F,..H.|
+00000420 91 b0 e5 3b c0 58 5d fe 5d bd 0a 6c 19 ea |...;.X].]..l..|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 02 11 9e 9e cf 44 84 |..............D.|
+00000010 df e7 23 47 2d 4e 85 fa f2 02 2a 79 4d 3a 3d df |..#G-N....*yM:=.|
+00000020 48 95 2e d7 0d 3c d0 05 fc bf bb 23 0a 25 59 76 |H....<.....#.%Yv|
+00000030 fd 04 f8 f0 81 88 85 9f 99 f0 55 91 9a 79 8a 39 |..........U..y.9|
+00000040 f4 6e 49 92 be ed 1d d1 20 19 77 bc 55 9b b0 da |.nI..... .w.U...|
+00000050 d1 c4 9f b5 2f 5c 1a 60 38 e1 92 9b f9 a1 97 6b |..../\.`8......k|
+00000060 1b d0 d0 d0 05 7a 41 26 d4 6b 12 a0 b3 c6 33 13 |.....zA&.k....3.|
+00000070 4f 74 10 d6 91 fb b0 69 46 46 ca de 7c 05 d6 62 |Ot.....iFF..|..b|
+00000080 51 23 12 58 00 ff 25 8e c8 5f 54 85 f4 2f e9 f9 |Q#.X..%.._T../..|
+00000090 f1 1e 32 b9 f1 a6 fb 90 9b a9 65 d2 c9 ea a7 1a |..2.......e.....|
+000000a0 e8 c9 a8 bb 7e 3d 3f 03 62 fc f4 06 a4 a2 f7 41 |....~=?.b......A|
+000000b0 60 f5 f1 df 3e d6 31 51 f4 dc b1 d3 60 4b 84 4f |`...>.1Q....`K.O|
+000000c0 99 e2 9f b2 f0 d5 fd b2 f3 5c 24 5f 91 a6 94 cd |.........\$_....|
+000000d0 37 61 91 4e cc ae cd c1 b5 cc 58 5f 9a 91 a1 13 |7a.N......X_....|
+000000e0 23 42 8a c5 27 4c 66 32 69 9c 75 9f 2a ed 73 1d |#B..'Lf2i.u.*.s.|
+000000f0 29 2e 36 50 34 b4 80 d2 08 e6 9f c6 3e da df 9f |).6P4.......>...|
+00000100 e0 2a 08 88 47 b6 d3 ff f7 6c 6c 91 1a 8e 53 89 |.*..G....ll...S.|
+00000110 53 6c b8 d7 83 37 ab 03 59 e6 4f 41 42 af d4 f9 |Sl...7..Y.OAB...|
+00000120 ac 9d ae d1 77 f1 71 79 a0 16 c4 c7 b5 a6 a9 9f |....w.qy........|
+00000130 59 da 55 fb c5 88 8c 13 04 c2 06 39 8f ae 7e ca |Y.U........9..~.|
+00000140 99 ce cd aa 86 0a 00 bd 56 f1 98 d9 c8 d2 c1 c0 |........V.......|
+00000150 df 16 c2 6f 78 da 66 3f cc 43 c7 38 33 1b 3b 5b |...ox.f?.C.83.;[|
+00000160 f8 7e d8 b7 ef 4c 6d c7 f6 84 56 8d 76 f7 0d 83 |.~...Lm...V.v...|
+00000170 94 e6 ad c5 f3 05 5c f4 17 69 d5 83 98 c3 43 8e |......\..i....C.|
+00000180 9f a5 5c 7b 12 ea f4 1f 39 ce 0d 83 15 b1 e6 ce |..\{....9.......|
+00000190 c1 35 9b 8c ec c6 d2 d7 f9 02 36 90 24 f4 3a 70 |.5........6.$.:p|
+000001a0 ce bb 8d bb 4b b2 aa 64 f0 b5 c0 88 cc 06 e3 9c |....K..d........|
+000001b0 f7 70 64 fd 5d 48 f5 c8 07 48 c2 09 c4 07 56 b9 |.pd.]H...H....V.|
+000001c0 86 e9 d6 7b dc ac a5 00 2c 1d 80 8f 47 f2 c4 c7 |...{....,...G...|
+000001d0 ab dc 7b 41 7b 3d 47 db 09 12 02 9f 1b 63 e7 cc |..{A{=G......c..|
+000001e0 38 1d 33 56 e0 ae 63 7a 95 73 5f e6 da 13 53 49 |8.3V..cz.s_...SI|
+000001f0 5f 69 e9 ff 86 26 bd 9a dd be 5c 75 e7 69 66 b4 |_i...&....\u.if.|
+00000200 27 3f 79 d2 2e 8e 79 9e 89 42 58 20 a2 ca 8c 2a |'?y...y..BX ...*|
+00000210 37 b8 99 81 66 3a 31 66 1a 95 4c 47 17 03 03 00 |7...f:1f..LG....|
+00000220 99 66 08 07 06 6d 95 fe f1 72 2a 7c de 84 06 b0 |.f...m...r*|....|
+00000230 3d d7 d1 6b 47 0e 4d fb 9e ab 55 f7 71 c5 5d 11 |=..kG.M...U.q.].|
+00000240 cb c7 fb 45 90 9d 22 eb ec 03 d6 ce 8c 01 ff 81 |...E..".........|
+00000250 a2 90 23 1d 7a f3 cb 16 76 a5 05 57 77 f6 af f0 |..#.z...v..Ww...|
+00000260 29 6c 6c 39 9e 99 55 c0 38 c3 31 68 49 b3 bf cc |)ll9..U.8.1hI...|
+00000270 31 e2 6d a4 4c e7 99 53 2f 31 3f 05 2c 7c 1b 10 |1.m.L..S/1?.,|..|
+00000280 60 ce 8b 60 47 16 eb e5 8b be 1b 7a 95 b9 3c 60 |`..`G......z..<`|
+00000290 1c d6 b5 13 5f ad b9 bb 13 dd d6 08 8e 70 cb 2a |...._........p.*|
+000002a0 26 3e df ce 7c 21 e5 27 7e 27 ec 75 b6 47 a0 89 |&>..|!.'~'.u.G..|
+000002b0 2e e1 3c ab 0d 72 90 d1 d5 07 17 03 03 00 35 82 |..<..r........5.|
+000002c0 6b 48 4a 9a 63 16 07 8f b2 d3 4a 65 7d e0 c4 e8 |kHJ.c.....Je}...|
+000002d0 27 3e ce 4a 0a c8 63 e0 f9 70 98 c0 6a 12 39 ec |'>.J..c..p..j.9.|
+000002e0 e1 52 de 73 58 2d f0 7c bc 8d 41 16 be 89 a0 88 |.R.sX-.|..A.....|
+000002f0 56 e5 ef f6 |V...|
+>>> Flow 4 (server to client)
+00000000 17 03 03 02 83 ce c4 10 39 1a fe 62 a2 ff 27 6d |........9..b..'m|
+00000010 b7 e3 1d d6 8e b8 a2 7e f5 30 87 35 16 41 fb 04 |.......~.0.5.A..|
+00000020 3c 79 9e 02 9b 06 4c a7 ba 01 5b cf 94 bc c8 08 |<y....L...[.....|
+00000030 15 03 91 2c 24 34 17 a4 60 dc a5 72 04 5d 78 49 |...,$4..`..r.]xI|
+00000040 4c 2f e4 6a df 1c 38 fe b2 8c 61 5e a8 ac 3e d1 |L/.j..8...a^..>.|
+00000050 58 7d fe c1 e3 78 79 31 48 d2 74 c0 8d 17 97 6f |X}...xy1H.t....o|
+00000060 30 bb 8a 2c 8c d4 76 3d 3f f0 20 24 3d 5a 21 0c |0..,..v=?. $=Z!.|
+00000070 37 7b 14 45 e6 69 db ed 52 50 a0 77 e9 a2 84 59 |7{.E.i..RP.w...Y|
+00000080 0c 96 c1 ad 48 ed 8d 9f 00 4d f2 15 86 71 c0 fa |....H....M...q..|
+00000090 14 b9 77 cb 9f 04 d9 1b be da 68 8e 31 8f 25 14 |..w.......h.1.%.|
+000000a0 f5 43 bd e5 6e c5 10 ab f7 68 22 7f c2 ba 5c a6 |.C..n....h"...\.|
+000000b0 88 31 c0 a5 fb 63 05 95 52 b3 04 94 14 fe eb 0c |.1...c..R.......|
+000000c0 53 a0 c2 bf ae 58 e3 f9 84 22 6b ca 95 33 12 80 |S....X..."k..3..|
+000000d0 09 e2 97 b0 2b 4b ed fa 34 e1 5a b1 de 52 b1 2c |....+K..4.Z..R.,|
+000000e0 a0 aa 11 d6 fa 07 e1 41 ed 36 9f 9a 1a 56 18 b0 |.......A.6...V..|
+000000f0 ef e7 85 dc 5b 53 23 56 c2 ac 34 64 c8 9d 4b 49 |....[S#V..4d..KI|
+00000100 6d 29 7e 4b 73 4f 0b 8e 30 86 87 ea cf 1c dd 62 |m)~KsO..0......b|
+00000110 c0 a4 96 aa fe 41 e7 25 94 8e 08 b5 4d 42 26 d3 |.....A.%....MB&.|
+00000120 ba 84 98 bf 27 2b d5 3d 37 b9 b1 b5 24 33 e3 4d |....'+.=7...$3.M|
+00000130 3f 05 38 54 fe 2c 15 63 20 2e 70 c0 c6 da 0e 89 |?.8T.,.c .p.....|
+00000140 b6 99 07 db e3 7c 3e 58 d0 a3 2b 50 c4 f3 21 92 |.....|>X..+P..!.|
+00000150 62 e0 e9 b5 d4 7a 6b 23 a2 05 ef 9c f5 f5 05 57 |b....zk#.......W|
+00000160 cd d4 4d 0a 2f 17 ca ac fc 9d 7e 60 ec 3c 80 8c |..M./.....~`.<..|
+00000170 1f 99 da b7 f6 14 7a e1 86 76 50 8d f8 6b 92 24 |......z..vP..k.$|
+00000180 f2 b7 82 fa 3c 9b 14 af 0f 37 40 ae 7f 10 f5 0a |....<....7@.....|
+00000190 f2 0f 0f bd 01 b7 0a f7 b6 d0 7f cf bf e6 67 55 |..............gU|
+000001a0 cc 36 af a6 d8 c4 ca 80 c7 af 35 ff 6e 83 56 30 |.6........5.n.V0|
+000001b0 62 26 49 bb 1a 04 8b 39 10 7b 0f 09 19 2b 0f 95 |b&I....9.{...+..|
+000001c0 08 9d c8 85 3b 5d 8c 97 16 ae cd 92 00 d5 3e 50 |....;]........>P|
+000001d0 54 66 85 8f 42 9b 60 3d f8 99 ca c7 07 3b 51 18 |Tf..B.`=.....;Q.|
+000001e0 d5 20 37 57 35 0a d8 c6 13 0f 48 94 8f 50 7d 0e |. 7W5.....H..P}.|
+000001f0 5a f0 98 b2 5d 5f 46 fb ba 85 c8 4f ba 02 19 86 |Z...]_F....O....|
+00000200 0b ef 4a 04 49 1f 06 cd be dc d5 32 74 14 d8 60 |..J.I......2t..`|
+00000210 17 a5 b5 a2 70 8e b1 75 29 bc e0 02 e0 a2 1c 7b |....p..u)......{|
+00000220 58 cd 96 69 84 0f 95 7b 78 3e 09 72 a6 e0 50 7e |X..i...{x>.r..P~|
+00000230 76 b0 7b 44 11 9b b8 7e 7d 09 49 91 75 5b 9b 6f |v.{D...~}.I.u[.o|
+00000240 42 a4 e6 54 4d c6 21 65 c4 64 7d c6 29 74 13 8d |B..TM.!e.d}.)t..|
+00000250 69 5f 20 8c f1 88 e8 1e 2d c3 13 d5 f5 52 70 24 |i_ .....-....Rp$|
+00000260 de ec 64 c7 00 3f 57 e2 3f c4 23 fe e9 65 e6 d9 |..d..?W.?.#..e..|
+00000270 92 ae f0 2f 05 4d 01 72 be 0d 7d c0 f4 30 ac 69 |.../.M.r..}..0.i|
+00000280 3c 7c c1 72 c1 b7 c4 c9 17 03 03 00 1e 73 8f 48 |<|.r.........s.H|
+00000290 cf 34 35 31 9b 63 59 59 1b 23 e1 6b b2 3a 0f df |.451.cYY.#.k.:..|
+000002a0 21 69 8e 73 1a 61 09 5b 82 c7 78 17 03 03 00 13 |!i.s.a.[..x.....|
+000002b0 4f a0 ab 25 3f a4 85 9e 78 58 69 d2 2c c3 b6 df |O..%?...xXi.,...|
+000002c0 32 4a 7f |2J.|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedNotGiven b/src/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedNotGiven
new file mode 100644
index 0000000..b839c95
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedNotGiven
@@ -0,0 +1,103 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 ca 01 00 00 c6 03 03 4a ea 7e 77 82 |...........J.~w.|
+00000010 17 37 46 db 49 14 d2 41 e4 14 b0 46 20 9d 50 45 |.7F.I..A...F .PE|
+00000020 d1 75 08 82 2b 8d bc 9a 75 e3 71 20 ce 77 9a 79 |.u..+...u.q .w.y|
+00000030 98 24 bc 15 be ac 30 fe 66 35 ab 51 be bd b4 fa |.$....0.f5.Q....|
+00000040 6f 53 1f e9 5f 54 58 75 ce 94 f9 47 00 04 13 01 |oS.._TXu...G....|
+00000050 00 ff 01 00 00 79 00 0b 00 04 03 00 01 02 00 0a |.....y..........|
+00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 16 |................|
+00000070 00 00 00 17 00 00 00 0d 00 1e 00 1c 04 03 05 03 |................|
+00000080 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................|
+00000090 08 06 04 01 05 01 06 01 00 2b 00 03 02 03 04 00 |.........+......|
+000000a0 2d 00 02 01 01 00 33 00 26 00 24 00 1d 00 20 e0 |-.....3.&.$... .|
+000000b0 64 7e 58 b6 e7 32 fc c9 d6 3e f7 e0 f5 6a 9c 3a |d~X..2...>...j.:|
+000000c0 e6 8f 83 d7 1c 27 62 72 71 06 71 de 49 96 05 |.....'brq.q.I..|
+>>> 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 ce 77 9a 79 |........... .w.y|
+00000030 98 24 bc 15 be ac 30 fe 66 35 ab 51 be bd b4 fa |.$....0.f5.Q....|
+00000040 6f 53 1f e9 5f 54 58 75 ce 94 f9 47 13 01 00 00 |oS.._TXu...G....|
+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 d0 8f 0a 7e 6c 33 |.............~l3|
+00000090 0b be 2a 24 0e fc af df 6e 7d ad 22 28 82 77 60 |..*$....n}."(.w`|
+000000a0 3d 17 03 03 00 3e 8f 87 8f f1 5a f6 6f eb eb d9 |=....>....Z.o...|
+000000b0 da aa fc 3c 6d ac 73 94 a3 13 5f fe 01 bb 75 eb |...<m.s..._...u.|
+000000c0 ce d5 75 68 39 3c 0b 3c 5d ab 3f dc eb 6d 30 79 |..uh9<.<].?..m0y|
+000000d0 25 35 a8 2b 72 57 e4 9f 6f 4a 1e 03 74 eb 04 f9 |%5.+rW..oJ..t...|
+000000e0 c4 4f c1 46 17 03 03 02 6d 50 d5 4a 67 1e a7 43 |.O.F....mP.Jg..C|
+000000f0 50 f5 b9 55 8d 57 a3 0e e4 b0 ae 6c 5b ca f9 d7 |P..U.W.....l[...|
+00000100 f7 22 34 92 72 76 a4 5b c4 c7 0a 75 cc 97 0c 03 |."4.rv.[...u....|
+00000110 37 25 04 65 a6 fc da a8 fb 8c ef f1 25 d6 4b f6 |7%.e........%.K.|
+00000120 ed d5 80 2b 10 b2 0b 31 f5 33 d7 df a7 9b c7 6e |...+...1.3.....n|
+00000130 52 f6 ed ac e0 20 1e f2 93 11 b7 bd b0 0d 5e 41 |R.... ........^A|
+00000140 be e4 b5 e4 a1 6d 21 45 27 1d 5e 65 fe 2c e9 f4 |.....m!E'.^e.,..|
+00000150 97 5c 45 5b 23 5a 8c dc 29 64 61 28 48 cf ae 3f |.\E[#Z..)da(H..?|
+00000160 2c 21 b1 68 9e 09 74 76 77 65 f4 85 07 dc f3 0e |,!.h..tvwe......|
+00000170 27 97 4d 60 47 35 31 13 92 15 90 f4 ca 24 84 6e |'.M`G51......$.n|
+00000180 da 91 13 a3 37 54 4e 52 d4 9c 2f 82 6e 76 fd d7 |....7TNR../.nv..|
+00000190 81 29 fa 76 ac be 32 04 0d 7e d0 09 b0 47 ff 6d |.).v..2..~...G.m|
+000001a0 37 32 6d 2c 8e d3 06 94 da 3f 20 87 56 f8 4a 2f |72m,.....? .V.J/|
+000001b0 d6 75 4d 90 5c c1 e5 f6 82 c4 3c d9 da a2 95 0a |.uM.\.....<.....|
+000001c0 4c 36 59 a9 10 50 a0 0d 61 06 4f 65 6e 64 bb 29 |L6Y..P..a.Oend.)|
+000001d0 42 9f 62 81 65 54 22 cb 4c a5 95 1b 2a 49 18 2f |B.b.eT".L...*I./|
+000001e0 fc 54 b4 38 27 3f cf ab b0 97 3e 17 8b ae 98 a0 |.T.8'?....>.....|
+000001f0 50 76 d6 79 39 e8 25 bc 3b d9 5a a4 a8 5e 08 6a |Pv.y9.%.;.Z..^.j|
+00000200 1c 48 b1 11 f0 d9 b9 48 39 e1 23 db 41 8c bf bd |.H.....H9.#.A...|
+00000210 20 27 7b 0c 89 10 1f b0 ae 70 18 9a 7f f2 b4 1d | '{......p......|
+00000220 20 cd 6d 80 38 00 a4 33 de 22 ef f6 42 52 c7 66 | .m.8..3."..BR.f|
+00000230 83 4a 67 18 6b a6 38 27 d3 40 cf a2 a9 3e 58 06 |.Jg.k.8'.@...>X.|
+00000240 91 a7 36 08 29 10 4d 8f 1b f9 7c 5a 17 05 81 b9 |..6.).M...|Z....|
+00000250 4b 60 48 40 49 73 63 8a ef 9f f2 9e 80 85 57 fa |K`H@Isc.......W.|
+00000260 0a b8 72 83 f3 26 fa 07 ae d2 47 99 b5 a6 5d c5 |..r..&....G...].|
+00000270 1e b5 fc ea 0f 17 f8 ba e2 5c 7d 59 70 53 2e 23 |.........\}YpS.#|
+00000280 f7 55 75 cb de 82 dc ca b1 bf 3f 5f 7d 7d 92 3c |.Uu.......?_}}.<|
+00000290 29 29 64 30 74 0a 01 0b c0 95 db 45 fe 20 be 38 |))d0t......E. .8|
+000002a0 c5 87 b7 e4 a9 93 63 67 6b 9a 2f 24 9e 62 8f 1d |......cgk./$.b..|
+000002b0 bd 8c 4a d4 b0 0f 95 2f 56 b2 1c e8 5a 58 81 2e |..J..../V...ZX..|
+000002c0 b5 b5 b5 f2 1b 7f 6c 39 58 75 51 dc 83 2a 59 0b |......l9XuQ..*Y.|
+000002d0 78 5e 22 7e af ee 59 af b9 8f dc 65 97 af a5 b5 |x^"~..Y....e....|
+000002e0 b8 50 af 35 51 30 e7 0a 75 e2 d0 33 e2 fb f4 b1 |.P.5Q0..u..3....|
+000002f0 99 cd 5f 72 6b a9 f8 85 a1 a5 19 7e 2b 91 01 19 |.._rk......~+...|
+00000300 09 dd 88 6e a7 d6 54 57 cd ef d0 97 6a 68 d9 6e |...n..TW....jh.n|
+00000310 52 38 ef a5 fa 84 63 70 f0 6d 64 ec 66 1a c9 b5 |R8....cp.md.f...|
+00000320 78 ba 17 74 f4 b4 2b a2 fe 9a 7f 38 b8 5e 8b 56 |x..t..+....8.^.V|
+00000330 a6 7b 2c 92 7f db 58 c8 fa f9 2d 6b 00 25 dc 0a |.{,...X...-k.%..|
+00000340 aa 13 e8 40 f3 fd 47 23 f6 bf 1c 30 fc 91 18 95 |...@..G#...0....|
+00000350 ac a8 82 3d f5 ef 17 03 03 00 99 7e 30 4f f1 00 |...=.......~0O..|
+00000360 1e dd eb c6 54 d2 f5 f7 21 aa 6b b0 83 0c fa 8b |....T...!.k.....|
+00000370 12 af ac 15 3e 54 b6 1c 85 9b 0c 80 02 d8 e3 5f |....>T........._|
+00000380 36 57 64 fe 7a b8 31 d0 aa 59 f1 e6 af e0 27 c5 |6Wd.z.1..Y....'.|
+00000390 b8 d8 2f ab e0 cc c3 02 18 73 30 36 b5 2a 0d 12 |../......s06.*..|
+000003a0 a4 45 e6 c3 79 9f 54 cb 51 61 1a b8 aa 87 45 43 |.E..y.T.Qa....EC|
+000003b0 8e 93 58 66 f2 97 cb 3b 44 df ae 93 17 de 22 99 |..Xf...;D.....".|
+000003c0 3c b4 9d 21 a6 db 03 ce 7b fb 67 b9 6e fb ab 50 |<..!....{.g.n..P|
+000003d0 f8 33 9f 20 a0 fb e9 54 bb 62 16 19 d6 df 8c fe |.3. ...T.b......|
+000003e0 3d 63 42 7c b0 72 2b 0d 87 1e f7 7d bb 59 ba f5 |=cB|.r+....}.Y..|
+000003f0 d6 e8 f3 57 17 03 03 00 35 9e 6f 39 92 2e 32 10 |...W....5.o9..2.|
+00000400 03 cd f0 28 2c 1a 32 77 19 c8 39 38 60 0c 28 b7 |...(,.2w..98`.(.|
+00000410 8c 3a d8 50 a1 44 e4 d6 c5 64 59 88 2d a4 23 c9 |.:.P.D...dY.-.#.|
+00000420 26 d1 96 0c c9 5d da 84 3e 8a 7d fe 80 77 |&....]..>.}..w|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 19 87 49 99 a6 d9 |............I...|
+00000010 ed cd f7 7a 75 14 e1 26 41 d2 6e 5c 79 a6 be 7c |...zu..&A.n\y..||
+00000020 5d 9d 44 36 17 03 03 00 35 1b 51 a9 b1 ce 11 ed |].D6....5.Q.....|
+00000030 95 47 34 b9 3d 2f 6e 27 b2 e5 31 54 7f e3 8a 11 |.G4.=/n'..1T....|
+00000040 fd 54 75 2c b6 8a 56 25 00 29 a7 5f 7a 1e 16 be |.Tu,..V%.)._z...|
+00000050 16 e3 86 3a 72 84 0e bc 40 ef fd ad 18 33 |...:r...@....3|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 8b 69 2e 81 c4 4d 43 a6 1f 96 b7 8e |.....i...MC.....|
+00000010 87 4a 9b be 48 3c 31 18 98 f4 8c 04 24 b2 52 96 |.J..H<1.....$.R.|
+00000020 04 b5 12 7c 54 37 83 6d 51 42 c6 52 f4 a5 bc d3 |...|T7.mQB.R....|
+00000030 d1 c8 29 ab 4f e4 02 da 74 ec 8e 13 ad 03 f3 e0 |..).O...t.......|
+00000040 7f 44 58 6b c7 28 a5 6a 75 30 b8 b1 31 38 fe ba |.DXk.(.ju0..18..|
+00000050 e7 27 ae b3 e7 cb 5e 78 24 82 03 61 ba ae dd 4c |.'....^x$..a...L|
+00000060 c6 7b f3 45 cf 6f a8 dc 7d 5d 73 65 db ae dc 10 |.{.E.o..}]se....|
+00000070 ff 32 dc 4c b4 5e dc ce 4c 34 37 83 a0 0c d5 20 |.2.L.^..L47.... |
+00000080 f1 f6 81 42 bc 63 65 47 80 d0 d6 f3 08 aa e2 58 |...B.ceG.......X|
+00000090 17 03 03 00 1e 85 84 f3 e4 0f a8 24 c0 fe fa 2c |...........$...,|
+000000a0 8b 60 52 32 73 2b 95 e9 37 3d 1c bd 2f ee ff e2 |.`R2s+..7=../...|
+000000b0 70 13 df 17 03 03 00 13 65 2b 11 5f 50 7c 11 eb |p.......e+._P|..|
+000000c0 3b 06 75 23 28 13 ca 4a b5 fb dc |;.u#(..J...|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-ECDHE-ECDSA-AES b/src/crypto/tls/testdata/Server-TLSv13-ECDHE-ECDSA-AES
new file mode 100644
index 0000000..d2ed2ee
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-ECDHE-ECDSA-AES
@@ -0,0 +1,93 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 ca 01 00 00 c6 03 03 be 5b 8c 08 2b |............[..+|
+00000010 26 a0 41 0f e3 4e b6 5c 9f 5d 53 04 67 4a 1d a2 |&.A..N.\.]S.gJ..|
+00000020 26 3b 83 ab b4 7b c6 ec f8 a6 41 20 a6 de ad e2 |&;...{....A ....|
+00000030 0c fd 02 99 11 51 c6 be e8 52 df 0b e2 b3 6f fe |.....Q...R....o.|
+00000040 33 3e 2f 90 ac d2 e8 a2 53 8b d9 05 00 04 13 01 |3>/.....S.......|
+00000050 00 ff 01 00 00 79 00 0b 00 04 03 00 01 02 00 0a |.....y..........|
+00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 16 |................|
+00000070 00 00 00 17 00 00 00 0d 00 1e 00 1c 04 03 05 03 |................|
+00000080 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................|
+00000090 08 06 04 01 05 01 06 01 00 2b 00 03 02 03 04 00 |.........+......|
+000000a0 2d 00 02 01 01 00 33 00 26 00 24 00 1d 00 20 31 |-.....3.&.$... 1|
+000000b0 8e dd f4 7c cf 22 04 c1 c3 04 5c 24 49 db ae ab |...|."....\$I...|
+000000c0 0a d0 42 e8 70 51 c7 4f 88 e2 4e 2e 0b 80 65 |..B.pQ.O..N...e|
+>>> 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 a6 de ad e2 |........... ....|
+00000030 0c fd 02 99 11 51 c6 be e8 52 df 0b e2 b3 6f fe |.....Q...R....o.|
+00000040 33 3e 2f 90 ac d2 e8 a2 53 8b d9 05 13 01 00 00 |3>/.....S.......|
+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 cc d0 60 a1 dc d6 |............`...|
+00000090 46 57 69 3d df 0e 0f 7f a8 34 2d 87 71 84 16 54 |FWi=.....4-.q..T|
+000000a0 9d 17 03 03 02 22 cb 9c f9 3e a0 fd bf 07 03 7c |....."...>.....||
+000000b0 53 0c 15 22 0b 78 e5 02 36 e6 e7 6c 5b f9 aa 8d |S..".x..6..l[...|
+000000c0 54 8e b1 15 d4 23 05 12 5e 6e 0f 0f 65 77 bf b5 |T....#..^n..ew..|
+000000d0 32 28 0e 32 ca 9f 61 c3 37 23 87 e8 ec 19 1d ba |2(.2..a.7#......|
+000000e0 ef f5 18 eb ba 49 2d 86 a6 d1 f7 c1 9e 67 10 9f |.....I-......g..|
+000000f0 a1 d2 62 bd 4c 6c 5e a4 41 f6 1e fa fd e7 55 bc |..b.Ll^.A.....U.|
+00000100 16 ad 91 91 de 03 86 d7 e1 88 87 ab 0e f4 f5 bb |................|
+00000110 16 da 37 bb a4 ce 4e 6c 5f 88 41 f9 a2 90 9a 2d |..7...Nl_.A....-|
+00000120 5c 14 d5 01 28 06 a9 20 a4 ae 92 17 c5 95 b1 dc |\...(.. ........|
+00000130 02 a8 3f 3b a7 97 91 5a 4f 56 bb db b6 30 0d 80 |..?;...ZOV...0..|
+00000140 35 ac 91 6f 4f ba 1e 10 c6 fc d2 ca 96 e4 9d 1f |5..oO...........|
+00000150 2f 29 00 3a 11 b7 77 dd d5 ed 76 9f 67 a1 b1 0c |/).:..w...v.g...|
+00000160 5d 34 34 eb 42 49 23 15 49 12 24 24 73 be a9 65 |]44.BI#.I.$$s..e|
+00000170 99 b6 b4 3f 18 0c d1 32 26 eb 86 93 5c 0e e8 06 |...?...2&...\...|
+00000180 fb d7 9f 0e d9 26 14 47 b8 e5 67 8c c8 cb 0c 55 |.....&.G..g....U|
+00000190 61 70 a9 ce 0d 4e bf ca 40 9c e7 0d 2b 5d 54 b7 |ap...N..@...+]T.|
+000001a0 5a 64 50 e6 a1 c9 fc 47 7d e7 0a 13 36 8d 70 eb |ZdP....G}...6.p.|
+000001b0 68 65 e4 9b 9d 12 d1 d9 0d 32 72 59 0f 46 b2 e2 |he.......2rY.F..|
+000001c0 21 ab 13 d4 ab f3 6e b6 44 16 b8 85 bb dc f4 f7 |!.....n.D.......|
+000001d0 d6 ce 5c 9f c0 4c 28 8f 36 39 ec 29 c7 33 bd ea |..\..L(.69.).3..|
+000001e0 2d 10 16 84 50 c5 18 5b 2c a3 99 bb 3b 0b 70 66 |-...P..[,...;.pf|
+000001f0 72 9a 83 01 06 2a bf 4a 60 c5 5d 41 a1 f0 92 bb |r....*.J`.]A....|
+00000200 3b 2a 1a 41 3a 57 c3 22 13 2c b4 7b 3e 47 52 ea |;*.A:W.".,.{>GR.|
+00000210 79 8a bf ef 2e 2c f7 89 c7 36 5a df 38 c2 04 b6 |y....,...6Z.8...|
+00000220 6f 96 cd 7c 01 b3 e3 cd 4a 83 56 40 06 58 8a 7c |o..|....J.V@.X.||
+00000230 8c 75 df b6 b8 76 63 71 89 72 0a 64 de 23 7d 50 |.u...vcq.r.d.#}P|
+00000240 77 a8 f6 a0 81 9d e9 ed 81 5e 20 c8 9f 65 3c 95 |w........^ ..e<.|
+00000250 cf ed 99 80 71 06 5e 00 46 0d 0c 22 b3 88 f0 c5 |....q.^.F.."....|
+00000260 33 3e 13 6b f2 07 9c db 20 31 9c 8d ea d7 73 e8 |3>.k.... 1....s.|
+00000270 00 e1 2b f4 c8 d7 34 37 4a 98 b9 4d 28 db 15 8a |..+...47J..M(...|
+00000280 af 53 14 3b 02 54 a3 0b 5f 10 ff 5d 20 1c 19 ae |.S.;.T.._..] ...|
+00000290 6b 8a 99 a5 8f e0 ac dd c1 ba 1f 85 56 a3 94 bc |k...........V...|
+000002a0 79 03 5f d5 dd e1 8e 62 b7 82 fa 92 c3 d5 8a fc |y._....b........|
+000002b0 6b 17 24 d9 af db 3d 9c 0f 51 82 3d a2 ec 5f 9c |k.$...=..Q.=.._.|
+000002c0 dc 69 a5 ce db d8 8b 87 17 03 03 00 a3 69 cd 7b |.i...........i.{|
+000002d0 9f ac ad 72 11 b2 5d ee 19 63 d0 35 12 6d 5e 3f |...r..]..c.5.m^?|
+000002e0 81 a8 18 4a d4 09 f3 80 38 4a 31 08 3e a0 4c 78 |...J....8J1.>.Lx|
+000002f0 48 08 e9 90 ba e7 2a b4 73 2e 2b 2b 15 60 ce 09 |H.....*.s.++.`..|
+00000300 7d df 49 31 e1 9d ff 92 1d b4 af 2e 8c f8 a6 2e |}.I1............|
+00000310 93 d7 b9 10 69 10 7f 04 0d 8d e2 37 09 a7 d0 2a |....i......7...*|
+00000320 ac ea 51 49 50 1d 1c 54 7f b9 15 ad 8c 77 ef 1d |..QIP..T.....w..|
+00000330 a6 59 a3 bf b2 53 f7 6c 21 92 e0 36 c5 0d 61 94 |.Y...S.l!..6..a.|
+00000340 be 61 5e 77 25 35 df e4 5f 67 c1 c6 af 51 e4 ce |.a^w%5.._g...Q..|
+00000350 c4 28 c5 4e bc f6 c6 ba 32 dc 8e c7 45 f3 4d a1 |.(.N....2...E.M.|
+00000360 70 53 98 46 8f 39 c2 cc b7 fc f7 24 11 97 72 b3 |pS.F.9.....$..r.|
+00000370 17 03 03 00 35 76 be b6 7a 3f e3 08 7a a2 65 25 |....5v..z?..z.e%|
+00000380 fd 0b c3 87 be ba eb ca cb 3d c1 25 10 e0 7b 00 |.........=.%..{.|
+00000390 37 7a 52 9e d6 b2 e7 ba 8e 51 de 15 c4 e8 16 eb |7zR......Q......|
+000003a0 c6 21 92 42 b1 62 f4 ce 27 ba 17 03 03 00 8b 54 |.!.B.b..'......T|
+000003b0 03 de d7 a7 85 2f 4b 23 2d d5 3a b4 3d 3d f6 00 |...../K#-.:.==..|
+000003c0 ac ab bd 6f dd bf 9f 24 fb 1b d4 01 39 3e c0 87 |...o...$....9>..|
+000003d0 bb 32 ca f6 61 b2 ef 5d 9c 2c 1b a5 10 66 7b fd |.2..a..].,...f{.|
+000003e0 4b d0 03 dc 53 a9 0d 5a d5 c4 4c 25 9c 55 e6 f8 |K...S..Z..L%.U..|
+000003f0 d1 d8 49 dc 36 a1 92 ae f1 3e 2f 11 66 87 93 69 |..I.6....>/.f..i|
+00000400 24 2e 5d 6c f6 79 15 68 a8 99 2e 1a 9c e2 85 4e |$.]l.y.h.......N|
+00000410 5f d6 a8 3c 70 e1 67 cb df b2 1b ab 2b ed dc b6 |_..<p.g.....+...|
+00000420 64 f4 bc 22 35 20 7f ff 64 b3 be d9 eb a1 ab 5d |d.."5 ..d......]|
+00000430 d9 3b ae 30 46 76 70 48 04 43 |.;.0FvpH.C|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 46 8b fa 42 0d |..........5F..B.|
+00000010 fa 3e 9e 80 76 12 ce 73 ae 85 67 ee af 1e 25 6e |.>..v..s..g...%n|
+00000020 0b 46 4c bd 5a 46 8e 5c 27 7a 0a 8d d3 9c 3c 29 |.FL.ZF.\'z....<)|
+00000030 4c c8 08 78 ac 9f f4 7a 38 8d 49 6a 01 b6 f5 83 |L..x...z8.Ij....|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e c2 1a dc 0a cb 9a 11 f7 a1 c2 1f |................|
+00000010 54 7d 32 6f 0e 13 b6 6b 9f e1 c6 14 63 fc 18 b9 |T}2o...k....c...|
+00000020 81 53 44 17 03 03 00 13 c9 72 ae 5e 2b c1 6f 64 |.SD......r.^+.od|
+00000030 e0 70 47 15 b1 ec c3 25 00 7f 4e |.pG....%..N|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-Ed25519 b/src/crypto/tls/testdata/Server-TLSv13-Ed25519
new file mode 100644
index 0000000..dea3675
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-Ed25519
@@ -0,0 +1,75 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 ca 01 00 00 c6 03 03 08 d3 0c d5 aa |................|
+00000010 d7 b1 55 99 bc fa a7 17 09 ed 93 47 96 44 70 28 |..U........G.Dp(|
+00000020 03 b7 c6 40 ee 98 fe 30 83 86 ea 20 d0 89 76 54 |...@...0... ..vT|
+00000030 87 71 b7 9c b7 fd f2 19 15 5f 3b 39 c9 ad 6b 97 |.q......._;9..k.|
+00000040 89 6e c4 69 cc 83 b1 f0 e7 94 68 85 00 04 13 03 |.n.i......h.....|
+00000050 00 ff 01 00 00 79 00 0b 00 04 03 00 01 02 00 0a |.....y..........|
+00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 16 |................|
+00000070 00 00 00 17 00 00 00 0d 00 1e 00 1c 04 03 05 03 |................|
+00000080 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................|
+00000090 08 06 04 01 05 01 06 01 00 2b 00 03 02 03 04 00 |.........+......|
+000000a0 2d 00 02 01 01 00 33 00 26 00 24 00 1d 00 20 d8 |-.....3.&.$... .|
+000000b0 dc 54 00 21 d1 f5 6e 1b fc a4 44 4e eb 97 4d 0f |.T.!..n...DN..M.|
+000000c0 4a 5c ab 4c 27 72 23 69 72 7e 37 e8 bf 69 15 |J\.L'r#ir~7..i.|
+>>> 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 d0 89 76 54 |........... ..vT|
+00000030 87 71 b7 9c b7 fd f2 19 15 5f 3b 39 c9 ad 6b 97 |.q......._;9..k.|
+00000040 89 6e c4 69 cc 83 b1 f0 e7 94 68 85 13 03 00 00 |.n.i......h.....|
+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 6a 47 be 2b 06 13 |..........jG.+..|
+00000090 cf 8b 2f c5 ee d5 b0 5b c1 47 9a b2 5e a2 0d c5 |../....[.G..^...|
+000000a0 41 17 03 03 01 50 c0 1e e0 f5 55 6e 92 52 99 d8 |A....P....Un.R..|
+000000b0 62 06 9a 59 c7 b0 d7 5e c9 6d 76 a6 7a c9 55 fe |b..Y...^.mv.z.U.|
+000000c0 83 d5 84 fc 3c f0 02 fe 0f f8 b4 2e a0 45 29 cd |....<........E).|
+000000d0 37 ea 9d 2e 75 c4 06 1e 58 5f 21 31 4b 8c 5e 91 |7...u...X_!1K.^.|
+000000e0 83 c1 0d 2c 21 68 1b 05 85 d2 35 1c 36 ee 9c b2 |...,!h....5.6...|
+000000f0 14 52 49 d8 7f 59 80 9c 80 a3 d8 99 34 d4 5c 01 |.RI..Y......4.\.|
+00000100 03 6c 52 fe cf a0 0a 47 11 e8 45 7c 85 76 6e 6e |.lR....G..E|.vnn|
+00000110 29 1f af b7 97 bb fd 52 bd 4d 0a 4d 53 04 db 01 |)......R.M.MS...|
+00000120 5c 63 da c6 5a 7c d4 d8 fb ab bf fb bd 6f 64 58 |\c..Z|.......odX|
+00000130 8b e4 91 48 16 20 06 ca 2a 1f 5e 1e 33 c3 e8 cb |...H. ..*.^.3...|
+00000140 ab d6 98 25 a6 12 86 28 95 d4 0c 0d c7 1e e3 ba |...%...(........|
+00000150 f5 78 f9 10 97 60 19 8c 43 90 f6 aa 4d df da 91 |.x...`..C...M...|
+00000160 89 63 f4 38 18 e6 70 42 66 be f2 ec d9 85 88 ad |.c.8..pBf.......|
+00000170 59 c7 d1 57 3c 52 70 4a d4 db c8 b4 2c 37 7b 61 |Y..W<RpJ....,7{a|
+00000180 a9 4f 6a 4f 4a 64 04 7a 61 2b 01 f3 eb f0 c9 6a |.OjOJd.za+.....j|
+00000190 65 9f 67 e2 94 16 66 5f 4c 62 e8 17 38 18 17 0a |e.g...f_Lb..8...|
+000001a0 e2 bc 75 cf 32 71 a2 ab ae 2f 61 c9 a1 fa 59 1f |..u.2q.../a...Y.|
+000001b0 3f 4e 67 4e 0e 44 22 8a 59 04 cb 8e b3 77 fa 3d |?NgN.D".Y....w.=|
+000001c0 c9 60 90 73 91 f6 a6 91 33 88 0b eb 4f 0e 48 be |.`.s....3...O.H.|
+000001d0 f7 6f 30 7f 17 4b d2 ec 6e 21 ec a6 24 9d f8 85 |.o0..K..n!..$...|
+000001e0 07 b2 b3 86 02 9f 27 b9 e5 26 c1 ae 54 1b d3 19 |......'..&..T...|
+000001f0 ea cc bb c0 d0 e5 17 03 03 00 59 e2 56 da fa 80 |..........Y.V...|
+00000200 90 07 f7 93 2e d9 16 e1 43 c6 bf 35 4c b2 1d 83 |........C..5L...|
+00000210 ca a3 03 b4 d5 e0 b6 bc da b1 6f 91 a8 dc b5 a9 |..........o.....|
+00000220 1a 99 31 32 a8 61 d8 d2 2b 95 df 6f a3 64 6b 52 |..12.a..+..o.dkR|
+00000230 72 52 4f 7d f3 59 75 2f 36 4e 7f 91 59 50 69 95 |rRO}.Yu/6N..YPi.|
+00000240 70 51 d3 74 a9 a3 3f bd 9d 0c af 9a ec d3 a1 85 |pQ.t..?.........|
+00000250 38 24 8a 97 17 03 03 00 35 a9 9e 65 43 66 a2 22 |8$......5..eCf."|
+00000260 dc 0d f2 48 64 09 64 71 a8 e1 cb 2e b5 a1 f2 6a |...Hd.dq.......j|
+00000270 d0 c9 fa 32 60 14 6a 74 3a 5e 77 67 5b 90 3d 69 |...2`.jt:^wg[.=i|
+00000280 2d 1c af e2 6d 9d 91 aa d3 0d f9 33 a5 a5 17 03 |-...m......3....|
+00000290 03 00 8b 34 60 2b a5 83 76 9b 8d b9 3c 83 a1 8f |...4`+..v...<...|
+000002a0 07 80 3c 47 11 3b 4a 98 ec ba 6a e9 f2 f9 44 f9 |..<G.;J...j...D.|
+000002b0 96 98 a5 23 c1 62 16 43 eb 8b 37 5d a0 87 7d 7c |...#.b.C..7]..}||
+000002c0 13 07 67 e7 85 b3 da e3 99 58 db d6 6c 32 c4 a7 |..g......X..l2..|
+000002d0 60 f6 1c 7d a1 05 b5 97 9a cf 64 b3 28 09 00 b0 |`..}......d.(...|
+000002e0 af 3d 9f ce ac f5 c6 ac 01 d0 bb c0 30 d6 1a f6 |.=..........0...|
+000002f0 ec 70 d8 28 27 5a f0 24 c9 66 aa 56 59 64 7f f1 |.p.('Z.$.f.VYd..|
+00000300 b1 7c 66 2e 7d c4 01 08 47 da a3 99 98 8a b3 89 |.|f.}...G.......|
+00000310 4a 04 4b 84 ea 15 98 4e fe 10 0f b9 27 0c |J.K....N....'.|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 b0 21 d1 14 37 |..........5.!..7|
+00000010 3e 4f 3c 00 bf 99 4d da f5 22 f8 ab d0 9b 0e 59 |>O<...M..".....Y|
+00000020 33 1c 21 44 53 cf c7 31 16 df 3f fb a7 e2 f6 32 |3.!DS..1..?....2|
+00000030 2c a6 c2 9f 35 d6 8a cc 0a 82 6c 46 c4 55 b1 a8 |,...5.....lF.U..|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e 0a 98 f1 c8 c1 dd 02 e9 bd b4 99 |................|
+00000010 80 aa dd 14 1d 2a 73 e2 20 e3 55 14 f8 5b c8 b6 |.....*s. .U..[..|
+00000020 55 98 73 17 03 03 00 13 e6 93 11 04 c5 32 15 7d |U.s..........2.}|
+00000030 44 db bd 6c 6d 84 60 90 11 0c 52 |D..lm.`...R|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-ExportKeyingMaterial b/src/crypto/tls/testdata/Server-TLSv13-ExportKeyingMaterial
new file mode 100644
index 0000000..0b4f8c0
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-ExportKeyingMaterial
@@ -0,0 +1,98 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 ce 01 00 00 ca 03 03 4b 42 c7 99 9e |...........KB...|
+00000010 1a 3d 10 18 84 4b 27 8e b7 49 cd 95 34 42 54 6e |.=...K'..I..4BTn|
+00000020 fa 08 92 9b 43 f5 ca b4 57 44 2b 20 2d 75 50 cf |....C...WD+ -uP.|
+00000030 7c f7 1a 45 b0 6d a0 d9 29 ee ac 2c 1f c9 b3 96 ||..E.m..)..,....|
+00000040 2f ad 77 69 fc 92 65 75 af 9f ab da 00 04 13 03 |/.wi..eu........|
+00000050 00 ff 01 00 00 7d 00 0b 00 04 03 00 01 02 00 0a |.....}..........|
+00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 23 |...............#|
+00000070 00 00 00 16 00 00 00 17 00 00 00 0d 00 1e 00 1c |................|
+00000080 04 03 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b |................|
+00000090 08 04 08 05 08 06 04 01 05 01 06 01 00 2b 00 03 |.............+..|
+000000a0 02 03 04 00 2d 00 02 01 01 00 33 00 26 00 24 00 |....-.....3.&.$.|
+000000b0 1d 00 20 1c b6 f8 ed 5c d6 4c 45 22 bb 99 6f e9 |.. ....\.LE"..o.|
+000000c0 f8 d8 78 d7 6f a3 28 4f 06 16 f9 18 64 6c 30 23 |..x.o.(O....dl0#|
+000000d0 8a a5 14 |...|
+>>> 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 2d 75 50 cf |........... -uP.|
+00000030 7c f7 1a 45 b0 6d a0 d9 29 ee ac 2c 1f c9 b3 96 ||..E.m..)..,....|
+00000040 2f ad 77 69 fc 92 65 75 af 9f ab da 13 03 00 00 |/.wi..eu........|
+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 1b 8e de 2f c7 92 |............./..|
+00000090 de 8e 8c fa 0c 7a e5 1f ee 4c 4c d9 42 de 76 3d |.....z...LL.B.v=|
+000000a0 2f 17 03 03 02 6d e9 b0 9a 48 a0 96 b9 52 a1 88 |/....m...H...R..|
+000000b0 e4 03 62 85 7d 6b 08 37 dc 50 13 7d aa 99 ba 73 |..b.}k.7.P.}...s|
+000000c0 38 08 e8 64 cd 37 a4 44 9d 86 e3 5e 24 df d9 da |8..d.7.D...^$...|
+000000d0 0a 3b 97 9c 30 37 d9 99 0f a6 17 ef 5a e7 1b e9 |.;..07......Z...|
+000000e0 f6 5e c3 2b fc cc 8c 98 b9 7e 5f de bb 3c 19 9a |.^.+.....~_..<..|
+000000f0 59 75 e4 5e db 06 64 28 8d 26 88 41 b3 c2 2e 7f |Yu.^..d(.&.A....|
+00000100 fd 17 78 79 a0 ab 9a 48 7e 3d ef 78 c0 f1 9c 96 |..xy...H~=.x....|
+00000110 b2 21 b1 a8 18 d2 69 25 ad 51 8c 48 0f 66 28 a5 |.!....i%.Q.H.f(.|
+00000120 cf 76 16 c3 68 17 d9 33 f2 1f 5c 5f a1 19 08 e8 |.v..h..3..\_....|
+00000130 77 da d0 e0 c0 dc 4a 77 78 65 d1 3a 36 60 d9 0b |w.....Jwxe.:6`..|
+00000140 e9 f8 5e 4f 41 32 71 c4 a9 6c ca 29 da 25 ad 35 |..^OA2q..l.).%.5|
+00000150 da 14 79 21 6d cb 57 b8 49 03 59 d4 d8 8b 76 71 |..y!m.W.I.Y...vq|
+00000160 11 9d 5f 03 62 52 01 bb 69 77 45 19 ee 5b 11 8f |.._.bR..iwE..[..|
+00000170 75 65 49 e4 df cd 87 7c ab c9 7d 0c 1c ed b0 08 |ueI....|..}.....|
+00000180 c7 ba 08 2d a7 26 75 80 1d 1d 0c 7f 01 15 6f 82 |...-.&u.......o.|
+00000190 bf 5a a3 84 cd ac 91 56 cb d2 17 78 a5 b0 22 bf |.Z.....V...x..".|
+000001a0 d2 f3 1e 9f 8f f7 66 b7 a0 ec 28 f1 c5 b6 4e 24 |......f...(...N$|
+000001b0 63 46 88 d2 7a 84 11 8e ce 5d ab 5f e7 81 7d a5 |cF..z....]._..}.|
+000001c0 2f df f3 a6 2d 1f d9 e1 01 80 53 cf 4f 2c be bc |/...-.....S.O,..|
+000001d0 dd 68 cf fe c1 ce 15 ed 7d 59 e2 48 57 ac c6 73 |.h......}Y.HW..s|
+000001e0 b0 70 68 d1 a3 9a b0 f2 e2 07 2c ae 8a 5f 04 e9 |.ph.......,.._..|
+000001f0 f2 f7 d8 d4 63 92 7d a1 bd 8b 57 61 1f 13 48 7e |....c.}...Wa..H~|
+00000200 8a a2 5d 51 a8 fb 0a a7 02 73 c7 33 4b 9e 28 d5 |..]Q.....s.3K.(.|
+00000210 ea dd a5 84 21 c4 ba 0b 77 2c 08 f1 30 ff 92 9b |....!...w,..0...|
+00000220 8b c3 17 db 08 15 b3 f7 7b 01 8b 2c a8 e1 a7 f6 |........{..,....|
+00000230 a3 73 3d 5f 03 13 b8 e8 8c 19 a1 d6 7f fd f7 9f |.s=_............|
+00000240 37 ee ce f5 70 26 d2 18 39 54 c4 4e 4e e6 08 5d |7...p&..9T.NN..]|
+00000250 6b 7f cc b4 68 78 50 75 e2 f1 ec 73 93 a3 12 7f |k...hxPu...s....|
+00000260 e5 1a ec 55 f4 85 d0 10 12 29 fd b0 e1 3e d5 d1 |...U.....)...>..|
+00000270 a6 d1 25 48 01 45 82 ec 83 e0 83 29 7b 46 c7 a9 |..%H.E.....){F..|
+00000280 5c ca bf e9 28 f1 76 ef c5 72 5f 92 41 84 0e 64 |\...(.v..r_.A..d|
+00000290 af 6f f4 94 23 0a b5 2d 8b 56 66 a8 6b bb 4f a9 |.o..#..-.Vf.k.O.|
+000002a0 90 b6 d5 0a ab 76 7e 18 5c 3f 67 d5 7b c2 01 80 |.....v~.\?g.{...|
+000002b0 ce c8 8e d4 cd 86 0b 90 84 3a 68 82 f4 46 bc 72 |.........:h..F.r|
+000002c0 91 aa 92 46 e8 40 3e 40 21 c9 6a e5 d6 5a b2 01 |...F.@>@!.j..Z..|
+000002d0 d0 ef a7 f1 4e f6 e6 32 0c e1 07 19 cc fb 6e ff |....N..2......n.|
+000002e0 f7 53 35 81 4d 09 75 fb 42 42 41 18 8f be cf 71 |.S5.M.u.BBA....q|
+000002f0 43 20 e0 23 b6 39 1c ab 52 6e 8e bf b2 d3 59 16 |C .#.9..Rn....Y.|
+00000300 a8 15 d6 b7 cc cd ed 28 5a 8e de 64 ae 85 f5 0d |.......(Z..d....|
+00000310 7f 58 66 17 03 03 00 99 51 80 02 3d be 7a 45 b3 |.Xf.....Q..=.zE.|
+00000320 c3 f6 68 39 59 03 7b 2e 0c b3 22 f1 b3 6e a6 b2 |..h9Y.{..."..n..|
+00000330 64 f4 c6 77 7b 38 e0 94 97 2c 69 5b 29 63 e2 6b |d..w{8...,i[)c.k|
+00000340 d5 d4 d0 b4 c1 45 04 4c c4 19 6d 75 fd ef 3a 77 |.....E.L..mu..:w|
+00000350 f2 81 e4 8d 51 97 11 6b 6c ce b7 7a 11 fd 71 f7 |....Q..kl..z..q.|
+00000360 ee 67 c6 83 27 31 39 1f d4 d1 be b8 c2 06 11 e3 |.g..'19.........|
+00000370 34 36 ff f3 c7 e6 1d b5 87 6b cf 12 56 2c e8 03 |46.......k..V,..|
+00000380 83 bf 03 f8 57 fd 54 c7 32 19 b1 ba fe e4 58 05 |....W.T.2.....X.|
+00000390 77 6f 48 f4 af 2f 99 dd 47 a5 1a 30 17 2f 1d 25 |woH../..G..0./.%|
+000003a0 80 8c d7 cd 33 b7 db d0 9d 58 4c 5d ef 14 2f 7a |....3....XL]../z|
+000003b0 f2 17 03 03 00 35 04 7f e7 0b a2 30 a0 93 c2 f7 |.....5.....0....|
+000003c0 84 64 be 47 37 b0 46 8d 78 1b 69 b8 40 90 db 57 |.d.G7.F.x.i.@..W|
+000003d0 f9 e5 4e fa ba a4 3c 3e af db 67 18 2c 5f 32 77 |..N...<>..g.,_2w|
+000003e0 88 1e 30 85 b4 c0 46 c9 5c 85 ef 17 03 03 00 8b |..0...F.\.......|
+000003f0 a6 13 6e 2a 9f 36 5e 06 de 8a f8 95 68 0a 05 2b |..n*.6^.....h..+|
+00000400 e7 e7 fa 1b 2c 69 0c 30 75 a1 81 5a e6 e6 ab c5 |....,i.0u..Z....|
+00000410 22 b0 7d e1 ba 4f d7 75 89 88 23 35 be 36 9d 64 |".}..O.u..#5.6.d|
+00000420 3e 16 8d 5f 42 0f 6f 9a 78 8f 45 df 21 3e 4b 34 |>.._B.o.x.E.!>K4|
+00000430 6c ae ea c6 4a 71 0b d8 fd 70 f3 ac ce 68 3d f8 |l...Jq...p...h=.|
+00000440 62 d4 86 1e ac 3f ab 7d 36 83 80 4f c6 be 54 b7 |b....?.}6..O..T.|
+00000450 c1 1e bd 82 ea ad 42 9a f0 c8 79 77 24 27 dd 24 |......B...yw$'.$|
+00000460 68 b0 ca 17 a6 a2 14 2e 1f 57 54 d1 79 94 99 d3 |h........WT.y...|
+00000470 96 68 db c2 19 14 ce 89 04 c2 b8 |.h.........|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 96 8c 0d e9 39 |..........5....9|
+00000010 98 d4 ed 41 d5 fe f8 55 00 51 f0 71 6c 12 ed bd |...A...U.Q.ql...|
+00000020 13 40 7d 4e 85 ef 8b 88 80 88 c3 fd 55 41 cb 7f |.@}N........UA..|
+00000030 d7 96 04 3d f0 d5 26 c7 92 0a 64 bf 59 18 2a bd |...=..&...d.Y.*.|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e 90 ae 0a 4e 61 d1 14 64 90 3b a0 |........Na..d.;.|
+00000010 cd 33 67 f7 87 e6 93 3d 41 18 81 66 0c b2 26 f0 |.3g....=A..f..&.|
+00000020 76 94 cd 17 03 03 00 13 ef 96 85 4e 34 8a 64 ed |v..........N4.d.|
+00000030 5d 4a 58 e4 74 50 35 7c 47 a6 a5 |]JX.tP5|G..|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-HelloRetryRequest b/src/crypto/tls/testdata/Server-TLSv13-HelloRetryRequest
new file mode 100644
index 0000000..55ecaf4
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-HelloRetryRequest
@@ -0,0 +1,123 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 c4 01 00 00 c0 03 03 53 14 36 0d 63 |...........S.6.c|
+00000010 da e2 6a da b6 ce ab a7 79 a4 49 94 af fc b3 cd |..j.....y.I.....|
+00000020 18 bb c3 4e ca c2 40 07 01 2b 5c 20 90 fc 6b be |...N..@..+\ ..k.|
+00000030 26 4f 94 c1 f7 06 e6 ae e6 0f 67 2f c7 de b0 6b |&O........g/...k|
+00000040 4a f8 9c a2 43 b6 64 62 08 27 0b 45 00 04 13 03 |J...C.db.'.E....|
+00000050 00 ff 01 00 00 73 00 0b 00 04 03 00 01 02 00 0a |.....s..........|
+00000060 00 06 00 04 00 1d 00 17 00 16 00 00 00 17 00 00 |................|
+00000070 00 0d 00 1e 00 1c 04 03 05 03 06 03 08 07 08 08 |................|
+00000080 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 |................|
+00000090 06 01 00 2b 00 03 02 03 04 00 2d 00 02 01 01 00 |...+......-.....|
+000000a0 33 00 26 00 24 00 1d 00 20 a5 12 8a 90 4d a6 20 |3.&.$... ....M. |
+000000b0 36 c8 47 e0 0e 02 2e c3 24 dd f0 33 b2 aa 57 54 |6.G.....$..3..WT|
+000000c0 9d e7 c4 d7 7a f1 42 12 0e |....z.B..|
+>>> 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 90 fc 6b be |..^......3. ..k.|
+00000030 26 4f 94 c1 f7 06 e6 ae e6 0f 67 2f c7 de b0 6b |&O........g/...k|
+00000040 4a f8 9c a2 43 b6 64 62 08 27 0b 45 13 03 00 00 |J...C.db.'.E....|
+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 00 e5 01 00 00 e1 03 |................|
+00000010 03 53 14 36 0d 63 da e2 6a da b6 ce ab a7 79 a4 |.S.6.c..j.....y.|
+00000020 49 94 af fc b3 cd 18 bb c3 4e ca c2 40 07 01 2b |I........N..@..+|
+00000030 5c 20 90 fc 6b be 26 4f 94 c1 f7 06 e6 ae e6 0f |\ ..k.&O........|
+00000040 67 2f c7 de b0 6b 4a f8 9c a2 43 b6 64 62 08 27 |g/...kJ...C.db.'|
+00000050 0b 45 00 04 13 03 00 ff 01 00 00 94 00 0b 00 04 |.E..............|
+00000060 03 00 01 02 00 0a 00 06 00 04 00 1d 00 17 00 16 |................|
+00000070 00 00 00 17 00 00 00 0d 00 1e 00 1c 04 03 05 03 |................|
+00000080 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................|
+00000090 08 06 04 01 05 01 06 01 00 2b 00 03 02 03 04 00 |.........+......|
+000000a0 2d 00 02 01 01 00 33 00 47 00 45 00 17 00 41 04 |-.....3.G.E...A.|
+000000b0 de 5f 45 a6 5a fb df 47 33 52 cf 63 63 b7 e2 c1 |._E.Z..G3R.cc...|
+000000c0 f0 ad 4e b7 a3 09 7a 83 cf 58 cb 26 98 51 59 ee |..N...z..X.&.QY.|
+000000d0 9e 33 a4 39 0d 49 17 98 35 31 99 9c 5a 84 c8 e5 |.3.9.I..51..Z...|
+000000e0 8c d4 90 22 45 ef 65 3b 9d 85 0f 92 b0 ab 0e 8f |..."E.e;........|
+>>> Flow 4 (server to client)
+00000000 16 03 03 00 9b 02 00 00 97 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 90 fc 6b be |........... ..k.|
+00000030 26 4f 94 c1 f7 06 e6 ae e6 0f 67 2f c7 de b0 6b |&O........g/...k|
+00000040 4a f8 9c a2 43 b6 64 62 08 27 0b 45 13 03 00 00 |J...C.db.'.E....|
+00000050 4f 00 2b 00 02 03 04 00 33 00 45 00 17 00 41 04 |O.+.....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 17 03 03 00 17 41 5e 1d 29 7e 4d ad 56 1c e4 42 |.....A^.)~M.V..B|
+000000b0 9d 99 61 93 95 d3 7a 1c 9c b0 1b ba 17 03 03 02 |..a...z.........|
+000000c0 6d 62 fd b6 84 db 87 5f ec 30 bc df 0c 5d b7 f9 |mb....._.0...]..|
+000000d0 58 6b 7e ce 19 54 a9 0c 3f 66 f6 23 b6 36 19 a9 |Xk~..T..?f.#.6..|
+000000e0 ba e2 44 28 70 b9 35 14 fe 33 50 64 30 dd b1 35 |..D(p.5..3Pd0..5|
+000000f0 9c e5 f6 f5 66 09 be 05 82 c8 9c 7a 28 d1 6a 3d |....f......z(.j=|
+00000100 31 a3 9d 0b 5a 1c 9e f1 77 c8 be eb 71 a7 9d 63 |1...Z...w...q..c|
+00000110 20 18 ef 97 4b fb 60 4d 2f 31 49 b2 1c 47 30 eb | ...K.`M/1I..G0.|
+00000120 80 c1 e6 28 e0 67 a8 1b 8f 79 9f 40 ca 97 bd d9 |...(.g...y.@....|
+00000130 b9 cc 55 56 00 32 8d 76 76 88 be 62 42 e9 2f 53 |..UV.2.vv..bB./S|
+00000140 9b ab 56 98 e6 03 15 17 1a 2b 70 50 8a d8 ba 9d |..V......+pP....|
+00000150 ab 5a ea 68 ec 98 7a f5 c1 9b 21 f8 f3 0b 5d a3 |.Z.h..z...!...].|
+00000160 7a 70 ae ff 67 e0 e8 2d 97 e5 72 d7 c4 27 9b 8d |zp..g..-..r..'..|
+00000170 f8 47 dd 9e 15 2a 1e 38 eb 82 24 e5 85 55 ec a4 |.G...*.8..$..U..|
+00000180 22 ee 1f 9d c2 f3 1c 47 7a 26 0b 1a 4b d8 e4 58 |"......Gz&..K..X|
+00000190 ad b2 99 72 5b f8 97 33 f6 26 58 e3 58 1e 66 12 |...r[..3.&X.X.f.|
+000001a0 51 ba dc 66 bb c7 7d af 90 4b c2 79 2c b3 d8 34 |Q..f..}..K.y,..4|
+000001b0 2a d2 6b 37 71 88 e0 4a c3 16 50 81 21 e1 a7 6d |*.k7q..J..P.!..m|
+000001c0 42 e7 f5 86 7e b3 4b b8 9d bb dc 49 7d ce 6c 98 |B...~.K....I}.l.|
+000001d0 fd 87 2e fc 1a 17 34 12 90 a0 bc 06 46 7b e9 0b |......4.....F{..|
+000001e0 d3 aa f7 77 30 43 6e 5f 4e fa e3 b1 a6 c8 80 47 |...w0Cn_N......G|
+000001f0 16 71 a0 bc 9e d3 89 14 49 ca 9a 87 8b b0 3b c7 |.q......I.....;.|
+00000200 a7 f4 6d 2a cb 0a 5e 8a e5 f1 45 65 e4 51 da b1 |..m*..^...Ee.Q..|
+00000210 5c e2 88 90 46 e7 cb 01 0b 99 64 fe 5b b4 b3 e6 |\...F.....d.[...|
+00000220 aa 6f 59 25 25 79 2b 8e 6b 59 65 15 51 a1 8f a2 |.oY%%y+.kYe.Q...|
+00000230 f5 cd db df 63 fb 86 72 a5 9d 6c 7d b9 a0 e9 d5 |....c..r..l}....|
+00000240 c7 79 ca f1 3f c3 ed 72 29 3c 58 ed bd 4e 3a 27 |.y..?..r)<X..N:'|
+00000250 2c 40 34 82 47 62 3d bb 5a 90 70 cb 33 f6 f3 31 |,@4.Gb=.Z.p.3..1|
+00000260 3d 49 5f 9c 7e 21 7e cc 9b 09 38 3c e5 33 9f 11 |=I_.~!~...8<.3..|
+00000270 2e eb a0 d6 df cd 86 ef 3c 6d b8 d4 5c 8b b4 ce |........<m..\...|
+00000280 8a f4 ef f8 78 5e ad c2 ea 52 ed 30 a2 4c 50 d2 |....x^...R.0.LP.|
+00000290 8a 4e 9e 1b 2a e6 04 86 e2 b8 84 f3 fe 6e 34 78 |.N..*........n4x|
+000002a0 28 fb 97 d7 30 66 a7 20 57 c1 ca e4 0c 7f a0 2c |(...0f. W......,|
+000002b0 4e e1 87 ee 3f cc fe 18 a7 49 a7 70 45 94 73 8c |N...?....I.pE.s.|
+000002c0 66 b8 b1 54 58 1a 39 3d 16 40 da e5 e5 51 c6 07 |f..TX.9=.@...Q..|
+000002d0 bc 30 ff 6a 66 3c bf 92 bc 0c 5c b5 c8 b9 55 6b |.0.jf<....\...Uk|
+000002e0 26 f3 cd 4c ab 40 05 f5 8e 8d f8 55 b1 90 6a 93 |&..L.@.....U..j.|
+000002f0 d3 74 72 54 26 c0 1d 56 26 15 4c cf 63 4e 51 8c |.trT&..V&.L.cNQ.|
+00000300 6f 92 85 8c 24 78 1e 8f c4 cd 13 6b 42 6f 58 9a |o...$x.....kBoX.|
+00000310 77 da 6c 73 1f dc 03 ff 33 9c d9 66 af 06 1d 1a |w.ls....3..f....|
+00000320 fe 6f 13 3a 83 b2 dc ac 01 b4 e6 ca 5c 9e 17 03 |.o.:........\...|
+00000330 03 00 99 d2 6f 24 aa 51 a7 3d 2d fa 18 57 8e 7c |....o$.Q.=-..W.||
+00000340 43 4f da 6c 31 97 bb d7 6f 64 2a db 7c 76 41 11 |CO.l1...od*.|vA.|
+00000350 cc e9 0f ea e8 03 99 49 4e c4 2c 43 36 54 b9 61 |.......IN.,C6T.a|
+00000360 af d1 56 00 9a e4 f2 c2 6d cf e9 25 32 f5 34 b6 |..V.....m..%2.4.|
+00000370 08 45 0f 43 71 6f 88 3f 7a 07 68 0b 91 fd 15 c3 |.E.Cqo.?z.h.....|
+00000380 43 8a 9d c3 bf f9 56 3c 3d 07 62 d0 94 11 14 95 |C.....V<=.b.....|
+00000390 63 27 28 d2 94 07 ff 1f 2b 99 76 a8 03 b4 8b 8f |c'(.....+.v.....|
+000003a0 dd 56 d9 55 5d 4a 47 bf 77 25 eb 6a 2a ee 1c ea |.V.U]JG.w%.j*...|
+000003b0 e9 58 0b 17 a5 56 99 d7 b6 9e 2a 4e 9a e4 07 68 |.X...V....*N...h|
+000003c0 dd df ce fc 8f 16 66 c1 4f f7 4b 20 17 03 03 00 |......f.O.K ....|
+000003d0 35 f6 71 3a 27 56 09 70 a2 dd 9d 5e 24 09 54 ce |5.q:'V.p...^$.T.|
+000003e0 f3 6d f1 74 49 48 3e 2f 72 73 88 c7 fc 29 ec 3f |.m.tIH>/rs...).?|
+000003f0 fa 0f 96 72 46 7d 6b 2f ed 23 63 75 b7 26 f2 ea |...rF}k/.#cu.&..|
+00000400 77 0f 3a 68 1e ee 17 03 03 00 8b b0 54 d9 ec c4 |w.:h........T...|
+00000410 44 cb e4 f6 f2 cb 66 31 c7 d8 ef 45 bf 9c 03 c4 |D.....f1...E....|
+00000420 7c 3f 91 e1 cf e8 c6 e5 a8 12 f1 e0 72 6b a2 9a ||?..........rk..|
+00000430 f7 73 3d 13 3d 30 91 54 27 02 f7 ab a3 7e bb 5f |.s=.=0.T'....~._|
+00000440 21 a6 fa 09 98 39 7f 99 13 5a c5 c5 6c 7b d2 91 |!....9...Z..l{..|
+00000450 7c de 26 88 b9 17 bd b9 b2 9a 7c 01 35 ad 7b 3b ||.&.......|.5.{;|
+00000460 3d 15 33 9e 78 ea a1 df 94 80 fa e4 59 ef 49 06 |=.3.x.......Y.I.|
+00000470 31 41 8a 83 e9 98 37 e6 5a 69 f9 0a 7d 63 8e 6a |1A....7.Zi..}c.j|
+00000480 9c bd 5b d4 69 72 3d 82 c9 c0 11 d6 68 13 17 9d |..[.ir=.....h...|
+00000490 0e 32 48 bf 33 ab |.2H.3.|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 35 c6 da dd 4b 11 a3 87 cd fd f9 99 |....5...K.......|
+00000010 a6 0b 76 c0 00 89 e1 87 d1 2c 43 0b f1 74 e5 60 |..v......,C..t.`|
+00000020 49 94 5f d2 d9 b5 0b bd 6c d8 2c 84 4d 4f da 43 |I._.....l.,.MO.C|
+00000030 f0 33 dd 54 bd 0c d9 f2 71 82 |.3.T....q.|
+>>> Flow 6 (server to client)
+00000000 17 03 03 00 1e 6d f2 53 68 26 89 6e 4a 66 6a a9 |.....m.Sh&.nJfj.|
+00000010 12 9e 89 f0 be eb ff ed b4 f0 ca f2 b8 7a b2 5e |.............z.^|
+00000020 98 50 cb 17 03 03 00 13 ab 2b 9c 98 f0 1b 5c a2 |.P.......+....\.|
+00000030 f3 b2 a1 16 e0 74 eb 02 c4 7d d5 |.....t...}.|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-IssueTicket b/src/crypto/tls/testdata/Server-TLSv13-IssueTicket
new file mode 100644
index 0000000..7fe5184
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-IssueTicket
@@ -0,0 +1,98 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 ce 01 00 00 ca 03 03 9b 80 62 b8 bb |.............b..|
+00000010 fc 09 cc 19 31 91 f7 4b 8a e8 fc 69 45 33 bd 64 |....1..K...iE3.d|
+00000020 8c 88 6e 07 0d 33 e7 f2 ce 4b 46 20 81 23 01 a2 |..n..3...KF .#..|
+00000030 64 c3 6d 55 ee 3c f1 c5 16 48 cb a7 61 fe 15 57 |d.mU.<...H..a..W|
+00000040 fa 9e 36 f2 ad 5b 19 2e 73 b9 8f 57 00 04 13 01 |..6..[..s..W....|
+00000050 00 ff 01 00 00 7d 00 0b 00 04 03 00 01 02 00 0a |.....}..........|
+00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 23 |...............#|
+00000070 00 00 00 16 00 00 00 17 00 00 00 0d 00 1e 00 1c |................|
+00000080 04 03 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b |................|
+00000090 08 04 08 05 08 06 04 01 05 01 06 01 00 2b 00 03 |.............+..|
+000000a0 02 03 04 00 2d 00 02 01 01 00 33 00 26 00 24 00 |....-.....3.&.$.|
+000000b0 1d 00 20 e2 26 c1 8e 1b 73 8a e1 ec 95 a0 01 1a |.. .&...s.......|
+000000c0 15 98 9d a2 d0 ac 02 4d 14 a9 8d 42 3a 68 e6 d2 |.......M...B:h..|
+000000d0 9f 09 49 |..I|
+>>> 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 81 23 01 a2 |........... .#..|
+00000030 64 c3 6d 55 ee 3c f1 c5 16 48 cb a7 61 fe 15 57 |d.mU.<...H..a..W|
+00000040 fa 9e 36 f2 ad 5b 19 2e 73 b9 8f 57 13 01 00 00 |..6..[..s..W....|
+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 c9 df 69 cf ca 6d |............i..m|
+00000090 b4 7b 81 46 34 f6 0c e3 5b 88 92 91 24 80 93 03 |.{.F4...[...$...|
+000000a0 f8 17 03 03 02 6d b9 46 75 89 0d 64 9d 7b 9a 2a |.....m.Fu..d.{.*|
+000000b0 48 78 eb 93 8d c8 4d 16 fb 7e 95 77 ff 06 d2 aa |Hx....M..~.w....|
+000000c0 30 34 cc 9e 5a f3 c1 b6 d5 17 fb b2 15 bb eb 11 |04..Z...........|
+000000d0 28 5a 2f 6b d6 87 8c c6 17 00 4d 58 d1 27 af 88 |(Z/k......MX.'..|
+000000e0 39 1f db 2e 0a 5b 36 8f a1 26 a9 00 be ba 5a b2 |9....[6..&....Z.|
+000000f0 65 fa 14 8a 53 3c 6a 9e b7 73 1f fa 80 fd 03 c2 |e...S<j..s......|
+00000100 0e 53 27 25 42 fb 4a 75 9e 18 80 09 d0 b5 dc 37 |.S'%B.Ju.......7|
+00000110 a7 d3 d6 9d a1 a0 4e bc 1a a6 c8 78 e4 b9 e2 02 |......N....x....|
+00000120 00 2a 4a c9 e5 8d 5a e3 83 60 ae 74 11 06 33 93 |.*J...Z..`.t..3.|
+00000130 5d ed 89 6c 17 6b a4 c4 45 06 d0 8d 64 9a 37 eb |]..l.k..E...d.7.|
+00000140 34 22 1d 70 b0 96 74 8b ba 17 ad bb 42 fd c7 30 |4".p..t.....B..0|
+00000150 16 6a cc dd a9 97 1d 0a 34 1e f9 52 3b e8 49 e7 |.j......4..R;.I.|
+00000160 41 ab 8a fb 29 b7 22 93 c1 ea 92 29 45 a1 e5 46 |A...)."....)E..F|
+00000170 92 98 30 5f 2e f1 90 f4 a0 cb b3 0a 64 16 be 4c |..0_........d..L|
+00000180 18 2c 83 ef 7b 7b e8 74 6f cf 99 c3 47 37 fd c4 |.,..{{.to...G7..|
+00000190 a7 57 ba 2b d2 69 01 71 47 37 ac bd 7d a3 d7 cf |.W.+.i.qG7..}...|
+000001a0 ce e5 bc d3 75 f8 d3 d8 e7 b4 57 81 8d 92 05 04 |....u.....W.....|
+000001b0 12 b1 76 d0 9a 5c d6 76 54 9a 99 03 19 ee 92 ff |..v..\.vT.......|
+000001c0 8e 12 50 50 d5 cb 2c d4 df 0b 6b 43 54 59 39 17 |..PP..,...kCTY9.|
+000001d0 0e 3c 6a 87 6c 34 3a ec fb 87 88 bc df aa fc 08 |.<j.l4:.........|
+000001e0 80 c8 c7 b8 5d 6e dc f9 e3 d3 15 36 5e db 64 cb |....]n.....6^.d.|
+000001f0 6d f5 09 87 3e f8 b8 7c e0 89 7c 9b ca 3d bf 68 |m...>..|..|..=.h|
+00000200 de 8f 68 89 02 c5 67 5a ff 71 02 34 00 96 15 d4 |..h...gZ.q.4....|
+00000210 01 6d 6d 31 dc 77 62 b8 3e 72 b0 ab 4d da ea 6d |.mm1.wb.>r..M..m|
+00000220 9a 2d 0e 5d b7 8e cc bc 5c 0a b3 13 5b 8c 86 de |.-.]....\...[...|
+00000230 e3 1a 70 cd 9d 63 4c ea e2 56 f9 3b 05 8e 0b 96 |..p..cL..V.;....|
+00000240 16 c9 a4 67 09 fe 88 ae 4b 8c d1 b3 19 10 0f fd |...g....K.......|
+00000250 07 33 86 3a 6a 54 ef 69 27 02 bf 76 7c 05 ab 40 |.3.:jT.i'..v|..@|
+00000260 e6 43 9e 3c 9b ee 0c d8 14 ff c1 09 a6 73 65 66 |.C.<.........sef|
+00000270 54 1f a9 9c af fb 73 c4 cb 8c a7 3b c7 23 d6 99 |T.....s....;.#..|
+00000280 a7 c6 af a1 62 54 30 f7 18 30 23 7d c0 e6 d3 fe |....bT0..0#}....|
+00000290 a0 58 f1 c5 5e 37 70 90 47 73 45 b0 70 a9 45 1c |.X..^7p.GsE.p.E.|
+000002a0 87 9f 0d ed bc ee 65 c2 50 91 55 a3 f9 eb 71 e8 |......e.P.U...q.|
+000002b0 5a ee b3 3f 79 75 3a c9 98 7d 57 fc 51 78 b5 e5 |Z..?yu:..}W.Qx..|
+000002c0 33 90 f1 d0 74 86 1a 51 2b f4 89 1a 19 48 2d 68 |3...t..Q+....H-h|
+000002d0 d0 7b be c1 bb 9e c7 3e af 4b 80 1c ab 8f a2 9d |.{.....>.K......|
+000002e0 17 96 da 42 16 49 a6 74 35 07 9a 7d 89 80 4d d6 |...B.I.t5..}..M.|
+000002f0 04 43 11 68 6b e4 87 32 33 43 82 b3 9e b0 03 eb |.C.hk..23C......|
+00000300 b9 15 01 86 01 db ea e3 67 5b 7f 9c 0e 54 03 21 |........g[...T.!|
+00000310 04 29 7e 17 03 03 00 99 21 c7 e4 ea 6e 27 82 c6 |.)~.....!...n'..|
+00000320 15 6a 4d cd 8d c5 41 e5 1e aa 5c 8b b9 e8 ee 2a |.jM...A...\....*|
+00000330 04 53 ee 39 3d a1 9b 53 ab f8 4a 97 95 69 53 ef |.S.9=..S..J..iS.|
+00000340 9b a9 3a d5 d1 0c a6 e3 fb 7d 30 b1 00 45 43 58 |..:......}0..ECX|
+00000350 51 65 1f 60 e7 f4 0a 6a f6 8a 06 60 9b 5b 60 31 |Qe.`...j...`.[`1|
+00000360 d5 df 8b 28 1a c4 cb 39 5d a3 2b fb eb c8 07 14 |...(...9].+.....|
+00000370 07 ee 02 11 7f 85 c9 78 d8 f5 c1 6b 70 c1 b3 c1 |.......x...kp...|
+00000380 c0 a8 a0 08 ac d3 4e 39 ca 21 b0 e6 1d ea 97 58 |......N9.!.....X|
+00000390 6a e0 ac ad 10 19 75 13 7e 35 5d c6 2c ad a1 a2 |j.....u.~5].,...|
+000003a0 79 ac 33 ed 4d 77 41 29 6c e2 05 80 d7 7b 05 a4 |y.3.MwA)l....{..|
+000003b0 03 17 03 03 00 35 4b 22 e9 78 9e b1 75 a9 cd 91 |.....5K".x..u...|
+000003c0 c6 4d f1 e9 f2 a7 42 59 d5 c0 9e f3 9e 8f 7a 17 |.M....BY......z.|
+000003d0 21 ba 01 5b d3 0f 91 52 63 12 d9 4f be 84 75 2e |!..[...Rc..O..u.|
+000003e0 a2 46 a9 45 f5 d6 a1 60 a0 17 79 17 03 03 00 8b |.F.E...`..y.....|
+000003f0 92 fc 11 26 97 33 82 f1 e4 62 5d 2a 56 3c d8 80 |...&.3...b]*V<..|
+00000400 6b 6d ce f9 5f 43 2f 8e 24 0b 46 0b a5 5a 22 d5 |km.._C/.$.F..Z".|
+00000410 ff 33 d7 e6 04 2e 37 5b 00 45 9d 8b 62 49 81 b1 |.3....7[.E..bI..|
+00000420 97 ca d5 84 dd f9 7e 1a 7a a3 45 46 b9 db a7 d4 |......~.z.EF....|
+00000430 07 3d 54 39 b1 de 54 16 bc d7 ba e7 b8 92 02 eb |.=T9..T.........|
+00000440 0c 3c b1 48 40 53 68 f5 fc 0f 6a 64 67 fb 79 cd |.<.H@Sh...jdg.y.|
+00000450 75 ed 65 7c 88 01 04 43 ed 00 44 68 c3 74 c1 bc |u.e|...C..Dh.t..|
+00000460 63 4a cf e9 e5 20 21 0e da da 09 fd ac c6 1c 7a |cJ... !........z|
+00000470 69 e4 90 fc e2 3b 12 df 3a 11 f4 |i....;..:..|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 0f c5 0c ac c4 |..........5.....|
+00000010 a9 7e 32 56 fd 68 b8 86 66 8a 66 da 65 0a 5a ee |.~2V.h..f.f.e.Z.|
+00000020 1a a5 11 ec 1c 42 28 2f 8e a3 98 49 80 a5 9e e3 |.....B(/...I....|
+00000030 5f cf 51 93 44 b2 f2 e0 6e 58 ea c6 50 84 14 ef |_.Q.D...nX..P...|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e 3c 0f a4 3b d6 72 2e 40 dd 5d 79 |.....<..;.r.@.]y|
+00000010 e4 57 25 46 95 76 98 6a 4f aa 75 b5 2f 40 67 2e |.W%F.v.jO.u./@g.|
+00000020 ff ac 49 17 03 03 00 13 93 90 ac d8 14 54 32 66 |..I..........T2f|
+00000030 fa af 38 24 7c 58 75 62 88 60 34 |..8$|Xub.`4|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-IssueTicketPreDisable b/src/crypto/tls/testdata/Server-TLSv13-IssueTicketPreDisable
new file mode 100644
index 0000000..abdf41d
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-IssueTicketPreDisable
@@ -0,0 +1,98 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 ce 01 00 00 ca 03 03 1f 69 f6 99 9f |............i...|
+00000010 ee 81 23 41 5d 81 d6 aa 1b 5a 44 9e 56 78 21 6a |..#A]....ZD.Vx!j|
+00000020 fa a1 17 9b 6f 97 3d d5 ee 11 7a 20 01 bd 29 e6 |....o.=...z ..).|
+00000030 6b be 9e 23 35 3a ab 47 92 6f 71 b3 69 82 63 7d |k..#5:.G.oq.i.c}|
+00000040 43 c0 ae eb 05 8e 54 9b e9 55 ec c2 00 04 13 01 |C.....T..U......|
+00000050 00 ff 01 00 00 7d 00 0b 00 04 03 00 01 02 00 0a |.....}..........|
+00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 23 |...............#|
+00000070 00 00 00 16 00 00 00 17 00 00 00 0d 00 1e 00 1c |................|
+00000080 04 03 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b |................|
+00000090 08 04 08 05 08 06 04 01 05 01 06 01 00 2b 00 03 |.............+..|
+000000a0 02 03 04 00 2d 00 02 01 01 00 33 00 26 00 24 00 |....-.....3.&.$.|
+000000b0 1d 00 20 9c 90 86 ec 0c c9 4e 43 4d d7 00 3d 39 |.. ......NCM..=9|
+000000c0 50 25 c9 b9 f8 7f cc 6a 39 95 bc f0 1f 0d bc a7 |P%.....j9.......|
+000000d0 21 ff 69 |!.i|
+>>> 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 01 bd 29 e6 |........... ..).|
+00000030 6b be 9e 23 35 3a ab 47 92 6f 71 b3 69 82 63 7d |k..#5:.G.oq.i.c}|
+00000040 43 c0 ae eb 05 8e 54 9b e9 55 ec c2 13 01 00 00 |C.....T..U......|
+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 05 f8 de 75 03 3e |.............u.>|
+00000090 8f 8d df 8d c4 31 5e 59 2b a6 26 2c 81 86 e0 93 |.....1^Y+.&,....|
+000000a0 98 17 03 03 02 6d 73 67 7c 14 ba 17 23 fc f1 2e |.....msg|...#...|
+000000b0 53 5b 47 58 e2 ed b3 6a 30 70 40 98 82 4b 43 0d |S[GX...j0p@..KC.|
+000000c0 f6 e4 74 09 c8 08 9e a2 6d 23 3c 81 64 a9 39 e4 |..t.....m#<.d.9.|
+000000d0 be cc 6e 4c f1 df 7c b1 a5 cd 91 7c e7 e0 e9 97 |..nL..|....|....|
+000000e0 a3 06 20 92 7c 1c f6 e1 93 cd b2 65 ba 10 c0 54 |.. .|......e...T|
+000000f0 32 89 60 7e 6f ac 29 7f df e8 ff d2 0f 0d 8a f8 |2.`~o.).........|
+00000100 2a 56 fd 4a 07 27 f1 cc c1 81 fb bd 5e 33 92 34 |*V.J.'......^3.4|
+00000110 24 e9 a6 7f ff 76 e4 19 82 ca b8 92 aa 98 9c ac |$....v..........|
+00000120 51 25 fc 3a 74 f6 f3 36 b4 ae 00 cd d9 e0 17 c4 |Q%.:t..6........|
+00000130 9f 56 67 d0 ab 22 a1 38 57 a9 58 66 b4 f8 60 0b |.Vg..".8W.Xf..`.|
+00000140 20 c4 0c d0 f1 bc ce 4d 20 d2 e0 6f 1e f2 dd f0 | ......M ..o....|
+00000150 14 98 5c 33 92 08 af a9 42 ec 9e 8d 6e 92 cf 87 |..\3....B...n...|
+00000160 b7 79 90 18 1b 3b 78 77 1e 55 c7 68 9b 98 ae ae |.y...;xw.U.h....|
+00000170 33 d8 50 b8 3d fa 6b 96 99 7a b5 ca 98 fa a9 21 |3.P.=.k..z.....!|
+00000180 46 6a a1 74 bf bc 2f 51 0e 66 e2 35 2c d3 c9 3c |Fj.t../Q.f.5,..<|
+00000190 06 d0 79 31 00 d2 0a 1d 77 dd da 07 3a 31 7c 51 |..y1....w...:1|Q|
+000001a0 5e 53 b0 fe 55 21 1c 6c fa d2 a3 71 18 1d 8f ec |^S..U!.l...q....|
+000001b0 a3 ab 89 10 19 6d 45 50 9e f8 bf aa 3a 91 3b 80 |.....mEP....:.;.|
+000001c0 68 33 c0 d2 4c 10 39 b6 01 79 aa 27 a5 3e e7 59 |h3..L.9..y.'.>.Y|
+000001d0 6e fa c3 16 68 7f 7e ce 05 b0 96 e9 dd 2c 4a 7b |n...h.~......,J{|
+000001e0 5e 63 65 e6 6f f1 05 95 40 e3 71 15 c6 bd ec 60 |^ce.o...@.q....`|
+000001f0 01 08 2b 23 d6 be c6 7f 00 aa 32 78 cb 77 d8 5c |..+#......2x.w.\|
+00000200 e5 b6 b8 be 08 84 1a 47 57 b7 d8 72 27 e7 f6 08 |.......GW..r'...|
+00000210 7b 8a fa d8 a6 06 15 68 cc 90 a4 fe 8e 25 5c cb |{......h.....%\.|
+00000220 03 e8 ab 19 32 05 f4 88 d9 11 03 72 48 a3 a9 b2 |....2......rH...|
+00000230 41 d3 60 80 d5 93 ae 18 1e 3d ed a7 ac 7f a6 eb |A.`......=......|
+00000240 3c 5c 78 11 fb a6 b8 00 d6 7b 98 67 d5 fd 7c 87 |<\x......{.g..|.|
+00000250 80 b9 a4 23 71 31 93 77 98 90 fc 29 95 f4 6d 09 |...#q1.w...)..m.|
+00000260 87 2e 4b e7 a7 98 af 72 10 c2 dd 05 6e 60 b9 4c |..K....r....n`.L|
+00000270 33 65 cf 26 fc 7d 81 cc f0 4d 83 34 11 d2 0f 13 |3e.&.}...M.4....|
+00000280 7f 97 4a 12 17 44 fc 9a 32 08 de eb 5e 2a 87 d6 |..J..D..2...^*..|
+00000290 ed 7f ea 2a ed e3 2d 7a ea 19 40 7c 6e a2 13 e6 |...*..-z..@|n...|
+000002a0 ff 9b f6 3c ff 5e 97 9c de f8 c3 52 cb d8 d2 b0 |...<.^.....R....|
+000002b0 45 45 6e 63 d4 9f bf a5 7c c8 f4 65 84 ff 62 30 |EEnc....|..e..b0|
+000002c0 71 d4 65 a8 9e 43 e2 73 12 e9 d0 58 8c 1a 6e 0c |q.e..C.s...X..n.|
+000002d0 2f 64 02 4d 1f 4f c0 69 d8 d5 44 97 7b 8a 09 d4 |/d.M.O.i..D.{...|
+000002e0 8f 68 13 68 b9 7f 7b d8 29 b8 d7 3a 8f 78 eb 73 |.h.h..{.)..:.x.s|
+000002f0 1b eb 1b 2d 7e 46 78 0b ad 89 e5 d9 69 4b 1c 46 |...-~Fx.....iK.F|
+00000300 e7 13 c3 0d 54 f0 70 f8 99 60 45 78 fc a3 fc 72 |....T.p..`Ex...r|
+00000310 ca 84 57 17 03 03 00 99 05 02 eb 76 1b 1a f0 aa |..W........v....|
+00000320 dd 0d 91 1e 0b c1 14 1c 6f 5e 9b b3 33 8c 70 87 |........o^..3.p.|
+00000330 f2 0e 1e 45 0e 36 1a 06 77 97 a1 95 cd d1 ec 3e |...E.6..w......>|
+00000340 24 f9 b2 d5 47 5a c8 99 49 ca 59 bc 1d 6a 16 e7 |$...GZ..I.Y..j..|
+00000350 9a 51 c8 9a f7 ab b9 e4 fe 1e 22 1f ed c8 bf 1a |.Q........".....|
+00000360 8e 06 6a 07 4a c7 ef 57 f9 4a 84 1c 4b 1b 60 24 |..j.J..W.J..K.`$|
+00000370 5a d7 c0 34 57 68 1c fd 3f 2a 0a 17 9a 1f 70 19 |Z..4Wh..?*....p.|
+00000380 08 ff c5 33 79 4e 85 fb 8c 8d 76 6c be 8c 9c bf |...3yN....vl....|
+00000390 7a ac 87 8a d1 ea d0 a4 1e 25 64 ae 63 e7 29 59 |z........%d.c.)Y|
+000003a0 d8 27 88 4c e2 c7 42 9d 08 75 62 49 df fa 84 e8 |.'.L..B..ubI....|
+000003b0 11 17 03 03 00 35 39 db 59 c8 ab 08 33 da 2c 19 |.....59.Y...3.,.|
+000003c0 04 10 bb 18 b3 10 78 4b 2c a2 2b a2 e2 67 d1 6f |......xK,.+..g.o|
+000003d0 07 9c 0b d2 e1 24 a8 ac 7b ce 77 55 7d b8 b3 9b |.....$..{.wU}...|
+000003e0 82 7f bc 18 7a 61 a8 28 e2 a9 1e 17 03 03 00 8b |....za.(........|
+000003f0 6e a6 11 39 b9 d7 7b a0 67 76 c2 a6 d0 e4 c4 ba |n..9..{.gv......|
+00000400 a3 3d 37 bb 6d 82 5e 2e 80 e8 e6 4b 98 89 69 e9 |.=7.m.^....K..i.|
+00000410 27 cb c9 83 a5 2b a4 78 00 dd 46 4d 45 f7 4e a7 |'....+.x..FME.N.|
+00000420 3b c2 e1 84 5c ff af 75 25 1a 52 c4 b6 29 48 bb |;...\..u%.R..)H.|
+00000430 31 30 e2 8c ac f0 e8 bd 78 26 f2 d1 d6 1e d5 3e |10......x&.....>|
+00000440 6d 61 7e 80 e5 bc 81 28 e3 1f 62 40 0e 31 0b e1 |ma~....(..b@.1..|
+00000450 23 1c e1 fa 32 94 c3 4e 1d 09 81 d9 b6 89 c4 9c |#...2..N........|
+00000460 5e 38 85 ab 38 29 03 42 ea c0 94 d7 65 40 1f 1d |^8..8).B....e@..|
+00000470 49 39 9a e9 76 92 38 2f 17 8b ee |I9..v.8/...|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 e1 c3 64 6d 3b |..........5..dm;|
+00000010 7d 3c d3 c6 ee 3a f9 cc a6 29 18 3a 7b bd b1 07 |}<...:...).:{...|
+00000020 01 b4 06 8d fe a0 6e 23 40 52 5a f1 a3 4c 59 0a |......n#@RZ..LY.|
+00000030 ea b5 e3 7f e3 b9 0e e5 70 8a 47 a1 1e 2a 00 03 |........p.G..*..|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e 4e a9 f3 57 a0 f8 b2 0b dd 8e 90 |.....N..W.......|
+00000010 61 96 d9 53 c8 69 87 65 fd f4 fb ae 55 95 0d 07 |a..S.i.e....U...|
+00000020 69 e3 29 17 03 03 00 13 02 ba 24 dc 82 fc 91 9f |i.).......$.....|
+00000030 91 ff b9 6e 71 8e e3 2d 2f e8 8f |...nq..-/..|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-P256 b/src/crypto/tls/testdata/Server-TLSv13-P256
new file mode 100644
index 0000000..c3a2ee0
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-P256
@@ -0,0 +1,101 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 e3 01 00 00 df 03 03 18 3b 05 4d 40 |............;.M@|
+00000010 41 61 2a 64 35 7a e4 a7 c2 8b ab e5 e3 90 04 6d |Aa*d5z.........m|
+00000020 18 75 15 88 88 c7 af ba 05 e7 9c 20 78 e2 6d 28 |.u......... x.m(|
+00000030 fb 06 f6 e8 33 cd cc ba db 53 6d 4e 28 54 ca 62 |....3....SmN(T.b|
+00000040 c8 44 e3 cc 58 b5 07 ec 84 c9 e6 45 00 04 13 03 |.D..X......E....|
+00000050 00 ff 01 00 00 92 00 0b 00 04 03 00 01 02 00 0a |................|
+00000060 00 04 00 02 00 17 00 16 00 00 00 17 00 00 00 0d |................|
+00000070 00 1e 00 1c 04 03 05 03 06 03 08 07 08 08 08 09 |................|
+00000080 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................|
+00000090 00 2b 00 03 02 03 04 00 2d 00 02 01 01 00 33 00 |.+......-.....3.|
+000000a0 47 00 45 00 17 00 41 04 a1 27 f2 a0 16 66 17 e9 |G.E...A..'...f..|
+000000b0 73 ff 49 d4 99 47 19 b6 c1 ea 67 ea ef fd ad 07 |s.I..G....g.....|
+000000c0 c8 f4 19 e8 16 da a2 d0 bc c2 cc 58 c8 e4 d0 89 |...........X....|
+000000d0 c6 75 8f ac 87 e0 d6 4a 44 fa 14 c5 d6 ac ce d8 |.u.....JD.......|
+000000e0 8f 1d 5f d0 06 96 6c bb |.._...l.|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 9b 02 00 00 97 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 78 e2 6d 28 |........... x.m(|
+00000030 fb 06 f6 e8 33 cd cc ba db 53 6d 4e 28 54 ca 62 |....3....SmN(T.b|
+00000040 c8 44 e3 cc 58 b5 07 ec 84 c9 e6 45 13 03 00 00 |.D..X......E....|
+00000050 4f 00 2b 00 02 03 04 00 33 00 45 00 17 00 41 04 |O.+.....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 14 03 03 00 01 01 17 03 03 00 17 ab 5f 7d 4f ab |............_}O.|
+000000b0 25 00 54 5f b7 5a f9 e3 f8 ce c1 79 9f db 25 bd |%.T_.Z.....y..%.|
+000000c0 23 17 17 03 03 02 6d 2f 59 02 6a af c5 7d a1 e1 |#.....m/Y.j..}..|
+000000d0 b3 f8 4d 80 c5 9f 54 2f 27 4c a0 c0 0d dd 0e b5 |..M...T/'L......|
+000000e0 5b 2c a4 54 f3 25 65 aa 3e 43 fb 5b de 15 76 51 |[,.T.%e.>C.[..vQ|
+000000f0 f0 5f a0 8f ce 3d 2b 27 de 0e cb af 97 65 7a 81 |._...=+'.....ez.|
+00000100 a3 d2 a1 f1 44 75 04 12 41 48 b0 70 7a b7 ce ba |....Du..AH.pz...|
+00000110 de b5 ba 49 a4 25 08 6c 90 cb 82 b9 74 02 cf 09 |...I.%.l....t...|
+00000120 f0 83 77 a3 a4 30 ea 49 fb 61 ea 89 f6 96 b8 c1 |..w..0.I.a......|
+00000130 8a 5d a6 3d f4 f8 66 9c 3f d8 66 90 b2 93 7c 5e |.].=..f.?.f...|^|
+00000140 3e 9d d7 4c bc 4a 2e ef d9 d1 00 db fd 83 f3 43 |>..L.J.........C|
+00000150 a4 d7 fa 84 dd 4f a4 44 2f d2 b7 4f 5e ab a2 0e |.....O.D/..O^...|
+00000160 86 ab 65 8d 3c 63 a2 e4 55 ce b5 72 3f 77 e8 a7 |..e.<c..U..r?w..|
+00000170 40 c7 04 4d a8 4a 38 a4 5c 6d 15 a1 3b 0c cc 2a |@..M.J8.\m..;..*|
+00000180 7e 67 02 3b 58 95 bc e8 85 6c 81 45 81 44 a9 dd |~g.;X....l.E.D..|
+00000190 b0 26 71 73 29 a6 1a 40 2f 5c 81 af f0 cc 2d bf |.&qs)..@/\....-.|
+000001a0 1e fc 2e b2 7a 3a 07 22 72 25 dc d3 d1 8f 38 07 |....z:."r%....8.|
+000001b0 63 2f 18 f5 da b0 91 66 a1 47 16 ad 76 82 98 07 |c/.....f.G..v...|
+000001c0 6f a7 c8 79 43 73 4c 8c 2b 5d af 5a 7c c2 19 18 |o..yCsL.+].Z|...|
+000001d0 8d ee e2 ba fc 07 9b df 7e 17 af 54 c4 1f d8 a1 |........~..T....|
+000001e0 bd 66 93 e3 80 7e 9d a3 43 46 34 eb f9 9e 0b 77 |.f...~..CF4....w|
+000001f0 24 52 a8 85 8c 29 0b 53 0d 8b bf ba eb 8b f7 39 |$R...).S.......9|
+00000200 e4 81 95 fd e0 0d e3 de 05 31 48 37 dc 41 45 4e |.........1H7.AEN|
+00000210 77 d1 bd f6 a8 b9 1f 82 c2 51 3f 8b d0 7e 8d 4a |w........Q?..~.J|
+00000220 7c 13 f3 f4 cd 95 b3 51 14 80 7e 6e 41 63 de 3d ||......Q..~nAc.=|
+00000230 f0 51 22 a4 47 43 9a 73 d2 22 58 67 47 df 1c 37 |.Q".GC.s."XgG..7|
+00000240 d7 30 ff 49 de 8b 30 1b a9 9e c9 f1 e0 3e 19 5f |.0.I..0......>._|
+00000250 da 15 87 69 99 e1 64 2c fc 6b 07 61 9d ca 2f 8f |...i..d,.k.a../.|
+00000260 b2 d4 bb a4 0e ec e2 66 eb ca aa b2 fe 91 eb 2f |.......f......./|
+00000270 b0 d9 98 bb 9e 36 e1 e0 1f 89 5d cd 87 c8 28 85 |.....6....]...(.|
+00000280 ef c9 4a 57 6e 45 ca 07 02 be 30 1b 74 0a e4 4d |..JWnE....0.t..M|
+00000290 2c c1 77 fe 42 73 63 e6 e4 11 15 5b c4 df 40 f7 |,.w.Bsc....[..@.|
+000002a0 83 b5 43 50 f2 a1 04 fe b1 0e 49 63 8c 73 ab b8 |..CP......Ic.s..|
+000002b0 b4 31 d7 5e d3 50 c4 2a a8 51 2b 81 c3 80 70 22 |.1.^.P.*.Q+...p"|
+000002c0 af d3 1f 36 ba b5 b3 d9 d9 49 17 8f d8 f7 a2 05 |...6.....I......|
+000002d0 6d 5e 46 7b 40 be 86 58 0e 90 42 46 91 6e 0d d7 |m^F{@..X..BF.n..|
+000002e0 7e f0 7f e9 5b 6e 9c d8 b5 fe 3b 8e 03 57 0a 9b |~...[n....;..W..|
+000002f0 72 ee 5c 49 50 79 0e 75 8f 84 dd e8 2e 8d d6 37 |r.\IPy.u.......7|
+00000300 ad a8 f4 47 a6 e4 c9 e4 3b a5 7c 7f 2a 36 c5 39 |...G....;.|.*6.9|
+00000310 32 77 e1 7b a9 e7 47 b9 f2 a6 6b 75 ab 90 63 66 |2w.{..G...ku..cf|
+00000320 8d 50 62 d3 76 07 65 aa 57 87 bb a6 01 fc cb 93 |.Pb.v.e.W.......|
+00000330 c8 ed b8 64 17 03 03 00 99 1b b1 7a 13 30 73 85 |...d.......z.0s.|
+00000340 5a a4 81 29 0b 66 58 57 93 d9 24 f9 2e f9 8d cd |Z..).fXW..$.....|
+00000350 18 d7 48 16 8d d5 95 68 42 d0 c1 1d 08 6d 12 85 |..H....hB....m..|
+00000360 ed 3d 0f a7 33 86 d9 92 fe 02 58 ce 74 7d 5c 04 |.=..3.....X.t}\.|
+00000370 12 3d af 89 c5 83 1e cd 6b 25 3a c2 c1 50 23 9a |.=......k%:..P#.|
+00000380 f7 0f 7f c4 d8 a3 a4 99 50 a0 56 81 30 09 93 db |........P.V.0...|
+00000390 7a eb 51 2f 65 f3 96 95 eb be 92 c6 47 57 d4 d7 |z.Q/e.......GW..|
+000003a0 cf 7c 97 19 1f 87 76 8e 41 16 af 2d 3e af 1c 1d |.|....v.A..->...|
+000003b0 ee 0d 51 99 5b 59 e4 03 3c cb ad 18 a1 3a ae 18 |..Q.[Y..<....:..|
+000003c0 10 f2 f0 38 8f ee a0 8a 65 fd 10 ac 64 ac a8 72 |...8....e...d..r|
+000003d0 cf 54 17 03 03 00 35 bc e8 03 81 94 22 f7 a9 16 |.T....5....."...|
+000003e0 0e 65 d4 7e 8d 18 58 b0 3c 18 97 35 0e 73 bf d0 |.e.~..X.<..5.s..|
+000003f0 65 dc 63 d7 e6 51 f6 52 75 22 f0 cf f7 70 1e ae |e.c..Q.Ru"...p..|
+00000400 cd 4c fb 1e 21 97 ea db 07 36 8a d3 17 03 03 00 |.L..!....6......|
+00000410 8b 73 a1 d3 6c f8 7d d5 c0 79 dc 30 e4 40 f8 2a |.s..l.}..y.0.@.*|
+00000420 60 57 69 61 b9 cb 81 9f de 74 7c c1 ee d2 bd f5 |`Wia.....t|.....|
+00000430 bf 22 99 17 e3 05 25 3c 94 22 ee e6 6b 01 6a e9 |."....%<."..k.j.|
+00000440 39 8b 9a 08 4e 2a a8 7d 96 ae 6d 43 25 e0 03 11 |9...N*.}..mC%...|
+00000450 07 84 fb 47 fa ff 13 8f 0d a2 7e e8 a5 5d 76 e5 |...G......~..]v.|
+00000460 07 10 7d 6d f4 64 d4 54 ff 45 d9 17 18 5f e2 dd |..}m.d.T.E..._..|
+00000470 54 ef 32 4a 69 7c 4a 16 06 6d 21 dc 67 0a 84 33 |T.2Ji|J..m!.g..3|
+00000480 13 65 86 99 0d 09 33 59 96 d8 5a 6c f4 b1 c7 8c |.e....3Y..Zl....|
+00000490 fc bf 2b 8e e2 ee 63 28 62 bd 73 fb |..+...c(b.s.|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 4c 7a 0a 1d 11 |..........5Lz...|
+00000010 7c 9f 98 44 c7 f6 03 8b 9f 7b b1 dc 25 18 c2 f0 ||..D.....{..%...|
+00000020 17 b4 8c 83 68 11 0e 95 7e ce 9c ad 13 cb 79 63 |....h...~.....yc|
+00000030 03 80 d8 59 7e 25 e9 75 95 d0 6c 40 ab f2 8b f9 |...Y~%.u..l@....|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e ce 93 89 a4 0d db 14 53 be 22 ff |............S.".|
+00000010 53 1d 78 31 d3 17 c7 90 66 8d 2e e0 fe 98 e6 4b |S.x1....f......K|
+00000020 ee 6d 41 17 03 03 00 13 5d b7 e7 82 68 6a 7a 71 |.mA.....]...hjzq|
+00000030 32 25 34 83 c4 63 12 f5 8e ab e9 |2%4..c.....|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-RSA-RSAPSS b/src/crypto/tls/testdata/Server-TLSv13-RSA-RSAPSS
new file mode 100644
index 0000000..1caf831
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-RSA-RSAPSS
@@ -0,0 +1,96 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 b2 01 00 00 ae 03 03 4f 1c 96 1a 7c |...........O...||
+00000010 56 ea 59 60 5f bc 59 a4 c8 c1 ab 17 86 0b f9 d6 |V.Y`_.Y.........|
+00000020 7d 15 e4 b7 01 d3 27 55 af 8d 45 20 4b 2c f9 5c |}.....'U..E K,.\|
+00000030 05 ff 79 28 e6 63 7e 1f d7 10 26 07 2d ec c7 ed |..y(.c~...&.-...|
+00000040 1c c2 07 f1 ac 3b e9 2d 1a 8d 71 a0 00 04 13 03 |.....;.-..q.....|
+00000050 00 ff 01 00 00 61 00 0b 00 04 03 00 01 02 00 0a |.....a..........|
+00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 16 |................|
+00000070 00 00 00 17 00 00 00 0d 00 06 00 04 08 06 08 04 |................|
+00000080 00 2b 00 03 02 03 04 00 2d 00 02 01 01 00 33 00 |.+......-.....3.|
+00000090 26 00 24 00 1d 00 20 bd 6f e3 5c 82 72 3d cf 0d |&.$... .o.\.r=..|
+000000a0 2e 49 d0 c9 7e cc 36 88 ff 05 ed b3 c6 f1 93 9b |.I..~.6.........|
+000000b0 2a 6c 5f ca e5 eb 0f |*l_....|
+>>> 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 4b 2c f9 5c |........... K,.\|
+00000030 05 ff 79 28 e6 63 7e 1f d7 10 26 07 2d ec c7 ed |..y(.c~...&.-...|
+00000040 1c c2 07 f1 ac 3b e9 2d 1a 8d 71 a0 13 03 00 00 |.....;.-..q.....|
+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 ce 73 37 c4 06 32 |...........s7..2|
+00000090 74 c4 3d 2d 55 10 b4 ce 3f 66 fa ec 9a 8c d1 4a |t.=-U...?f.....J|
+000000a0 cd 17 03 03 02 6d 6a 73 5d 98 e7 fc 37 d2 b8 5d |.....mjs]...7..]|
+000000b0 2a 1c 75 80 b3 a9 ce 6e e2 d0 b5 5c 70 2b e5 c0 |*.u....n...\p+..|
+000000c0 28 4e bf 8c af 5a 78 a2 bc 29 fd 60 68 f8 fa ed |(N...Zx..).`h...|
+000000d0 5d 92 b2 d0 e8 69 e7 f7 1b 71 0b 30 4b c5 46 53 |]....i...q.0K.FS|
+000000e0 df 73 b9 95 65 6e cd df 26 b3 2b fd 7a 41 e9 4b |.s..en..&.+.zA.K|
+000000f0 8c 27 a3 d5 96 ed 44 01 9d 50 a8 39 28 f7 63 3d |.'....D..P.9(.c=|
+00000100 9e b7 1c 70 bf 2c d9 c4 67 5f 4f a7 7d b1 7a 4d |...p.,..g_O.}.zM|
+00000110 eb bd a3 4c 3b 0b ca 92 c4 db 21 dd 36 f2 4e ce |...L;.....!.6.N.|
+00000120 17 95 25 df bc 4a 2a 82 bb 5c 12 e4 6f ab 5a 03 |..%..J*..\..o.Z.|
+00000130 b7 7b 9f 8b 8e df ce c1 14 61 39 f1 8d f6 bb 90 |.{.......a9.....|
+00000140 a6 3a c0 21 13 9b a0 28 f6 05 34 a1 5a c5 ed 13 |.:.!...(..4.Z...|
+00000150 43 3d b6 3a 06 f8 89 ac fe 8f 71 76 58 43 32 56 |C=.:......qvXC2V|
+00000160 71 5c ad 4c 19 e6 54 ba 32 49 83 c7 b6 5a a8 9d |q\.L..T.2I...Z..|
+00000170 00 37 05 09 50 db c9 52 98 0d 96 03 11 22 a3 39 |.7..P..R.....".9|
+00000180 75 fe a7 34 20 0e f6 9c a9 79 0f 9e 05 fc 5a 4e |u..4 ....y....ZN|
+00000190 76 7c 13 0e a7 6a 1e 4a f7 ba a7 a8 18 8d 89 4a |v|...j.J.......J|
+000001a0 ad 34 40 81 2c e9 07 18 ba 95 48 dd 11 e7 11 0b |.4@.,.....H.....|
+000001b0 27 fe 9f 3c e6 44 72 16 89 dc 7d 8e 22 cf 4d 96 |'..<.Dr...}.".M.|
+000001c0 60 3c 78 7a ed 6e a9 ba d1 c3 59 b7 a7 32 bc 44 |`<xz.n....Y..2.D|
+000001d0 07 ef 1d b6 c0 21 5b 8b b6 b9 df 4b 47 90 64 f0 |.....![....KG.d.|
+000001e0 32 3c 09 4c 8d f2 17 75 81 5a 82 f3 d8 d0 05 7b |2<.L...u.Z.....{|
+000001f0 c8 d0 59 e3 59 a5 88 60 cc 31 0c 69 b2 05 fd b1 |..Y.Y..`.1.i....|
+00000200 16 c1 a5 00 1a 42 9e 4c 88 e0 3a 1c 68 2e 31 05 |.....B.L..:.h.1.|
+00000210 e6 09 04 c3 ef 57 00 ae 9e de a2 a3 5f fd 4e c9 |.....W......_.N.|
+00000220 e9 4c a4 51 dd 9b e1 a9 03 5c b4 19 ed 54 3f a0 |.L.Q.....\...T?.|
+00000230 a8 41 a9 bf df ca 74 ec e7 af 4b 0d 24 ad e7 e0 |.A....t...K.$...|
+00000240 27 eb 06 26 9e 32 5c 08 3c e4 93 8e d0 50 b5 f9 |'..&.2\.<....P..|
+00000250 33 4d c5 94 f6 f1 de 02 80 9f 1e 5c 09 c2 a1 8a |3M.........\....|
+00000260 15 89 91 91 41 71 48 2c 03 89 b7 bd e9 bd 7b 0c |....AqH,......{.|
+00000270 61 74 f5 2a 50 bd 44 da 06 37 77 55 10 6c 5a 75 |at.*P.D..7wU.lZu|
+00000280 f0 fd c3 db c7 46 fa b5 de cf 53 f6 09 de 03 77 |.....F....S....w|
+00000290 90 57 a7 4d 4a 2c 77 10 6c 99 5d b2 24 32 c7 b3 |.W.MJ,w.l.].$2..|
+000002a0 fc 09 4e d6 e9 a7 7e a3 c8 b7 22 b5 e3 4e a1 1f |..N...~..."..N..|
+000002b0 f9 81 06 d6 cd 42 09 49 ea 2d 98 d0 da 4f ad c2 |.....B.I.-...O..|
+000002c0 78 bd 8f 7c 2f 65 9e fc 35 be 46 bb f4 4a 2a 8f |x..|/e..5.F..J*.|
+000002d0 46 a3 94 f5 1d b2 4b 39 07 53 d1 2a 8e e1 eb 73 |F.....K9.S.*...s|
+000002e0 57 88 16 34 03 55 56 52 50 c8 42 45 28 ef 20 ef |W..4.UVRP.BE(. .|
+000002f0 ea c3 77 c9 a5 fe 92 51 2d ee d4 39 33 43 ae fa |..w....Q-..93C..|
+00000300 bb 85 d1 cb eb e6 37 2c 98 f6 b5 b9 5e 1b e6 22 |......7,....^.."|
+00000310 2a 63 92 17 03 03 00 99 c6 ed c3 5d 8e 74 7e f3 |*c.........].t~.|
+00000320 f6 cc 5f e8 24 4d 78 1c cd f1 a0 38 50 84 3a cb |.._.$Mx....8P.:.|
+00000330 ae 8c d4 73 33 a0 10 de ff 7b 3f a7 df 85 84 3b |...s3....{?....;|
+00000340 36 04 4e 9e 47 fa 87 9b a6 01 be 59 85 3c a4 ef |6.N.G......Y.<..|
+00000350 9a 58 81 9b 67 1e 16 74 34 64 b1 3e 43 0e 83 a0 |.X..g..t4d.>C...|
+00000360 41 51 24 49 1f e3 09 16 cd b6 4a db 62 ce 8f 79 |AQ$I......J.b..y|
+00000370 19 6b 4d e4 e9 61 4f ef 43 31 e1 82 e3 57 32 01 |.kM..aO.C1...W2.|
+00000380 58 d5 67 5f bd 5e d6 f5 b9 3c 91 65 96 49 81 b2 |X.g_.^...<.e.I..|
+00000390 8c 6d a8 ba 37 2f dd 8b bc 3a 33 9a 44 8a da e7 |.m..7/...:3.D...|
+000003a0 16 e1 d7 67 09 3a 3c d6 9f be bd 2b 50 d6 5d 3f |...g.:<....+P.]?|
+000003b0 96 17 03 03 00 35 77 34 06 35 5c 89 77 e6 a2 f8 |.....5w4.5\.w...|
+000003c0 3f b4 9e 45 ce 29 a8 f7 24 45 7c 00 36 96 f9 c4 |?..E.)..$E|.6...|
+000003d0 7b 6b 29 78 9e 13 78 95 9f 21 64 cb 5f a0 f1 ef |{k)x..x..!d._...|
+000003e0 3b 19 47 30 85 08 67 8f 84 b8 9c 17 03 03 00 8b |;.G0..g.........|
+000003f0 af fb c3 c3 f4 33 c3 e7 52 e0 c2 1b 3d f3 7f 40 |.....3..R...=..@|
+00000400 7d 33 38 8e 59 7d 3e 4f 8e 93 95 f8 9c 09 56 1b |}38.Y}>O......V.|
+00000410 68 d8 0c 11 a9 e6 6a c6 ea 6c 00 1e eb 3d d1 7b |h.....j..l...=.{|
+00000420 fc 1b 8e 52 69 f1 30 8c 3d 9d 3a 26 6e 9e 72 d9 |...Ri.0.=.:&n.r.|
+00000430 c4 00 a1 ae 87 ca 21 fc 45 ae af 58 9f 09 38 10 |......!.E..X..8.|
+00000440 94 b2 4c 58 46 da 8f fd c5 4a 60 0c ee 79 b7 6b |..LXF....J`..y.k|
+00000450 5a 74 f6 b4 e6 a0 1b 0c 8f 94 d9 79 07 36 05 ea |Zt.........y.6..|
+00000460 3b a3 11 ec 4a 86 b8 22 3c 94 eb da e1 d6 d4 91 |;...J.."<.......|
+00000470 e7 99 af 6b 39 4a 6c ef d7 8b c7 |...k9Jl....|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 e9 ef 1b b1 01 |..........5.....|
+00000010 b9 f2 6f e6 eb a0 52 01 81 f6 18 cf 28 f7 8a 09 |..o...R.....(...|
+00000020 65 32 30 4b 67 1b df d5 9c 4c cb 83 11 4e 3d 7f |e20Kg....L...N=.|
+00000030 d2 b8 a2 03 de 28 2d ef d0 68 b0 92 db 70 04 e2 |.....(-..h...p..|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e d8 d0 6a a0 02 0a cf 78 95 08 e1 |.......j....x...|
+00000010 2f dd 6b e3 db dc 8c f7 e3 5d 6e e2 48 5d d7 2c |/.k......]n.H].,|
+00000020 2c 26 7b 17 03 03 00 13 0a cd 02 95 d2 79 5a 1c |,&{..........yZ.|
+00000030 8a 27 a4 90 d3 7f ff 5c f1 b9 d8 |.'.....\...|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-RSA-RSAPSS-TooSmall b/src/crypto/tls/testdata/Server-TLSv13-RSA-RSAPSS-TooSmall
new file mode 100644
index 0000000..6d27e90
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-RSA-RSAPSS-TooSmall
@@ -0,0 +1,15 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 b0 01 00 00 ac 03 03 15 df ef fb ff |................|
+00000010 00 89 4d bf 59 d2 30 f1 f3 e7 20 24 c6 06 ba a4 |..M.Y.0... $....|
+00000020 28 b4 ba 3d 00 f2 18 9b 98 a3 f2 20 7e d9 d0 58 |(..=....... ~..X|
+00000030 50 25 90 2d f0 af 72 66 fb f8 54 33 6e d4 2b f0 |P%.-..rf..T3n.+.|
+00000040 0f 1a ea dc 9e 08 34 ed 68 a8 d8 bd 00 04 13 03 |......4.h.......|
+00000050 00 ff 01 00 00 5f 00 0b 00 04 03 00 01 02 00 0a |....._..........|
+00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 16 |................|
+00000070 00 00 00 17 00 00 00 0d 00 04 00 02 08 06 00 2b |...............+|
+00000080 00 03 02 03 04 00 2d 00 02 01 01 00 33 00 26 00 |......-.....3.&.|
+00000090 24 00 1d 00 20 6e 42 98 d4 04 32 d1 21 0f 64 c9 |$... nB...2.!.d.|
+000000a0 b7 f2 b2 52 6f 2b b7 b1 95 4b 57 85 7b 69 d9 63 |...Ro+...KW.{i.c|
+000000b0 19 48 d2 1c 1e |.H...|
+>>> Flow 2 (server to client)
+00000000 15 03 03 00 02 02 28 |......(|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-Resume b/src/crypto/tls/testdata/Server-TLSv13-Resume
new file mode 100644
index 0000000..29e41c6
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-Resume
@@ -0,0 +1,59 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 01 66 01 00 01 62 03 03 45 a3 e1 2e f2 |....f...b..E....|
+00000010 03 d1 82 45 cb cd fc da ae 9d 47 ce 2b fd 5a df |...E......G.+.Z.|
+00000020 ad dd 7b 1a 4a 14 93 bb d1 fe f5 20 78 6c c9 94 |..{.J...... xl..|
+00000030 6a b6 3e 65 97 42 9f c3 80 3c 8a 23 f5 af 6d 4b |j.>e.B...<.#..mK|
+00000040 cb dc e9 93 22 bd bf b5 e6 09 0d e1 00 04 13 01 |...."...........|
+00000050 00 ff 01 00 01 15 00 0b 00 04 03 00 01 02 00 0a |................|
+00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 23 |...............#|
+00000070 00 00 00 16 00 00 00 17 00 00 00 0d 00 1e 00 1c |................|
+00000080 04 03 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b |................|
+00000090 08 04 08 05 08 06 04 01 05 01 06 01 00 2b 00 03 |.............+..|
+000000a0 02 03 04 00 2d 00 02 01 01 00 33 00 26 00 24 00 |....-.....3.&.$.|
+000000b0 1d 00 20 49 31 09 86 3b 71 6b ff 6c bc 6f 40 4c |.. I1..;qk.l.o@L|
+000000c0 3a 04 44 c3 83 6c 9b 1d 99 a6 10 c7 07 f9 9d 57 |:.D..l.........W|
+000000d0 2d b4 59 00 29 00 94 00 6f 00 69 00 00 00 00 00 |-.Y.)...o.i.....|
+000000e0 00 00 00 00 00 00 00 00 00 00 00 94 68 2d a3 82 |............h-..|
+000000f0 51 ed 14 ef 68 ca 42 c5 5c 95 7a 77 9a 7a 61 99 |Q...h.B.\.zw.za.|
+00000100 c6 44 1e e6 5d 71 41 c8 77 d1 d4 b6 39 bb 38 57 |.D..]qA.w...9.8W|
+00000110 41 b8 41 f2 02 96 d0 b0 5b 99 76 3c 2b 52 f2 8f |A.A.....[.v<+R..|
+00000120 5f 33 94 fa 66 74 cc f0 60 1b ee 0a 38 30 78 b2 |_3..ft..`...80x.|
+00000130 9e 54 16 d6 71 0e b2 ea 4e 0f 13 f0 6e 63 88 e7 |.T..q...N...nc..|
+00000140 9f 55 65 0b 00 00 00 00 00 21 20 21 c5 95 b2 62 |.Ue......! !...b|
+00000150 61 dc b6 32 34 60 19 58 8c 6b 4b de dc 39 c7 d6 |a..24`.X.kK..9..|
+00000160 82 55 c8 de 80 dc b7 05 0c be a6 |.U.........|
+>>> 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 78 6c c9 94 |........... xl..|
+00000030 6a b6 3e 65 97 42 9f c3 80 3c 8a 23 f5 af 6d 4b |j.>e.B...<.#..mK|
+00000040 cb dc e9 93 22 bd bf b5 e6 09 0d e1 13 01 00 00 |...."...........|
+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 b4 11 54 4d 78 28 66 53 0f fd c8 7c d5 1c 1d b2 |..TMx(fS...|....|
+000000a0 06 31 23 27 a4 70 b2 17 03 03 00 35 86 87 b6 21 |.1#'.p.....5...!|
+000000b0 1c db f6 8c 4f ae 46 26 27 23 5d 1f 41 1d 42 94 |....O.F&'#].A.B.|
+000000c0 68 32 e5 49 19 e9 bc ba 4e 0a e2 71 7e 31 d2 a0 |h2.I....N..q~1..|
+000000d0 c2 24 b3 a9 3d 26 a5 eb c9 44 09 03 7a 14 54 5d |.$..=&...D..z.T]|
+000000e0 8f 17 03 03 00 8b fd cd ed ac c5 f2 7c 99 66 85 |............|.f.|
+000000f0 e6 0c 3b 9d ca a2 fb 22 69 fc 40 61 3a 98 f2 db |..;...."i.@a:...|
+00000100 84 7b d9 70 06 7f 00 20 53 cb ce 27 f1 93 fd 01 |.{.p... S..'....|
+00000110 fb 0d 32 61 0d 04 93 d3 53 94 a4 37 ed a6 6e 5c |..2a....S..7..n\|
+00000120 2f 9a 9a a9 1b b2 26 1d 24 9f 78 05 53 1d aa 40 |/.....&.$.x.S..@|
+00000130 bb 3f 27 29 ac 56 97 d7 f8 a8 77 e9 d4 b3 c0 43 |.?').V....w....C|
+00000140 a8 27 12 0f 13 fd 62 27 01 54 90 b5 66 fd d8 41 |.'....b'.T..f..A|
+00000150 a0 3a 5f b5 eb 53 25 83 f0 35 65 b2 7b f7 c6 a1 |.:_..S%..5e.{...|
+00000160 47 20 c5 91 00 69 b4 28 32 3c 55 8d 34 b9 ab b7 |G ...i.(2<U.4...|
+00000170 4b |K|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 fb 04 e7 9f ad |..........5.....|
+00000010 51 52 7e 72 61 46 df d0 80 5b 1a f3 ce 78 9e ae |QR~raF...[...x..|
+00000020 f8 cb 08 7e 2b 45 e9 f6 20 10 e0 99 4f 1a 62 51 |...~+E.. ...O.bQ|
+00000030 4f b6 d4 2a 5e b8 04 2b 09 06 4a 03 c4 01 ca bf |O..*^..+..J.....|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e 5c c3 b1 a5 d9 f3 a7 0b 48 b6 1f |.....\.......H..|
+00000010 73 ca d2 f5 07 6c e5 37 e9 b0 5f 87 a4 59 0d da |s....l.7.._..Y..|
+00000020 e2 3f ee 17 03 03 00 13 06 d0 6c 12 91 3c 0d cf |.?........l..<..|
+00000030 d2 0f 7f 74 e6 26 79 87 cf 76 71 |...t.&y..vq|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-Resume-HelloRetryRequest b/src/crypto/tls/testdata/Server-TLSv13-Resume-HelloRetryRequest
new file mode 100644
index 0000000..8896455
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-Resume-HelloRetryRequest
@@ -0,0 +1,94 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 01 60 01 00 01 5c 03 03 c6 2c d1 55 71 |....`...\...,.Uq|
+00000010 9a 6b 02 54 cb 33 30 34 5f 22 2a bc 96 df 2e d3 |.k.T.304_"*.....|
+00000020 43 9c 9a be c9 93 b9 e1 9f 42 74 20 5d a2 d5 2d |C........Bt ]..-|
+00000030 d6 9f 76 0c 14 dd e0 d3 71 a6 44 6a bc 3c ff a5 |..v.....q.Dj.<..|
+00000040 97 49 56 e0 3f 5b 47 87 31 83 1f 80 00 04 13 01 |.IV.?[G.1.......|
+00000050 00 ff 01 00 01 0f 00 0b 00 04 03 00 01 02 00 0a |................|
+00000060 00 06 00 04 00 1d 00 17 00 23 00 00 00 16 00 00 |.........#......|
+00000070 00 17 00 00 00 0d 00 1e 00 1c 04 03 05 03 06 03 |................|
+00000080 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 |................|
+00000090 04 01 05 01 06 01 00 2b 00 03 02 03 04 00 2d 00 |.......+......-.|
+000000a0 02 01 01 00 33 00 26 00 24 00 1d 00 20 8e a4 3b |....3.&.$... ..;|
+000000b0 ae a1 3e 4f be 70 12 25 be 4d 07 59 da dc 08 4c |..>O.p.%.M.Y...L|
+000000c0 53 e3 f3 15 b0 99 6f 5a 2d 16 30 e6 37 00 29 00 |S.....oZ-.0.7.).|
+000000d0 94 00 6f 00 69 00 00 00 00 00 00 00 00 00 00 00 |..o.i...........|
+000000e0 00 00 00 00 00 94 68 2d a3 82 51 ed 14 ef 68 ca |......h-..Q...h.|
+000000f0 42 c5 5c 95 7a 77 9a 7a 61 99 c6 44 1e e6 5d 71 |B.\.zw.za..D..]q|
+00000100 41 c8 77 d1 d4 b6 39 bb 38 57 41 b8 41 f2 02 96 |A.w...9.8WA.A...|
+00000110 d0 b0 5b 99 76 3c 2b 52 f2 8f 5f 33 94 fa 66 74 |..[.v<+R.._3..ft|
+00000120 cc f0 60 1b ee 0a 38 30 78 b2 9e 54 16 d6 71 0e |..`...80x..T..q.|
+00000130 b2 ea 4e 0f 13 f0 6e 63 88 e7 9f 55 65 0b 00 00 |..N...nc...Ue...|
+00000140 00 00 00 21 20 f1 10 27 87 e9 eb 1d b9 5f 0e f4 |...! ..'....._..|
+00000150 67 e3 19 b6 52 b4 1a 9f b7 68 0c 4e 25 42 3a 78 |g...R....h.N%B:x|
+00000160 91 e1 9d 62 f4 |...b.|
+>>> 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 5d a2 d5 2d |..^......3. ]..-|
+00000030 d6 9f 76 0c 14 dd e0 d3 71 a6 44 6a bc 3c ff a5 |..v.....q.Dj.<..|
+00000040 97 49 56 e0 3f 5b 47 87 31 83 1f 80 13 01 00 00 |.IV.?[G.1.......|
+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 81 01 00 01 7d 03 |..............}.|
+00000010 03 c6 2c d1 55 71 9a 6b 02 54 cb 33 30 34 5f 22 |..,.Uq.k.T.304_"|
+00000020 2a bc 96 df 2e d3 43 9c 9a be c9 93 b9 e1 9f 42 |*.....C........B|
+00000030 74 20 5d a2 d5 2d d6 9f 76 0c 14 dd e0 d3 71 a6 |t ]..-..v.....q.|
+00000040 44 6a bc 3c ff a5 97 49 56 e0 3f 5b 47 87 31 83 |Dj.<...IV.?[G.1.|
+00000050 1f 80 00 04 13 01 00 ff 01 00 01 30 00 0b 00 04 |...........0....|
+00000060 03 00 01 02 00 0a 00 06 00 04 00 1d 00 17 00 23 |...............#|
+00000070 00 00 00 16 00 00 00 17 00 00 00 0d 00 1e 00 1c |................|
+00000080 04 03 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b |................|
+00000090 08 04 08 05 08 06 04 01 05 01 06 01 00 2b 00 03 |.............+..|
+000000a0 02 03 04 00 2d 00 02 01 01 00 33 00 47 00 45 00 |....-.....3.G.E.|
+000000b0 17 00 41 04 ef 92 7c 5c e3 0d 1b 5c 8f 56 a2 93 |..A...|\...\.V..|
+000000c0 62 86 e4 5d ea 0b 63 1e e1 ea db 85 a0 28 68 89 |b..]..c......(h.|
+000000d0 07 47 d6 18 b0 6e db c2 3c 7d b4 7e a3 cb 54 25 |.G...n..<}.~..T%|
+000000e0 73 9f f6 d1 83 c1 2e 67 2a db ec 4a 09 9e 20 cf |s......g*..J.. .|
+000000f0 3f 8b 5d 9d 00 29 00 94 00 6f 00 69 00 00 00 00 |?.]..)...o.i....|
+00000100 00 00 00 00 00 00 00 00 00 00 00 00 94 68 2d a3 |.............h-.|
+00000110 82 51 ed 14 ef 68 ca 42 c5 5c 95 7a 77 9a 7a 61 |.Q...h.B.\.zw.za|
+00000120 99 c6 44 1e e6 5d 71 41 c8 77 d1 d4 b6 39 bb 38 |..D..]qA.w...9.8|
+00000130 57 41 b8 41 f2 02 96 d0 b0 5b 99 76 3c 2b 52 f2 |WA.A.....[.v<+R.|
+00000140 8f 5f 33 94 fa 66 74 cc f0 60 1b ee 0a 38 30 78 |._3..ft..`...80x|
+00000150 b2 9e 54 16 d6 71 0e b2 ea 4e 0f 13 f0 6e 63 88 |..T..q...N...nc.|
+00000160 e7 9f 55 65 0b 00 00 00 00 00 21 20 fa ea cb 6c |..Ue......! ...l|
+00000170 87 dc 71 c9 d3 b8 c5 6b d2 4d a7 dd 01 6c f0 26 |..q....k.M...l.&|
+00000180 c6 bd 6a ce e8 37 5b a9 d3 ac 87 2d |..j..7[....-|
+>>> 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 5d a2 d5 2d |........... ]..-|
+00000030 d6 9f 76 0c 14 dd e0 d3 71 a6 44 6a bc 3c ff a5 |..v.....q.Dj.<..|
+00000040 97 49 56 e0 3f 5b 47 87 31 83 1f 80 13 01 00 00 |.IV.?[G.1.......|
+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 47 b9 2a 97 3d |.).........G.*.=|
+000000b0 84 f9 65 f5 cf 27 b3 52 6d 2d 49 9d c1 c4 ea 14 |..e..'.Rm-I.....|
+000000c0 d5 dc 17 03 03 00 35 21 4d a1 eb 9f 49 63 35 99 |......5!M...Ic5.|
+000000d0 a3 85 ce 3a 40 cf 53 29 e6 d5 59 d5 26 12 78 c6 |...:@.S)..Y.&.x.|
+000000e0 be 01 c9 a2 f2 3d ba f9 ad 80 a1 f4 78 08 71 5e |.....=......x.q^|
+000000f0 04 7c df 80 0f 2d 5d e4 be 50 74 31 17 03 03 00 |.|...-]..Pt1....|
+00000100 8b 90 1a fd 79 a1 b9 08 4d db 32 01 6d 36 be 1a |....y...M.2.m6..|
+00000110 3f a8 b3 c7 5b 7b b1 f0 5d 55 67 ed af 87 50 16 |?...[{..]Ug...P.|
+00000120 ad d9 f1 af d2 3c 18 83 52 d5 3b e3 6d 7e ab 9a |.....<..R.;.m~..|
+00000130 33 cd 2c e7 f4 18 84 3a db 8b 73 d2 89 45 39 cf |3.,....:..s..E9.|
+00000140 f0 19 78 ab 20 b6 81 3c 3b b5 55 2c c1 6d 6f d8 |..x. ..<;.U,.mo.|
+00000150 52 1f 90 b5 ed eb e3 0c 35 40 16 ff f3 15 06 4e |R.......5@.....N|
+00000160 7e 98 3b f7 43 f9 98 80 84 36 1c 63 a0 3c 4b 57 |~.;.C....6.c.<KW|
+00000170 f1 89 57 df 64 b3 9a 77 86 d4 bc 85 eb 8a 1c e5 |..W.d..w........|
+00000180 98 d9 f6 cb 98 e0 20 84 07 8e 9b 2b |...... ....+|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 35 dc 6e fd 7a 4f d5 b9 d5 d8 71 b7 |....5.n.zO....q.|
+00000010 14 b1 cb 86 5b e0 01 b1 75 ff 33 a3 42 36 bf fc |....[...u.3.B6..|
+00000020 98 cc 15 c6 27 b2 57 1b ce f0 b7 93 15 52 29 77 |....'.W......R)w|
+00000030 9e fe d2 4e fe 05 d3 a5 f7 01 |...N......|
+>>> Flow 6 (server to client)
+00000000 17 03 03 00 1e 70 33 b5 fd 3d b0 d6 e4 54 9b 15 |.....p3..=...T..|
+00000010 f9 d5 2e 12 4a ce d2 ba b2 5d fe 92 ab d0 26 da |....J....]....&.|
+00000020 7c 0b 9e 17 03 03 00 13 ba a1 6a a9 db 16 2d cf ||.........j...-.|
+00000030 7e 54 77 8b 0a 6e 7d 31 fc dd 5e |~Tw..n}1..^|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-ResumeDisabled b/src/crypto/tls/testdata/Server-TLSv13-ResumeDisabled
new file mode 100644
index 0000000..9f14b60
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-ResumeDisabled
@@ -0,0 +1,99 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 01 6e 01 00 01 6a 03 03 0f 31 f0 17 d6 |....n...j...1...|
+00000010 3e ee f6 b9 14 05 57 cb 41 0b a4 6a 2f 70 9e 69 |>.....W.A..j/p.i|
+00000020 09 2a eb ec 9a f4 47 61 09 43 09 20 d2 5d cf 57 |.*....Ga.C. .].W|
+00000030 b8 81 3c a5 0a 77 50 0a c3 88 79 7a dc d0 2f 8a |..<..wP...yz../.|
+00000040 08 ea 5f 53 54 a6 ff 43 d2 03 55 0e 00 04 13 01 |.._ST..C..U.....|
+00000050 00 ff 01 00 01 1d 00 0b 00 04 03 00 01 02 00 0a |................|
+00000060 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 23 |...............#|
+00000070 00 00 00 16 00 00 00 17 00 00 00 0d 00 1e 00 1c |................|
+00000080 04 03 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b |................|
+00000090 08 04 08 05 08 06 04 01 05 01 06 01 00 2b 00 03 |.............+..|
+000000a0 02 03 04 00 2d 00 02 01 01 00 33 00 26 00 24 00 |....-.....3.&.$.|
+000000b0 1d 00 20 b4 ef 07 d4 1b 0e a1 42 ee f1 f3 84 3e |.. .......B....>|
+000000c0 9f fe bb a6 af 59 9d 04 96 03 1b 43 1a b8 f7 7f |.....Y.....C....|
+000000d0 44 64 60 00 29 00 9c 00 77 00 71 50 46 ad c1 db |Dd`.)...w.qPF...|
+000000e0 a8 38 86 7b 2b bb fd d0 c3 42 3e 00 00 00 00 00 |.8.{+....B>.....|
+000000f0 00 00 00 00 00 00 00 00 00 00 00 94 68 2c a3 82 |............h,..|
+00000100 51 ed 14 ef 68 ca 42 c5 5c 90 6b 88 83 a9 b3 63 |Q...h.B.\.k....c|
+00000110 7c 1c 04 ce dd be 5a 26 ef 4e 37 52 ea 9a 45 6b ||.....Z&.N7R..Ek|
+00000120 ea 89 a5 26 7d c3 ea 67 db 99 76 3c e5 52 89 d0 |...&}..g..v<.R..|
+00000130 4b 46 41 2e 62 5c ce a8 2e 9a 67 e9 52 f0 40 d2 |KFA.b\....g.R.@.|
+00000140 f1 0e ab 02 0f 54 c8 0b 5e 91 8f 8b 00 00 00 00 |.....T..^.......|
+00000150 00 21 20 e0 71 35 06 a0 30 9f bf 5a 6e f3 14 fd |.! .q5..0..Zn...|
+00000160 34 0b 6d d5 36 08 82 8f d0 79 cc f3 74 7c a9 a5 |4.m.6....y..t|..|
+00000170 c3 81 27 |..'|
+>>> 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 d2 5d cf 57 |........... .].W|
+00000030 b8 81 3c a5 0a 77 50 0a c3 88 79 7a dc d0 2f 8a |..<..wP...yz../.|
+00000040 08 ea 5f 53 54 a6 ff 43 d2 03 55 0e 13 01 00 00 |.._ST..C..U.....|
+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 df 85 83 6b 9d e0 |.............k..|
+00000090 8d b4 da b1 f2 c7 ff c1 13 33 d4 53 b8 92 bf 83 |.........3.S....|
+000000a0 6c 17 03 03 02 6d 6b 0f f6 15 41 46 aa 92 06 af |l....mk...AF....|
+000000b0 c9 a2 73 c5 31 64 c1 cd 3a e5 e6 9a d9 04 f4 01 |..s.1d..:.......|
+000000c0 d5 0e d6 30 e2 7a 6d 0c 23 d5 4b b1 70 58 c8 ca |...0.zm.#.K.pX..|
+000000d0 5d 1f c9 7c 76 f8 f9 90 b0 f6 05 f6 85 d2 10 b6 |]..|v...........|
+000000e0 bb b1 49 07 8a ba 9b d8 1a f4 48 18 f5 c5 90 f1 |..I.......H.....|
+000000f0 a7 24 cd 3b ab 2f 49 28 fa 3c 64 80 50 a6 38 d9 |.$.;./I(.<d.P.8.|
+00000100 38 15 b1 37 ca 8d 38 58 5b 8d c6 7f 01 98 f1 98 |8..7..8X[.......|
+00000110 3b 33 47 44 b5 47 d3 84 d4 96 bd 48 58 3f 62 86 |;3GD.G.....HX?b.|
+00000120 2a 50 18 8d 64 7c 8d 79 70 3d c1 4f 8a 0a 40 09 |*P..d|.yp=.O..@.|
+00000130 54 7d bf 8a b6 86 12 c8 d8 bd 7a c9 ff 2c 6a b1 |T}........z..,j.|
+00000140 20 a1 c1 90 4b 7a bc 4f 43 b4 f5 bd b6 1d cb de | ...Kz.OC.......|
+00000150 aa e5 b6 13 a5 ee 52 c4 9a d9 46 d6 2e e8 28 97 |......R...F...(.|
+00000160 84 7d 9f 14 dd a9 2b bd 00 f9 3e ff 48 32 e5 9b |.}....+...>.H2..|
+00000170 37 13 08 f2 cc cb bb f5 55 d5 7d 97 5e 6a df 11 |7.......U.}.^j..|
+00000180 33 fd 34 65 99 c2 40 7b a3 7a 04 92 63 ad 19 9d |3.4e..@{.z..c...|
+00000190 02 2a 6f d1 c8 f7 e1 d1 0f a1 c3 5b 81 70 b0 e5 |.*o........[.p..|
+000001a0 97 a4 b2 76 c5 9b 55 f5 da 2d 53 d2 49 4b a7 6a |...v..U..-S.IK.j|
+000001b0 0f 0f c8 d6 a5 00 83 52 fb 12 c6 6b 98 51 a3 4e |.......R...k.Q.N|
+000001c0 86 39 ab 7e 76 1f 31 b5 5e 50 53 1b 21 af 7f a0 |.9.~v.1.^PS.!...|
+000001d0 b9 3c cf 59 19 c7 c8 b6 ef d7 4f e5 ea 5e bc 67 |.<.Y......O..^.g|
+000001e0 00 47 97 50 85 15 54 19 eb de b8 11 0e 39 9a b0 |.G.P..T......9..|
+000001f0 be cd db d9 53 88 9c 78 e8 b9 5e 12 4b 30 63 d5 |....S..x..^.K0c.|
+00000200 eb 48 d1 d4 95 94 58 61 9c 53 ad 97 bd 45 3a 09 |.H....Xa.S...E:.|
+00000210 d0 83 a7 ba 8c 64 87 42 b7 e1 fa 1b 32 58 8b de |.....d.B....2X..|
+00000220 70 34 34 6d fb 0f a0 27 c3 8b 69 61 43 30 24 b2 |p44m...'..iaC0$.|
+00000230 32 4b ca 6c 0b ea f7 4b df e5 5f 3d 06 ea 0d 31 |2K.l...K.._=...1|
+00000240 4a c6 19 44 61 a1 5b 45 ee 9b ea 69 42 8f 35 86 |J..Da.[E...iB.5.|
+00000250 09 c7 83 51 32 e6 7b 45 bb fb 11 1f 4d 3f b8 10 |...Q2.{E....M?..|
+00000260 6a 0c 52 4c fd 20 62 0f 75 26 8a 65 67 e9 7e 56 |j.RL. b.u&.eg.~V|
+00000270 f4 ed 01 67 9e 27 0d 39 98 b4 97 44 50 f6 26 11 |...g.'.9...DP.&.|
+00000280 3c e4 40 17 5c f1 eb 85 1f 13 f9 8d 22 66 2d 2e |<.@.\......."f-.|
+00000290 3b f8 eb 08 7d df f6 ba 7b ec 15 34 04 e2 6d aa |;...}...{..4..m.|
+000002a0 e2 1c 5a e6 e8 4f 00 0c 07 1b dd 6e 07 03 ed 6d |..Z..O.....n...m|
+000002b0 df c0 7d ed 05 84 bb ad 0c 1f df 8b 8d 0a ad 33 |..}............3|
+000002c0 90 38 44 db 8a 32 9f 9d b3 ae 2e 92 d6 ab d3 25 |.8D..2.........%|
+000002d0 12 32 2d 6e a9 17 0d c9 f9 79 25 17 f0 62 1b 91 |.2-n.....y%..b..|
+000002e0 ad d5 2d ec 0d ea cd c4 86 77 04 92 ab a8 8d ea |..-......w......|
+000002f0 ce fc 13 7b a0 ca 32 96 50 49 99 dd 25 d7 73 93 |...{..2.PI..%.s.|
+00000300 f2 00 72 ca 31 07 fd 7e 12 8a 8b 76 51 4e fe 30 |..r.1..~...vQN.0|
+00000310 4d 5c 65 17 03 03 00 99 5b 19 25 c3 5a 4d f0 bd |M\e.....[.%.ZM..|
+00000320 71 0e 48 63 61 bb 55 6b d3 26 81 25 cf ea 45 e6 |q.Hca.Uk.&.%..E.|
+00000330 52 e4 4e c9 5a a8 c2 e2 72 97 51 8a 38 c6 8d 27 |R.N.Z...r.Q.8..'|
+00000340 8d df 09 ce 37 87 a6 41 cb c4 bd 6d 19 ef 56 1a |....7..A...m..V.|
+00000350 e8 79 df ad 76 9e a6 92 e3 da b3 a6 0d 9f 6f 6f |.y..v.........oo|
+00000360 3f 76 0b 62 b4 cf 2c 5b 24 65 bd c1 90 bb 88 ec |?v.b..,[$e......|
+00000370 8b 0c 7d 6b 42 38 26 78 62 5c b0 21 74 95 5f fe |..}kB8&xb\.!t._.|
+00000380 68 7d 31 8c 5f f5 dc a4 f0 23 6b 75 be 70 ea b3 |h}1._....#ku.p..|
+00000390 19 cc 83 9b 8a f6 cb cc 04 2e 66 b5 77 bb 11 68 |..........f.w..h|
+000003a0 56 85 0c b1 b8 b1 4e ed ca bd ea 3c 91 38 8a 63 |V.....N....<.8.c|
+000003b0 f3 17 03 03 00 35 06 2f 99 10 0c 41 cf 70 d2 aa |.....5./...A.p..|
+000003c0 f9 74 e7 3a cb bb 77 1c e6 5c bf f9 3f 02 df af |.t.:..w..\..?...|
+000003d0 ba 08 fa f7 42 60 ad de 65 62 2e 54 5f 35 90 4f |....B`..eb.T_5.O|
+000003e0 9c b1 34 3d 5d f5 6e 04 d8 5a 50 |..4=].n..ZP|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 7e dc fc 3f 66 |..........5~..?f|
+00000010 cb ed 57 e3 5c 83 19 22 31 18 cb eb d5 b8 d2 3c |..W.\.."1......<|
+00000020 6c 10 1f be 5c 04 cf 88 6b ec 04 3d aa 0d 15 68 |l...\...k..=...h|
+00000030 e4 42 bb c9 86 12 ef f7 90 c4 f5 41 39 56 62 d0 |.B.........A9Vb.|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e ee b9 1c 7b 56 61 76 91 40 90 11 |........{Vav.@..|
+00000010 61 4a 0c 46 60 e2 c1 a7 dd 0c a1 0d da 65 98 3e |aJ.F`........e.>|
+00000020 30 62 98 17 03 03 00 13 27 7a 29 e5 53 f1 9b 41 |0b......'z).S..A|
+00000030 7a 19 ec cd 29 0e 04 57 90 59 7e |z...)..W.Y~|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-X25519 b/src/crypto/tls/testdata/Server-TLSv13-X25519
new file mode 100644
index 0000000..62cd23b
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-X25519
@@ -0,0 +1,97 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 c2 01 00 00 be 03 03 c1 f4 f0 72 fe |..............r.|
+00000010 b9 17 c8 9e 71 08 cf 40 80 1a 11 06 68 dc de 21 |....q..@....h..!|
+00000020 14 fe e2 2f 6e 55 cf 9b 83 87 dd 20 63 a3 3f 38 |.../nU..... c.?8|
+00000030 4c 26 be 3c c0 2e e0 e0 5d 49 1b 92 45 6b 82 a9 |L&.<....]I..Ek..|
+00000040 10 ae c0 e4 65 b0 ce 48 75 5f 5b 12 00 04 13 03 |....e..Hu_[.....|
+00000050 00 ff 01 00 00 71 00 0b 00 04 03 00 01 02 00 0a |.....q..........|
+00000060 00 04 00 02 00 1d 00 16 00 00 00 17 00 00 00 0d |................|
+00000070 00 1e 00 1c 04 03 05 03 06 03 08 07 08 08 08 09 |................|
+00000080 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................|
+00000090 00 2b 00 03 02 03 04 00 2d 00 02 01 01 00 33 00 |.+......-.....3.|
+000000a0 26 00 24 00 1d 00 20 3e 7f 8c d5 2f 42 d2 cd 67 |&.$... >.../B..g|
+000000b0 24 07 69 fe 7e d0 3e 70 24 e4 62 aa 19 d6 c2 00 |$.i.~.>p$.b.....|
+000000c0 5c 0d 25 10 5f 36 09 |\.%._6.|
+>>> 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 63 a3 3f 38 |........... c.?8|
+00000030 4c 26 be 3c c0 2e e0 e0 5d 49 1b 92 45 6b 82 a9 |L&.<....]I..Ek..|
+00000040 10 ae c0 e4 65 b0 ce 48 75 5f 5b 12 13 03 00 00 |....e..Hu_[.....|
+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 4f 52 70 18 74 9c |..........ORp.t.|
+00000090 40 4e b0 5a 7a bc aa b0 b9 22 70 b1 90 9c 04 ef |@N.Zz...."p.....|
+000000a0 e7 17 03 03 02 6d a8 7e 5a 4a 5f 3d 97 f2 74 93 |.....m.~ZJ_=..t.|
+000000b0 ce 75 f5 be 0f 2e c4 58 d6 91 4d fb 9f 80 56 3c |.u.....X..M...V<|
+000000c0 9c d8 ea 20 2e f7 ce 34 80 af 47 0f 41 3f f9 2f |... ...4..G.A?./|
+000000d0 23 c1 94 9e de 51 43 c5 1e 31 98 e6 15 33 63 64 |#....QC..1...3cd|
+000000e0 22 39 87 83 87 66 d0 9e 85 2a b2 62 5e fd 50 ec |"9...f...*.b^.P.|
+000000f0 0f d0 ec dd d4 75 57 0d 3f 7e a3 a4 40 f7 67 d2 |.....uW.?~..@.g.|
+00000100 22 ba 5f a1 38 0b ea 8e 7d 95 43 70 52 0f b0 5f |"._.8...}.CpR.._|
+00000110 ef 26 5a 52 a6 94 b4 69 89 e9 0e 4f f5 d8 60 1b |.&ZR...i...O..`.|
+00000120 d3 6a fd 74 8d 19 ce 6a 72 f1 c1 96 f9 86 66 3b |.j.t...jr.....f;|
+00000130 2b 38 b3 e3 76 4b fd 4a 82 3e f2 2c bc 4c 19 d7 |+8..vK.J.>.,.L..|
+00000140 7a 62 21 3e 7c 41 ff 23 87 66 81 79 f0 ad a1 3e |zb!>|A.#.f.y...>|
+00000150 c2 e9 f3 ba 38 3a b5 ad 49 f3 ae 70 71 0a af d2 |....8:..I..pq...|
+00000160 f3 ae 70 df fd 93 8c 3d ca bd 8c 86 39 c9 9c d4 |..p....=....9...|
+00000170 a9 a8 37 04 92 9b 0a 4e 8d 43 96 3d a4 b5 e0 5d |..7....N.C.=...]|
+00000180 18 b1 03 32 0a b5 f2 e6 8c ca 1d ff cf 39 b7 00 |...2.........9..|
+00000190 5a 5a 1a 3d de 75 17 84 12 a4 f1 08 9d b3 ae 56 |ZZ.=.u.........V|
+000001a0 9d e9 af 30 67 64 fb 13 9a de 2e ba 03 ee 52 4c |...0gd........RL|
+000001b0 4f 85 f3 1b fc d0 ef 75 1a 31 99 d9 89 74 41 9d |O......u.1...tA.|
+000001c0 c8 96 48 49 f5 f3 ca 8c 6f 08 67 2a d1 b5 05 19 |..HI....o.g*....|
+000001d0 13 6b 0b 4c 87 f8 00 ab 83 70 4e bb 7e c7 f3 1e |.k.L.....pN.~...|
+000001e0 ba 83 4b 7f 65 c2 42 8d 00 b1 3e 3d f8 4d c3 7a |..K.e.B...>=.M.z|
+000001f0 b9 af 68 dc 0d 24 7a a6 41 15 16 db fb 57 99 68 |..h..$z.A....W.h|
+00000200 a9 35 77 40 6a 45 94 d3 e0 03 8d 41 86 d5 51 c6 |.5w@jE.....A..Q.|
+00000210 05 27 c5 56 97 30 41 44 26 18 e0 0f 93 cc f2 5e |.'.V.0AD&......^|
+00000220 f1 35 35 0f 54 25 51 23 78 37 39 80 d9 c2 e8 54 |.55.T%Q#x79....T|
+00000230 79 16 e0 e0 36 cf f1 8b 23 fa 67 46 66 e0 25 0e |y...6...#.gFf.%.|
+00000240 25 33 c4 52 93 ac 12 e0 8e f9 e8 c9 ec e7 f8 e6 |%3.R............|
+00000250 09 81 c1 d1 89 33 24 a3 c6 c7 27 6c 3b c8 b7 4f |.....3$...'l;..O|
+00000260 8a 14 ed 58 a7 5f ba fc cc 4f 6b eb ff c2 60 68 |...X._...Ok...`h|
+00000270 41 9c 4b b6 34 10 a6 8f f8 3c 47 2f 39 75 86 03 |A.K.4....<G/9u..|
+00000280 60 35 06 84 f2 96 35 39 0a c2 3e cb 3c fa d8 fa |`5....59..>.<...|
+00000290 66 3c 9c c9 6b 32 3f ea bd 5d 4d 75 e5 4b 88 93 |f<..k2?..]Mu.K..|
+000002a0 1f 47 73 3b 55 8a e0 e4 7e e5 2f dc 2d d4 f6 c0 |.Gs;U...~./.-...|
+000002b0 3a b4 e4 72 b2 5a 0d d1 10 28 3f 61 73 96 94 d0 |:..r.Z...(?as...|
+000002c0 fb 26 83 95 0e 7a 47 6d 75 d4 f4 ad cc 3e 8f 4c |.&...zGmu....>.L|
+000002d0 3b 95 83 61 40 4f 3e 82 58 d0 ca 7f 1d 9a e3 86 |;..a@O>.X.......|
+000002e0 48 53 1f 5d 35 9d 1e 46 c2 4b 70 53 60 1e 1d 04 |HS.]5..F.KpS`...|
+000002f0 9c 5b 6a f2 0b fc 4d 04 a6 38 85 b8 f1 06 cd 40 |.[j...M..8.....@|
+00000300 bb 73 fa bf 75 21 70 93 31 83 8d 8a a4 b3 4a 2f |.s..u!p.1.....J/|
+00000310 45 f0 b2 17 03 03 00 99 eb ae 23 e6 63 22 52 ac |E.........#.c"R.|
+00000320 2b 69 05 9d 7d b3 c6 b6 1f 5b 00 7c fb 67 1b af |+i..}....[.|.g..|
+00000330 42 38 40 ea ca bb dc 7d 92 94 dd ed 1a 20 65 8a |B8@....}..... e.|
+00000340 5c a3 5c 28 9f 10 8b 11 61 bb 0a 56 5a ef ec 7a |\.\(....a..VZ..z|
+00000350 50 b5 2d 67 62 77 80 dc ee a6 cd f3 09 ff 8f d8 |P.-gbw..........|
+00000360 ff 6d d8 47 95 58 cf 2b e7 b0 f8 26 61 58 35 a3 |.m.G.X.+...&aX5.|
+00000370 07 4d 2f 99 5d 33 6b e8 ac 6a 14 ef 2c 57 9a e3 |.M/.]3k..j..,W..|
+00000380 b7 1b bf d6 bf b8 6a 29 4a 74 0d 15 91 90 c3 4a |......j)Jt.....J|
+00000390 40 13 8c 52 e6 67 d6 de 6c d8 4e 35 20 d3 0b e6 |@..R.g..l.N5 ...|
+000003a0 36 58 4e 79 3a 03 f0 bc 34 1b 3e 7e e3 ad d8 e3 |6XNy:...4.>~....|
+000003b0 58 17 03 03 00 35 ba 6d a2 40 3a cb 43 80 cb af |X....5.m.@:.C...|
+000003c0 df 8f 2c 0d 20 53 f5 13 06 6b 0b e8 e7 36 31 4b |..,. S...k...61K|
+000003d0 19 ad 86 5e 39 2e 52 5a d9 86 f4 64 0e 8c 9a d5 |...^9.RZ...d....|
+000003e0 9a a2 c1 81 65 1e da 05 28 8a 36 17 03 03 00 8b |....e...(.6.....|
+000003f0 48 2d b0 5b 7e 39 95 b2 6a de 46 53 fb ba 7b 12 |H-.[~9..j.FS..{.|
+00000400 26 a1 1a b0 24 c0 8c c3 77 e1 0e 09 1c 5f 6a 7b |&...$...w...._j{|
+00000410 03 0b 3d 92 77 81 b1 97 22 0f 6e cd 04 97 28 79 |..=.w...".n...(y|
+00000420 eb 88 3d 7b 20 93 0b 67 df 32 2e bb 38 13 8f 28 |..={ ..g.2..8..(|
+00000430 c1 b8 2c 22 75 42 01 b8 50 2c 20 30 91 0d e5 a0 |..,"uB..P, 0....|
+00000440 5c dd 5b 53 c6 30 fd b4 a5 f7 e9 6f 49 61 70 32 |\.[S.0.....oIap2|
+00000450 7f fd bb 08 c4 93 e8 e2 0a f6 7d 0f e8 94 22 fe |..........}...".|
+00000460 af b7 b6 4a 35 d1 63 6c bd ce 1e 72 63 ca 05 7c |...J5.cl...rc..||
+00000470 64 4d ae 94 28 b2 15 b5 71 16 77 |dM..(...q.w|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 97 9f be 06 f2 |..........5.....|
+00000010 96 ae fa 11 e0 23 2b 6a b0 2e f5 e9 fc 10 b2 36 |.....#+j.......6|
+00000020 dc 62 b0 70 1e 42 e3 c5 ce c8 f7 a7 cb 1b c6 3b |.b.p.B.........;|
+00000030 59 23 d0 10 be f5 f0 1e 38 f4 63 bd 36 28 24 eb |Y#......8.c.6($.|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e 05 1b a2 f1 4b 74 46 76 1b 23 77 |.........KtFv.#w|
+00000010 79 df f1 67 bf e9 39 f3 b7 56 76 ba fa 4f 30 49 |y..g..9..Vv..O0I|
+00000020 18 7b 52 17 03 03 00 13 ef 66 20 67 cb 74 a9 b6 |.{R......f g.t..|
+00000030 93 6f cc a3 9e d5 f2 7d 81 10 71 |.o.....}..q|
diff --git a/src/crypto/tls/testdata/example-cert.pem b/src/crypto/tls/testdata/example-cert.pem
new file mode 100644
index 0000000..e0bf7db
--- /dev/null
+++ b/src/crypto/tls/testdata/example-cert.pem
@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE-----
+MIIBhTCCASugAwIBAgIQIRi6zePL6mKjOipn+dNuaTAKBggqhkjOPQQDAjASMRAw
+DgYDVQQKEwdBY21lIENvMB4XDTE3MTAyMDE5NDMwNloXDTE4MTAyMDE5NDMwNlow
+EjEQMA4GA1UEChMHQWNtZSBDbzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABD0d
+7VNhbWvZLWPuj/RtHFjvtJBEwOkhbN/BnnE8rnZR8+sbwnc/KhCk3FhnpHZnQz7B
+5aETbbIgmuvewdjvSBSjYzBhMA4GA1UdDwEB/wQEAwICpDATBgNVHSUEDDAKBggr
+BgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MCkGA1UdEQQiMCCCDmxvY2FsaG9zdDo1
+NDUzgg4xMjcuMC4wLjE6NTQ1MzAKBggqhkjOPQQDAgNIADBFAiEA2zpJEPQyz6/l
+Wf86aX6PepsntZv2GYlA5UpabfT2EZICICpJ5h/iI+i341gBmLiAFQOyTDT+/wQc
+6MF9+Yw1Yy0t
+-----END CERTIFICATE-----
diff --git a/src/crypto/tls/testdata/example-key.pem b/src/crypto/tls/testdata/example-key.pem
new file mode 100644
index 0000000..104fb09
--- /dev/null
+++ b/src/crypto/tls/testdata/example-key.pem
@@ -0,0 +1,5 @@
+-----BEGIN EC PRIVATE KEY-----
+MHcCAQEEIIrYSSNQFaA2Hwf1duRSxKtLYX5CB04fSeQ6tF1aY/PuoAoGCCqGSM49
+AwEHoUQDQgAEPR3tU2Fta9ktY+6P9G0cWO+0kETA6SFs38GecTyudlHz6xvCdz8q
+EKTcWGekdmdDPsHloRNtsiCa697B2O9IFA==
+-----END EC PRIVATE KEY-----
diff --git a/src/crypto/tls/ticket.go b/src/crypto/tls/ticket.go
new file mode 100644
index 0000000..b43101f
--- /dev/null
+++ b/src/crypto/tls/ticket.go
@@ -0,0 +1,421 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+ "crypto/aes"
+ "crypto/cipher"
+ "crypto/hmac"
+ "crypto/sha256"
+ "crypto/subtle"
+ "crypto/x509"
+ "errors"
+ "io"
+
+ "golang.org/x/crypto/cryptobyte"
+)
+
+// A SessionState is a resumable session.
+type SessionState struct {
+ // Encoded as a SessionState (in the language of RFC 8446, Section 3).
+ //
+ // enum { server(1), client(2) } SessionStateType;
+ //
+ // opaque Certificate<1..2^24-1>;
+ //
+ // 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>;
+ // Extra extra<0..2^24-1>;
+ // uint8 ext_master_secret = { 0, 1 };
+ // uint8 early_data = { 0, 1 };
+ // CertificateEntry certificate_list<0..2^24-1>;
+ // CertificateChain verified_chains<0..2^24-1>; /* excluding leaf */
+ // select (SessionState.early_data) {
+ // case 0: Empty;
+ // case 1: opaque alpn<1..2^8-1>;
+ // };
+ // select (SessionState.type) {
+ // case server: Empty;
+ // case client: struct {
+ // select (SessionState.version) {
+ // case VersionTLS10..VersionTLS12: Empty;
+ // case VersionTLS13: struct {
+ // uint64 use_by;
+ // uint32 age_add;
+ // };
+ // };
+ // };
+ // };
+ // } SessionState;
+ //
+
+ // Extra is ignored by crypto/tls, but is encoded by [SessionState.Bytes]
+ // and parsed by [ParseSessionState].
+ //
+ // This allows [Config.UnwrapSession]/[Config.WrapSession] and
+ // [ClientSessionCache] implementations to store and retrieve additional
+ // data alongside this session.
+ //
+ // 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
+ // decline to offer 0-RTT even if supported.
+ EarlyData bool
+
+ version uint16
+ isClient bool
+ cipherSuite uint16
+ // createdAt is the generation time of the secret on the sever (which for
+ // TLS 1.0–1.2 might be earlier than the current session) and the time at
+ // which the ticket was received on the client.
+ createdAt uint64 // seconds since UNIX epoch
+ secret []byte // master secret for TLS 1.2, or the PSK for TLS 1.3
+ extMasterSecret bool
+ peerCertificates []*x509.Certificate
+ activeCertHandles []*activeCert
+ ocspResponse []byte
+ scts [][]byte
+ verifiedChains [][]*x509.Certificate
+ alpnProtocol string // only set if EarlyData is true
+
+ // Client-side TLS 1.3-only fields.
+ useBy uint64 // seconds since UNIX epoch
+ ageAdd uint32
+}
+
+// Bytes encodes the session, including any private fields, so that it can be
+// parsed by [ParseSessionState]. The encoding contains secret values critical
+// to the security of future and possibly past sessions.
+//
+// The specific encoding should be considered opaque and may change incompatibly
+// between Go versions.
+func (s *SessionState) Bytes() ([]byte, error) {
+ var b cryptobyte.Builder
+ b.AddUint16(s.version)
+ if s.isClient {
+ b.AddUint8(2) // client
+ } else {
+ b.AddUint8(1) // server
+ }
+ b.AddUint16(s.cipherSuite)
+ addUint64(&b, s.createdAt)
+ b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(s.secret)
+ })
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ for _, extra := range s.Extra {
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(extra)
+ })
+ }
+ })
+ if s.extMasterSecret {
+ b.AddUint8(1)
+ } else {
+ b.AddUint8(0)
+ }
+ if s.EarlyData {
+ b.AddUint8(1)
+ } else {
+ b.AddUint8(0)
+ }
+ marshalCertificate(&b, Certificate{
+ Certificate: certificatesToBytesSlice(s.peerCertificates),
+ OCSPStaple: s.ocspResponse,
+ SignedCertificateTimestamps: s.scts,
+ })
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ for _, chain := range s.verifiedChains {
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ // We elide the first certificate because it's always the leaf.
+ if len(chain) == 0 {
+ b.SetError(errors.New("tls: internal error: empty verified chain"))
+ return
+ }
+ for _, cert := range chain[1:] {
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(cert.Raw)
+ })
+ }
+ })
+ }
+ })
+ if s.EarlyData {
+ b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes([]byte(s.alpnProtocol))
+ })
+ }
+ if s.isClient {
+ if s.version >= VersionTLS13 {
+ addUint64(&b, s.useBy)
+ b.AddUint32(s.ageAdd)
+ }
+ }
+ return b.Bytes()
+}
+
+func certificatesToBytesSlice(certs []*x509.Certificate) [][]byte {
+ s := make([][]byte, 0, len(certs))
+ for _, c := range certs {
+ s = append(s, c.Raw)
+ }
+ return s
+}
+
+// ParseSessionState parses a [SessionState] encoded by [SessionState.Bytes].
+func ParseSessionState(data []byte) (*SessionState, error) {
+ ss := &SessionState{}
+ 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) ||
+ !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
+ case 1:
+ ss.extMasterSecret = true
+ default:
+ return nil, errors.New("tls: invalid session encoding")
+ }
+ switch earlyData {
+ case 0:
+ ss.EarlyData = false
+ case 1:
+ ss.EarlyData = true
+ default:
+ return nil, errors.New("tls: invalid session encoding")
+ }
+ for _, cert := range cert.Certificate {
+ c, err := globalCertCache.newCert(cert)
+ if err != nil {
+ return nil, err
+ }
+ ss.activeCertHandles = append(ss.activeCertHandles, c)
+ ss.peerCertificates = append(ss.peerCertificates, c.cert)
+ }
+ ss.ocspResponse = cert.OCSPStaple
+ ss.scts = cert.SignedCertificateTimestamps
+ var chainList cryptobyte.String
+ if !s.ReadUint24LengthPrefixed(&chainList) {
+ return nil, errors.New("tls: invalid session encoding")
+ }
+ for !chainList.Empty() {
+ var certList cryptobyte.String
+ if !chainList.ReadUint24LengthPrefixed(&certList) {
+ return nil, errors.New("tls: invalid session encoding")
+ }
+ var chain []*x509.Certificate
+ if len(ss.peerCertificates) == 0 {
+ return nil, errors.New("tls: invalid session encoding")
+ }
+ chain = append(chain, ss.peerCertificates[0])
+ for !certList.Empty() {
+ var cert []byte
+ if !readUint24LengthPrefixed(&certList, &cert) {
+ return nil, errors.New("tls: invalid session encoding")
+ }
+ c, err := globalCertCache.newCert(cert)
+ if err != nil {
+ return nil, err
+ }
+ ss.activeCertHandles = append(ss.activeCertHandles, c)
+ chain = append(chain, c.cert)
+ }
+ ss.verifiedChains = append(ss.verifiedChains, chain)
+ }
+ if ss.EarlyData {
+ var alpn []byte
+ if !readUint8LengthPrefixed(&s, &alpn) {
+ return nil, errors.New("tls: invalid session encoding")
+ }
+ ss.alpnProtocol = string(alpn)
+ }
+ if isClient := typ == 2; !isClient {
+ if !s.Empty() {
+ return nil, errors.New("tls: invalid session encoding")
+ }
+ return ss, nil
+ }
+ ss.isClient = true
+ if len(ss.peerCertificates) == 0 {
+ return nil, errors.New("tls: no server certificates in client session")
+ }
+ if ss.version < VersionTLS13 {
+ if !s.Empty() {
+ return nil, errors.New("tls: invalid session encoding")
+ }
+ return ss, nil
+ }
+ if !s.ReadUint64(&ss.useBy) || !s.ReadUint32(&ss.ageAdd) || !s.Empty() {
+ return nil, errors.New("tls: invalid session encoding")
+ }
+ return ss, nil
+}
+
+// sessionState returns a partially filled-out [SessionState] with information
+// from the current connection.
+func (c *Conn) sessionState() (*SessionState, error) {
+ return &SessionState{
+ version: c.vers,
+ cipherSuite: c.cipherSuite,
+ createdAt: uint64(c.config.time().Unix()),
+ alpnProtocol: c.clientProtocol,
+ peerCertificates: c.peerCertificates,
+ activeCertHandles: c.activeCertHandles,
+ ocspResponse: c.ocspResponse,
+ scts: c.scts,
+ isClient: c.isClient,
+ extMasterSecret: c.extMasterSecret,
+ verifiedChains: c.verifiedChains,
+ }, nil
+}
+
+// EncryptTicket encrypts a ticket with the Config's configured (or default)
+// session ticket keys. It can be used as a [Config.WrapSession] implementation.
+func (c *Config) EncryptTicket(cs ConnectionState, ss *SessionState) ([]byte, error) {
+ ticketKeys := c.ticketKeys(nil)
+ stateBytes, err := ss.Bytes()
+ if err != nil {
+ return nil, err
+ }
+ return c.encryptTicket(stateBytes, ticketKeys)
+}
+
+func (c *Config) encryptTicket(state []byte, ticketKeys []ticketKey) ([]byte, error) {
+ if len(ticketKeys) == 0 {
+ return nil, errors.New("tls: internal error: session ticket keys unavailable")
+ }
+
+ encrypted := make([]byte, aes.BlockSize+len(state)+sha256.Size)
+ iv := encrypted[:aes.BlockSize]
+ ciphertext := encrypted[aes.BlockSize : len(encrypted)-sha256.Size]
+ authenticated := encrypted[:len(encrypted)-sha256.Size]
+ macBytes := encrypted[len(encrypted)-sha256.Size:]
+
+ if _, err := io.ReadFull(c.rand(), iv); err != nil {
+ return nil, err
+ }
+ key := ticketKeys[0]
+ block, err := aes.NewCipher(key.aesKey[:])
+ if err != nil {
+ return nil, errors.New("tls: failed to create cipher while encrypting ticket: " + err.Error())
+ }
+ cipher.NewCTR(block, iv).XORKeyStream(ciphertext, state)
+
+ mac := hmac.New(sha256.New, key.hmacKey[:])
+ mac.Write(authenticated)
+ mac.Sum(macBytes[:0])
+
+ return encrypted, nil
+}
+
+// DecryptTicket decrypts a ticket encrypted by [Config.EncryptTicket]. It can
+// be used as a [Config.UnwrapSession] implementation.
+//
+// If the ticket can't be decrypted or parsed, DecryptTicket returns (nil, nil).
+func (c *Config) DecryptTicket(identity []byte, cs ConnectionState) (*SessionState, error) {
+ ticketKeys := c.ticketKeys(nil)
+ stateBytes := c.decryptTicket(identity, ticketKeys)
+ if stateBytes == nil {
+ return nil, nil
+ }
+ s, err := ParseSessionState(stateBytes)
+ if err != nil {
+ return nil, nil // drop unparsable tickets on the floor
+ }
+ return s, nil
+}
+
+func (c *Config) decryptTicket(encrypted []byte, ticketKeys []ticketKey) []byte {
+ if len(encrypted) < aes.BlockSize+sha256.Size {
+ return nil
+ }
+
+ iv := encrypted[:aes.BlockSize]
+ ciphertext := encrypted[aes.BlockSize : len(encrypted)-sha256.Size]
+ authenticated := encrypted[:len(encrypted)-sha256.Size]
+ macBytes := encrypted[len(encrypted)-sha256.Size:]
+
+ for _, key := range ticketKeys {
+ mac := hmac.New(sha256.New, key.hmacKey[:])
+ mac.Write(authenticated)
+ expected := mac.Sum(nil)
+
+ if subtle.ConstantTimeCompare(macBytes, expected) != 1 {
+ continue
+ }
+
+ block, err := aes.NewCipher(key.aesKey[:])
+ if err != nil {
+ return nil
+ }
+ plaintext := make([]byte, len(ciphertext))
+ cipher.NewCTR(block, iv).XORKeyStream(plaintext, ciphertext)
+
+ return plaintext
+ }
+
+ return nil
+}
+
+// ClientSessionState contains the state needed by a client to
+// resume a previous TLS session.
+type ClientSessionState struct {
+ ticket []byte
+ session *SessionState
+}
+
+// ResumptionState returns the session ticket sent by the server (also known as
+// the session's identity) and the state necessary to resume this session.
+//
+// It can be called by [ClientSessionCache.Put] to serialize (with
+// [SessionState.Bytes]) and store the session.
+func (cs *ClientSessionState) ResumptionState() (ticket []byte, state *SessionState, err error) {
+ return cs.ticket, cs.session, nil
+}
+
+// NewResumptionState returns a state value that can be returned by
+// [ClientSessionCache.Get] to resume a previous session.
+//
+// state needs to be returned by [ParseSessionState], and the ticket and session
+// state must have been returned by [ClientSessionState.ResumptionState].
+func NewResumptionState(ticket []byte, state *SessionState) (*ClientSessionState, error) {
+ return &ClientSessionState{
+ ticket: ticket, session: state,
+ }, nil
+}
diff --git a/src/crypto/tls/ticket_test.go b/src/crypto/tls/ticket_test.go
new file mode 100644
index 0000000..f925451
--- /dev/null
+++ b/src/crypto/tls/ticket_test.go
@@ -0,0 +1,8 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+var _ = &Config{WrapSession: (&Config{}).EncryptTicket}
+var _ = &Config{UnwrapSession: (&Config{}).DecryptTicket}
diff --git a/src/crypto/tls/tls.go b/src/crypto/tls/tls.go
new file mode 100644
index 0000000..b529c70
--- /dev/null
+++ b/src/crypto/tls/tls.go
@@ -0,0 +1,356 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package tls partially implements TLS 1.2, as specified in RFC 5246,
+// and TLS 1.3, as specified in RFC 8446.
+package tls
+
+// BUG(agl): The crypto/tls package only implements some countermeasures
+// against Lucky13 attacks on CBC-mode encryption, and only on SHA1
+// variants. See http://www.isg.rhul.ac.uk/tls/TLStiming.pdf and
+// https://www.imperialviolet.org/2013/02/04/luckythirteen.html.
+
+import (
+ "bytes"
+ "context"
+ "crypto"
+ "crypto/ecdsa"
+ "crypto/ed25519"
+ "crypto/rsa"
+ "crypto/x509"
+ "encoding/pem"
+ "errors"
+ "fmt"
+ "net"
+ "os"
+ "strings"
+)
+
+// Server returns a new TLS server side connection
+// using conn as the underlying transport.
+// The configuration config must be non-nil and must include
+// at least one certificate or else set GetCertificate.
+func Server(conn net.Conn, config *Config) *Conn {
+ c := &Conn{
+ conn: conn,
+ config: config,
+ }
+ c.handshakeFn = c.serverHandshake
+ return c
+}
+
+// Client returns a new TLS client side connection
+// using conn as the underlying transport.
+// The config cannot be nil: users must set either ServerName or
+// InsecureSkipVerify in the config.
+func Client(conn net.Conn, config *Config) *Conn {
+ c := &Conn{
+ conn: conn,
+ config: config,
+ isClient: true,
+ }
+ c.handshakeFn = c.clientHandshake
+ return c
+}
+
+// A listener implements a network listener (net.Listener) for TLS connections.
+type listener struct {
+ net.Listener
+ config *Config
+}
+
+// Accept waits for and returns the next incoming TLS connection.
+// The returned connection is of type *Conn.
+func (l *listener) Accept() (net.Conn, error) {
+ c, err := l.Listener.Accept()
+ if err != nil {
+ return nil, err
+ }
+ return Server(c, l.config), nil
+}
+
+// NewListener creates a Listener which accepts connections from an inner
+// Listener and wraps each connection with Server.
+// The configuration config must be non-nil and must include
+// at least one certificate or else set GetCertificate.
+func NewListener(inner net.Listener, config *Config) net.Listener {
+ l := new(listener)
+ l.Listener = inner
+ l.config = config
+ return l
+}
+
+// Listen creates a TLS listener accepting connections on the
+// given network address using net.Listen.
+// The configuration config must be non-nil and must include
+// at least one certificate or else set GetCertificate.
+func Listen(network, laddr string, config *Config) (net.Listener, error) {
+ if config == nil || len(config.Certificates) == 0 &&
+ config.GetCertificate == nil && config.GetConfigForClient == nil {
+ return nil, errors.New("tls: neither Certificates, GetCertificate, nor GetConfigForClient set in Config")
+ }
+ l, err := net.Listen(network, laddr)
+ if err != nil {
+ return nil, err
+ }
+ return NewListener(l, config), nil
+}
+
+type timeoutError struct{}
+
+func (timeoutError) Error() string { return "tls: DialWithDialer timed out" }
+func (timeoutError) Timeout() bool { return true }
+func (timeoutError) Temporary() bool { return true }
+
+// DialWithDialer connects to the given network address using dialer.Dial and
+// then initiates a TLS handshake, returning the resulting TLS connection. Any
+// timeout or deadline given in the dialer apply to connection and TLS
+// handshake as a whole.
+//
+// DialWithDialer interprets a nil configuration as equivalent to the zero
+// configuration; see the documentation of Config for the defaults.
+//
+// DialWithDialer uses context.Background internally; to specify the context,
+// use Dialer.DialContext with NetDialer set to the desired dialer.
+func DialWithDialer(dialer *net.Dialer, network, addr string, config *Config) (*Conn, error) {
+ return dial(context.Background(), dialer, network, addr, config)
+}
+
+func dial(ctx context.Context, netDialer *net.Dialer, network, addr string, config *Config) (*Conn, error) {
+ if netDialer.Timeout != 0 {
+ var cancel context.CancelFunc
+ ctx, cancel = context.WithTimeout(ctx, netDialer.Timeout)
+ defer cancel()
+ }
+
+ if !netDialer.Deadline.IsZero() {
+ var cancel context.CancelFunc
+ ctx, cancel = context.WithDeadline(ctx, netDialer.Deadline)
+ defer cancel()
+ }
+
+ rawConn, err := netDialer.DialContext(ctx, network, addr)
+ if err != nil {
+ return nil, err
+ }
+
+ colonPos := strings.LastIndex(addr, ":")
+ if colonPos == -1 {
+ colonPos = len(addr)
+ }
+ hostname := addr[:colonPos]
+
+ if config == nil {
+ config = defaultConfig()
+ }
+ // If no ServerName is set, infer the ServerName
+ // from the hostname we're connecting to.
+ if config.ServerName == "" {
+ // Make a copy to avoid polluting argument or default.
+ c := config.Clone()
+ c.ServerName = hostname
+ config = c
+ }
+
+ conn := Client(rawConn, config)
+ if err := conn.HandshakeContext(ctx); err != nil {
+ rawConn.Close()
+ return nil, err
+ }
+ return conn, nil
+}
+
+// Dial connects to the given network address using net.Dial
+// and then initiates a TLS handshake, returning the resulting
+// TLS connection.
+// Dial interprets a nil configuration as equivalent to
+// the zero configuration; see the documentation of Config
+// for the defaults.
+func Dial(network, addr string, config *Config) (*Conn, error) {
+ return DialWithDialer(new(net.Dialer), network, addr, config)
+}
+
+// Dialer dials TLS connections given a configuration and a Dialer for the
+// underlying connection.
+type Dialer struct {
+ // NetDialer is the optional dialer to use for the TLS connections'
+ // underlying TCP connections.
+ // A nil NetDialer is equivalent to the net.Dialer zero value.
+ NetDialer *net.Dialer
+
+ // Config is the TLS configuration to use for new connections.
+ // A nil configuration is equivalent to the zero
+ // configuration; see the documentation of Config for the
+ // defaults.
+ Config *Config
+}
+
+// Dial connects to the given network address and initiates a TLS
+// handshake, returning the resulting TLS connection.
+//
+// The returned Conn, if any, will always be of type *Conn.
+//
+// Dial uses context.Background internally; to specify the context,
+// use DialContext.
+func (d *Dialer) Dial(network, addr string) (net.Conn, error) {
+ return d.DialContext(context.Background(), network, addr)
+}
+
+func (d *Dialer) netDialer() *net.Dialer {
+ if d.NetDialer != nil {
+ return d.NetDialer
+ }
+ return new(net.Dialer)
+}
+
+// DialContext connects to the given network address and initiates a TLS
+// handshake, returning the resulting TLS connection.
+//
+// The provided Context must be non-nil. If the context expires before
+// the connection is complete, an error is returned. Once successfully
+// connected, any expiration of the context will not affect the
+// connection.
+//
+// The returned Conn, if any, will always be of type *Conn.
+func (d *Dialer) DialContext(ctx context.Context, network, addr string) (net.Conn, error) {
+ c, err := dial(ctx, d.netDialer(), network, addr, d.Config)
+ if err != nil {
+ // Don't return c (a typed nil) in an interface.
+ return nil, err
+ }
+ return c, nil
+}
+
+// LoadX509KeyPair reads and parses a public/private key pair from a pair
+// of files. The files must contain PEM encoded data. The certificate file
+// may contain intermediate certificates following the leaf certificate to
+// form a certificate chain. On successful return, Certificate.Leaf will
+// be nil because the parsed form of the certificate is not retained.
+func LoadX509KeyPair(certFile, keyFile string) (Certificate, error) {
+ certPEMBlock, err := os.ReadFile(certFile)
+ if err != nil {
+ return Certificate{}, err
+ }
+ keyPEMBlock, err := os.ReadFile(keyFile)
+ if err != nil {
+ return Certificate{}, err
+ }
+ return X509KeyPair(certPEMBlock, keyPEMBlock)
+}
+
+// X509KeyPair parses a public/private key pair from a pair of
+// PEM encoded data. On successful return, Certificate.Leaf will be nil because
+// the parsed form of the certificate is not retained.
+func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (Certificate, error) {
+ fail := func(err error) (Certificate, error) { return Certificate{}, err }
+
+ var cert Certificate
+ var skippedBlockTypes []string
+ for {
+ var certDERBlock *pem.Block
+ certDERBlock, certPEMBlock = pem.Decode(certPEMBlock)
+ if certDERBlock == nil {
+ break
+ }
+ if certDERBlock.Type == "CERTIFICATE" {
+ cert.Certificate = append(cert.Certificate, certDERBlock.Bytes)
+ } else {
+ skippedBlockTypes = append(skippedBlockTypes, certDERBlock.Type)
+ }
+ }
+
+ if len(cert.Certificate) == 0 {
+ if len(skippedBlockTypes) == 0 {
+ return fail(errors.New("tls: failed to find any PEM data in certificate input"))
+ }
+ if len(skippedBlockTypes) == 1 && strings.HasSuffix(skippedBlockTypes[0], "PRIVATE KEY") {
+ return fail(errors.New("tls: failed to find certificate PEM data in certificate input, but did find a private key; PEM inputs may have been switched"))
+ }
+ return fail(fmt.Errorf("tls: failed to find \"CERTIFICATE\" PEM block in certificate input after skipping PEM blocks of the following types: %v", skippedBlockTypes))
+ }
+
+ skippedBlockTypes = skippedBlockTypes[:0]
+ var keyDERBlock *pem.Block
+ for {
+ keyDERBlock, keyPEMBlock = pem.Decode(keyPEMBlock)
+ if keyDERBlock == nil {
+ if len(skippedBlockTypes) == 0 {
+ return fail(errors.New("tls: failed to find any PEM data in key input"))
+ }
+ if len(skippedBlockTypes) == 1 && skippedBlockTypes[0] == "CERTIFICATE" {
+ return fail(errors.New("tls: found a certificate rather than a key in the PEM for the private key"))
+ }
+ return fail(fmt.Errorf("tls: failed to find PEM block with type ending in \"PRIVATE KEY\" in key input after skipping PEM blocks of the following types: %v", skippedBlockTypes))
+ }
+ if keyDERBlock.Type == "PRIVATE KEY" || strings.HasSuffix(keyDERBlock.Type, " PRIVATE KEY") {
+ break
+ }
+ skippedBlockTypes = append(skippedBlockTypes, keyDERBlock.Type)
+ }
+
+ // We don't need to parse the public key for TLS, but we so do anyway
+ // to check that it looks sane and matches the private key.
+ x509Cert, err := x509.ParseCertificate(cert.Certificate[0])
+ if err != nil {
+ return fail(err)
+ }
+
+ cert.PrivateKey, err = parsePrivateKey(keyDERBlock.Bytes)
+ if err != nil {
+ return fail(err)
+ }
+
+ switch pub := x509Cert.PublicKey.(type) {
+ case *rsa.PublicKey:
+ priv, ok := cert.PrivateKey.(*rsa.PrivateKey)
+ if !ok {
+ return fail(errors.New("tls: private key type does not match public key type"))
+ }
+ if pub.N.Cmp(priv.N) != 0 {
+ return fail(errors.New("tls: private key does not match public key"))
+ }
+ case *ecdsa.PublicKey:
+ priv, ok := cert.PrivateKey.(*ecdsa.PrivateKey)
+ if !ok {
+ return fail(errors.New("tls: private key type does not match public key type"))
+ }
+ if pub.X.Cmp(priv.X) != 0 || pub.Y.Cmp(priv.Y) != 0 {
+ return fail(errors.New("tls: private key does not match public key"))
+ }
+ case ed25519.PublicKey:
+ priv, ok := cert.PrivateKey.(ed25519.PrivateKey)
+ if !ok {
+ return fail(errors.New("tls: private key type does not match public key type"))
+ }
+ if !bytes.Equal(priv.Public().(ed25519.PublicKey), pub) {
+ return fail(errors.New("tls: private key does not match public key"))
+ }
+ default:
+ return fail(errors.New("tls: unknown public key algorithm"))
+ }
+
+ return cert, nil
+}
+
+// Attempt to parse the given private key DER block. OpenSSL 0.9.8 generates
+// PKCS #1 private keys by default, while OpenSSL 1.0.0 generates PKCS #8 keys.
+// OpenSSL ecparam generates SEC1 EC private keys for ECDSA. We try all three.
+func parsePrivateKey(der []byte) (crypto.PrivateKey, error) {
+ if key, err := x509.ParsePKCS1PrivateKey(der); err == nil {
+ return key, nil
+ }
+ if key, err := x509.ParsePKCS8PrivateKey(der); err == nil {
+ switch key := key.(type) {
+ case *rsa.PrivateKey, *ecdsa.PrivateKey, ed25519.PrivateKey:
+ return key, nil
+ default:
+ return nil, errors.New("tls: found unknown private key type in PKCS#8 wrapping")
+ }
+ }
+ if key, err := x509.ParseECPrivateKey(der); err == nil {
+ return key, nil
+ }
+
+ return nil, errors.New("tls: failed to parse private key")
+}
diff --git a/src/crypto/tls/tls_test.go b/src/crypto/tls/tls_test.go
new file mode 100644
index 0000000..c3f16c7
--- /dev/null
+++ b/src/crypto/tls/tls_test.go
@@ -0,0 +1,1804 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tls
+
+import (
+ "bytes"
+ "context"
+ "crypto"
+ "crypto/x509"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "internal/testenv"
+ "io"
+ "math"
+ "net"
+ "os"
+ "reflect"
+ "sort"
+ "strings"
+ "testing"
+ "time"
+)
+
+var rsaCertPEM = `-----BEGIN CERTIFICATE-----
+MIIB0zCCAX2gAwIBAgIJAI/M7BYjwB+uMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
+BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
+aWRnaXRzIFB0eSBMdGQwHhcNMTIwOTEyMjE1MjAyWhcNMTUwOTEyMjE1MjAyWjBF
+MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
+ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANLJ
+hPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wok/4xIA+ui35/MmNa
+rtNuC+BdZ1tMuVCPFZcCAwEAAaNQME4wHQYDVR0OBBYEFJvKs8RfJaXTH08W+SGv
+zQyKn0H8MB8GA1UdIwQYMBaAFJvKs8RfJaXTH08W+SGvzQyKn0H8MAwGA1UdEwQF
+MAMBAf8wDQYJKoZIhvcNAQEFBQADQQBJlffJHybjDGxRMqaRmDhX0+6v02TUKZsW
+r5QuVbpQhH6u+0UgcW0jp9QwpxoPTLTWGXEWBBBurxFwiCBhkQ+V
+-----END CERTIFICATE-----
+`
+
+var rsaKeyPEM = testingKey(`-----BEGIN RSA TESTING KEY-----
+MIIBOwIBAAJBANLJhPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wo
+k/4xIA+ui35/MmNartNuC+BdZ1tMuVCPFZcCAwEAAQJAEJ2N+zsR0Xn8/Q6twa4G
+6OB1M1WO+k+ztnX/1SvNeWu8D6GImtupLTYgjZcHufykj09jiHmjHx8u8ZZB/o1N
+MQIhAPW+eyZo7ay3lMz1V01WVjNKK9QSn1MJlb06h/LuYv9FAiEA25WPedKgVyCW
+SmUwbPw8fnTcpqDWE3yTO3vKcebqMSsCIBF3UmVue8YU3jybC3NxuXq3wNm34R8T
+xVLHwDXh/6NJAiEAl2oHGGLz64BuAfjKrqwz7qMYr9HCLIe/YsoWq/olzScCIQDi
+D2lWusoe2/nEqfDVVWGWlyJ7yOmqaVm/iNUN9B2N2g==
+-----END RSA TESTING KEY-----
+`)
+
+// keyPEM is the same as rsaKeyPEM, but declares itself as just
+// "PRIVATE KEY", not "RSA PRIVATE KEY". https://golang.org/issue/4477
+var keyPEM = testingKey(`-----BEGIN TESTING KEY-----
+MIIBOwIBAAJBANLJhPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wo
+k/4xIA+ui35/MmNartNuC+BdZ1tMuVCPFZcCAwEAAQJAEJ2N+zsR0Xn8/Q6twa4G
+6OB1M1WO+k+ztnX/1SvNeWu8D6GImtupLTYgjZcHufykj09jiHmjHx8u8ZZB/o1N
+MQIhAPW+eyZo7ay3lMz1V01WVjNKK9QSn1MJlb06h/LuYv9FAiEA25WPedKgVyCW
+SmUwbPw8fnTcpqDWE3yTO3vKcebqMSsCIBF3UmVue8YU3jybC3NxuXq3wNm34R8T
+xVLHwDXh/6NJAiEAl2oHGGLz64BuAfjKrqwz7qMYr9HCLIe/YsoWq/olzScCIQDi
+D2lWusoe2/nEqfDVVWGWlyJ7yOmqaVm/iNUN9B2N2g==
+-----END TESTING KEY-----
+`)
+
+var ecdsaCertPEM = `-----BEGIN CERTIFICATE-----
+MIIB/jCCAWICCQDscdUxw16XFDAJBgcqhkjOPQQBMEUxCzAJBgNVBAYTAkFVMRMw
+EQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0
+eSBMdGQwHhcNMTIxMTE0MTI0MDQ4WhcNMTUxMTE0MTI0MDQ4WjBFMQswCQYDVQQG
+EwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lk
+Z2l0cyBQdHkgTHRkMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBY9+my9OoeSUR
+lDQdV/x8LsOuLilthhiS1Tz4aGDHIPwC1mlvnf7fg5lecYpMCrLLhauAc1UJXcgl
+01xoLuzgtAEAgv2P/jgytzRSpUYvgLBt1UA0leLYBy6mQQbrNEuqT3INapKIcUv8
+XxYP0xMEUksLPq6Ca+CRSqTtrd/23uTnapkwCQYHKoZIzj0EAQOBigAwgYYCQXJo
+A7Sl2nLVf+4Iu/tAX/IF4MavARKC4PPHK3zfuGfPR3oCCcsAoz3kAzOeijvd0iXb
+H5jBImIxPL4WxQNiBTexAkF8D1EtpYuWdlVQ80/h/f4pBcGiXPqX5h2PQSQY7hP1
++jwM1FGS4fREIOvlBYr/SzzQRtwrvrzGYxDEDbsC0ZGRnA==
+-----END CERTIFICATE-----
+`
+
+var ecdsaKeyPEM = testingKey(`-----BEGIN EC PARAMETERS-----
+BgUrgQQAIw==
+-----END EC PARAMETERS-----
+-----BEGIN EC TESTING KEY-----
+MIHcAgEBBEIBrsoKp0oqcv6/JovJJDoDVSGWdirrkgCWxrprGlzB9o0X8fV675X0
+NwuBenXFfeZvVcwluO7/Q9wkYoPd/t3jGImgBwYFK4EEACOhgYkDgYYABAFj36bL
+06h5JRGUNB1X/Hwuw64uKW2GGJLVPPhoYMcg/ALWaW+d/t+DmV5xikwKssuFq4Bz
+VQldyCXTXGgu7OC0AQCC/Y/+ODK3NFKlRi+AsG3VQDSV4tgHLqZBBus0S6pPcg1q
+kohxS/xfFg/TEwRSSws+roJr4JFKpO2t3/be5OdqmQ==
+-----END EC TESTING KEY-----
+`)
+
+var keyPairTests = []struct {
+ algo string
+ cert string
+ key string
+}{
+ {"ECDSA", ecdsaCertPEM, ecdsaKeyPEM},
+ {"RSA", rsaCertPEM, rsaKeyPEM},
+ {"RSA-untyped", rsaCertPEM, keyPEM}, // golang.org/issue/4477
+}
+
+func TestX509KeyPair(t *testing.T) {
+ t.Parallel()
+ var pem []byte
+ for _, test := range keyPairTests {
+ pem = []byte(test.cert + test.key)
+ if _, err := X509KeyPair(pem, pem); err != nil {
+ t.Errorf("Failed to load %s cert followed by %s key: %s", test.algo, test.algo, err)
+ }
+ pem = []byte(test.key + test.cert)
+ if _, err := X509KeyPair(pem, pem); err != nil {
+ t.Errorf("Failed to load %s key followed by %s cert: %s", test.algo, test.algo, err)
+ }
+ }
+}
+
+func TestX509KeyPairErrors(t *testing.T) {
+ _, err := X509KeyPair([]byte(rsaKeyPEM), []byte(rsaCertPEM))
+ if err == nil {
+ t.Fatalf("X509KeyPair didn't return an error when arguments were switched")
+ }
+ if subStr := "been switched"; !strings.Contains(err.Error(), subStr) {
+ t.Fatalf("Expected %q in the error when switching arguments to X509KeyPair, but the error was %q", subStr, err)
+ }
+
+ _, err = X509KeyPair([]byte(rsaCertPEM), []byte(rsaCertPEM))
+ if err == nil {
+ t.Fatalf("X509KeyPair didn't return an error when both arguments were certificates")
+ }
+ if subStr := "certificate"; !strings.Contains(err.Error(), subStr) {
+ t.Fatalf("Expected %q in the error when both arguments to X509KeyPair were certificates, but the error was %q", subStr, err)
+ }
+
+ const nonsensePEM = `
+-----BEGIN NONSENSE-----
+Zm9vZm9vZm9v
+-----END NONSENSE-----
+`
+
+ _, err = X509KeyPair([]byte(nonsensePEM), []byte(nonsensePEM))
+ if err == nil {
+ t.Fatalf("X509KeyPair didn't return an error when both arguments were nonsense")
+ }
+ if subStr := "NONSENSE"; !strings.Contains(err.Error(), subStr) {
+ t.Fatalf("Expected %q in the error when both arguments to X509KeyPair were nonsense, but the error was %q", subStr, err)
+ }
+}
+
+func TestX509MixedKeyPair(t *testing.T) {
+ if _, err := X509KeyPair([]byte(rsaCertPEM), []byte(ecdsaKeyPEM)); err == nil {
+ t.Error("Load of RSA certificate succeeded with ECDSA private key")
+ }
+ if _, err := X509KeyPair([]byte(ecdsaCertPEM), []byte(rsaKeyPEM)); err == nil {
+ t.Error("Load of ECDSA certificate succeeded with RSA private key")
+ }
+}
+
+func newLocalListener(t testing.TB) net.Listener {
+ ln, err := net.Listen("tcp", "127.0.0.1:0")
+ if err != nil {
+ ln, err = net.Listen("tcp6", "[::1]:0")
+ }
+ if err != nil {
+ t.Fatal(err)
+ }
+ return ln
+}
+
+func TestDialTimeout(t *testing.T) {
+ if testing.Short() {
+ t.Skip("skipping in short mode")
+ }
+
+ timeout := 100 * time.Microsecond
+ for !t.Failed() {
+ acceptc := make(chan net.Conn)
+ listener := newLocalListener(t)
+ go func() {
+ for {
+ conn, err := listener.Accept()
+ if err != nil {
+ close(acceptc)
+ return
+ }
+ acceptc <- conn
+ }
+ }()
+
+ addr := listener.Addr().String()
+ dialer := &net.Dialer{
+ Timeout: timeout,
+ }
+ if conn, err := DialWithDialer(dialer, "tcp", addr, nil); err == nil {
+ conn.Close()
+ t.Errorf("DialWithTimeout unexpectedly completed successfully")
+ } else if !isTimeoutError(err) {
+ t.Errorf("resulting error not a timeout: %v\nType %T: %#v", err, err, err)
+ }
+
+ listener.Close()
+
+ // We're looking for a timeout during the handshake, so check that the
+ // Listener actually accepted the connection to initiate it. (If the server
+ // takes too long to accept the connection, we might cancel before the
+ // underlying net.Conn is ever dialed — without ever attempting a
+ // handshake.)
+ lconn, ok := <-acceptc
+ if ok {
+ // The Listener accepted a connection, so assume that it was from our
+ // Dial: we triggered the timeout at the point where we wanted it!
+ t.Logf("Listener accepted a connection from %s", lconn.RemoteAddr())
+ lconn.Close()
+ }
+ // Close any spurious extra connecitions from the listener. (This is
+ // possible if there are, for example, stray Dial calls from other tests.)
+ for extraConn := range acceptc {
+ t.Logf("spurious extra connection from %s", extraConn.RemoteAddr())
+ extraConn.Close()
+ }
+ if ok {
+ break
+ }
+
+ t.Logf("with timeout %v, DialWithDialer returned before listener accepted any connections; retrying", timeout)
+ timeout *= 2
+ }
+}
+
+func TestDeadlineOnWrite(t *testing.T) {
+ if testing.Short() {
+ t.Skip("skipping in short mode")
+ }
+
+ ln := newLocalListener(t)
+ defer ln.Close()
+
+ srvCh := make(chan *Conn, 1)
+
+ go func() {
+ sconn, err := ln.Accept()
+ if err != nil {
+ srvCh <- nil
+ return
+ }
+ srv := Server(sconn, testConfig.Clone())
+ if err := srv.Handshake(); err != nil {
+ srvCh <- nil
+ return
+ }
+ srvCh <- srv
+ }()
+
+ clientConfig := testConfig.Clone()
+ clientConfig.MaxVersion = VersionTLS12
+ conn, err := Dial("tcp", ln.Addr().String(), clientConfig)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer conn.Close()
+
+ srv := <-srvCh
+ if srv == nil {
+ t.Error(err)
+ }
+
+ // Make sure the client/server is setup correctly and is able to do a typical Write/Read
+ buf := make([]byte, 6)
+ if _, err := srv.Write([]byte("foobar")); err != nil {
+ t.Errorf("Write err: %v", err)
+ }
+ if n, err := conn.Read(buf); n != 6 || err != nil || string(buf) != "foobar" {
+ t.Errorf("Read = %d, %v, data %q; want 6, nil, foobar", n, err, buf)
+ }
+
+ // Set a deadline which should cause Write to timeout
+ if err = srv.SetDeadline(time.Now()); err != nil {
+ t.Fatalf("SetDeadline(time.Now()) err: %v", err)
+ }
+ if _, err = srv.Write([]byte("should fail")); err == nil {
+ t.Fatal("Write should have timed out")
+ }
+
+ // Clear deadline and make sure it still times out
+ if err = srv.SetDeadline(time.Time{}); err != nil {
+ t.Fatalf("SetDeadline(time.Time{}) err: %v", err)
+ }
+ if _, err = srv.Write([]byte("This connection is permanently broken")); err == nil {
+ t.Fatal("Write which previously failed should still time out")
+ }
+
+ // Verify the error
+ if ne := err.(net.Error); ne.Temporary() != false {
+ t.Error("Write timed out but incorrectly classified the error as Temporary")
+ }
+ if !isTimeoutError(err) {
+ t.Error("Write timed out but did not classify the error as a Timeout")
+ }
+}
+
+type readerFunc func([]byte) (int, error)
+
+func (f readerFunc) Read(b []byte) (int, error) { return f(b) }
+
+// TestDialer tests that tls.Dialer.DialContext can abort in the middle of a handshake.
+// (The other cases are all handled by the existing dial tests in this package, which
+// all also flow through the same code shared code paths)
+func TestDialer(t *testing.T) {
+ ln := newLocalListener(t)
+ defer ln.Close()
+
+ unblockServer := make(chan struct{}) // close-only
+ defer close(unblockServer)
+ go func() {
+ conn, err := ln.Accept()
+ if err != nil {
+ return
+ }
+ defer conn.Close()
+ <-unblockServer
+ }()
+
+ ctx, cancel := context.WithCancel(context.Background())
+ d := Dialer{Config: &Config{
+ Rand: readerFunc(func(b []byte) (n int, err error) {
+ // By the time crypto/tls wants randomness, that means it has a TCP
+ // connection, so we're past the Dialer's dial and now blocked
+ // in a handshake. Cancel our context and see if we get unstuck.
+ // (Our TCP listener above never reads or writes, so the Handshake
+ // would otherwise be stuck forever)
+ cancel()
+ return len(b), nil
+ }),
+ ServerName: "foo",
+ }}
+ _, err := d.DialContext(ctx, "tcp", ln.Addr().String())
+ if err != context.Canceled {
+ t.Errorf("err = %v; want context.Canceled", err)
+ }
+}
+
+func isTimeoutError(err error) bool {
+ if ne, ok := err.(net.Error); ok {
+ return ne.Timeout()
+ }
+ return false
+}
+
+// tests that Conn.Read returns (non-zero, io.EOF) instead of
+// (non-zero, nil) when a Close (alertCloseNotify) is sitting right
+// behind the application data in the buffer.
+func TestConnReadNonzeroAndEOF(t *testing.T) {
+ // This test is racy: it assumes that after a write to a
+ // localhost TCP connection, the peer TCP connection can
+ // immediately read it. Because it's racy, we skip this test
+ // in short mode, and then retry it several times with an
+ // increasing sleep in between our final write (via srv.Close
+ // below) and the following read.
+ if testing.Short() {
+ t.Skip("skipping in short mode")
+ }
+ var err error
+ for delay := time.Millisecond; delay <= 64*time.Millisecond; delay *= 2 {
+ if err = testConnReadNonzeroAndEOF(t, delay); err == nil {
+ return
+ }
+ }
+ t.Error(err)
+}
+
+func testConnReadNonzeroAndEOF(t *testing.T, delay time.Duration) error {
+ ln := newLocalListener(t)
+ defer ln.Close()
+
+ srvCh := make(chan *Conn, 1)
+ var serr error
+ go func() {
+ sconn, err := ln.Accept()
+ if err != nil {
+ serr = err
+ srvCh <- nil
+ return
+ }
+ serverConfig := testConfig.Clone()
+ srv := Server(sconn, serverConfig)
+ if err := srv.Handshake(); err != nil {
+ serr = fmt.Errorf("handshake: %v", err)
+ srvCh <- nil
+ return
+ }
+ srvCh <- srv
+ }()
+
+ clientConfig := testConfig.Clone()
+ // In TLS 1.3, alerts are encrypted and disguised as application data, so
+ // the opportunistic peek won't work.
+ clientConfig.MaxVersion = VersionTLS12
+ conn, err := Dial("tcp", ln.Addr().String(), clientConfig)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer conn.Close()
+
+ srv := <-srvCh
+ if srv == nil {
+ return serr
+ }
+
+ buf := make([]byte, 6)
+
+ srv.Write([]byte("foobar"))
+ n, err := conn.Read(buf)
+ if n != 6 || err != nil || string(buf) != "foobar" {
+ return fmt.Errorf("Read = %d, %v, data %q; want 6, nil, foobar", n, err, buf)
+ }
+
+ srv.Write([]byte("abcdef"))
+ srv.Close()
+ time.Sleep(delay)
+ n, err = conn.Read(buf)
+ if n != 6 || string(buf) != "abcdef" {
+ return fmt.Errorf("Read = %d, buf= %q; want 6, abcdef", n, buf)
+ }
+ if err != io.EOF {
+ return fmt.Errorf("Second Read error = %v; want io.EOF", err)
+ }
+ return nil
+}
+
+func TestTLSUniqueMatches(t *testing.T) {
+ ln := newLocalListener(t)
+ defer ln.Close()
+
+ serverTLSUniques := make(chan []byte)
+ parentDone := make(chan struct{})
+ childDone := make(chan struct{})
+ defer close(parentDone)
+ go func() {
+ defer close(childDone)
+ for i := 0; i < 2; i++ {
+ sconn, err := ln.Accept()
+ if err != nil {
+ t.Error(err)
+ return
+ }
+ serverConfig := testConfig.Clone()
+ serverConfig.MaxVersion = VersionTLS12 // TLSUnique is not defined in TLS 1.3
+ srv := Server(sconn, serverConfig)
+ if err := srv.Handshake(); err != nil {
+ t.Error(err)
+ return
+ }
+ select {
+ case <-parentDone:
+ return
+ case serverTLSUniques <- srv.ConnectionState().TLSUnique:
+ }
+ }
+ }()
+
+ clientConfig := testConfig.Clone()
+ clientConfig.ClientSessionCache = NewLRUClientSessionCache(1)
+ conn, err := Dial("tcp", ln.Addr().String(), clientConfig)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ var serverTLSUniquesValue []byte
+ select {
+ case <-childDone:
+ return
+ case serverTLSUniquesValue = <-serverTLSUniques:
+ }
+
+ if !bytes.Equal(conn.ConnectionState().TLSUnique, serverTLSUniquesValue) {
+ t.Error("client and server channel bindings differ")
+ }
+ if serverTLSUniquesValue == nil || bytes.Equal(serverTLSUniquesValue, make([]byte, 12)) {
+ t.Error("tls-unique is empty or zero")
+ }
+ conn.Close()
+
+ conn, err = Dial("tcp", ln.Addr().String(), clientConfig)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer conn.Close()
+ if !conn.ConnectionState().DidResume {
+ t.Error("second session did not use resumption")
+ }
+
+ select {
+ case <-childDone:
+ return
+ case serverTLSUniquesValue = <-serverTLSUniques:
+ }
+
+ if !bytes.Equal(conn.ConnectionState().TLSUnique, serverTLSUniquesValue) {
+ t.Error("client and server channel bindings differ when session resumption is used")
+ }
+ if serverTLSUniquesValue == nil || bytes.Equal(serverTLSUniquesValue, make([]byte, 12)) {
+ t.Error("resumption tls-unique is empty or zero")
+ }
+}
+
+func TestVerifyHostname(t *testing.T) {
+ testenv.MustHaveExternalNetwork(t)
+
+ c, err := Dial("tcp", "www.google.com:https", nil)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err := c.VerifyHostname("www.google.com"); err != nil {
+ t.Fatalf("verify www.google.com: %v", err)
+ }
+ if err := c.VerifyHostname("www.yahoo.com"); err == nil {
+ t.Fatalf("verify www.yahoo.com succeeded")
+ }
+
+ c, err = Dial("tcp", "www.google.com:https", &Config{InsecureSkipVerify: true})
+ if err != nil {
+ t.Fatal(err)
+ }
+ if err := c.VerifyHostname("www.google.com"); err == nil {
+ t.Fatalf("verify www.google.com succeeded with InsecureSkipVerify=true")
+ }
+}
+
+func TestConnCloseBreakingWrite(t *testing.T) {
+ ln := newLocalListener(t)
+ defer ln.Close()
+
+ srvCh := make(chan *Conn, 1)
+ var serr error
+ var sconn net.Conn
+ go func() {
+ var err error
+ sconn, err = ln.Accept()
+ if err != nil {
+ serr = err
+ srvCh <- nil
+ return
+ }
+ serverConfig := testConfig.Clone()
+ srv := Server(sconn, serverConfig)
+ if err := srv.Handshake(); err != nil {
+ serr = fmt.Errorf("handshake: %v", err)
+ srvCh <- nil
+ return
+ }
+ srvCh <- srv
+ }()
+
+ cconn, err := net.Dial("tcp", ln.Addr().String())
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer cconn.Close()
+
+ conn := &changeImplConn{
+ Conn: cconn,
+ }
+
+ clientConfig := testConfig.Clone()
+ tconn := Client(conn, clientConfig)
+ if err := tconn.Handshake(); err != nil {
+ t.Fatal(err)
+ }
+
+ srv := <-srvCh
+ if srv == nil {
+ t.Fatal(serr)
+ }
+ defer sconn.Close()
+
+ connClosed := make(chan struct{})
+ conn.closeFunc = func() error {
+ close(connClosed)
+ return nil
+ }
+
+ inWrite := make(chan bool, 1)
+ var errConnClosed = errors.New("conn closed for test")
+ conn.writeFunc = func(p []byte) (n int, err error) {
+ inWrite <- true
+ <-connClosed
+ return 0, errConnClosed
+ }
+
+ closeReturned := make(chan bool, 1)
+ go func() {
+ <-inWrite
+ tconn.Close() // test that this doesn't block forever.
+ closeReturned <- true
+ }()
+
+ _, err = tconn.Write([]byte("foo"))
+ if err != errConnClosed {
+ t.Errorf("Write error = %v; want errConnClosed", err)
+ }
+
+ <-closeReturned
+ if err := tconn.Close(); err != net.ErrClosed {
+ t.Errorf("Close error = %v; want net.ErrClosed", err)
+ }
+}
+
+func TestConnCloseWrite(t *testing.T) {
+ ln := newLocalListener(t)
+ defer ln.Close()
+
+ clientDoneChan := make(chan struct{})
+
+ serverCloseWrite := func() error {
+ sconn, err := ln.Accept()
+ if err != nil {
+ return fmt.Errorf("accept: %v", err)
+ }
+ defer sconn.Close()
+
+ serverConfig := testConfig.Clone()
+ srv := Server(sconn, serverConfig)
+ if err := srv.Handshake(); err != nil {
+ return fmt.Errorf("handshake: %v", err)
+ }
+ defer srv.Close()
+
+ data, err := io.ReadAll(srv)
+ if err != nil {
+ return err
+ }
+ if len(data) > 0 {
+ return fmt.Errorf("Read data = %q; want nothing", data)
+ }
+
+ if err := srv.CloseWrite(); err != nil {
+ return fmt.Errorf("server CloseWrite: %v", err)
+ }
+
+ // Wait for clientCloseWrite to finish, so we know we
+ // tested the CloseWrite before we defer the
+ // sconn.Close above, which would also cause the
+ // client to unblock like CloseWrite.
+ <-clientDoneChan
+ return nil
+ }
+
+ clientCloseWrite := func() error {
+ defer close(clientDoneChan)
+
+ clientConfig := testConfig.Clone()
+ conn, err := Dial("tcp", ln.Addr().String(), clientConfig)
+ if err != nil {
+ return err
+ }
+ if err := conn.Handshake(); err != nil {
+ return err
+ }
+ defer conn.Close()
+
+ if err := conn.CloseWrite(); err != nil {
+ return fmt.Errorf("client CloseWrite: %v", err)
+ }
+
+ if _, err := conn.Write([]byte{0}); err != errShutdown {
+ return fmt.Errorf("CloseWrite error = %v; want errShutdown", err)
+ }
+
+ data, err := io.ReadAll(conn)
+ if err != nil {
+ return err
+ }
+ if len(data) > 0 {
+ return fmt.Errorf("Read data = %q; want nothing", data)
+ }
+ return nil
+ }
+
+ errChan := make(chan error, 2)
+
+ go func() { errChan <- serverCloseWrite() }()
+ go func() { errChan <- clientCloseWrite() }()
+
+ for i := 0; i < 2; i++ {
+ select {
+ case err := <-errChan:
+ if err != nil {
+ t.Fatal(err)
+ }
+ case <-time.After(10 * time.Second):
+ t.Fatal("deadlock")
+ }
+ }
+
+ // Also test CloseWrite being called before the handshake is
+ // finished:
+ {
+ ln2 := newLocalListener(t)
+ defer ln2.Close()
+
+ netConn, err := net.Dial("tcp", ln2.Addr().String())
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer netConn.Close()
+ conn := Client(netConn, testConfig.Clone())
+
+ if err := conn.CloseWrite(); err != errEarlyCloseWrite {
+ t.Errorf("CloseWrite error = %v; want errEarlyCloseWrite", err)
+ }
+ }
+}
+
+func TestWarningAlertFlood(t *testing.T) {
+ ln := newLocalListener(t)
+ defer ln.Close()
+
+ server := func() error {
+ sconn, err := ln.Accept()
+ if err != nil {
+ return fmt.Errorf("accept: %v", err)
+ }
+ defer sconn.Close()
+
+ serverConfig := testConfig.Clone()
+ srv := Server(sconn, serverConfig)
+ if err := srv.Handshake(); err != nil {
+ return fmt.Errorf("handshake: %v", err)
+ }
+ defer srv.Close()
+
+ _, err = io.ReadAll(srv)
+ if err == nil {
+ return errors.New("unexpected lack of error from server")
+ }
+ const expected = "too many ignored"
+ if str := err.Error(); !strings.Contains(str, expected) {
+ return fmt.Errorf("expected error containing %q, but saw: %s", expected, str)
+ }
+
+ return nil
+ }
+
+ errChan := make(chan error, 1)
+ go func() { errChan <- server() }()
+
+ clientConfig := testConfig.Clone()
+ clientConfig.MaxVersion = VersionTLS12 // there are no warning alerts in TLS 1.3
+ conn, err := Dial("tcp", ln.Addr().String(), clientConfig)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer conn.Close()
+ if err := conn.Handshake(); err != nil {
+ t.Fatal(err)
+ }
+
+ for i := 0; i < maxUselessRecords+1; i++ {
+ conn.sendAlert(alertNoRenegotiation)
+ }
+
+ if err := <-errChan; err != nil {
+ t.Fatal(err)
+ }
+}
+
+func TestCloneFuncFields(t *testing.T) {
+ const expectedCount = 8
+ called := 0
+
+ c1 := Config{
+ Time: func() time.Time {
+ called |= 1 << 0
+ return time.Time{}
+ },
+ GetCertificate: func(*ClientHelloInfo) (*Certificate, error) {
+ called |= 1 << 1
+ return nil, nil
+ },
+ GetClientCertificate: func(*CertificateRequestInfo) (*Certificate, error) {
+ called |= 1 << 2
+ return nil, nil
+ },
+ GetConfigForClient: func(*ClientHelloInfo) (*Config, error) {
+ called |= 1 << 3
+ return nil, nil
+ },
+ VerifyPeerCertificate: func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
+ called |= 1 << 4
+ return nil
+ },
+ VerifyConnection: func(ConnectionState) error {
+ called |= 1 << 5
+ return nil
+ },
+ UnwrapSession: func(identity []byte, cs ConnectionState) (*SessionState, error) {
+ called |= 1 << 6
+ return nil, nil
+ },
+ WrapSession: func(cs ConnectionState, ss *SessionState) ([]byte, error) {
+ called |= 1 << 7
+ return nil, nil
+ },
+ }
+
+ c2 := c1.Clone()
+
+ c2.Time()
+ c2.GetCertificate(nil)
+ c2.GetClientCertificate(nil)
+ c2.GetConfigForClient(nil)
+ c2.VerifyPeerCertificate(nil, nil)
+ c2.VerifyConnection(ConnectionState{})
+ c2.UnwrapSession(nil, ConnectionState{})
+ c2.WrapSession(ConnectionState{}, nil)
+
+ if called != (1<<expectedCount)-1 {
+ t.Fatalf("expected %d calls but saw calls %b", expectedCount, called)
+ }
+}
+
+func TestCloneNonFuncFields(t *testing.T) {
+ var c1 Config
+ v := reflect.ValueOf(&c1).Elem()
+
+ typ := v.Type()
+ for i := 0; i < typ.NumField(); i++ {
+ f := v.Field(i)
+ // testing/quick can't handle functions or interfaces and so
+ // isn't used here.
+ switch fn := typ.Field(i).Name; fn {
+ case "Rand":
+ f.Set(reflect.ValueOf(io.Reader(os.Stdin)))
+ case "Time", "GetCertificate", "GetConfigForClient", "VerifyPeerCertificate", "VerifyConnection", "GetClientCertificate", "WrapSession", "UnwrapSession":
+ // DeepEqual can't compare functions. If you add a
+ // function field to this list, you must also change
+ // TestCloneFuncFields to ensure that the func field is
+ // cloned.
+ case "Certificates":
+ f.Set(reflect.ValueOf([]Certificate{
+ {Certificate: [][]byte{{'b'}}},
+ }))
+ case "NameToCertificate":
+ f.Set(reflect.ValueOf(map[string]*Certificate{"a": nil}))
+ case "RootCAs", "ClientCAs":
+ f.Set(reflect.ValueOf(x509.NewCertPool()))
+ case "ClientSessionCache":
+ f.Set(reflect.ValueOf(NewLRUClientSessionCache(10)))
+ case "KeyLogWriter":
+ f.Set(reflect.ValueOf(io.Writer(os.Stdout)))
+ case "NextProtos":
+ f.Set(reflect.ValueOf([]string{"a", "b"}))
+ case "ServerName":
+ f.Set(reflect.ValueOf("b"))
+ case "ClientAuth":
+ f.Set(reflect.ValueOf(VerifyClientCertIfGiven))
+ case "InsecureSkipVerify", "SessionTicketsDisabled", "DynamicRecordSizingDisabled", "PreferServerCipherSuites":
+ f.Set(reflect.ValueOf(true))
+ case "MinVersion", "MaxVersion":
+ f.Set(reflect.ValueOf(uint16(VersionTLS12)))
+ case "SessionTicketKey":
+ f.Set(reflect.ValueOf([32]byte{}))
+ case "CipherSuites":
+ f.Set(reflect.ValueOf([]uint16{1, 2}))
+ case "CurvePreferences":
+ f.Set(reflect.ValueOf([]CurveID{CurveP256}))
+ case "Renegotiation":
+ f.Set(reflect.ValueOf(RenegotiateOnceAsClient))
+ case "mutex", "autoSessionTicketKeys", "sessionTicketKeys":
+ continue // these are unexported fields that are handled separately
+ default:
+ t.Errorf("all fields must be accounted for, but saw unknown field %q", fn)
+ }
+ }
+ // Set the unexported fields related to session ticket keys, which are copied with Clone().
+ c1.autoSessionTicketKeys = []ticketKey{c1.ticketKeyFromBytes(c1.SessionTicketKey)}
+ c1.sessionTicketKeys = []ticketKey{c1.ticketKeyFromBytes(c1.SessionTicketKey)}
+
+ c2 := c1.Clone()
+ if !reflect.DeepEqual(&c1, c2) {
+ t.Errorf("clone failed to copy a field")
+ }
+}
+
+func TestCloneNilConfig(t *testing.T) {
+ var config *Config
+ if cc := config.Clone(); cc != nil {
+ t.Fatalf("Clone with nil should return nil, got: %+v", cc)
+ }
+}
+
+// changeImplConn is a net.Conn which can change its Write and Close
+// methods.
+type changeImplConn struct {
+ net.Conn
+ writeFunc func([]byte) (int, error)
+ closeFunc func() error
+}
+
+func (w *changeImplConn) Write(p []byte) (n int, err error) {
+ if w.writeFunc != nil {
+ return w.writeFunc(p)
+ }
+ return w.Conn.Write(p)
+}
+
+func (w *changeImplConn) Close() error {
+ if w.closeFunc != nil {
+ return w.closeFunc()
+ }
+ return w.Conn.Close()
+}
+
+func throughput(b *testing.B, version uint16, totalBytes int64, dynamicRecordSizingDisabled bool) {
+ ln := newLocalListener(b)
+ defer ln.Close()
+
+ N := b.N
+
+ // Less than 64KB because Windows appears to use a TCP rwin < 64KB.
+ // See Issue #15899.
+ const bufsize = 32 << 10
+
+ go func() {
+ buf := make([]byte, bufsize)
+ for i := 0; i < N; i++ {
+ sconn, err := ln.Accept()
+ if err != nil {
+ // panic rather than synchronize to avoid benchmark overhead
+ // (cannot call b.Fatal in goroutine)
+ panic(fmt.Errorf("accept: %v", err))
+ }
+ serverConfig := testConfig.Clone()
+ serverConfig.CipherSuites = nil // the defaults may prefer faster ciphers
+ serverConfig.DynamicRecordSizingDisabled = dynamicRecordSizingDisabled
+ srv := Server(sconn, serverConfig)
+ if err := srv.Handshake(); err != nil {
+ panic(fmt.Errorf("handshake: %v", err))
+ }
+ if _, err := io.CopyBuffer(srv, srv, buf); err != nil {
+ panic(fmt.Errorf("copy buffer: %v", err))
+ }
+ }
+ }()
+
+ b.SetBytes(totalBytes)
+ clientConfig := testConfig.Clone()
+ clientConfig.CipherSuites = nil // the defaults may prefer faster ciphers
+ clientConfig.DynamicRecordSizingDisabled = dynamicRecordSizingDisabled
+ clientConfig.MaxVersion = version
+
+ buf := make([]byte, bufsize)
+ chunks := int(math.Ceil(float64(totalBytes) / float64(len(buf))))
+ for i := 0; i < N; i++ {
+ conn, err := Dial("tcp", ln.Addr().String(), clientConfig)
+ if err != nil {
+ b.Fatal(err)
+ }
+ for j := 0; j < chunks; j++ {
+ _, err := conn.Write(buf)
+ if err != nil {
+ b.Fatal(err)
+ }
+ _, err = io.ReadFull(conn, buf)
+ if err != nil {
+ b.Fatal(err)
+ }
+ }
+ conn.Close()
+ }
+}
+
+func BenchmarkThroughput(b *testing.B) {
+ for _, mode := range []string{"Max", "Dynamic"} {
+ for size := 1; size <= 64; size <<= 1 {
+ name := fmt.Sprintf("%sPacket/%dMB", mode, size)
+ b.Run(name, func(b *testing.B) {
+ b.Run("TLSv12", func(b *testing.B) {
+ throughput(b, VersionTLS12, int64(size<<20), mode == "Max")
+ })
+ b.Run("TLSv13", func(b *testing.B) {
+ throughput(b, VersionTLS13, int64(size<<20), mode == "Max")
+ })
+ })
+ }
+ }
+}
+
+type slowConn struct {
+ net.Conn
+ bps int
+}
+
+func (c *slowConn) Write(p []byte) (int, error) {
+ if c.bps == 0 {
+ panic("too slow")
+ }
+ t0 := time.Now()
+ wrote := 0
+ for wrote < len(p) {
+ time.Sleep(100 * time.Microsecond)
+ allowed := int(time.Since(t0).Seconds()*float64(c.bps)) / 8
+ if allowed > len(p) {
+ allowed = len(p)
+ }
+ if wrote < allowed {
+ n, err := c.Conn.Write(p[wrote:allowed])
+ wrote += n
+ if err != nil {
+ return wrote, err
+ }
+ }
+ }
+ return len(p), nil
+}
+
+func latency(b *testing.B, version uint16, bps int, dynamicRecordSizingDisabled bool) {
+ ln := newLocalListener(b)
+ defer ln.Close()
+
+ N := b.N
+
+ go func() {
+ for i := 0; i < N; i++ {
+ sconn, err := ln.Accept()
+ if err != nil {
+ // panic rather than synchronize to avoid benchmark overhead
+ // (cannot call b.Fatal in goroutine)
+ panic(fmt.Errorf("accept: %v", err))
+ }
+ serverConfig := testConfig.Clone()
+ serverConfig.DynamicRecordSizingDisabled = dynamicRecordSizingDisabled
+ srv := Server(&slowConn{sconn, bps}, serverConfig)
+ if err := srv.Handshake(); err != nil {
+ panic(fmt.Errorf("handshake: %v", err))
+ }
+ io.Copy(srv, srv)
+ }
+ }()
+
+ clientConfig := testConfig.Clone()
+ clientConfig.DynamicRecordSizingDisabled = dynamicRecordSizingDisabled
+ clientConfig.MaxVersion = version
+
+ buf := make([]byte, 16384)
+ peek := make([]byte, 1)
+
+ for i := 0; i < N; i++ {
+ conn, err := Dial("tcp", ln.Addr().String(), clientConfig)
+ if err != nil {
+ b.Fatal(err)
+ }
+ // make sure we're connected and previous connection has stopped
+ if _, err := conn.Write(buf[:1]); err != nil {
+ b.Fatal(err)
+ }
+ if _, err := io.ReadFull(conn, peek); err != nil {
+ b.Fatal(err)
+ }
+ if _, err := conn.Write(buf); err != nil {
+ b.Fatal(err)
+ }
+ if _, err = io.ReadFull(conn, peek); err != nil {
+ b.Fatal(err)
+ }
+ conn.Close()
+ }
+}
+
+func BenchmarkLatency(b *testing.B) {
+ for _, mode := range []string{"Max", "Dynamic"} {
+ for _, kbps := range []int{200, 500, 1000, 2000, 5000} {
+ name := fmt.Sprintf("%sPacket/%dkbps", mode, kbps)
+ b.Run(name, func(b *testing.B) {
+ b.Run("TLSv12", func(b *testing.B) {
+ latency(b, VersionTLS12, kbps*1000, mode == "Max")
+ })
+ b.Run("TLSv13", func(b *testing.B) {
+ latency(b, VersionTLS13, kbps*1000, mode == "Max")
+ })
+ })
+ }
+ }
+}
+
+func TestConnectionStateMarshal(t *testing.T) {
+ cs := &ConnectionState{}
+ _, err := json.Marshal(cs)
+ if err != nil {
+ t.Errorf("json.Marshal failed on ConnectionState: %v", err)
+ }
+}
+
+func TestConnectionState(t *testing.T) {
+ issuer, err := x509.ParseCertificate(testRSACertificateIssuer)
+ if err != nil {
+ panic(err)
+ }
+ rootCAs := x509.NewCertPool()
+ rootCAs.AddCert(issuer)
+
+ now := func() time.Time { return time.Unix(1476984729, 0) }
+
+ const alpnProtocol = "golang"
+ const serverName = "example.golang"
+ var scts = [][]byte{[]byte("dummy sct 1"), []byte("dummy sct 2")}
+ var ocsp = []byte("dummy ocsp")
+
+ for _, v := range []uint16{VersionTLS12, VersionTLS13} {
+ var name string
+ switch v {
+ case VersionTLS12:
+ name = "TLSv12"
+ case VersionTLS13:
+ name = "TLSv13"
+ }
+ t.Run(name, func(t *testing.T) {
+ config := &Config{
+ Time: now,
+ Rand: zeroSource{},
+ Certificates: make([]Certificate, 1),
+ MaxVersion: v,
+ RootCAs: rootCAs,
+ ClientCAs: rootCAs,
+ ClientAuth: RequireAndVerifyClientCert,
+ NextProtos: []string{alpnProtocol},
+ ServerName: serverName,
+ }
+ config.Certificates[0].Certificate = [][]byte{testRSACertificate}
+ config.Certificates[0].PrivateKey = testRSAPrivateKey
+ config.Certificates[0].SignedCertificateTimestamps = scts
+ config.Certificates[0].OCSPStaple = ocsp
+
+ ss, cs, err := testHandshake(t, config, config)
+ if err != nil {
+ t.Fatalf("Handshake failed: %v", err)
+ }
+
+ if ss.Version != v || cs.Version != v {
+ t.Errorf("Got versions %x (server) and %x (client), expected %x", ss.Version, cs.Version, v)
+ }
+
+ if !ss.HandshakeComplete || !cs.HandshakeComplete {
+ t.Errorf("Got HandshakeComplete %v (server) and %v (client), expected true", ss.HandshakeComplete, cs.HandshakeComplete)
+ }
+
+ if ss.DidResume || cs.DidResume {
+ t.Errorf("Got DidResume %v (server) and %v (client), expected false", ss.DidResume, cs.DidResume)
+ }
+
+ if ss.CipherSuite == 0 || cs.CipherSuite == 0 {
+ t.Errorf("Got invalid cipher suite: %v (server) and %v (client)", ss.CipherSuite, cs.CipherSuite)
+ }
+
+ if ss.NegotiatedProtocol != alpnProtocol || cs.NegotiatedProtocol != alpnProtocol {
+ t.Errorf("Got negotiated protocol %q (server) and %q (client), expected %q", ss.NegotiatedProtocol, cs.NegotiatedProtocol, alpnProtocol)
+ }
+
+ if !cs.NegotiatedProtocolIsMutual {
+ t.Errorf("Got false NegotiatedProtocolIsMutual on the client side")
+ }
+ // NegotiatedProtocolIsMutual on the server side is unspecified.
+
+ if ss.ServerName != serverName {
+ t.Errorf("Got server name %q, expected %q", ss.ServerName, serverName)
+ }
+ if cs.ServerName != serverName {
+ t.Errorf("Got server name on client connection %q, expected %q", cs.ServerName, serverName)
+ }
+
+ if len(ss.PeerCertificates) != 1 || len(cs.PeerCertificates) != 1 {
+ t.Errorf("Got %d (server) and %d (client) peer certificates, expected %d", len(ss.PeerCertificates), len(cs.PeerCertificates), 1)
+ }
+
+ if len(ss.VerifiedChains) != 1 || len(cs.VerifiedChains) != 1 {
+ t.Errorf("Got %d (server) and %d (client) verified chains, expected %d", len(ss.VerifiedChains), len(cs.VerifiedChains), 1)
+ } else if len(ss.VerifiedChains[0]) != 2 || len(cs.VerifiedChains[0]) != 2 {
+ t.Errorf("Got %d (server) and %d (client) long verified chain, expected %d", len(ss.VerifiedChains[0]), len(cs.VerifiedChains[0]), 2)
+ }
+
+ if len(cs.SignedCertificateTimestamps) != 2 {
+ t.Errorf("Got %d SCTs, expected %d", len(cs.SignedCertificateTimestamps), 2)
+ }
+ if !bytes.Equal(cs.OCSPResponse, ocsp) {
+ t.Errorf("Got OCSPs %x, expected %x", cs.OCSPResponse, ocsp)
+ }
+ // Only TLS 1.3 supports OCSP and SCTs on client certs.
+ if v == VersionTLS13 {
+ if len(ss.SignedCertificateTimestamps) != 2 {
+ t.Errorf("Got %d client SCTs, expected %d", len(ss.SignedCertificateTimestamps), 2)
+ }
+ if !bytes.Equal(ss.OCSPResponse, ocsp) {
+ t.Errorf("Got client OCSPs %x, expected %x", ss.OCSPResponse, ocsp)
+ }
+ }
+
+ if v == VersionTLS13 {
+ if ss.TLSUnique != nil || cs.TLSUnique != nil {
+ t.Errorf("Got TLSUnique %x (server) and %x (client), expected nil in TLS 1.3", ss.TLSUnique, cs.TLSUnique)
+ }
+ } else {
+ if ss.TLSUnique == nil || cs.TLSUnique == nil {
+ t.Errorf("Got TLSUnique %x (server) and %x (client), expected non-nil", ss.TLSUnique, cs.TLSUnique)
+ }
+ }
+ })
+ }
+}
+
+// Issue 28744: Ensure that we don't modify memory
+// that Config doesn't own such as Certificates.
+func TestBuildNameToCertificate_doesntModifyCertificates(t *testing.T) {
+ c0 := Certificate{
+ Certificate: [][]byte{testRSACertificate},
+ PrivateKey: testRSAPrivateKey,
+ }
+ c1 := Certificate{
+ Certificate: [][]byte{testSNICertificate},
+ PrivateKey: testRSAPrivateKey,
+ }
+ config := testConfig.Clone()
+ config.Certificates = []Certificate{c0, c1}
+
+ config.BuildNameToCertificate()
+ got := config.Certificates
+ want := []Certificate{c0, c1}
+ if !reflect.DeepEqual(got, want) {
+ t.Fatalf("Certificates were mutated by BuildNameToCertificate\nGot: %#v\nWant: %#v\n", got, want)
+ }
+}
+
+func testingKey(s string) string { return strings.ReplaceAll(s, "TESTING KEY", "PRIVATE KEY") }
+
+func TestClientHelloInfo_SupportsCertificate(t *testing.T) {
+ rsaCert := &Certificate{
+ Certificate: [][]byte{testRSACertificate},
+ PrivateKey: testRSAPrivateKey,
+ }
+ pkcs1Cert := &Certificate{
+ Certificate: [][]byte{testRSACertificate},
+ PrivateKey: testRSAPrivateKey,
+ SupportedSignatureAlgorithms: []SignatureScheme{PKCS1WithSHA1, PKCS1WithSHA256},
+ }
+ ecdsaCert := &Certificate{
+ // ECDSA P-256 certificate
+ Certificate: [][]byte{testP256Certificate},
+ PrivateKey: testP256PrivateKey,
+ }
+ ed25519Cert := &Certificate{
+ Certificate: [][]byte{testEd25519Certificate},
+ PrivateKey: testEd25519PrivateKey,
+ }
+
+ tests := []struct {
+ c *Certificate
+ chi *ClientHelloInfo
+ wantErr string
+ }{
+ {rsaCert, &ClientHelloInfo{
+ ServerName: "example.golang",
+ SignatureSchemes: []SignatureScheme{PSSWithSHA256},
+ SupportedVersions: []uint16{VersionTLS13},
+ }, ""},
+ {ecdsaCert, &ClientHelloInfo{
+ SignatureSchemes: []SignatureScheme{PSSWithSHA256, ECDSAWithP256AndSHA256},
+ SupportedVersions: []uint16{VersionTLS13, VersionTLS12},
+ }, ""},
+ {rsaCert, &ClientHelloInfo{
+ ServerName: "example.com",
+ SignatureSchemes: []SignatureScheme{PSSWithSHA256},
+ SupportedVersions: []uint16{VersionTLS13},
+ }, "not valid for requested server name"},
+ {ecdsaCert, &ClientHelloInfo{
+ SignatureSchemes: []SignatureScheme{ECDSAWithP384AndSHA384},
+ SupportedVersions: []uint16{VersionTLS13},
+ }, "signature algorithms"},
+ {pkcs1Cert, &ClientHelloInfo{
+ SignatureSchemes: []SignatureScheme{PSSWithSHA256, ECDSAWithP256AndSHA256},
+ SupportedVersions: []uint16{VersionTLS13},
+ }, "signature algorithms"},
+
+ {rsaCert, &ClientHelloInfo{
+ CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
+ SignatureSchemes: []SignatureScheme{PKCS1WithSHA1},
+ SupportedVersions: []uint16{VersionTLS13, VersionTLS12},
+ }, "signature algorithms"},
+ {rsaCert, &ClientHelloInfo{
+ CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
+ SignatureSchemes: []SignatureScheme{PKCS1WithSHA1},
+ SupportedVersions: []uint16{VersionTLS13, VersionTLS12},
+ config: &Config{
+ MaxVersion: VersionTLS12,
+ },
+ }, ""}, // Check that mutual version selection works.
+
+ {ecdsaCert, &ClientHelloInfo{
+ CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
+ SupportedCurves: []CurveID{CurveP256},
+ SupportedPoints: []uint8{pointFormatUncompressed},
+ SignatureSchemes: []SignatureScheme{ECDSAWithP256AndSHA256},
+ SupportedVersions: []uint16{VersionTLS12},
+ }, ""},
+ {ecdsaCert, &ClientHelloInfo{
+ CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
+ SupportedCurves: []CurveID{CurveP256},
+ SupportedPoints: []uint8{pointFormatUncompressed},
+ SignatureSchemes: []SignatureScheme{ECDSAWithP384AndSHA384},
+ SupportedVersions: []uint16{VersionTLS12},
+ }, ""}, // TLS 1.2 does not restrict curves based on the SignatureScheme.
+ {ecdsaCert, &ClientHelloInfo{
+ CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
+ SupportedCurves: []CurveID{CurveP256},
+ SupportedPoints: []uint8{pointFormatUncompressed},
+ SignatureSchemes: nil,
+ SupportedVersions: []uint16{VersionTLS12},
+ }, ""}, // TLS 1.2 comes with default signature schemes.
+ {ecdsaCert, &ClientHelloInfo{
+ CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
+ SupportedCurves: []CurveID{CurveP256},
+ SupportedPoints: []uint8{pointFormatUncompressed},
+ SignatureSchemes: []SignatureScheme{ECDSAWithP256AndSHA256},
+ SupportedVersions: []uint16{VersionTLS12},
+ }, "cipher suite"},
+ {ecdsaCert, &ClientHelloInfo{
+ CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
+ SupportedCurves: []CurveID{CurveP256},
+ SupportedPoints: []uint8{pointFormatUncompressed},
+ SignatureSchemes: []SignatureScheme{ECDSAWithP256AndSHA256},
+ SupportedVersions: []uint16{VersionTLS12},
+ config: &Config{
+ CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
+ },
+ }, "cipher suite"},
+ {ecdsaCert, &ClientHelloInfo{
+ CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
+ SupportedCurves: []CurveID{CurveP384},
+ SupportedPoints: []uint8{pointFormatUncompressed},
+ SignatureSchemes: []SignatureScheme{ECDSAWithP256AndSHA256},
+ SupportedVersions: []uint16{VersionTLS12},
+ }, "certificate curve"},
+ {ecdsaCert, &ClientHelloInfo{
+ CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
+ SupportedCurves: []CurveID{CurveP256},
+ SupportedPoints: []uint8{1},
+ SignatureSchemes: []SignatureScheme{ECDSAWithP256AndSHA256},
+ SupportedVersions: []uint16{VersionTLS12},
+ }, "doesn't support ECDHE"},
+ {ecdsaCert, &ClientHelloInfo{
+ CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
+ SupportedCurves: []CurveID{CurveP256},
+ SupportedPoints: []uint8{pointFormatUncompressed},
+ SignatureSchemes: []SignatureScheme{PSSWithSHA256},
+ SupportedVersions: []uint16{VersionTLS12},
+ }, "signature algorithms"},
+
+ {ed25519Cert, &ClientHelloInfo{
+ CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
+ SupportedCurves: []CurveID{CurveP256}, // only relevant for ECDHE support
+ SupportedPoints: []uint8{pointFormatUncompressed},
+ SignatureSchemes: []SignatureScheme{Ed25519},
+ SupportedVersions: []uint16{VersionTLS12},
+ }, ""},
+ {ed25519Cert, &ClientHelloInfo{
+ CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
+ SupportedCurves: []CurveID{CurveP256}, // only relevant for ECDHE support
+ SupportedPoints: []uint8{pointFormatUncompressed},
+ SignatureSchemes: []SignatureScheme{Ed25519},
+ SupportedVersions: []uint16{VersionTLS10},
+ }, "doesn't support Ed25519"},
+ {ed25519Cert, &ClientHelloInfo{
+ CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
+ SupportedCurves: []CurveID{},
+ SupportedPoints: []uint8{pointFormatUncompressed},
+ SignatureSchemes: []SignatureScheme{Ed25519},
+ SupportedVersions: []uint16{VersionTLS12},
+ }, "doesn't support ECDHE"},
+
+ {rsaCert, &ClientHelloInfo{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
+ SupportedCurves: []CurveID{CurveP256}, // only relevant for ECDHE support
+ SupportedPoints: []uint8{pointFormatUncompressed},
+ SupportedVersions: []uint16{VersionTLS10},
+ }, ""},
+ {rsaCert, &ClientHelloInfo{
+ CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
+ SupportedVersions: []uint16{VersionTLS12},
+ }, ""}, // static RSA fallback
+ }
+ for i, tt := range tests {
+ err := tt.chi.SupportsCertificate(tt.c)
+ switch {
+ case tt.wantErr == "" && err != nil:
+ t.Errorf("%d: unexpected error: %v", i, err)
+ case tt.wantErr != "" && err == nil:
+ t.Errorf("%d: unexpected success", i)
+ case tt.wantErr != "" && !strings.Contains(err.Error(), tt.wantErr):
+ t.Errorf("%d: got error %q, expected %q", i, err, tt.wantErr)
+ }
+ }
+}
+
+func TestCipherSuites(t *testing.T) {
+ var lastID uint16
+ for _, c := range CipherSuites() {
+ if lastID > c.ID {
+ t.Errorf("CipherSuites are not ordered by ID: got %#04x after %#04x", c.ID, lastID)
+ } else {
+ lastID = c.ID
+ }
+
+ if c.Insecure {
+ t.Errorf("%#04x: Insecure CipherSuite returned by CipherSuites()", c.ID)
+ }
+ }
+ lastID = 0
+ for _, c := range InsecureCipherSuites() {
+ if lastID > c.ID {
+ t.Errorf("InsecureCipherSuites are not ordered by ID: got %#04x after %#04x", c.ID, lastID)
+ } else {
+ lastID = c.ID
+ }
+
+ if !c.Insecure {
+ t.Errorf("%#04x: not Insecure CipherSuite returned by InsecureCipherSuites()", c.ID)
+ }
+ }
+
+ CipherSuiteByID := func(id uint16) *CipherSuite {
+ for _, c := range CipherSuites() {
+ if c.ID == id {
+ return c
+ }
+ }
+ for _, c := range InsecureCipherSuites() {
+ if c.ID == id {
+ return c
+ }
+ }
+ return nil
+ }
+
+ for _, c := range cipherSuites {
+ cc := CipherSuiteByID(c.id)
+ if cc == nil {
+ t.Errorf("%#04x: no CipherSuite entry", c.id)
+ continue
+ }
+
+ if tls12Only := c.flags&suiteTLS12 != 0; tls12Only && len(cc.SupportedVersions) != 1 {
+ t.Errorf("%#04x: suite is TLS 1.2 only, but SupportedVersions is %v", c.id, cc.SupportedVersions)
+ } else if !tls12Only && len(cc.SupportedVersions) != 3 {
+ t.Errorf("%#04x: suite TLS 1.0-1.2, but SupportedVersions is %v", c.id, cc.SupportedVersions)
+ }
+
+ if got := CipherSuiteName(c.id); got != cc.Name {
+ t.Errorf("%#04x: unexpected CipherSuiteName: got %q, expected %q", c.id, got, cc.Name)
+ }
+ }
+ for _, c := range cipherSuitesTLS13 {
+ cc := CipherSuiteByID(c.id)
+ if cc == nil {
+ t.Errorf("%#04x: no CipherSuite entry", c.id)
+ continue
+ }
+
+ if cc.Insecure {
+ t.Errorf("%#04x: Insecure %v, expected false", c.id, cc.Insecure)
+ }
+ if len(cc.SupportedVersions) != 1 || cc.SupportedVersions[0] != VersionTLS13 {
+ t.Errorf("%#04x: suite is TLS 1.3 only, but SupportedVersions is %v", c.id, cc.SupportedVersions)
+ }
+
+ if got := CipherSuiteName(c.id); got != cc.Name {
+ t.Errorf("%#04x: unexpected CipherSuiteName: got %q, expected %q", c.id, got, cc.Name)
+ }
+ }
+
+ if got := CipherSuiteName(0xabc); got != "0x0ABC" {
+ t.Errorf("unexpected fallback CipherSuiteName: got %q, expected 0x0ABC", got)
+ }
+
+ if len(cipherSuitesPreferenceOrder) != len(cipherSuites) {
+ t.Errorf("cipherSuitesPreferenceOrder is not the same size as cipherSuites")
+ }
+ if len(cipherSuitesPreferenceOrderNoAES) != len(cipherSuitesPreferenceOrder) {
+ t.Errorf("cipherSuitesPreferenceOrderNoAES is not the same size as cipherSuitesPreferenceOrder")
+ }
+
+ // Check that disabled suites are at the end of the preference lists, and
+ // that they are marked insecure.
+ for i, id := range disabledCipherSuites {
+ offset := len(cipherSuitesPreferenceOrder) - len(disabledCipherSuites)
+ if cipherSuitesPreferenceOrder[offset+i] != id {
+ t.Errorf("disabledCipherSuites[%d]: not at the end of cipherSuitesPreferenceOrder", i)
+ }
+ if cipherSuitesPreferenceOrderNoAES[offset+i] != id {
+ t.Errorf("disabledCipherSuites[%d]: not at the end of cipherSuitesPreferenceOrderNoAES", i)
+ }
+ c := CipherSuiteByID(id)
+ if c == nil {
+ t.Errorf("%#04x: no CipherSuite entry", id)
+ continue
+ }
+ if !c.Insecure {
+ t.Errorf("%#04x: disabled by default but not marked insecure", id)
+ }
+ }
+
+ for i, prefOrder := range [][]uint16{cipherSuitesPreferenceOrder, cipherSuitesPreferenceOrderNoAES} {
+ // Check that insecure and HTTP/2 bad cipher suites are at the end of
+ // the preference lists.
+ var sawInsecure, sawBad bool
+ for _, id := range prefOrder {
+ c := CipherSuiteByID(id)
+ if c == nil {
+ t.Errorf("%#04x: no CipherSuite entry", id)
+ continue
+ }
+
+ if c.Insecure {
+ sawInsecure = true
+ } else if sawInsecure {
+ t.Errorf("%#04x: secure suite after insecure one(s)", id)
+ }
+
+ if http2isBadCipher(id) {
+ sawBad = true
+ } else if sawBad {
+ t.Errorf("%#04x: non-bad suite after bad HTTP/2 one(s)", id)
+ }
+ }
+
+ // Check that the list is sorted according to the documented criteria.
+ isBetter := func(a, b int) bool {
+ aSuite, bSuite := cipherSuiteByID(prefOrder[a]), cipherSuiteByID(prefOrder[b])
+ aName, bName := CipherSuiteName(prefOrder[a]), CipherSuiteName(prefOrder[b])
+ // * < RC4
+ if !strings.Contains(aName, "RC4") && strings.Contains(bName, "RC4") {
+ return true
+ } else if strings.Contains(aName, "RC4") && !strings.Contains(bName, "RC4") {
+ return false
+ }
+ // * < CBC_SHA256
+ if !strings.Contains(aName, "CBC_SHA256") && strings.Contains(bName, "CBC_SHA256") {
+ return true
+ } else if strings.Contains(aName, "CBC_SHA256") && !strings.Contains(bName, "CBC_SHA256") {
+ return false
+ }
+ // * < 3DES
+ if !strings.Contains(aName, "3DES") && strings.Contains(bName, "3DES") {
+ return true
+ } else if strings.Contains(aName, "3DES") && !strings.Contains(bName, "3DES") {
+ return false
+ }
+ // ECDHE < *
+ if aSuite.flags&suiteECDHE != 0 && bSuite.flags&suiteECDHE == 0 {
+ return true
+ } else if aSuite.flags&suiteECDHE == 0 && bSuite.flags&suiteECDHE != 0 {
+ return false
+ }
+ // AEAD < CBC
+ if aSuite.aead != nil && bSuite.aead == nil {
+ return true
+ } else if aSuite.aead == nil && bSuite.aead != nil {
+ return false
+ }
+ // AES < ChaCha20
+ if strings.Contains(aName, "AES") && strings.Contains(bName, "CHACHA20") {
+ return i == 0 // true for cipherSuitesPreferenceOrder
+ } else if strings.Contains(aName, "CHACHA20") && strings.Contains(bName, "AES") {
+ return i != 0 // true for cipherSuitesPreferenceOrderNoAES
+ }
+ // AES-128 < AES-256
+ if strings.Contains(aName, "AES_128") && strings.Contains(bName, "AES_256") {
+ return true
+ } else if strings.Contains(aName, "AES_256") && strings.Contains(bName, "AES_128") {
+ return false
+ }
+ // ECDSA < RSA
+ if aSuite.flags&suiteECSign != 0 && bSuite.flags&suiteECSign == 0 {
+ return true
+ } else if aSuite.flags&suiteECSign == 0 && bSuite.flags&suiteECSign != 0 {
+ return false
+ }
+ t.Fatalf("two ciphersuites are equal by all criteria: %v and %v", aName, bName)
+ panic("unreachable")
+ }
+ if !sort.SliceIsSorted(prefOrder, isBetter) {
+ t.Error("preference order is not sorted according to the rules")
+ }
+ }
+}
+
+func TestVersionName(t *testing.T) {
+ if got, exp := VersionName(VersionTLS13), "TLS 1.3"; got != exp {
+ t.Errorf("unexpected VersionName: got %q, expected %q", got, exp)
+ }
+ if got, exp := VersionName(0x12a), "0x012A"; got != exp {
+ t.Errorf("unexpected fallback VersionName: got %q, expected %q", got, exp)
+ }
+}
+
+// http2isBadCipher is copied from net/http.
+// TODO: if it ends up exposed somewhere, use that instead.
+func http2isBadCipher(cipher uint16) bool {
+ switch cipher {
+ case TLS_RSA_WITH_RC4_128_SHA,
+ TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+ TLS_RSA_WITH_AES_128_CBC_SHA,
+ TLS_RSA_WITH_AES_256_CBC_SHA,
+ TLS_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_RSA_WITH_AES_256_GCM_SHA384,
+ TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_RC4_128_SHA,
+ TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
+ return true
+ default:
+ return false
+ }
+}
+
+type brokenSigner struct{ crypto.Signer }
+
+func (s brokenSigner) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) {
+ // Replace opts with opts.HashFunc(), so rsa.PSSOptions are discarded.
+ return s.Signer.Sign(rand, digest, opts.HashFunc())
+}
+
+// TestPKCS1OnlyCert uses a client certificate with a broken crypto.Signer that
+// always makes PKCS #1 v1.5 signatures, so can't be used with RSA-PSS.
+func TestPKCS1OnlyCert(t *testing.T) {
+ clientConfig := testConfig.Clone()
+ clientConfig.Certificates = []Certificate{{
+ Certificate: [][]byte{testRSACertificate},
+ PrivateKey: brokenSigner{testRSAPrivateKey},
+ }}
+ serverConfig := testConfig.Clone()
+ serverConfig.MaxVersion = VersionTLS12 // TLS 1.3 doesn't support PKCS #1 v1.5
+ serverConfig.ClientAuth = RequireAnyClientCert
+
+ // If RSA-PSS is selected, the handshake should fail.
+ if _, _, err := testHandshake(t, clientConfig, serverConfig); err == nil {
+ t.Fatal("expected broken certificate to cause connection to fail")
+ }
+
+ clientConfig.Certificates[0].SupportedSignatureAlgorithms =
+ []SignatureScheme{PKCS1WithSHA1, PKCS1WithSHA256}
+
+ // But if the certificate restricts supported algorithms, RSA-PSS should not
+ // be selected, and the handshake should succeed.
+ if _, _, err := testHandshake(t, clientConfig, serverConfig); err != nil {
+ t.Error(err)
+ }
+}
+
+func TestVerifyCertificates(t *testing.T) {
+ // See https://go.dev/issue/31641.
+ t.Run("TLSv12", func(t *testing.T) { testVerifyCertificates(t, VersionTLS12) })
+ t.Run("TLSv13", func(t *testing.T) { testVerifyCertificates(t, VersionTLS13) })
+}
+
+func testVerifyCertificates(t *testing.T, version uint16) {
+ tests := []struct {
+ name string
+
+ InsecureSkipVerify bool
+ ClientAuth ClientAuthType
+ ClientCertificates bool
+ }{
+ {
+ name: "defaults",
+ },
+ {
+ name: "InsecureSkipVerify",
+ InsecureSkipVerify: true,
+ },
+ {
+ name: "RequestClientCert with no certs",
+ ClientAuth: RequestClientCert,
+ },
+ {
+ name: "RequestClientCert with certs",
+ ClientAuth: RequestClientCert,
+ ClientCertificates: true,
+ },
+ {
+ name: "RequireAnyClientCert",
+ ClientAuth: RequireAnyClientCert,
+ ClientCertificates: true,
+ },
+ {
+ name: "VerifyClientCertIfGiven with no certs",
+ ClientAuth: VerifyClientCertIfGiven,
+ },
+ {
+ name: "VerifyClientCertIfGiven with certs",
+ ClientAuth: VerifyClientCertIfGiven,
+ ClientCertificates: true,
+ },
+ {
+ name: "RequireAndVerifyClientCert",
+ ClientAuth: RequireAndVerifyClientCert,
+ ClientCertificates: true,
+ },
+ }
+
+ issuer, err := x509.ParseCertificate(testRSACertificateIssuer)
+ if err != nil {
+ t.Fatal(err)
+ }
+ rootCAs := x509.NewCertPool()
+ rootCAs.AddCert(issuer)
+
+ for _, test := range tests {
+ test := test
+ t.Run(test.name, func(t *testing.T) {
+ t.Parallel()
+
+ var serverVerifyConnection, clientVerifyConnection bool
+ var serverVerifyPeerCertificates, clientVerifyPeerCertificates bool
+
+ clientConfig := testConfig.Clone()
+ clientConfig.Time = func() time.Time { return time.Unix(1476984729, 0) }
+ clientConfig.MaxVersion = version
+ clientConfig.MinVersion = version
+ clientConfig.RootCAs = rootCAs
+ clientConfig.ServerName = "example.golang"
+ clientConfig.ClientSessionCache = NewLRUClientSessionCache(1)
+ serverConfig := clientConfig.Clone()
+ serverConfig.ClientCAs = rootCAs
+
+ clientConfig.VerifyConnection = func(cs ConnectionState) error {
+ clientVerifyConnection = true
+ return nil
+ }
+ clientConfig.VerifyPeerCertificate = func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
+ clientVerifyPeerCertificates = true
+ return nil
+ }
+ serverConfig.VerifyConnection = func(cs ConnectionState) error {
+ serverVerifyConnection = true
+ return nil
+ }
+ serverConfig.VerifyPeerCertificate = func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
+ serverVerifyPeerCertificates = true
+ return nil
+ }
+
+ clientConfig.InsecureSkipVerify = test.InsecureSkipVerify
+ serverConfig.ClientAuth = test.ClientAuth
+ if !test.ClientCertificates {
+ clientConfig.Certificates = nil
+ }
+
+ if _, _, err := testHandshake(t, clientConfig, serverConfig); err != nil {
+ t.Fatal(err)
+ }
+
+ want := serverConfig.ClientAuth != NoClientCert
+ if serverVerifyPeerCertificates != want {
+ t.Errorf("VerifyPeerCertificates on the server: got %v, want %v",
+ serverVerifyPeerCertificates, want)
+ }
+ if !clientVerifyPeerCertificates {
+ t.Errorf("VerifyPeerCertificates not called on the client")
+ }
+ if !serverVerifyConnection {
+ t.Error("VerifyConnection did not get called on the server")
+ }
+ if !clientVerifyConnection {
+ t.Error("VerifyConnection did not get called on the client")
+ }
+
+ serverVerifyPeerCertificates, clientVerifyPeerCertificates = false, false
+ serverVerifyConnection, clientVerifyConnection = false, false
+ cs, _, err := testHandshake(t, clientConfig, serverConfig)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if !cs.DidResume {
+ t.Error("expected resumption")
+ }
+
+ if serverVerifyPeerCertificates {
+ t.Error("VerifyPeerCertificates got called on the server on resumption")
+ }
+ if clientVerifyPeerCertificates {
+ t.Error("VerifyPeerCertificates got called on the client on resumption")
+ }
+ if !serverVerifyConnection {
+ t.Error("VerifyConnection did not get called on the server on resumption")
+ }
+ if !clientVerifyConnection {
+ t.Error("VerifyConnection did not get called on the client on resumption")
+ }
+ })
+ }
+}