summaryrefslogtreecommitdiffstats
path: root/src/crypto/tls
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 13:18:25 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 13:18:25 +0000
commit109be507377fe7f6e8819ac94041d3fdcdf6fd2f (patch)
tree2806a689f8fab4a2ec9fc949830ef270a91d667d /src/crypto/tls
parentInitial commit. (diff)
downloadgolang-1.19-109be507377fe7f6e8819ac94041d3fdcdf6fd2f.tar.xz
golang-1.19-109be507377fe7f6e8819ac94041d3fdcdf6fd2f.zip
Adding upstream version 1.19.8.upstream/1.19.8upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/crypto/tls')
-rw-r--r--src/crypto/tls/alert.go99
-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/cipher_suites.go702
-rw-r--r--src/crypto/tls/common.go1485
-rw-r--r--src/crypto/tls/common_string.go116
-rw-r--r--src/crypto/tls/conn.go1573
-rw-r--r--src/crypto/tls/conn_test.go287
-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.go172
-rw-r--r--src/crypto/tls/handshake_client.go1028
-rw-r--r--src/crypto/tls/handshake_client_test.go2597
-rw-r--r--src/crypto/tls/handshake_client_tls13.go704
-rw-r--r--src/crypto/tls/handshake_messages.go1852
-rw-r--r--src/crypto/tls/handshake_messages_test.go495
-rw-r--r--src/crypto/tls/handshake_server.go891
-rw-r--r--src/crypto/tls/handshake_server_test.go2046
-rw-r--r--src/crypto/tls/handshake_server_tls13.go889
-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.go357
-rw-r--r--src/crypto/tls/key_schedule.go216
-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.go283
-rw-r--r--src/crypto/tls/prf_test.go140
-rw-r--r--src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-ECDSA134
-rw-r--r--src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-RSA138
-rw-r--r--src/crypto/tls/testdata/Client-TLSv10-ClientCert-Ed25519110
-rw-r--r--src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-ECDSA133
-rw-r--r--src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-RSA137
-rw-r--r--src/crypto/tls/testdata/Client-TLSv10-ECDHE-ECDSA-AES91
-rw-r--r--src/crypto/tls/testdata/Client-TLSv10-ECDHE-RSA-AES95
-rw-r--r--src/crypto/tls/testdata/Client-TLSv10-Ed255190
-rw-r--r--src/crypto/tls/testdata/Client-TLSv10-ExportKeyingMaterial95
-rw-r--r--src/crypto/tls/testdata/Client-TLSv10-RSA-RC484
-rw-r--r--src/crypto/tls/testdata/Client-TLSv11-ECDHE-ECDSA-AES93
-rw-r--r--src/crypto/tls/testdata/Client-TLSv11-ECDHE-RSA-AES97
-rw-r--r--src/crypto/tls/testdata/Client-TLSv11-Ed255190
-rw-r--r--src/crypto/tls/testdata/Client-TLSv11-RSA-RC484
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-AES128-GCM-SHA25686
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-AES128-SHA25695
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-AES256-GCM-SHA38486
-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-ECDSA139
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-RSA139
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ClientCert-Ed25519119
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-AES256-GCM-SHA384137
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-ECDSA138
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSA137
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSAPKCS1v15134
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSAPSS142
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES93
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES-GCM88
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES128-SHA25697
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES256-GCM-SHA38488
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-CHACHA20-POLY130584
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES97
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES128-SHA256101
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-CHACHA20-POLY130588
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-Ed2551968
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-ExportKeyingMaterial90
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-P256-ECDHE98
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-RSA-RC484
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-RenegotiateOnce244
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwice343
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwiceRejected247
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-RenegotiationRejected95
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-SCT113
-rw-r--r--src/crypto/tls/testdata/Client-TLSv12-X25519-ECDHE92
-rw-r--r--src/crypto/tls/testdata/Client-TLSv13-AES128-SHA25690
-rw-r--r--src/crypto/tls/testdata/Client-TLSv13-AES256-SHA38492
-rw-r--r--src/crypto/tls/testdata/Client-TLSv13-ALPN93
-rw-r--r--src/crypto/tls/testdata/Client-TLSv13-CHACHA20-SHA25690
-rw-r--r--src/crypto/tls/testdata/Client-TLSv13-ClientCert-ECDSA-RSA139
-rw-r--r--src/crypto/tls/testdata/Client-TLSv13-ClientCert-Ed25519122
-rw-r--r--src/crypto/tls/testdata/Client-TLSv13-ClientCert-RSA-ECDSA134
-rw-r--r--src/crypto/tls/testdata/Client-TLSv13-ClientCert-RSA-RSAPSS143
-rw-r--r--src/crypto/tls/testdata/Client-TLSv13-ECDSA86
-rw-r--r--src/crypto/tls/testdata/Client-TLSv13-Ed2551968
-rw-r--r--src/crypto/tls/testdata/Client-TLSv13-ExportKeyingMaterial90
-rw-r--r--src/crypto/tls/testdata/Client-TLSv13-HelloRetryRequest119
-rw-r--r--src/crypto/tls/testdata/Client-TLSv13-KeyUpdate102
-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-AES80
-rw-r--r--src/crypto/tls/testdata/Server-TLSv10-ExportKeyingMaterial93
-rw-r--r--src/crypto/tls/testdata/Server-TLSv10-RSA-3DES76
-rw-r--r--src/crypto/tls/testdata/Server-TLSv10-RSA-AES79
-rw-r--r--src/crypto/tls/testdata/Server-TLSv10-RSA-RC473
-rw-r--r--src/crypto/tls/testdata/Server-TLSv11-FallbackSCSV11
-rw-r--r--src/crypto/tls/testdata/Server-TLSv11-RSA-RC473
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-ALPN92
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-ALPN-Fallback91
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch14
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-ALPN-NotConfigured91
-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-AES85
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-Ed2551958
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-ExportKeyingMaterial89
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-IssueTicket91
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-IssueTicketPreDisable91
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-P25686
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-RSA-3DES80
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-RSA-AES84
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-RSA-AES-GCM82
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-RSA-AES256-GCM-SHA38482
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-RSA-RC476
-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-Resume46
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-ResumeDisabled91
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-SNI84
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-SNI-GetCertificate84
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-SNI-GetCertificateNotFound84
-rw-r--r--src/crypto/tls/testdata/Server-TLSv12-X2551982
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-AES128-SHA256100
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-AES256-SHA384103
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-ALPN100
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-ALPN-Fallback100
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-ALPN-NoMatch27
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-ALPN-NotConfigured100
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-CHACHA20-SHA256100
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndECDSAGiven179
-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-ClientAuthRequestedNotGiven104
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-ECDHE-ECDSA-AES96
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-Ed2551976
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-ExportKeyingMaterial99
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-HelloRetryRequest123
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-IssueTicket99
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-IssueTicketPreDisable99
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-P256102
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-RSA-RSAPSS97
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-RSA-RSAPSS-TooSmall15
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-Resume60
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-Resume-HelloRetryRequest96
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-ResumeDisabled99
-rw-r--r--src/crypto/tls/testdata/Server-TLSv13-X2551998
-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.go185
-rw-r--r--src/crypto/tls/tls.go356
-rw-r--r--src/crypto/tls/tls_test.go1611
155 files changed, 32264 insertions, 0 deletions
diff --git a/src/crypto/tls/alert.go b/src/crypto/tls/alert.go
new file mode 100644
index 0000000..4790b73
--- /dev/null
+++ b/src/crypto/tls/alert.go
@@ -0,0 +1,99 @@
+// 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"
+
+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/cipher_suites.go b/src/crypto/tls/cipher_suites.go
new file mode 100644
index 0000000..9a1fa31
--- /dev/null
+++ b/src/crypto/tls/cipher_suites.go
@@ -0,0 +1,702 @@
+// 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,
+}
+
+var nonAESGCMAEADCiphers = map[uint16]bool{
+ // TLS 1.2
+ TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305: true,
+ TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305: true,
+ // TLS 1.3
+ TLS_CHACHA20_POLY1305_SHA256: 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)
+}
+
+// xoredNonceAEAD 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..14427cc
--- /dev/null
+++ b/src/crypto/tls/common.go
@@ -0,0 +1,1485 @@
+// 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
+)
+
+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
+ 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
+ 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 []*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 [][]*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 all
+ // resumed connections.
+ //
+ // Deprecated: there are conditions in which this value 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.
+ 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.
+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
+ }
+}
+
+// ClientSessionState contains the state needed by clients to resume TLS
+// sessions.
+type ClientSessionState struct {
+ sessionTicket []uint8 // Encrypted ticket used for session resumption with server
+ vers uint16 // TLS version negotiated for the session
+ cipherSuite uint16 // Ciphersuite negotiated for the session
+ masterSecret []byte // Full handshake MasterSecret, or TLS 1.3 resumption_master_secret
+ serverCertificates []*x509.Certificate // Certificate chain presented by the server
+ verifiedChains [][]*x509.Certificate // Certificate chains we built for verification
+ receivedAt time.Time // When the session ticket was received from the server
+ ocspResponse []byte // Stapled OCSP response presented by the server
+ scts [][]byte // SCTs presented by the server
+
+ // TLS 1.3 fields.
+ nonce []byte // Ticket nonce sent by the server, to derive PSK
+ useBy time.Time // Expiration of the ticket lifetime as set by the server
+ ageAdd uint32 // Random obfuscation factor for sending the ticket age
+}
+
+// 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.
+ 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.
+ 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 by
+ // setting InsecureSkipVerify, or (for a server) when ClientAuth is
+ // RequestClientCert or RequireAnyClientCert, then this callback will
+ // be considered but the verifiedChains argument will always be nil.
+ 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
+ // 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
+
+ // 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
+ // 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 (
+ // ticketKeyNameLen is the number of bytes of identifier that is prepended to
+ // an encrypted session ticket in order to identify the key used to encrypt it.
+ ticketKeyNameLen = 16
+
+ // 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 {
+ // keyName is an opaque byte string that serves to identify the session
+ // ticket key. It's exposed as plaintext in every session ticket.
+ keyName [ticketKeyNameLen]byte
+ 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[:])
+ copy(key.keyName[:], hashed[:ticketKeyNameLen])
+ copy(key.aesKey[:], hashed[ticketKeyNameLen:ticketKeyNameLen+16])
+ copy(key.hmacKey[:], hashed[ticketKeyNameLen+16:ticketKeyNameLen+32])
+ 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 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,
+ 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 := []byte(fmt.Sprintf("%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
+}
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..73f0c17
--- /dev/null
+++ b/src/crypto/tls/conn.go
@@ -0,0 +1,1573 @@
+// 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
+
+ // handshakeStatus is 1 if the connection is currently transferring
+ // application data (i.e. is not currently processing a handshake).
+ // handshakeStatus == 1 implies handshakeErr == nil.
+ // This field is only to be accessed with sync/atomic.
+ handshakeStatus uint32
+ // 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
+ 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
+ // 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
+ // NewSessionTicket messages. nil if config.SessionTicketsDisabled.
+ 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 is an atomic int32; the low bit is whether Close has
+ // been called. the rest of the bits are the number of goroutines
+ // in Conn.Write.
+ activeCall 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
+
+ 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, secret []byte) {
+ hc.trafficSecret = secret
+ 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.handshakeComplete()
+
+ // 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)
+
+ // 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])
+ n := int(hdr[3])<<8 | int(hdr[4])
+ if c.haveVers && c.vers != VersionTLS13 && vers != c.vers {
+ c.sendAlert(alertProtocolVersion)
+ msg := fmt.Sprintf("received record with version %x when expecting version %x", vers, c.vers)
+ 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 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
+}
+
+// sendAlert sends a TLS alert message.
+func (c *Conn) sendAlertLocked(err alert) error {
+ 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) {
+ 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
+}
+
+// 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) {
+ for c.hand.Len() < 4 {
+ if err := c.readRecord(); 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))
+ }
+ for c.hand.Len() < 4+n {
+ if err := c.readRecord(); err != nil {
+ return nil, err
+ }
+ }
+ data = c.hand.Next(4 + n)
+ 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 := atomic.LoadInt32(&c.activeCall)
+ if x&1 != 0 {
+ return 0, net.ErrClosed
+ }
+ if atomic.CompareAndSwapInt32(&c.activeCall, x, x+2) {
+ break
+ }
+ }
+ defer atomic.AddInt32(&c.activeCall, -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.handshakeComplete() {
+ 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()
+
+ atomic.StoreUint32(&c.handshakeStatus, 0)
+ 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)
+ default:
+ c.sendAlert(alertUnexpectedMessage)
+ return fmt.Errorf("tls: received unexpected handshake message of type %T", msg)
+ }
+}
+
+func (c *Conn) handleKeyUpdate(keyUpdate *keyUpdateMsg) error {
+ cipherSuite := cipherSuiteTLS13ByID(c.cipherSuite)
+ if cipherSuite == nil {
+ return c.in.setErrorLocked(c.sendAlert(alertInternalError))
+ }
+
+ newSecret := cipherSuite.nextTrafficSecret(c.in.trafficSecret)
+ c.in.setTrafficSecret(cipherSuite, 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, 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 = atomic.LoadInt32(&c.activeCall)
+ if x&1 != 0 {
+ return net.ErrClosed
+ }
+ if atomic.CompareAndSwapInt32(&c.activeCall, 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.handshakeComplete() {
+ 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.handshakeComplete() {
+ 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.
+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.handshakeComplete() {
+ 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()
+
+ // 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.
+ if ctx.Done() != nil {
+ 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.handshakeComplete() {
+ 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.handshakeComplete() {
+ c.handshakeErr = errors.New("tls: internal error: handshake should have had a result")
+ }
+ if c.handshakeErr != nil && c.handshakeComplete() {
+ panic("tls: internal error: handshake returned an error but is marked successful")
+ }
+
+ 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.handshakeComplete()
+ 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.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.handshakeComplete() {
+ 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)
+}
+
+func (c *Conn) handshakeComplete() bool {
+ return atomic.LoadUint32(&c.handshakeStatus) == 1
+}
diff --git a/src/crypto/tls/conn_test.go b/src/crypto/tls/conn_test.go
new file mode 100644
index 0000000..78935b1
--- /dev/null
+++ b/src/crypto/tls/conn_test.go
@@ -0,0 +1,287 @@
+// 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()
+}
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..74509c9
--- /dev/null
+++ b/src/crypto/tls/generate_cert.go
@@ -0,0 +1,172 @@
+// 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)
+ return
+ }
+ 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..898d2e9
--- /dev/null
+++ b/src/crypto/tls/handshake_client.go
@@ -0,0 +1,1028 @@
+// 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/ecdsa"
+ "crypto/ed25519"
+ "crypto/rsa"
+ "crypto/subtle"
+ "crypto/x509"
+ "errors"
+ "fmt"
+ "hash"
+ "io"
+ "net"
+ "strings"
+ "sync/atomic"
+ "time"
+)
+
+type clientHandshakeState struct {
+ c *Conn
+ ctx context.Context
+ serverHello *serverHelloMsg
+ hello *clientHelloMsg
+ suite *cipherSuite
+ finishedHash finishedHash
+ masterSecret []byte
+ session *ClientSessionState
+}
+
+var testingOnlyForceClientHelloSignatureAlgorithms []SignatureScheme
+
+func (c *Conn) makeClientHello() (*clientHelloMsg, ecdheParameters, 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),
+ sessionId: make([]byte, 32),
+ 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).
+ 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 params ecdheParameters
+ if hello.supportedVersions[0] == VersionTLS13 {
+ if hasAESGCMHardwareSupport {
+ hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13...)
+ } else {
+ hello.cipherSuites = append(hello.cipherSuites, defaultCipherSuitesTLS13NoAES...)
+ }
+
+ curveID := config.curvePreferences()[0]
+ if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok {
+ return nil, nil, errors.New("tls: CurvePreferences includes unsupported curve")
+ }
+ params, err = generateECDHEParameters(config.rand(), curveID)
+ if err != nil {
+ return nil, nil, err
+ }
+ hello.keyShares = []keyShare{{group: curveID, data: params.PublicKey()}}
+ }
+
+ return hello, params, 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, ecdheParams, err := c.makeClientHello()
+ if err != nil {
+ return err
+ }
+ c.serverName = hello.serverName
+
+ cacheKey, session, earlySecret, binderKey, err := c.loadSession(hello)
+ if err != nil {
+ return err
+ }
+ if cacheKey != "" && 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 {
+ c.config.ClientSessionCache.Put(cacheKey, nil)
+ }
+ }()
+ }
+
+ if _, err := c.writeHandshakeRecord(hello, nil); 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)
+ }
+
+ 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,
+ ecdheParams: ecdheParams,
+ 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
+ }
+
+ // If we had a successful handshake and hs.session is different from
+ // the one already cached - cache a new one.
+ if cacheKey != "" && hs.session != nil && session != hs.session {
+ c.config.ClientSessionCache.Put(cacheKey, hs.session)
+ }
+
+ return nil
+}
+
+func (c *Conn) loadSession(hello *clientHelloMsg) (cacheKey string,
+ session *ClientSessionState, 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 = clientSessionCacheKey(c.conn.RemoteAddr(), c.config)
+ session, ok := c.config.ClientSessionCache.Get(cacheKey)
+ if !ok || session == nil {
+ return cacheKey, nil, nil, nil, nil
+ }
+
+ // Check that version used for the previous session is still valid.
+ versOk := false
+ for _, v := range hello.supportedVersions {
+ if v == session.vers {
+ versOk = true
+ break
+ }
+ }
+ if !versOk {
+ return cacheKey, 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.InsecureSkipVerify {
+ if len(session.verifiedChains) == 0 {
+ // The original connection had InsecureSkipVerify, while this doesn't.
+ return cacheKey, nil, nil, nil, nil
+ }
+ serverCert := session.serverCertificates[0]
+ if c.config.time().After(serverCert.NotAfter) {
+ // Expired certificate, delete the entry.
+ c.config.ClientSessionCache.Put(cacheKey, nil)
+ return cacheKey, nil, nil, nil, nil
+ }
+ if err := serverCert.VerifyHostname(c.config.ServerName); err != nil {
+ return cacheKey, nil, nil, nil, nil
+ }
+ }
+
+ if session.vers != 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 cacheKey, nil, nil, nil, nil
+ }
+
+ hello.sessionTicket = session.sessionTicket
+ return
+ }
+
+ // Check that the session ticket is not expired.
+ if c.config.time().After(session.useBy) {
+ c.config.ClientSessionCache.Put(cacheKey, nil)
+ return cacheKey, 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 cacheKey, 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 cacheKey, nil, nil, nil, nil
+ }
+
+ // Set the pre_shared_key extension. See RFC 8446, Section 4.2.11.1.
+ ticketAge := uint32(c.config.time().Sub(session.receivedAt) / time.Millisecond)
+ identity := pskIdentity{
+ label: session.sessionTicket,
+ obfuscatedTicketAge: ticketAge + 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.
+ psk := cipherSuite.expandLabel(session.masterSecret, "resumption",
+ session.nonce, cipherSuite.hash.Size())
+ earlySecret = cipherSuite.extract(psk, 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
+ }
+ }
+
+ c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random)
+ atomic.StoreUint32(&c.handshakeStatus, 1)
+
+ 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 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, hs.masterSecret)
+ 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.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())
+ }
+
+ 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); 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.vers != 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")
+ }
+
+ // Restore masterSecret, peerCerts, and ocspResponse from previous state
+ hs.masterSecret = hs.session.masterSecret
+ c.peerCertificates = hs.session.serverCertificates
+ 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) error {
+ if serverProto == "" {
+ 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
+ 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.session = &ClientSessionState{
+ sessionTicket: sessionTicketMsg.ticket,
+ vers: c.vers,
+ cipherSuite: hs.suite.id,
+ masterSecret: hs.masterSecret,
+ serverCertificates: c.peerCertificates,
+ verifiedChains: c.verifiedChains,
+ receivedAt: c.config.time(),
+ ocspResponse: c.ocspResponse,
+ scts: c.scts,
+ }
+
+ 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
+}
+
+// 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 {
+ certs := make([]*x509.Certificate, len(certificates))
+ for i, asn1Data := range certificates {
+ cert, err := x509.ParseCertificate(asn1Data)
+ if err != nil {
+ c.sendAlert(alertBadCertificate)
+ return errors.New("tls: failed to parse certificate from server: " + err.Error())
+ }
+ certs[i] = 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 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.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 clientSessionCacheKey(serverAddr net.Addr, config *Config) string {
+ if len(config.ServerName) > 0 {
+ return config.ServerName
+ }
+ return serverAddr.String()
+}
+
+// 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..749c9fc
--- /dev/null
+++ b/src/crypto/tls/handshake_client_test.go
@@ -0,0 +1,2597 @@
+// 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) {
+ _, 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.sessionTicket
+ }
+ 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.masterSecret[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()) && version != VersionTLS13 {
+ t.Fatal("first ticket doesn't match ticket after resumption")
+ }
+ if bytes.Equal(ticket, getTicket()) && version == VersionTLS13 {
+ t.Fatal("ticket didn't change after resumption")
+ }
+
+ // An old session ticket can resume, but the server will provide a ticket encrypted with a fresh key.
+ serverConfig.Time = func() time.Time { return time.Now().Add(24*time.Hour + time.Minute) }
+ testResumeState("ResumeWithOldTicket", true)
+ if bytes.Equal(ticket[:ticketKeyNameLen], getTicket()[:ticketKeyNameLen]) {
+ t.Fatal("old first ticket matches the fresh one")
+ }
+
+ // Now the session tickey key is expired, so a full handshake should occur.
+ 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
+ for i := 0; i < 13; i++ {
+ d += 12 * time.Hour
+ serverConfig.Time = func() time.Time { return time.Now().Add(d) }
+ 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
+ serverConfig.Time = func() time.Time { return time.Now().Add(d) }
+ 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)
+
+ // 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)
+}
+
+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")
+ }
+}
diff --git a/src/crypto/tls/handshake_client_tls13.go b/src/crypto/tls/handshake_client_tls13.go
new file mode 100644
index 0000000..0f2dee4
--- /dev/null
+++ b/src/crypto/tls/handshake_client_tls13.go
@@ -0,0 +1,704 @@
+// 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"
+ "errors"
+ "hash"
+ "sync/atomic"
+ "time"
+)
+
+type clientHandshakeStateTLS13 struct {
+ c *Conn
+ ctx context.Context
+ serverHello *serverHelloMsg
+ hello *clientHelloMsg
+ ecdheParams ecdheParameters
+
+ session *ClientSessionState
+ 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.ecdheParams, 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.ecdheParams == 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
+ }
+
+ atomic.StoreUint32(&c.handshakeStatus, 1)
+
+ 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.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.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 hs.ecdheParams.CurveID() == curveID {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: server sent an unnecessary HelloRetryRequest key_share")
+ }
+ if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok {
+ c.sendAlert(alertInternalError)
+ return errors.New("tls: CurvePreferences includes unsupported curve")
+ }
+ params, err := generateECDHEParameters(c.config.rand(), curveID)
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+ hs.ecdheParams = params
+ hs.hello.keyShares = []keyShare{{group: curveID, data: params.PublicKey()}}
+ }
+
+ 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 := uint32(c.config.time().Sub(hs.session.receivedAt) / time.Millisecond)
+ hs.hello.pskIdentities[0].obfuscatedTicketAge = ticketAge + 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, hs.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 _, 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 hs.serverHello.serverShare.group != hs.ecdheParams.CurveID() {
+ 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.serverCertificates
+ 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
+
+ sharedKey := hs.ecdheParams.SharedKey(hs.serverHello.serverShare.data)
+ if sharedKey == 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, clientSecret)
+ serverSecret := hs.suite.deriveSecret(handshakeSecret,
+ serverHandshakeTrafficLabel, hs.transcript)
+ c.in.setTrafficSecret(hs.suite, 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); err != nil {
+ c.sendAlert(alertUnsupportedExtension)
+ return err
+ }
+ c.clientProtocol = encryptedExtensions.alpnProtocol
+
+ 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, 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, hs.trafficSecret)
+
+ if !c.config.SessionTicketsDisabled && c.config.ClientSessionCache != nil {
+ c.resumptionSecret = hs.suite.deriveSecret(hs.masterSecret,
+ resumptionLabel, hs.transcript)
+ }
+
+ 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")
+ }
+
+ cipherSuite := cipherSuiteTLS13ByID(c.cipherSuite)
+ if cipherSuite == nil || c.resumptionSecret == nil {
+ return c.sendAlert(alertInternalError)
+ }
+
+ // Save the resumption_master_secret and nonce instead of deriving the PSK
+ // to do the least amount of work on NewSessionTicket messages before we
+ // know if the ticket will be used. Forward secrecy of resumed connections
+ // is guaranteed by the requirement for pskModeDHE.
+ session := &ClientSessionState{
+ sessionTicket: msg.label,
+ vers: c.vers,
+ cipherSuite: c.cipherSuite,
+ masterSecret: c.resumptionSecret,
+ serverCertificates: c.peerCertificates,
+ verifiedChains: c.verifiedChains,
+ receivedAt: c.config.time(),
+ nonce: msg.nonce,
+ useBy: c.config.time().Add(lifetime),
+ ageAdd: msg.ageAdd,
+ ocspResponse: c.ocspResponse,
+ scts: c.scts,
+ }
+
+ cacheKey := clientSessionCacheKey(c.conn.RemoteAddr(), c.config)
+ c.config.ClientSessionCache.Put(cacheKey, session)
+
+ return nil
+}
diff --git a/src/crypto/tls/handshake_messages.go b/src/crypto/tls/handshake_messages.go
new file mode 100644
index 0000000..695aacf
--- /dev/null
+++ b/src/crypto/tls/handshake_messages.go
@@ -0,0 +1,1852 @@
+// 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
+ alpnProtocols []string
+ scts bool
+ supportedVersions []uint16
+ cookie []byte
+ keyShares []keyShare
+ earlyData bool
+ pskModes []uint8
+ pskIdentities []pskIdentity
+ pskBinders [][]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 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 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 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 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
+ 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 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 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
+}
+
+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))
+ })
+ })
+ })
+ }
+ })
+ })
+
+ 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)
+ 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..206e2fb
--- /dev/null
+++ b/src/crypto/tls/handshake_messages_test.go
@@ -0,0 +1,495 @@
+// 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"
+ "encoding/hex"
+ "math/rand"
+ "reflect"
+ "strings"
+ "testing"
+ "testing/quick"
+ "time"
+)
+
+var tests = []any{
+ &clientHelloMsg{},
+ &serverHelloMsg{},
+ &finishedMsg{},
+
+ &certificateMsg{},
+ &certificateRequestMsg{},
+ &certificateVerifyMsg{
+ hasSignatureAlgorithm: true,
+ },
+ &certificateStatusMsg{},
+ &clientKeyExchangeMsg{},
+ &newSessionTicketMsg{},
+ &sessionState{},
+ &sessionStateTLS13{},
+ &encryptedExtensionsMsg{},
+ &endOfEarlyDataMsg{},
+ &keyUpdateMsg{},
+ &newSessionTicketMsgTLS13{},
+ &certificateRequestMsgTLS13{},
+ &certificateMsgTLS13{},
+}
+
+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, iface := range tests {
+ ty := reflect.ValueOf(iface).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)
+ m2 := iface.(handshakeMessage)
+ if !m2.unmarshal(marshaled) {
+ t.Errorf("#%d failed to unmarshal %#v %x", i, m1, marshaled)
+ break
+ }
+ m2.marshal() // to fill any marshal cache in the message
+
+ if !reflect.DeepEqual(m1, m2) {
+ t.Errorf("#%d got:%#v want:%#v %x", i, m2, 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 m2.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 _, iface := range tests {
+ m := iface.(handshakeMessage)
+
+ for j := 0; j < 1000; j++ {
+ len := rand.Intn(100)
+ 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)
+ }
+ 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.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.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)
+ }
+
+ 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)
+}
+
+func (*sessionState) Generate(rand *rand.Rand, size int) reflect.Value {
+ s := &sessionState{}
+ s.vers = uint16(rand.Intn(10000))
+ s.cipherSuite = uint16(rand.Intn(10000))
+ s.masterSecret = randomBytes(rand.Intn(100)+1, rand)
+ s.createdAt = uint64(rand.Int63())
+ for i := 0; i < rand.Intn(20); i++ {
+ s.certificates = append(s.certificates, randomBytes(rand.Intn(500)+1, rand))
+ }
+ return reflect.ValueOf(s)
+}
+
+func (*sessionStateTLS13) Generate(rand *rand.Rand, size int) reflect.Value {
+ s := &sessionStateTLS13{}
+ s.cipherSuite = uint16(rand.Intn(10000))
+ s.resumptionSecret = randomBytes(rand.Intn(100)+1, rand)
+ s.createdAt = uint64(rand.Int63())
+ for i := 0; i < rand.Intn(2)+1; i++ {
+ s.certificate.Certificate = append(
+ s.certificate.Certificate, randomBytes(rand.Intn(500)+1, rand))
+ }
+ if rand.Intn(10) > 5 {
+ s.certificate.OCSPStaple = randomBytes(rand.Intn(100)+1, rand)
+ }
+ if rand.Intn(10) > 5 {
+ for i := 0; i < rand.Intn(2)+1; i++ {
+ s.certificate.SignedCertificateTimestamps = append(
+ s.certificate.SignedCertificateTimestamps, randomBytes(rand.Intn(500)+1, rand))
+ }
+ }
+ return reflect.ValueOf(s)
+}
+
+func (*endOfEarlyDataMsg) Generate(rand *rand.Rand, size int) reflect.Value {
+ m := &endOfEarlyDataMsg{}
+ return reflect.ValueOf(m)
+}
+
+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..8cb9acf
--- /dev/null
+++ b/src/crypto/tls/handshake_server.go
@@ -0,0 +1,891 @@
+// 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"
+ "sync/atomic"
+ "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 hs.checkForResumption() {
+ // The client has included a session ticket and so we do an abbreviated handshake.
+ c.didResume = true
+ 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)
+ atomic.StoreUint32(&c.handshakeStatus, 1)
+
+ 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.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)
+ 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) (string, error) {
+ if len(serverProtos) == 0 || len(clientProtos) == 0 {
+ 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() bool {
+ c := hs.c
+
+ if c.config.SessionTicketsDisabled {
+ return false
+ }
+
+ plaintext, usedOldKey := c.decryptTicket(hs.clientHello.sessionTicket)
+ if plaintext == nil {
+ return false
+ }
+ hs.sessionState = &sessionState{usedOldKey: usedOldKey}
+ ok := hs.sessionState.unmarshal(plaintext)
+ if !ok {
+ return false
+ }
+
+ createdAt := time.Unix(int64(hs.sessionState.createdAt), 0)
+ if c.config.time().Sub(createdAt) > maxSessionTicketLifetime {
+ return false
+ }
+
+ // Never resume a session for a different TLS version.
+ if c.vers != hs.sessionState.vers {
+ return false
+ }
+
+ cipherSuiteOk := false
+ // Check that the client is still offering the ciphersuite in the session.
+ for _, id := range hs.clientHello.cipherSuites {
+ if id == hs.sessionState.cipherSuite {
+ cipherSuiteOk = true
+ break
+ }
+ }
+ if !cipherSuiteOk {
+ return false
+ }
+
+ // Check that we also support the ciphersuite from the session.
+ hs.suite = selectCipherSuite([]uint16{hs.sessionState.cipherSuite},
+ c.config.cipherSuites(), hs.cipherSuiteOk)
+ if hs.suite == nil {
+ return false
+ }
+
+ sessionHasClientCerts := len(hs.sessionState.certificates) != 0
+ needClientCerts := requiresClientCert(c.config.ClientAuth)
+ if needClientCerts && !sessionHasClientCerts {
+ return false
+ }
+ if sessionHasClientCerts && c.config.ClientAuth == NoClientCert {
+ return false
+ }
+
+ return true
+}
+
+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
+ hs.hello.ticketSupported = hs.sessionState.usedOldKey
+ 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 err := c.processCertsFromClient(Certificate{
+ Certificate: hs.sessionState.certificates,
+ }); 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.masterSecret
+
+ 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
+ }
+ 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, hs.masterSecret)
+ 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 {
+ // ticketSupported is set in a resumption handshake if the
+ // ticket from the client was encrypted with an old session
+ // ticket key and thus a refreshed ticket should be sent.
+ if !hs.hello.ticketSupported {
+ return nil
+ }
+
+ c := hs.c
+ m := new(newSessionTicketMsg)
+
+ createdAt := uint64(c.config.time().Unix())
+ if hs.sessionState != nil {
+ // If this is re-wrapping an old key, then keep
+ // the original time it was created.
+ createdAt = hs.sessionState.createdAt
+ }
+
+ var certsFromClient [][]byte
+ for _, cert := range c.peerCertificates {
+ certsFromClient = append(certsFromClient, cert.Raw)
+ }
+ state := sessionState{
+ vers: c.vers,
+ cipherSuite: hs.suite.id,
+ createdAt: createdAt,
+ masterSecret: hs.masterSecret,
+ certificates: certsFromClient,
+ }
+ stateBytes, err := state.marshal()
+ if err != nil {
+ return err
+ }
+ m.ticket, err = c.encryptTicket(stateBytes)
+ 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 or from a sessionState and verifies them. It returns
+// the public key of the leaf certificate.
+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 len(certs) == 0 && requiresClientCert(c.config.ClientAuth) {
+ 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 {
+ c.sendAlert(alertBadCertificate)
+ return errors.New("tls: failed to verify client certificate: " + err.Error())
+ }
+
+ 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..b2e8107
--- /dev/null
+++ b/src/crypto/tls/handshake_server_test.go
@@ -0,0 +1,2046 @@
+// 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/elliptic"
+ "crypto/x509"
+ "encoding/pem"
+ "errors"
+ "fmt"
+ "io"
+ "net"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "runtime"
+ "strings"
+ "testing"
+ "time"
+
+ "golang.org/x/crypto/curve25519"
+)
+
+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
+ hs := &serverHandshakeStateTLS13{
+ c: &Conn{
+ config: &Config{},
+ vers: VersionTLS13,
+ },
+ clientHello: &clientHelloMsg{
+ cipherSuites: tc.clientCiphers,
+ supportedVersions: []uint16{VersionTLS13},
+ compressionMethods: []uint8{compressionNone},
+ keyShares: []keyShare{{group: X25519, data: curve25519.Basepoint}},
+ },
+ }
+
+ 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..0043e16
--- /dev/null
+++ b/src/crypto/tls/handshake_server_tls13.go
@@ -0,0 +1,889 @@
+// 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"
+ "sync/atomic"
+ "time"
+)
+
+// maxClientPSKIdentities is the number of client PSK identities the server will
+// attempt to validate. It will ignore the rest not to let cheap ClientHello
+// messages cause too much work in session ticket decryption attempts.
+const maxClientPSKIdentities = 5
+
+type serverHandshakeStateTLS13 struct {
+ c *Conn
+ ctx context.Context
+ clientHello *clientHelloMsg
+ hello *serverHelloMsg
+ sentDummyCCS bool
+ usingPSK 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
+ }
+
+ atomic.StoreUint32(&c.handshakeStatus, 1)
+
+ 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 {
+ // 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); selectedGroup != X25519 && !ok {
+ c.sendAlert(alertInternalError)
+ return errors.New("tls: CurvePreferences includes unsupported curve")
+ }
+ params, err := generateECDHEParameters(c.config.rand(), selectedGroup)
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+ hs.hello.serverShare = keyShare{group: selectedGroup, data: params.PublicKey()}
+ hs.sharedKey = params.SharedKey(clientKeyShare.data)
+ if hs.sharedKey == nil {
+ c.sendAlert(alertIllegalParameter)
+ return errors.New("tls: invalid client key share")
+ }
+
+ 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
+ }
+
+ plaintext, _ := c.decryptTicket(identity.label)
+ if plaintext == nil {
+ continue
+ }
+ sessionState := new(sessionStateTLS13)
+ if ok := sessionState.unmarshal(plaintext); !ok {
+ continue
+ }
+
+ createdAt := time.Unix(int64(sessionState.createdAt), 0)
+ if c.config.time().Sub(createdAt) > maxSessionTicketLifetime {
+ continue
+ }
+
+ // We don't check the obfuscated ticket age because it's affected by
+ // clock skew and it's only a freshness signal useful for shrinking the
+ // window for replay attacks, which don't affect us as we don't do 0-RTT.
+
+ pskSuite := cipherSuiteTLS13ByID(sessionState.cipherSuite)
+ if pskSuite == nil || pskSuite.hash != hs.suite.hash {
+ continue
+ }
+
+ // PSK connections don't re-establish client certificates, but carry
+ // them over in the session ticket. Ensure the presence of client certs
+ // in the ticket is consistent with the configured requirements.
+ sessionHasClientCerts := len(sessionState.certificate.Certificate) != 0
+ needClientCerts := requiresClientCert(c.config.ClientAuth)
+ if needClientCerts && !sessionHasClientCerts {
+ continue
+ }
+ if sessionHasClientCerts && c.config.ClientAuth == NoClientCert {
+ continue
+ }
+
+ psk := hs.suite.expandLabel(sessionState.resumptionSecret, "resumption",
+ nil, hs.suite.hash.Size())
+ hs.earlySecret = hs.suite.extract(psk, nil)
+ binderKey := hs.suite.deriveSecret(hs.earlySecret, resumptionBinderLabel, nil)
+ // Clone the transcript in case a HelloRetryRequest was recorded.
+ transcript := cloneHash(hs.transcript, hs.suite.hash)
+ if transcript == nil {
+ c.sendAlert(alertInternalError)
+ return 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")
+ }
+
+ c.didResume = true
+ if err := c.processCertsFromClient(sessionState.certificate); err != nil {
+ return err
+ }
+
+ 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.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, clientSecret)
+ serverSecret := hs.suite.deriveSecret(hs.handshakeSecret,
+ serverHandshakeTrafficLabel, hs.transcript)
+ c.out.setTrafficSecret(hs.suite, serverSecret)
+
+ 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)
+
+ selectedProto, err := negotiateALPN(c.config.NextProtos, hs.clientHello.alpnProtocols)
+ if err != nil {
+ c.sendAlert(alertNoApplicationProtocol)
+ return err
+ }
+ encryptedExtensions.alpnProtocol = selectedProto
+ c.clientProtocol = selectedProto
+
+ 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, 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
+ }
+
+ // 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
+ }
+
+ if !hs.shouldSendSessionTickets() {
+ return nil
+ }
+
+ resumptionSecret := hs.suite.deriveSecret(hs.masterSecret,
+ resumptionLabel, hs.transcript)
+
+ m := new(newSessionTicketMsgTLS13)
+
+ var certsFromClient [][]byte
+ for _, cert := range c.peerCertificates {
+ certsFromClient = append(certsFromClient, cert.Raw)
+ }
+ state := sessionStateTLS13{
+ cipherSuite: hs.suite.id,
+ createdAt: uint64(c.config.time().Unix()),
+ resumptionSecret: resumptionSecret,
+ certificate: Certificate{
+ Certificate: certsFromClient,
+ OCSPStaple: c.ocspResponse,
+ SignedCertificateTimestamps: c.scts,
+ },
+ }
+ stateBytes, err := state.marshal()
+ if err != nil {
+ c.sendAlert(alertInternalError)
+ return err
+ }
+ m.label, err = c.encryptTicket(stateBytes)
+ 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 = hs.c.config.rand().Read(ageAdd)
+ if err != nil {
+ return err
+ }
+ m.ageAdd = binary.LittleEndian.Uint32(ageAdd)
+
+ // ticket_nonce, which must be unique per connection, is always left at
+ // zero because we only ever send one ticket per connection.
+
+ 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, 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..c28a64f
--- /dev/null
+++ b/src/crypto/tls/key_agreement.go
@@ -0,0 +1,357 @@
+// 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/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
+ params ecdheParameters
+
+ // 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); curveID != X25519 && !ok {
+ return nil, errors.New("tls: CurvePreferences includes unsupported curve")
+ }
+
+ params, err := generateECDHEParameters(config.rand(), curveID)
+ if err != nil {
+ return nil, err
+ }
+ ka.params = params
+
+ // See RFC 4492, Section 5.4.
+ ecdhePublic := params.PublicKey()
+ 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
+ }
+
+ preMasterSecret := ka.params.SharedKey(ckx.ciphertext[1:])
+ if preMasterSecret == 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); curveID != X25519 && !ok {
+ return errors.New("tls: server selected unsupported curve")
+ }
+
+ params, err := generateECDHEParameters(config.rand(), curveID)
+ if err != nil {
+ return err
+ }
+ ka.params = params
+
+ ka.preMasterSecret = params.SharedKey(publicKey)
+ if ka.preMasterSecret == nil {
+ return errServerKeyExchange
+ }
+
+ ourPublicKey := params.PublicKey()
+ 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..185137b
--- /dev/null
+++ b/src/crypto/tls/key_schedule.go
@@ -0,0 +1,216 @@
+// 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/elliptic"
+ "crypto/hmac"
+ "errors"
+ "fmt"
+ "hash"
+ "io"
+ "math/big"
+
+ "golang.org/x/crypto/cryptobyte"
+ "golang.org/x/crypto/curve25519"
+ "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"
+ 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
+ }
+}
+
+// ecdheParameters implements Diffie-Hellman with either NIST curves or X25519,
+// according to RFC 8446, Section 4.2.8.2.
+type ecdheParameters interface {
+ CurveID() CurveID
+ PublicKey() []byte
+ SharedKey(peerPublicKey []byte) []byte
+}
+
+func generateECDHEParameters(rand io.Reader, curveID CurveID) (ecdheParameters, error) {
+ if curveID == X25519 {
+ privateKey := make([]byte, curve25519.ScalarSize)
+ if _, err := io.ReadFull(rand, privateKey); err != nil {
+ return nil, err
+ }
+ publicKey, err := curve25519.X25519(privateKey, curve25519.Basepoint)
+ if err != nil {
+ return nil, err
+ }
+ return &x25519Parameters{privateKey: privateKey, publicKey: publicKey}, nil
+ }
+
+ curve, ok := curveForCurveID(curveID)
+ if !ok {
+ return nil, errors.New("tls: internal error: unsupported curve")
+ }
+
+ p := &nistParameters{curveID: curveID}
+ var err error
+ p.privateKey, p.x, p.y, err = elliptic.GenerateKey(curve, rand)
+ if err != nil {
+ return nil, err
+ }
+ return p, nil
+}
+
+func curveForCurveID(id CurveID) (elliptic.Curve, bool) {
+ switch id {
+ case CurveP256:
+ return elliptic.P256(), true
+ case CurveP384:
+ return elliptic.P384(), true
+ case CurveP521:
+ return elliptic.P521(), true
+ default:
+ return nil, false
+ }
+}
+
+type nistParameters struct {
+ privateKey []byte
+ x, y *big.Int // public key
+ curveID CurveID
+}
+
+func (p *nistParameters) CurveID() CurveID {
+ return p.curveID
+}
+
+func (p *nistParameters) PublicKey() []byte {
+ curve, _ := curveForCurveID(p.curveID)
+ return elliptic.Marshal(curve, p.x, p.y)
+}
+
+func (p *nistParameters) SharedKey(peerPublicKey []byte) []byte {
+ curve, _ := curveForCurveID(p.curveID)
+ // Unmarshal also checks whether the given point is on the curve.
+ x, y := elliptic.Unmarshal(curve, peerPublicKey)
+ if x == nil {
+ return nil
+ }
+
+ xShared, _ := curve.ScalarMult(x, y, p.privateKey)
+ sharedKey := make([]byte, (curve.Params().BitSize+7)/8)
+ return xShared.FillBytes(sharedKey)
+}
+
+type x25519Parameters struct {
+ privateKey []byte
+ publicKey []byte
+}
+
+func (p *x25519Parameters) CurveID() CurveID {
+ return X25519
+}
+
+func (p *x25519Parameters) PublicKey() []byte {
+ return p.publicKey[:]
+}
+
+func (p *x25519Parameters) SharedKey(peerPublicKey []byte) []byte {
+ sharedKey, err := curve25519.X25519(p.privateKey, peerPublicKey)
+ if err != nil {
+ return nil
+ }
+ return sharedKey
+}
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..8c392ff
--- /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..13bfa00
--- /dev/null
+++ b/src/crypto/tls/prf.go
@@ -0,0 +1,283 @@
+// 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 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
+}
+
+// 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, masterSecret []byte) []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/testdata/Client-TLSv10-ClientCert-ECDSA-ECDSA b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-ECDSA
new file mode 100644
index 0000000..c7fa530
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-ECDSA
@@ -0,0 +1,134 @@
+>>> 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 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 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 92 4c b7 e6 07 |....Y...U...L...|
+00000010 09 b4 4a 47 6a 29 c7 79 18 0d 43 37 86 26 21 5a |..JGj).y..C7.&!Z|
+00000020 25 35 db 5f ae d0 20 0d 85 67 f7 20 75 e5 cb 25 |%5._.. ..g. u..%|
+00000030 4b 5d 95 87 78 00 fc 3f 78 26 e8 77 b5 0d d4 0e |K]..x..?x&.w....|
+00000040 54 06 66 b4 14 dc 6b db f2 af f3 2a c0 09 00 00 |T.f...k....*....|
+00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................|
+00000060 01 02 0e 0b 00 02 0a 00 02 07 00 02 04 30 82 02 |.............0..|
+00000070 00 30 82 01 62 02 09 00 b8 bf 2d 47 a0 d2 eb f4 |.0..b.....-G....|
+00000080 30 09 06 07 2a 86 48 ce 3d 04 01 30 45 31 0b 30 |0...*.H.=..0E1.0|
+00000090 09 06 03 55 04 06 13 02 41 55 31 13 30 11 06 03 |...U....AU1.0...|
+000000a0 55 04 08 13 0a 53 6f 6d 65 2d 53 74 61 74 65 31 |U....Some-State1|
+000000b0 21 30 1f 06 03 55 04 0a 13 18 49 6e 74 65 72 6e |!0...U....Intern|
+000000c0 65 74 20 57 69 64 67 69 74 73 20 50 74 79 20 4c |et Widgits Pty L|
+000000d0 74 64 30 1e 17 0d 31 32 31 31 32 32 31 35 30 36 |td0...1211221506|
+000000e0 33 32 5a 17 0d 32 32 31 31 32 30 31 35 30 36 33 |32Z..22112015063|
+000000f0 32 5a 30 45 31 0b 30 09 06 03 55 04 06 13 02 41 |2Z0E1.0...U....A|
+00000100 55 31 13 30 11 06 03 55 04 08 13 0a 53 6f 6d 65 |U1.0...U....Some|
+00000110 2d 53 74 61 74 65 31 21 30 1f 06 03 55 04 0a 13 |-State1!0...U...|
+00000120 18 49 6e 74 65 72 6e 65 74 20 57 69 64 67 69 74 |.Internet Widgit|
+00000130 73 20 50 74 79 20 4c 74 64 30 81 9b 30 10 06 07 |s Pty Ltd0..0...|
+00000140 2a 86 48 ce 3d 02 01 06 05 2b 81 04 00 23 03 81 |*.H.=....+...#..|
+00000150 86 00 04 00 c4 a1 ed be 98 f9 0b 48 73 36 7e c3 |...........Hs6~.|
+00000160 16 56 11 22 f2 3d 53 c3 3b 4d 21 3d cd 6b 75 e6 |.V.".=S.;M!=.ku.|
+00000170 f6 b0 dc 9a df 26 c1 bc b2 87 f0 72 32 7c b3 64 |.....&.....r2|.d|
+00000180 2f 1c 90 bc ea 68 23 10 7e fe e3 25 c0 48 3a 69 |/....h#.~..%.H:i|
+00000190 e0 28 6d d3 37 00 ef 04 62 dd 0d a0 9c 70 62 83 |.(m.7...b....pb.|
+000001a0 d8 81 d3 64 31 aa 9e 97 31 bd 96 b0 68 c0 9b 23 |...d1...1...h..#|
+000001b0 de 76 64 3f 1a 5c 7f e9 12 0e 58 58 b6 5f 70 dd |.vd?.\....XX._p.|
+000001c0 9b d8 ea d5 d7 f5 d5 cc b9 b6 9f 30 66 5b 66 9a |...........0f[f.|
+000001d0 20 e2 27 e5 bf fe 3b 30 09 06 07 2a 86 48 ce 3d | .'...;0...*.H.=|
+000001e0 04 01 03 81 8c 00 30 81 88 02 42 01 88 a2 4f eb |......0...B...O.|
+000001f0 e2 45 c5 48 7d 1b ac f5 ed 98 9d ae 47 70 c0 5e |.E.H}.......Gp.^|
+00000200 1b b6 2f bd f1 b6 4d b7 61 40 d3 11 a2 ce ee 0b |../...M.a@......|
+00000210 7e 92 7e ff 76 9d c3 3b 7e a5 3f ce fa 10 e2 59 |~.~.v..;~.?....Y|
+00000220 ec 47 2d 7c ac da 4e 97 0e 15 a0 6f d0 02 42 01 |.G-|..N....o..B.|
+00000230 4d fc be 67 13 9c 2d 05 0e bd 3f a3 8c 25 c1 33 |M..g..-...?..%.3|
+00000240 13 83 0d 94 06 bb d4 37 7a f6 ec 7a c9 86 2e dd |.......7z..z....|
+00000250 d7 11 69 7f 85 7c 56 de fb 31 78 2b e4 c7 78 0d |..i..|V..1x+..x.|
+00000260 ae cb be 9e 4e 36 24 31 7b 6a 0f 39 95 12 07 8f |....N6$1{j.9....|
+00000270 2a 16 03 01 00 b5 0c 00 00 b1 03 00 1d 20 d7 b5 |*............ ..|
+00000280 51 8e b5 01 4f 02 2f 43 11 2b de 94 7d 82 e6 49 |Q...O./C.+..}..I|
+00000290 1b a6 ee a0 7f 12 35 a2 3a 62 46 ce 07 25 00 8b |......5.:bF..%..|
+000002a0 30 81 88 02 42 00 83 45 db 03 db b9 74 ce 77 35 |0...B..E....t.w5|
+000002b0 1b e5 76 18 dc 3a d3 ee 32 18 f3 16 a6 c3 62 be |..v..:..2.....b.|
+000002c0 46 47 40 80 2d a0 08 c5 1e 5a 4a 42 69 8c ee e5 |FG@.-....ZJBi...|
+000002d0 70 b5 71 30 2f 54 32 54 5f 5b 26 62 e1 81 52 9e |p.q0/T2T_[&b..R.|
+000002e0 49 70 d4 81 e4 76 f1 02 42 01 70 f6 87 84 bb 58 |Ip...v..B.p....X|
+000002f0 5d e4 a1 72 87 d5 35 53 99 9c 3f 30 2b 80 7e c9 |]..r..5S..?0+.~.|
+00000300 79 eb d8 97 3c 82 ff 37 a5 8d 36 bc 27 c1 51 58 |y...<..7..6.'.QX|
+00000310 e6 2a 48 05 bf 9b a4 a5 b1 7f 77 b8 d9 3e 37 c6 |.*H.......w..>7.|
+00000320 67 ad ef 8c 72 ea f6 ba bb af 00 16 03 01 00 0a |g...r...........|
+00000330 0d 00 00 06 03 01 02 40 00 00 16 03 01 00 04 0e |.......@........|
+00000340 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 f0 c3 b2 6e e2 a3 |....0...B....n..|
+00000250 cd 76 02 7a d5 b5 66 fa b6 66 4e 4b a0 17 d6 bd |.v.z..f..fNK....|
+00000260 ec f6 8c 1f f9 b4 32 18 a9 ba 66 a8 67 a4 fa c8 |......2...f.g...|
+00000270 f7 73 5f 22 fb f2 22 e2 4d a1 f6 30 a2 55 76 51 |.s_"..".M..0.UvQ|
+00000280 b7 61 7d 13 68 0a 89 9d 34 31 46 02 42 01 fa 8b |.a}.h...41F.B...|
+00000290 61 f6 91 8e 88 ca 84 e6 33 e0 da 92 7e ee 21 1c |a.......3...~.!.|
+000002a0 df 47 c2 5d 07 d8 ae 1b 04 58 f9 50 16 13 74 ea |.G.].....X.P..t.|
+000002b0 04 cc 18 2d 2b 9a 08 89 24 e8 b8 01 bb c6 84 6c |...-+...$......l|
+000002c0 e6 9a c6 8a 44 74 1c 3a 79 0c e9 3c 11 ba 1b 14 |....Dt.:y..<....|
+000002d0 03 01 00 01 01 16 03 01 00 30 1d 4b df 00 de 1c |.........0.K....|
+000002e0 b5 30 7b ea 64 a0 09 89 8c c5 be fc 9b 07 7e 45 |.0{.d.........~E|
+000002f0 27 00 e7 78 da 3e a3 04 97 87 b0 c2 17 32 01 91 |'..x.>.......2..|
+00000300 6e 66 7b dd 9e 28 bc cc 66 65 |nf{..(..fe|
+>>> Flow 4 (server to client)
+00000000 14 03 01 00 01 01 16 03 01 00 30 51 68 ca 97 63 |..........0Qh..c|
+00000010 c6 c0 24 1c 87 20 70 ac f7 47 16 45 44 17 cc 92 |..$.. p..G.ED...|
+00000020 b3 6d 8b fa d1 3c b8 10 d7 da e4 a7 35 3c a2 d0 |.m...<......5<..|
+00000030 da 4b 50 e4 89 94 4b bc 20 6b e3 |.KP...K. k.|
+>>> Flow 5 (client to server)
+00000000 17 03 01 00 20 fc fa 90 90 d0 51 0d 35 0f 6a 6d |.... .....Q.5.jm|
+00000010 c2 32 ec 92 46 9f d7 e9 66 37 02 2a f6 c6 2e e2 |.2..F...f7.*....|
+00000020 13 aa fa fa d3 17 03 01 00 20 45 a9 36 19 7d a8 |......... E.6.}.|
+00000030 44 4c 8b aa 4e 47 c8 79 0c 97 a5 20 fa 6f 1f f7 |DL..NG.y... .o..|
+00000040 d3 bc d7 6d c2 67 23 c8 d6 05 15 03 01 00 20 f1 |...m.g#....... .|
+00000050 f1 ed f9 fc c2 f6 61 c8 42 9d c9 8a b0 d0 de d3 |......a.B.......|
+00000060 42 c7 04 64 eb 9e eb 58 3b c3 7d 0d 4d 16 d4 |B..d...X;.}.M..|
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..81e5191
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-ECDSA-RSA
@@ -0,0 +1,138 @@
+>>> 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 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 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 ca 72 6a a1 69 |....Y...U...rj.i|
+00000010 18 a4 f8 76 4a c3 5c e8 d5 c1 fb 06 c6 9a 14 67 |...vJ.\........g|
+00000020 ce e4 f6 52 67 ab 64 48 28 5a 63 20 55 ea ff 87 |...Rg.dH(Zc U...|
+00000030 5a 78 5c cb 21 af 83 a5 ed 1b d3 2c 39 81 e5 ca |Zx\.!......,9...|
+00000040 63 d2 5c 57 27 1d d0 f9 41 40 43 b0 c0 13 00 00 |c.\W'...A@C.....|
+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 e8 a5 9c e4 73 3d 75 |........ ....s=u|
+000002d0 0c 3e f2 de 21 9c 0f 91 b4 fd 94 f0 27 f6 d9 7d |.>..!.......'..}|
+000002e0 cd 0c 4c 50 b0 47 db dd 12 00 80 04 c0 be d5 bb |..LP.G..........|
+000002f0 e8 e2 a2 2e d9 2e 75 fa b6 07 d0 f7 75 52 fb 2f |......u.....uR./|
+00000300 50 cd 43 68 bd 42 11 6d d6 9f a3 d1 00 fd a9 14 |P.Ch.B.m........|
+00000310 0c 2a dd 76 ea 73 21 52 00 3a 83 cf d7 07 c7 bd |.*.v.s!R.:......|
+00000320 78 21 ce 35 80 b3 06 22 f1 96 a7 20 41 f8 aa 61 |x!.5..."... A..a|
+00000330 94 b4 77 d4 d9 92 f2 66 c5 1c d1 82 f3 b9 e2 9d |..w....f........|
+00000340 a9 30 1c e2 4e ec 0d 32 3d 0d 61 22 c8 e5 95 9f |.0..N..2=.a"....|
+00000350 cf 3e fc a8 c5 c3 f8 45 45 29 ea a7 e7 b7 a6 17 |.>.....EE)......|
+00000360 9e 5f 83 d4 b3 f0 da 31 73 94 f2 16 03 01 00 0a |._.....1s.......|
+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 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 9a b9 f6 98 e3 ed |....0...B.......|
+00000250 ed 0d a3 0e 54 51 9f 73 d4 87 40 4e a9 39 4b 2d |....TQ.s..@N.9K-|
+00000260 2a b9 4d 8d e3 46 c3 b6 39 f2 ca a9 c9 0f 79 c1 |*.M..F..9.....y.|
+00000270 0c 90 6f de 58 97 72 fc a8 c1 4c 12 aa a4 85 57 |..o.X.r...L....W|
+00000280 50 7c a0 02 8a 12 c5 80 aa b6 39 02 42 00 9c b7 |P|........9.B...|
+00000290 95 b4 04 83 5b 3a e1 ac da 78 86 11 f5 30 75 4a |....[:...x...0uJ|
+000002a0 25 67 6c fd ef 5a d8 56 d3 60 93 cf 65 07 2b 1f |%gl..Z.V.`..e.+.|
+000002b0 a9 40 a8 ba cd 0e 41 2d 10 43 a4 61 93 b7 0a 11 |.@....A-.C.a....|
+000002c0 78 d1 72 2b 20 07 49 5a 76 02 17 57 87 78 c7 14 |x.r+ .IZv..W.x..|
+000002d0 03 01 00 01 01 16 03 01 00 30 93 de 1b 64 0e 56 |.........0...d.V|
+000002e0 d9 a8 da f7 37 cb ac ac 3e f5 e2 f9 87 19 f2 79 |....7...>......y|
+000002f0 24 76 19 a4 a2 41 d6 9e 7d ca aa 3e 1d d7 22 dd |$v...A..}..>..".|
+00000300 05 aa dd 74 03 db fd a2 de ee |...t......|
+>>> Flow 4 (server to client)
+00000000 14 03 01 00 01 01 16 03 01 00 30 4d 4f d6 67 05 |..........0MO.g.|
+00000010 32 8c 16 cb 19 35 b3 b9 02 d8 5e 24 b6 c8 b7 3a |2....5....^$...:|
+00000020 17 34 98 77 e1 73 e0 cd a9 30 a8 15 60 8c f4 9a |.4.w.s...0..`...|
+00000030 dc cf 7a fd 86 85 1c 2b 33 21 e8 |..z....+3!.|
+>>> Flow 5 (client to server)
+00000000 17 03 01 00 20 b8 c5 17 b7 92 d8 93 7a b2 fd 4f |.... .......z..O|
+00000010 15 d1 db b9 47 54 00 a0 f6 77 92 03 a8 89 e5 ba |....GT...w......|
+00000020 cc eb d9 bd 27 17 03 01 00 20 57 d5 9a f6 36 b2 |....'.... W...6.|
+00000030 57 ba cd 64 77 36 b9 74 fb bd 95 51 03 61 e8 45 |W..dw6.t...Q.a.E|
+00000040 cb b8 35 f0 05 17 b3 08 c6 cb 15 03 01 00 20 28 |..5........... (|
+00000050 43 03 ab 3f e2 f5 d0 33 4c 7f 50 a4 ee 7b 46 e6 |C..?...3L.P..{F.|
+00000060 12 76 d0 fd c3 99 5c 63 a4 04 ea 4b e3 bd 99 |.v....\c...K...|
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..3ee661e
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-ECDSA
@@ -0,0 +1,133 @@
+>>> 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 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 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 b4 ff c0 49 36 |....Y...U.....I6|
+00000010 1d 31 9a a7 f6 33 f5 16 78 d7 10 9e 19 eb 1d 67 |.1...3..x......g|
+00000020 20 39 f8 73 7e 27 e2 dc d1 ab 03 20 79 64 67 f7 | 9.s~'..... ydg.|
+00000030 8b c8 97 f0 b4 87 0e 2d 4b 22 6c ed 92 48 85 52 |.......-K"l..H.R|
+00000040 eb 57 56 a8 cf 19 9f 4d e3 38 5e a0 c0 09 00 00 |.WV....M.8^.....|
+00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................|
+00000060 01 02 0e 0b 00 02 0a 00 02 07 00 02 04 30 82 02 |.............0..|
+00000070 00 30 82 01 62 02 09 00 b8 bf 2d 47 a0 d2 eb f4 |.0..b.....-G....|
+00000080 30 09 06 07 2a 86 48 ce 3d 04 01 30 45 31 0b 30 |0...*.H.=..0E1.0|
+00000090 09 06 03 55 04 06 13 02 41 55 31 13 30 11 06 03 |...U....AU1.0...|
+000000a0 55 04 08 13 0a 53 6f 6d 65 2d 53 74 61 74 65 31 |U....Some-State1|
+000000b0 21 30 1f 06 03 55 04 0a 13 18 49 6e 74 65 72 6e |!0...U....Intern|
+000000c0 65 74 20 57 69 64 67 69 74 73 20 50 74 79 20 4c |et Widgits Pty L|
+000000d0 74 64 30 1e 17 0d 31 32 31 31 32 32 31 35 30 36 |td0...1211221506|
+000000e0 33 32 5a 17 0d 32 32 31 31 32 30 31 35 30 36 33 |32Z..22112015063|
+000000f0 32 5a 30 45 31 0b 30 09 06 03 55 04 06 13 02 41 |2Z0E1.0...U....A|
+00000100 55 31 13 30 11 06 03 55 04 08 13 0a 53 6f 6d 65 |U1.0...U....Some|
+00000110 2d 53 74 61 74 65 31 21 30 1f 06 03 55 04 0a 13 |-State1!0...U...|
+00000120 18 49 6e 74 65 72 6e 65 74 20 57 69 64 67 69 74 |.Internet Widgit|
+00000130 73 20 50 74 79 20 4c 74 64 30 81 9b 30 10 06 07 |s Pty Ltd0..0...|
+00000140 2a 86 48 ce 3d 02 01 06 05 2b 81 04 00 23 03 81 |*.H.=....+...#..|
+00000150 86 00 04 00 c4 a1 ed be 98 f9 0b 48 73 36 7e c3 |...........Hs6~.|
+00000160 16 56 11 22 f2 3d 53 c3 3b 4d 21 3d cd 6b 75 e6 |.V.".=S.;M!=.ku.|
+00000170 f6 b0 dc 9a df 26 c1 bc b2 87 f0 72 32 7c b3 64 |.....&.....r2|.d|
+00000180 2f 1c 90 bc ea 68 23 10 7e fe e3 25 c0 48 3a 69 |/....h#.~..%.H:i|
+00000190 e0 28 6d d3 37 00 ef 04 62 dd 0d a0 9c 70 62 83 |.(m.7...b....pb.|
+000001a0 d8 81 d3 64 31 aa 9e 97 31 bd 96 b0 68 c0 9b 23 |...d1...1...h..#|
+000001b0 de 76 64 3f 1a 5c 7f e9 12 0e 58 58 b6 5f 70 dd |.vd?.\....XX._p.|
+000001c0 9b d8 ea d5 d7 f5 d5 cc b9 b6 9f 30 66 5b 66 9a |...........0f[f.|
+000001d0 20 e2 27 e5 bf fe 3b 30 09 06 07 2a 86 48 ce 3d | .'...;0...*.H.=|
+000001e0 04 01 03 81 8c 00 30 81 88 02 42 01 88 a2 4f eb |......0...B...O.|
+000001f0 e2 45 c5 48 7d 1b ac f5 ed 98 9d ae 47 70 c0 5e |.E.H}.......Gp.^|
+00000200 1b b6 2f bd f1 b6 4d b7 61 40 d3 11 a2 ce ee 0b |../...M.a@......|
+00000210 7e 92 7e ff 76 9d c3 3b 7e a5 3f ce fa 10 e2 59 |~.~.v..;~.?....Y|
+00000220 ec 47 2d 7c ac da 4e 97 0e 15 a0 6f d0 02 42 01 |.G-|..N....o..B.|
+00000230 4d fc be 67 13 9c 2d 05 0e bd 3f a3 8c 25 c1 33 |M..g..-...?..%.3|
+00000240 13 83 0d 94 06 bb d4 37 7a f6 ec 7a c9 86 2e dd |.......7z..z....|
+00000250 d7 11 69 7f 85 7c 56 de fb 31 78 2b e4 c7 78 0d |..i..|V..1x+..x.|
+00000260 ae cb be 9e 4e 36 24 31 7b 6a 0f 39 95 12 07 8f |....N6$1{j.9....|
+00000270 2a 16 03 01 00 b4 0c 00 00 b0 03 00 1d 20 ec 38 |*............ .8|
+00000280 f7 41 d0 f3 f4 6a ca 47 18 74 f1 22 2c 47 ee 39 |.A...j.G.t.",G.9|
+00000290 c9 a2 db 64 05 01 ae 5d 08 65 53 7f 24 78 00 8a |...d...].eS.$x..|
+000002a0 30 81 87 02 41 64 39 65 56 fa d4 69 e7 c5 a5 32 |0...Ad9eV..i...2|
+000002b0 4c 52 55 96 fe 01 cd 41 3c 18 ed df fd 09 c3 89 |LRU....A<.......|
+000002c0 80 bd 88 9e d7 a1 85 16 d1 a4 5a f0 9a 76 e9 2f |..........Z..v./|
+000002d0 d2 a4 42 a4 89 98 6c 87 64 b1 49 4e 6a 68 d2 43 |..B...l.d.INjh.C|
+000002e0 41 a2 c7 a6 2f f7 02 42 01 6c bb 32 c0 47 7e 08 |A.../..B.l.2.G~.|
+000002f0 6b 7a 44 18 b7 5d 4c 4d 6d 80 92 bb e5 65 98 1b |kzD..]LMm....e..|
+00000300 d7 a6 a3 1b b5 f3 46 1a e7 e0 89 04 40 b0 29 aa |......F.....@.).|
+00000310 fe 85 6a 9a 4b 18 75 ab 00 52 71 54 41 8d eb 31 |..j.K.u..RqTA..1|
+00000320 47 69 9b 9d dc 3b 1b 3e 76 27 16 03 01 00 0a 0d |Gi...;.>v'......|
+00000330 00 00 06 03 01 02 40 00 00 16 03 01 00 04 0e 00 |......@.........|
+00000340 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 05 7e 70 eb cb ef e3 d9 6f |........~p.....o|
+00000240 59 29 b5 da f2 07 f5 42 62 4e 74 9b cf 00 e1 5c |Y).....BbNt....\|
+00000250 69 a5 67 3a b0 b2 ca f2 10 ed 1c b4 81 5d 7d 9e |i.g:.........]}.|
+00000260 1a 45 69 42 13 c5 b0 86 dc 3d 60 e5 cf fd ae 0f |.EiB.....=`.....|
+00000270 17 bb 4a ed d7 06 eb f1 6d 47 98 b7 e8 87 eb 3c |..J.....mG.....<|
+00000280 12 55 2c 06 de 55 48 c7 59 85 cb 62 d6 e7 1d 05 |.U,..UH.Y..b....|
+00000290 1e 6d 69 84 cd 16 8e dd ed 5b 5a 2f f2 97 b7 78 |.mi......[Z/...x|
+000002a0 93 c1 fb 75 26 c8 b5 58 43 17 c7 52 54 20 4f 7d |...u&..XC..RT O}|
+000002b0 7c 46 89 65 fe 51 29 14 03 01 00 01 01 16 03 01 ||F.e.Q).........|
+000002c0 00 30 d9 59 e6 7e c0 a6 2a af 36 0c 2e cf 0f 42 |.0.Y.~..*.6....B|
+000002d0 54 d4 41 c6 3c f8 84 d9 2a a6 82 94 22 2d ac ae |T.A.<...*..."-..|
+000002e0 d9 f7 68 22 f6 f0 2e 56 c1 97 80 73 0d b3 f0 70 |..h"...V...s...p|
+000002f0 49 78 |Ix|
+>>> Flow 4 (server to client)
+00000000 14 03 01 00 01 01 16 03 01 00 30 06 19 79 49 41 |..........0..yIA|
+00000010 f9 9c 75 84 73 95 96 bd 1e 25 56 a9 49 ed 8e 38 |..u.s....%V.I..8|
+00000020 34 40 60 dc f0 2d f3 6c cf 5b 80 84 2b 81 db 5f |4@`..-.l.[..+.._|
+00000030 f4 27 03 ad b8 8d 80 0c 99 69 6f |.'.......io|
+>>> Flow 5 (client to server)
+00000000 17 03 01 00 20 20 67 bd ff 84 9b 0e 58 f3 45 1e |.... g.....X.E.|
+00000010 7a 25 d5 ae f0 26 4b 42 c7 f3 a5 77 7b 2f 42 21 |z%...&KB...w{/B!|
+00000020 2e c6 c9 81 23 17 03 01 00 20 69 1c 2a b9 05 16 |....#.... i.*...|
+00000030 8b 71 3a c2 18 76 bd 25 1f de 83 e9 14 e2 a3 5c |.q:..v.%.......\|
+00000040 9b 33 ee 14 39 da e2 e7 a3 a7 15 03 01 00 20 e9 |.3..9......... .|
+00000050 dc 16 0c 13 56 7a e5 fd ce b9 4f d1 c7 20 3f ca |....Vz....O.. ?.|
+00000060 72 20 15 f7 11 81 fe 88 ab 90 4c dc 0b a5 11 |r ........L....|
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..980f933
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv10-ClientCert-RSA-RSA
@@ -0,0 +1,137 @@
+>>> 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 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 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 4d 6d 71 59 6b |....Y...U..MmqYk|
+00000010 cd 8c 6e b0 11 bf 4a 9e 25 90 12 cc ac b4 3f be |..n...J.%.....?.|
+00000020 86 1b 13 47 a6 be 3d a0 8f 0b 77 20 6b b5 57 6d |...G..=...w k.Wm|
+00000030 39 74 b0 9d b4 ae 2e 72 7e 90 d2 ab ed 32 fa 65 |9t.....r~....2.e|
+00000040 ed 85 63 d2 16 ef 47 af a6 37 17 88 c0 13 00 00 |..c...G..7......|
+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 96 0b 2f 57 e1 1e 07 |........ ../W...|
+000002d0 e0 7f a4 91 67 97 d0 a0 19 d3 9a b2 49 79 f9 5f |....g.......Iy._|
+000002e0 7f b5 65 d4 3a 89 92 8f 11 00 80 08 29 72 0b f7 |..e.:.......)r..|
+000002f0 7b 68 38 5e 47 15 89 f1 ee be f3 a9 26 a4 9c 6d |{h8^G.......&..m|
+00000300 2c 2a ff f0 d6 2d 25 a5 b0 93 66 7d 8c fb fe a5 |,*...-%...f}....|
+00000310 3b cc b6 71 f4 1b 55 c4 ef 08 73 b1 49 47 2c e6 |;..q..U...s.IG,.|
+00000320 a1 ef 53 ca bb 15 e3 25 ea e7 48 44 18 88 e1 d2 |..S....%..HD....|
+00000330 3b e9 f6 92 61 5e 5c 06 44 83 37 6c e6 b6 26 32 |;...a^\.D.7l..&2|
+00000340 fd d6 00 fc 87 a2 37 e3 84 d2 ad 2d 99 0d e1 ba |......7....-....|
+00000350 bb 2f 3b 0b dd 56 5c c2 14 af 86 58 2c 8b f8 64 |./;..V\....X,..d|
+00000360 75 ab d3 35 41 59 fa fe a5 48 26 16 03 01 00 0a |u..5AY...H&.....|
+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 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 8f 5d a5 27 13 09 5e 49 5f |........].'..^I_|
+00000240 ff fd d6 88 75 83 cc 74 f3 e1 af 44 76 6a 35 16 |....u..t...Dvj5.|
+00000250 e8 36 5f b7 dc 21 69 77 61 12 c5 69 f7 0d 98 1f |.6_..!iwa..i....|
+00000260 d5 15 f1 e8 88 c5 30 e8 b5 c3 2a e5 26 93 cc a4 |......0...*.&...|
+00000270 eb 31 c6 d7 f5 f4 7c d5 f7 a2 3f 1f 75 cd b2 b2 |.1....|...?.u...|
+00000280 82 3a 03 8c 5e 15 0a d2 98 b8 65 cb 5f d5 db d0 |.:..^.....e._...|
+00000290 b6 36 8c 89 7e 48 fa 3a 9f 9a bd c1 48 e7 d6 20 |.6..~H.:....H.. |
+000002a0 ef 45 5b 24 32 04 58 82 b3 7b 42 fd fe ba 78 32 |.E[$2.X..{B...x2|
+000002b0 2a f5 b7 81 33 da db 14 03 01 00 01 01 16 03 01 |*...3...........|
+000002c0 00 30 5f 96 98 94 17 6d ff 84 72 d3 63 fd 14 59 |.0_....m..r.c..Y|
+000002d0 eb bf 5f 3e 8f dc f1 c1 dc 77 8a 33 f6 2e a2 4a |.._>.....w.3...J|
+000002e0 15 d1 2e a4 ec 0d 3c 0b 18 07 09 6c 0d 09 34 2e |......<....l..4.|
+000002f0 a4 6f |.o|
+>>> Flow 4 (server to client)
+00000000 14 03 01 00 01 01 16 03 01 00 30 b7 4a 5c 0c e6 |..........0.J\..|
+00000010 7c d9 43 7c e7 b4 2f d7 b5 c6 5e 36 c7 87 dd 82 ||.C|../...^6....|
+00000020 da d3 b2 4e 05 ae f5 8c b0 4d db c2 53 62 55 73 |...N.....M..SbUs|
+00000030 8c 2a 1b d5 df e4 7c a4 cf db 8b |.*....|....|
+>>> Flow 5 (client to server)
+00000000 17 03 01 00 20 b9 26 60 87 38 9c d9 c4 65 17 8e |.... .&`.8...e..|
+00000010 3c 7f 1a b4 23 cd 27 fd 4e 92 ee 0e f2 11 dc e2 |<...#.'.N.......|
+00000020 23 e4 26 f3 55 17 03 01 00 20 5e 89 33 21 f0 dc |#.&.U.... ^.3!..|
+00000030 e8 4f 33 1c 66 56 99 38 a5 4c 0e 0e 93 41 b7 48 |.O3.fV.8.L...A.H|
+00000040 5d ce 49 d0 d2 8a 56 a6 2d 68 15 03 01 00 20 05 |].I...V.-h.... .|
+00000050 e0 ed f9 c2 56 ec 64 e5 e7 0b f4 8a e2 41 96 9e |....V.d......A..|
+00000060 ed 94 c8 95 69 d7 ce 2d 0e bb 5b 18 5f 30 52 |....i..-..[._0R|
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..6fc506f
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv10-ECDHE-ECDSA-AES
@@ -0,0 +1,91 @@
+>>> 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 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 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 a3 4e 79 27 af |....Y...U...Ny'.|
+00000010 c8 a3 15 a4 c2 7a 54 58 54 0e 0d 93 c2 ff e1 f9 |.....zTXT.......|
+00000020 55 ab 2c ea 32 cf d2 47 2e d7 8e 20 49 08 d1 66 |U.,.2..G... I..f|
+00000030 9b 9e aa af c9 90 95 ec cb 64 2e 3d f6 27 d5 f6 |.........d.=.'..|
+00000040 23 10 d5 6e 50 5f bc 89 fe c7 d7 de c0 09 00 00 |#..nP_..........|
+00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................|
+00000060 01 02 0e 0b 00 02 0a 00 02 07 00 02 04 30 82 02 |.............0..|
+00000070 00 30 82 01 62 02 09 00 b8 bf 2d 47 a0 d2 eb f4 |.0..b.....-G....|
+00000080 30 09 06 07 2a 86 48 ce 3d 04 01 30 45 31 0b 30 |0...*.H.=..0E1.0|
+00000090 09 06 03 55 04 06 13 02 41 55 31 13 30 11 06 03 |...U....AU1.0...|
+000000a0 55 04 08 13 0a 53 6f 6d 65 2d 53 74 61 74 65 31 |U....Some-State1|
+000000b0 21 30 1f 06 03 55 04 0a 13 18 49 6e 74 65 72 6e |!0...U....Intern|
+000000c0 65 74 20 57 69 64 67 69 74 73 20 50 74 79 20 4c |et Widgits Pty L|
+000000d0 74 64 30 1e 17 0d 31 32 31 31 32 32 31 35 30 36 |td0...1211221506|
+000000e0 33 32 5a 17 0d 32 32 31 31 32 30 31 35 30 36 33 |32Z..22112015063|
+000000f0 32 5a 30 45 31 0b 30 09 06 03 55 04 06 13 02 41 |2Z0E1.0...U....A|
+00000100 55 31 13 30 11 06 03 55 04 08 13 0a 53 6f 6d 65 |U1.0...U....Some|
+00000110 2d 53 74 61 74 65 31 21 30 1f 06 03 55 04 0a 13 |-State1!0...U...|
+00000120 18 49 6e 74 65 72 6e 65 74 20 57 69 64 67 69 74 |.Internet Widgit|
+00000130 73 20 50 74 79 20 4c 74 64 30 81 9b 30 10 06 07 |s Pty Ltd0..0...|
+00000140 2a 86 48 ce 3d 02 01 06 05 2b 81 04 00 23 03 81 |*.H.=....+...#..|
+00000150 86 00 04 00 c4 a1 ed be 98 f9 0b 48 73 36 7e c3 |...........Hs6~.|
+00000160 16 56 11 22 f2 3d 53 c3 3b 4d 21 3d cd 6b 75 e6 |.V.".=S.;M!=.ku.|
+00000170 f6 b0 dc 9a df 26 c1 bc b2 87 f0 72 32 7c b3 64 |.....&.....r2|.d|
+00000180 2f 1c 90 bc ea 68 23 10 7e fe e3 25 c0 48 3a 69 |/....h#.~..%.H:i|
+00000190 e0 28 6d d3 37 00 ef 04 62 dd 0d a0 9c 70 62 83 |.(m.7...b....pb.|
+000001a0 d8 81 d3 64 31 aa 9e 97 31 bd 96 b0 68 c0 9b 23 |...d1...1...h..#|
+000001b0 de 76 64 3f 1a 5c 7f e9 12 0e 58 58 b6 5f 70 dd |.vd?.\....XX._p.|
+000001c0 9b d8 ea d5 d7 f5 d5 cc b9 b6 9f 30 66 5b 66 9a |...........0f[f.|
+000001d0 20 e2 27 e5 bf fe 3b 30 09 06 07 2a 86 48 ce 3d | .'...;0...*.H.=|
+000001e0 04 01 03 81 8c 00 30 81 88 02 42 01 88 a2 4f eb |......0...B...O.|
+000001f0 e2 45 c5 48 7d 1b ac f5 ed 98 9d ae 47 70 c0 5e |.E.H}.......Gp.^|
+00000200 1b b6 2f bd f1 b6 4d b7 61 40 d3 11 a2 ce ee 0b |../...M.a@......|
+00000210 7e 92 7e ff 76 9d c3 3b 7e a5 3f ce fa 10 e2 59 |~.~.v..;~.?....Y|
+00000220 ec 47 2d 7c ac da 4e 97 0e 15 a0 6f d0 02 42 01 |.G-|..N....o..B.|
+00000230 4d fc be 67 13 9c 2d 05 0e bd 3f a3 8c 25 c1 33 |M..g..-...?..%.3|
+00000240 13 83 0d 94 06 bb d4 37 7a f6 ec 7a c9 86 2e dd |.......7z..z....|
+00000250 d7 11 69 7f 85 7c 56 de fb 31 78 2b e4 c7 78 0d |..i..|V..1x+..x.|
+00000260 ae cb be 9e 4e 36 24 31 7b 6a 0f 39 95 12 07 8f |....N6$1{j.9....|
+00000270 2a 16 03 01 00 b5 0c 00 00 b1 03 00 1d 20 4a 7c |*............ J||
+00000280 0a 86 8a 81 f2 60 4a 3c ac d7 7d 3b fc 00 a5 b4 |.....`J<..};....|
+00000290 85 45 45 45 fb 09 53 d7 4a cf 24 9d c8 1a 00 8b |.EEE..S.J.$.....|
+000002a0 30 81 88 02 42 01 7a c9 c0 76 8c 26 98 63 4e a3 |0...B.z..v.&.cN.|
+000002b0 ad 4f 4e a3 d7 c7 d6 4a 69 28 cf d2 7b 0b 36 fb |.ON....Ji(..{.6.|
+000002c0 a3 ae 2f e1 83 ea ea 4a b7 2d ef a8 2d 13 96 e4 |../....J.-..-...|
+000002d0 73 83 66 70 5e 5c d9 5a d1 1c d1 33 18 0b b3 30 |s.fp^\.Z...3...0|
+000002e0 2a 21 d7 78 d8 70 18 02 42 00 c4 ab 80 33 8f f1 |*!.x.p..B....3..|
+000002f0 c2 74 1b 58 2f 59 d4 27 a1 19 42 bf 14 ea a8 a2 |.t.X/Y.'..B.....|
+00000300 cb bf 96 2d 60 7b 84 40 cc 31 f5 c4 e8 51 87 b8 |...-`{.@.1...Q..|
+00000310 7b 47 ec c4 c0 4a 9b 09 59 1e f8 b5 9a e1 45 a4 |{G...J..Y.....E.|
+00000320 a1 9b ee 78 55 f8 f5 fa 1a fb c5 16 03 01 00 04 |...xU...........|
+00000330 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 b0 5e 4a 8a 07 e3 86 43 05 16 68 |....0.^J....C..h|
+00000040 0e d1 58 a6 05 49 e9 a6 42 89 2c 3f 33 68 8b 26 |..X..I..B.,?3h.&|
+00000050 23 21 3b 62 ab 7a 21 74 d8 49 15 03 b3 1e c6 53 |#!;b.z!t.I.....S|
+00000060 74 1e 1c 4e 0f |t..N.|
+>>> Flow 4 (server to client)
+00000000 14 03 01 00 01 01 16 03 01 00 30 64 4b 3c 1a e3 |..........0dK<..|
+00000010 7d bb bb bb 64 d8 51 c3 eb 92 65 65 58 35 dd 7b |}...d.Q...eeX5.{|
+00000020 d2 fd f0 0c c1 10 71 a5 a8 f7 14 84 69 b4 81 18 |......q.....i...|
+00000030 1e 0d d3 19 b6 23 72 1a a7 43 0e |.....#r..C.|
+>>> Flow 5 (client to server)
+00000000 17 03 01 00 20 c3 e6 70 2c 44 4f 04 0c fb 0b 7f |.... ..p,DO.....|
+00000010 1d 2c ef 4d cc c3 21 ba a2 db 74 76 46 ea 00 40 |.,.M..!...tvF..@|
+00000020 54 2d 4a fe 59 17 03 01 00 20 0c 6b 39 0d b5 f3 |T-J.Y.... .k9...|
+00000030 ed 7e d0 de 01 18 0c 32 4e 59 93 46 d3 c5 4f c0 |.~.....2NY.F..O.|
+00000040 f5 fd f1 d2 79 07 7d 07 b0 24 15 03 01 00 20 1d |....y.}..$.... .|
+00000050 f7 53 a2 e7 3f 88 87 35 01 6e a5 b1 d6 81 37 5b |.S..?..5.n....7[|
+00000060 a7 64 4c 29 f4 71 59 a1 36 c1 1a 24 93 31 7d |.dL).qY.6..$.1}|
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..24da556
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv10-ECDHE-RSA-AES
@@ -0,0 +1,95 @@
+>>> 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 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 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 63 68 ea 52 0b |....Y...U..ch.R.|
+00000010 dc 68 c7 d0 75 3e 7d 6f 0b 8c cb 25 48 b0 bb df |.h..u>}o...%H...|
+00000020 7a 56 93 a9 d5 4f 0c 3a e2 37 ab 20 1f 0f a4 d3 |zV...O.:.7. ....|
+00000030 b4 f6 66 6f 39 6f 62 fb 6a 1f 41 09 4b 02 5c 15 |..fo9ob.j.A.K.\.|
+00000040 a0 ba cb a6 f9 bd 3b ec cb 76 6e ea c0 13 00 00 |......;..vn.....|
+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 04 9f 8b 4f 13 83 26 |........ ...O..&|
+000002d0 a3 cf 08 6e 59 bf b5 49 b8 ff 95 94 21 8d 2a 56 |...nY..I....!.*V|
+000002e0 2e 4b be ad ac 89 6e 52 4d 00 80 5f 63 93 43 a2 |.K....nRM.._c.C.|
+000002f0 a6 fb 53 b0 ac 93 3f 55 1d c1 0f 71 1e 96 ba 9f |..S...?U...q....|
+00000300 86 19 f3 83 7d 90 ce 06 24 9a 60 69 f0 35 24 5d |....}...$.`i.5$]|
+00000310 9d ce 49 0d 6f ba 31 59 3c f2 64 27 66 76 0e f1 |..I.o.1Y<.d'fv..|
+00000320 33 eb b8 70 61 d3 0c 93 a3 62 c7 5e c2 06 9d 48 |3..pa....b.^...H|
+00000330 16 2e a6 62 50 18 f6 c0 79 c2 09 f3 d5 74 bf db |...bP...y....t..|
+00000340 b8 d4 25 06 a7 be 4a b0 62 82 86 d0 00 86 5e a2 |..%...J.b.....^.|
+00000350 34 49 9b 37 37 9a b6 eb cc b9 8b 17 1f 29 4b a3 |4I.77........)K.|
+00000360 51 e3 c3 e8 3e 6e df c4 1d e5 48 16 03 01 00 04 |Q...>n....H.....|
+00000370 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 a6 3a 66 02 e6 09 6a dd 68 56 bc |....0.:f...j.hV.|
+00000040 aa ec 82 c4 69 9b b9 45 44 ec e2 c2 5b 49 5d 9b |....i..ED...[I].|
+00000050 f8 0e 81 1e 23 9e 13 72 d1 d2 0c 24 01 4f 35 aa |....#..r...$.O5.|
+00000060 27 fc b3 cc 08 |'....|
+>>> Flow 4 (server to client)
+00000000 14 03 01 00 01 01 16 03 01 00 30 0e 25 d7 a9 c0 |..........0.%...|
+00000010 18 3b bf 55 c0 47 3a 95 2d cb 6f c2 2c de e3 94 |.;.U.G:.-.o.,...|
+00000020 32 d3 eb e2 b6 6b 5f 42 9c 1e 47 d6 76 0c eb 95 |2....k_B..G.v...|
+00000030 fd 2d c3 9a ee ee 83 87 e8 8d 83 |.-.........|
+>>> Flow 5 (client to server)
+00000000 17 03 01 00 20 ba b0 c4 22 ee 52 81 ca 55 97 4d |.... ...".R..U.M|
+00000010 39 16 b9 37 bf df 7b d1 ae 4b 47 ac 10 12 a9 77 |9..7..{..KG....w|
+00000020 69 50 f3 60 13 17 03 01 00 20 90 d5 17 e4 96 38 |iP.`..... .....8|
+00000030 cd f7 30 6e 19 45 4e 32 ad 5f 1b 00 bf 22 9d c2 |..0n.EN2._..."..|
+00000040 16 30 fe 92 c7 fc 91 38 29 30 15 03 01 00 20 c0 |.0.....8)0.... .|
+00000050 02 ff 81 82 c9 25 c6 b0 06 ee 18 61 19 c8 d2 20 |.....%.....a... |
+00000060 d8 4e 7b a4 a5 57 17 64 4d ad 1e 1e 16 1e 52 |.N{..W.dM.....R|
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..6a40d83
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv10-ExportKeyingMaterial
@@ -0,0 +1,95 @@
+>>> 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 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 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 05 31 9d 41 04 |....Y...U...1.A.|
+00000010 c0 d4 34 1a fc 0f 63 26 47 d6 13 7f a0 d8 aa bf |..4...c&G.......|
+00000020 28 92 04 80 02 75 58 e6 01 e1 30 20 3c fc b0 02 |(....uX...0 <...|
+00000030 8b a4 9e 9e b2 5c 17 3c 48 0b 96 6f 15 80 d5 38 |.....\.<H..o...8|
+00000040 25 a2 f8 fb 6b fd 47 27 c2 53 6c 60 c0 13 00 00 |%...k.G'.Sl`....|
+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 a4 50 9a 0d c7 2a 1b |........ .P...*.|
+000002d0 f6 d4 78 49 68 ac 5f 8b e7 78 68 05 4b f8 c6 b3 |..xIh._..xh.K...|
+000002e0 eb 28 79 96 d5 e6 aa c1 54 00 80 22 66 ec fd 14 |.(y.....T.."f...|
+000002f0 83 7b 03 86 14 75 84 a4 a6 d0 ee d3 d0 f7 95 d8 |.{...u..........|
+00000300 43 48 a4 eb 83 af 96 ac cf e8 65 20 05 c3 18 9a |CH........e ....|
+00000310 54 63 f5 2f b7 17 06 e0 2a b3 65 6a 2f cc cd 93 |Tc./....*.ej/...|
+00000320 1e b3 5a 4d 09 da 70 b0 12 46 60 11 e4 9f ee 9f |..ZM..p..F`.....|
+00000330 3b 6f ef df bc db 69 22 5e e8 4c 41 d6 b7 7b 06 |;o....i"^.LA..{.|
+00000340 b6 99 1c 6d 01 5a 61 7c 4e 3a af 3e 01 7e 46 bd |...m.Za|N:.>.~F.|
+00000350 c8 15 28 ba 7f b3 d6 9d 95 74 04 36 6c 38 16 86 |..(......t.6l8..|
+00000360 d2 1d 8a 85 d1 21 5c 33 17 50 a1 16 03 01 00 04 |.....!\3.P......|
+00000370 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 f0 15 ea 81 0f a6 22 0a cd a5 a1 |....0......"....|
+00000040 38 4a da 1b 6c 81 19 d5 35 b7 af e9 ec 16 4d 98 |8J..l...5.....M.|
+00000050 21 c2 0e f7 0b fb ff d8 1e 2d 8b 04 56 82 48 c4 |!........-..V.H.|
+00000060 e5 f9 38 8c d2 |..8..|
+>>> Flow 4 (server to client)
+00000000 14 03 01 00 01 01 16 03 01 00 30 f0 b5 a3 bb bb |..........0.....|
+00000010 9d 85 7d 6f e7 a9 17 31 65 74 82 69 56 a9 33 21 |..}o...1et.iV.3!|
+00000020 16 9d 75 3a 28 88 a5 c2 a9 e1 a7 43 6e 03 26 96 |..u:(......Cn.&.|
+00000030 37 4b de 63 be 49 cb c8 d4 a2 b6 |7K.c.I.....|
+>>> Flow 5 (client to server)
+00000000 17 03 01 00 20 a9 9c 8f 74 ce f9 77 bc b3 86 2e |.... ...t..w....|
+00000010 a5 8e 94 3d 08 a6 96 bf 25 0b 10 c4 66 c2 59 9a |...=....%...f.Y.|
+00000020 4a 1a b4 77 12 17 03 01 00 20 03 72 60 38 58 88 |J..w..... .r`8X.|
+00000030 86 20 20 3f 18 52 c5 ca 55 3c 04 04 c7 e1 74 6f |. ?.R..U<....to|
+00000040 ca 1f cd 27 64 f2 51 12 9c ee 15 03 01 00 20 30 |...'d.Q....... 0|
+00000050 71 2a 78 bf 8b d5 11 7c 63 11 c7 25 0e 56 25 ce |q*x....|c..%.V%.|
+00000060 24 d5 d7 de a0 ba c7 ba e6 dc db 8e e3 93 a6 |$..............|
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..dcc18ad
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv10-RSA-RC4
@@ -0,0 +1,84 @@
+>>> 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 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 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 51 02 00 00 4d 03 01 2a 09 26 d2 61 |....Q...M..*.&.a|
+00000010 ac 38 91 3d 18 3f f7 a9 3c 34 91 b0 b1 e1 29 68 |.8.=.?..<4....)h|
+00000020 dd cb b9 a9 d8 39 0b 64 c6 93 7d 20 ea 51 ff 63 |.....9.d..} .Q.c|
+00000030 97 03 b2 6f a3 d6 55 0d 64 65 2a 5d 3a fe e9 3e |...o..U.de*]:..>|
+00000040 47 c1 7d c5 d8 03 c6 22 19 2f 6c 5a 00 05 00 00 |G.}...."./lZ....|
+00000050 05 ff 01 00 01 00 16 03 01 02 59 0b 00 02 55 00 |..........Y...U.|
+00000060 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......|
+00000070 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..|
+00000080 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.|
+00000090 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..|
+000000a0 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..|
+000000b0 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..|
+000000c0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1|
+000000d0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.|
+000000e0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...|
+000000f0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0|
+00000100 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.|
+00000110 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6|
+00000120 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.|
+00000130 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....|
+00000140 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......|
+00000150 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$|
+00000160 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..|
+00000170 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u|
+00000180 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.|
+00000190 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........|
+000001a0 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.|
+000001b0 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......|
+000001c0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.|
+000001d0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>|
+000001e0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#|
+000001f0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..|
+00000200 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0|
+00000210 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan|
+00000220 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........|
+00000230 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...|
+00000240 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1|
+00000250 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d|
+00000260 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..|
+00000270 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....|
+00000280 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......|
+00000290 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..|
+000002a0 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.|
+000002b0 3b e9 fa e7 16 03 01 00 04 0e 00 00 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 29 ee 6c 54 d6 21 5e 31 30 9e |.....$).lT.!^10.|
+000000a0 fd 02 69 bb 32 c2 9e ad 28 b1 2d 94 49 0a 12 0c |..i.2...(.-.I...|
+000000b0 a1 12 b0 98 a6 33 eb 63 2b e4 |.....3.c+.|
+>>> Flow 4 (server to client)
+00000000 14 03 01 00 01 01 16 03 01 00 24 32 3e 45 f2 3a |..........$2>E.:|
+00000010 01 05 50 db 37 25 f6 b5 67 8e 38 3d f5 ba b7 90 |..P.7%..g.8=....|
+00000020 e0 05 a8 cb e0 33 1a 79 ab 44 86 d5 0c fd 86 |.....3.y.D.....|
+>>> Flow 5 (client to server)
+00000000 17 03 01 00 1a ac 0c 1f 12 4e d4 31 10 dd c1 04 |.........N.1....|
+00000010 8b 55 a2 2e a5 f4 e4 80 aa 23 7e bd 79 b0 ee 15 |.U.......#~.y...|
+00000020 03 01 00 16 fa d9 ff 50 7d 41 01 2a d2 13 ee 33 |.......P}A.*...3|
+00000030 52 ab 20 c5 e7 73 81 5d 81 60 |R. ..s.].`|
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..92cdc4c
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv11-ECDHE-ECDSA-AES
@@ -0,0 +1,93 @@
+>>> 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 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 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 02 00 59 02 00 00 55 03 02 bf ac 6b 91 53 |....Y...U....k.S|
+00000010 dc 1f d6 ee 0e 71 d6 a4 f5 a2 7c f0 10 69 41 dd |.....q....|..iA.|
+00000020 4a b7 30 53 e6 28 07 31 34 8f e5 20 59 d1 bd e1 |J.0S.(.14.. Y...|
+00000030 20 44 c4 05 07 e9 07 90 5d de 08 73 72 55 04 a6 | D......]..srU..|
+00000040 11 20 bf 32 e0 dd 46 d4 1d ed 45 62 c0 09 00 00 |. .2..F...Eb....|
+00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................|
+00000060 02 02 0e 0b 00 02 0a 00 02 07 00 02 04 30 82 02 |.............0..|
+00000070 00 30 82 01 62 02 09 00 b8 bf 2d 47 a0 d2 eb f4 |.0..b.....-G....|
+00000080 30 09 06 07 2a 86 48 ce 3d 04 01 30 45 31 0b 30 |0...*.H.=..0E1.0|
+00000090 09 06 03 55 04 06 13 02 41 55 31 13 30 11 06 03 |...U....AU1.0...|
+000000a0 55 04 08 13 0a 53 6f 6d 65 2d 53 74 61 74 65 31 |U....Some-State1|
+000000b0 21 30 1f 06 03 55 04 0a 13 18 49 6e 74 65 72 6e |!0...U....Intern|
+000000c0 65 74 20 57 69 64 67 69 74 73 20 50 74 79 20 4c |et Widgits Pty L|
+000000d0 74 64 30 1e 17 0d 31 32 31 31 32 32 31 35 30 36 |td0...1211221506|
+000000e0 33 32 5a 17 0d 32 32 31 31 32 30 31 35 30 36 33 |32Z..22112015063|
+000000f0 32 5a 30 45 31 0b 30 09 06 03 55 04 06 13 02 41 |2Z0E1.0...U....A|
+00000100 55 31 13 30 11 06 03 55 04 08 13 0a 53 6f 6d 65 |U1.0...U....Some|
+00000110 2d 53 74 61 74 65 31 21 30 1f 06 03 55 04 0a 13 |-State1!0...U...|
+00000120 18 49 6e 74 65 72 6e 65 74 20 57 69 64 67 69 74 |.Internet Widgit|
+00000130 73 20 50 74 79 20 4c 74 64 30 81 9b 30 10 06 07 |s Pty Ltd0..0...|
+00000140 2a 86 48 ce 3d 02 01 06 05 2b 81 04 00 23 03 81 |*.H.=....+...#..|
+00000150 86 00 04 00 c4 a1 ed be 98 f9 0b 48 73 36 7e c3 |...........Hs6~.|
+00000160 16 56 11 22 f2 3d 53 c3 3b 4d 21 3d cd 6b 75 e6 |.V.".=S.;M!=.ku.|
+00000170 f6 b0 dc 9a df 26 c1 bc b2 87 f0 72 32 7c b3 64 |.....&.....r2|.d|
+00000180 2f 1c 90 bc ea 68 23 10 7e fe e3 25 c0 48 3a 69 |/....h#.~..%.H:i|
+00000190 e0 28 6d d3 37 00 ef 04 62 dd 0d a0 9c 70 62 83 |.(m.7...b....pb.|
+000001a0 d8 81 d3 64 31 aa 9e 97 31 bd 96 b0 68 c0 9b 23 |...d1...1...h..#|
+000001b0 de 76 64 3f 1a 5c 7f e9 12 0e 58 58 b6 5f 70 dd |.vd?.\....XX._p.|
+000001c0 9b d8 ea d5 d7 f5 d5 cc b9 b6 9f 30 66 5b 66 9a |...........0f[f.|
+000001d0 20 e2 27 e5 bf fe 3b 30 09 06 07 2a 86 48 ce 3d | .'...;0...*.H.=|
+000001e0 04 01 03 81 8c 00 30 81 88 02 42 01 88 a2 4f eb |......0...B...O.|
+000001f0 e2 45 c5 48 7d 1b ac f5 ed 98 9d ae 47 70 c0 5e |.E.H}.......Gp.^|
+00000200 1b b6 2f bd f1 b6 4d b7 61 40 d3 11 a2 ce ee 0b |../...M.a@......|
+00000210 7e 92 7e ff 76 9d c3 3b 7e a5 3f ce fa 10 e2 59 |~.~.v..;~.?....Y|
+00000220 ec 47 2d 7c ac da 4e 97 0e 15 a0 6f d0 02 42 01 |.G-|..N....o..B.|
+00000230 4d fc be 67 13 9c 2d 05 0e bd 3f a3 8c 25 c1 33 |M..g..-...?..%.3|
+00000240 13 83 0d 94 06 bb d4 37 7a f6 ec 7a c9 86 2e dd |.......7z..z....|
+00000250 d7 11 69 7f 85 7c 56 de fb 31 78 2b e4 c7 78 0d |..i..|V..1x+..x.|
+00000260 ae cb be 9e 4e 36 24 31 7b 6a 0f 39 95 12 07 8f |....N6$1{j.9....|
+00000270 2a 16 03 02 00 b5 0c 00 00 b1 03 00 1d 20 ab ea |*............ ..|
+00000280 ff 17 1e b1 ef f6 22 03 40 8b e1 1a fa ab 01 cf |......".@.......|
+00000290 0f f0 b0 6d 43 3c 1f 03 a1 d6 4a 9d 79 43 00 8b |...mC<....J.yC..|
+000002a0 30 81 88 02 42 00 a1 b4 50 4b 9b a3 a5 ec ef dc |0...B...PK......|
+000002b0 bf c1 a2 65 24 2a 6c aa ab 26 01 ed d1 ad 2e 37 |...e$*l..&.....7|
+000002c0 4f f5 8b ff 98 ac ef 15 3e d9 46 07 a3 d2 35 de |O.......>.F...5.|
+000002d0 91 bc 3d a0 1f f1 68 55 28 ef 60 ad 13 05 ac 65 |..=...hU(.`....e|
+000002e0 e5 67 02 3f 85 8b 1b 02 42 01 26 3f fc 62 e3 93 |.g.?....B.&?.b..|
+000002f0 8e fa fb 93 0f 0b ff 68 25 46 ea 71 16 ae 6e d4 |.......h%F.q..n.|
+00000300 36 9e 48 2c 77 2b d8 f5 f6 1d 69 68 ed 28 8f e7 |6.H,w+....ih.(..|
+00000310 79 7e 78 56 52 ff e8 62 fc e2 bd 2e c7 e8 9f 3f |y~xVR..b.......?|
+00000320 93 47 d2 62 6c f6 5c 0e a2 b8 fe 16 03 02 00 04 |.G.bl.\.........|
+00000330 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 0f 55 37 4b 93 d5 ce b1 1c 6f a3 |......U7K.....o.|
+00000050 6d 56 32 f5 de 19 f6 a3 15 b0 6a 90 06 92 60 ca |mV2.......j...`.|
+00000060 ec 0e 2b d4 24 16 0a 26 f3 bd 3d ca c5 9f d2 9b |..+.$..&..=.....|
+00000070 79 2f af b6 b0 |y/...|
+>>> Flow 4 (server to client)
+00000000 14 03 02 00 01 01 16 03 02 00 40 4d e3 a9 af 51 |..........@M...Q|
+00000010 f5 d1 cd 04 f1 cf c5 48 0f 2e 0b 6e 57 4c 11 28 |.......H...nWL.(|
+00000020 dd 89 19 14 98 8e 2e 92 db 3c a4 0f 85 32 90 7e |.........<...2.~|
+00000030 49 13 17 a0 85 fa c6 25 79 24 13 90 86 dc ec 45 |I......%y$.....E|
+00000040 7c 74 35 92 e4 89 04 c2 51 27 66 ||t5.....Q'f|
+>>> 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 f9 ac 17 1f 08 b7 80 fb 70 87 e2 |.............p..|
+00000020 53 00 27 60 78 6c 80 5b 57 e7 70 72 8a e3 1b 32 |S.'`xl.[W.pr...2|
+00000030 8c f0 67 82 82 15 03 02 00 30 00 00 00 00 00 00 |..g......0......|
+00000040 00 00 00 00 00 00 00 00 00 00 01 e1 86 47 7f 65 |.............G.e|
+00000050 a9 d2 1c 22 7d 99 7c 41 dc 17 f5 16 40 5b b3 7f |..."}.|A....@[..|
+00000060 cc 0b 97 41 0c ae 1f 0c 39 e0 |...A....9.|
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..b2b7ecb
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv11-ECDHE-RSA-AES
@@ -0,0 +1,97 @@
+>>> 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 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 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 02 00 59 02 00 00 55 03 02 95 6e 24 5a ab |....Y...U...n$Z.|
+00000010 ae 3c 73 52 9d 31 63 50 cf f9 50 99 3c e4 94 22 |.<sR.1cP..P.<.."|
+00000020 5b 6f 0e f8 e3 a8 64 4c d2 8c 00 20 8b 2d 25 47 |[o....dL... .-%G|
+00000030 f9 74 41 93 b1 82 b5 c5 fc 3e 42 c9 35 fc 68 27 |.tA......>B.5.h'|
+00000040 c4 2b 35 0f f8 1c e3 28 e6 8a 59 dc c0 13 00 00 |.+5....(..Y.....|
+00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................|
+00000060 02 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 02 00 |.=.`.\!.;.......|
+000002c0 aa 0c 00 00 a6 03 00 1d 20 b5 75 ee e5 26 6b c0 |........ .u..&k.|
+000002d0 af 34 8a 24 f7 c5 25 58 29 38 4c 08 d3 a2 0c 48 |.4.$..%X)8L....H|
+000002e0 18 eb a0 5b e8 64 62 62 78 00 80 d0 1c 9c 11 1a |...[.dbbx.......|
+000002f0 58 4c 46 5f 18 03 d7 d7 76 47 d5 56 7a bb bd 95 |XLF_....vG.Vz...|
+00000300 16 46 e8 0b 28 6e df 15 65 1a f6 95 fb 4a 6c 42 |.F..(n..e....JlB|
+00000310 1b 4c 5c 30 c5 de d0 83 08 d3 2e 4d 59 7e 7b 1b |.L\0.......MY~{.|
+00000320 20 9e b5 19 76 fe a3 dd 87 04 f4 9a 3e 3c c0 4a | ...v.......><.J|
+00000330 16 7f e3 4e 9a 1f 0a 36 1d f5 09 b4 88 09 b1 1b |...N...6........|
+00000340 9b 60 97 dc d7 ea 97 f4 d6 06 16 45 98 ee 5c 39 |.`.........E..\9|
+00000350 62 3f 7c 82 7b c3 52 59 01 d4 89 8c a6 e2 d5 eb |b?|.{.RY........|
+00000360 e8 30 a6 78 49 1e ec a5 92 ad 24 16 03 02 00 04 |.0.xI.....$.....|
+00000370 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 28 ab ed 77 d3 56 29 a8 4a 38 c8 |.....(..w.V).J8.|
+00000050 64 1c a5 d9 4e f9 6b 0e fa 82 42 ad 0d be 15 69 |d...N.k...B....i|
+00000060 9a ff 79 64 db 8f 3e 16 b3 86 93 82 6f 78 c4 2e |..yd..>.....ox..|
+00000070 7c 54 6c 4f 90 ||TlO.|
+>>> Flow 4 (server to client)
+00000000 14 03 02 00 01 01 16 03 02 00 40 15 e9 c5 15 59 |..........@....Y|
+00000010 b3 0d 46 22 0c ae a6 41 02 b4 f3 da 11 dc 85 79 |..F"...A.......y|
+00000020 bb d9 3f 23 38 51 24 1a 08 b5 a0 63 dc 4b 86 50 |..?#8Q$....c.K.P|
+00000030 ef b2 32 07 fd b5 e1 01 06 19 42 ce ba 69 ab 1a |..2.......B..i..|
+00000040 c9 bb db 7d d0 9f f9 7c f2 6c 18 |...}...|.l.|
+>>> 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 67 ef de df a4 91 69 58 b8 3f 06 |.....g.....iX.?.|
+00000020 c4 05 4e ad 88 9b c5 12 35 cf 63 39 3a 61 e9 4c |..N.....5.c9:a.L|
+00000030 49 22 93 f4 10 15 03 02 00 30 00 00 00 00 00 00 |I".......0......|
+00000040 00 00 00 00 00 00 00 00 00 00 00 2a 5a ba 39 7e |...........*Z.9~|
+00000050 a8 be 2e 72 f3 ba 7e 0a 32 b5 8c d8 f5 1b 93 6c |...r..~.2......l|
+00000060 3e 35 d8 ba cc f3 9f f4 19 74 |>5.......t|
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..aeba311
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv11-RSA-RC4
@@ -0,0 +1,84 @@
+>>> 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 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 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 02 00 51 02 00 00 4d 03 02 82 5b 12 ac 33 |....Q...M...[..3|
+00000010 08 d4 28 8c 91 6e 52 c4 c6 09 13 24 bf 42 d2 37 |..(..nR....$.B.7|
+00000020 6d 78 60 b0 ea bd 9e b3 08 99 43 20 05 5a 93 f9 |mx`.......C .Z..|
+00000030 a4 39 43 4f c4 e3 27 20 7d 4c fa 7a 28 c1 c7 33 |.9CO..' }L.z(..3|
+00000040 72 fa 14 b8 ba c3 89 b0 a5 54 a3 7c 00 05 00 00 |r........T.|....|
+00000050 05 ff 01 00 01 00 16 03 02 02 59 0b 00 02 55 00 |..........Y...U.|
+00000060 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......|
+00000070 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..|
+00000080 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.|
+00000090 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..|
+000000a0 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..|
+000000b0 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..|
+000000c0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1|
+000000d0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.|
+000000e0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...|
+000000f0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0|
+00000100 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.|
+00000110 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6|
+00000120 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.|
+00000130 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....|
+00000140 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......|
+00000150 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$|
+00000160 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..|
+00000170 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u|
+00000180 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.|
+00000190 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........|
+000001a0 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.|
+000001b0 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......|
+000001c0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.|
+000001d0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>|
+000001e0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#|
+000001f0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..|
+00000200 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0|
+00000210 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan|
+00000220 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........|
+00000230 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...|
+00000240 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1|
+00000250 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d|
+00000260 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..|
+00000270 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....|
+00000280 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......|
+00000290 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..|
+000002a0 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.|
+000002b0 3b e9 fa e7 16 03 02 00 04 0e 00 00 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 e1 1a bf e9 fd 4c fb 56 41 82 |.....$.....L.VA.|
+000000a0 c2 48 fc ca d9 d5 ec 2a 0a ee 63 25 e0 5f 53 cf |.H.....*..c%._S.|
+000000b0 24 ff fe da 6f f5 8b 61 b7 b9 |$...o..a..|
+>>> Flow 4 (server to client)
+00000000 14 03 02 00 01 01 16 03 02 00 24 99 2c e7 fa d0 |..........$.,...|
+00000010 29 d9 92 07 39 56 b0 0c ad 23 30 c8 d7 0b 38 da |)...9V...#0...8.|
+00000020 6f d3 c7 f9 66 d2 ec 8c 52 85 cb db a6 22 50 |o...f...R...."P|
+>>> Flow 5 (client to server)
+00000000 17 03 02 00 1a 9f 70 c4 77 f3 0a a8 e0 1a 75 87 |......p.w.....u.|
+00000010 ab 2a f1 23 52 79 9f 5c 8e af 5d ba 27 45 f9 15 |.*.#Ry.\..].'E..|
+00000020 03 02 00 16 f0 28 f3 71 a0 97 6b ba 7e 97 81 85 |.....(.q..k.~...|
+00000030 11 59 1b c9 fa a0 48 32 e9 65 |.Y....H2.e|
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..ce92872
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-AES128-GCM-SHA256
@@ -0,0 +1,86 @@
+>>> 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 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 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 51 02 00 00 4d 03 03 a4 26 bb e9 70 |....Q...M...&..p|
+00000010 57 4e ec f8 ea 23 01 75 c3 f3 a9 d4 d6 e8 71 2b |WN...#.u......q+|
+00000020 01 5e c0 73 19 2b b9 d8 8e 3e d1 20 c8 c3 0a 22 |.^.s.+...>. ..."|
+00000030 7b ee cd 2e c9 e8 95 db 90 db 70 f5 59 e6 90 65 |{.........p.Y..e|
+00000040 35 87 a6 d4 bb dd 85 34 43 e8 66 49 00 9c 00 00 |5......4C.fI....|
+00000050 05 ff 01 00 01 00 16 03 03 02 59 0b 00 02 55 00 |..........Y...U.|
+00000060 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......|
+00000070 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..|
+00000080 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.|
+00000090 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..|
+000000a0 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..|
+000000b0 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..|
+000000c0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1|
+000000d0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.|
+000000e0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...|
+000000f0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0|
+00000100 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.|
+00000110 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6|
+00000120 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.|
+00000130 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....|
+00000140 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......|
+00000150 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$|
+00000160 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..|
+00000170 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u|
+00000180 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.|
+00000190 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........|
+000001a0 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.|
+000001b0 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......|
+000001c0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.|
+000001d0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>|
+000001e0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#|
+000001f0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..|
+00000200 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0|
+00000210 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan|
+00000220 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........|
+00000230 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...|
+00000240 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1|
+00000250 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d|
+00000260 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..|
+00000270 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....|
+00000280 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......|
+00000290 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..|
+000002a0 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.|
+000002b0 3b e9 fa e7 16 03 03 00 04 0e 00 00 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 64 6c |.....(........dl|
+000000a0 08 78 1d 03 0c ed dd 01 30 d4 fb 7c 3f 24 45 cc |.x......0..|?$E.|
+000000b0 f6 b2 e3 42 07 93 8f 34 a8 21 d1 b0 08 e3 |...B...4.!....|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 28 75 9b 91 cd 7d |..........(u...}|
+00000010 8d f7 3c a0 d6 5e d4 f2 24 1a 0a f3 04 b1 d9 0b |..<..^..$.......|
+00000020 1d 31 ca 1c 8b e7 38 c0 8e 7d 12 19 89 33 28 4d |.1....8..}...3(M|
+00000030 83 28 b6 |.(.|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 7d fe 53 |.............}.S|
+00000010 73 aa ca 3d f3 27 b7 01 56 9e e7 c9 6d 79 2a 97 |s..=.'..V...my*.|
+00000020 b2 21 42 15 03 03 00 1a 00 00 00 00 00 00 00 02 |.!B.............|
+00000030 de bd 3e 9e 8f c0 98 ec bd b4 9b 89 90 a2 26 a8 |..>...........&.|
+00000040 28 97 |(.|
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..15394c7
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-AES128-SHA256
@@ -0,0 +1,95 @@
+>>> 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 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 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 51 02 00 00 4d 03 03 8a a8 2c 00 d8 |....Q...M....,..|
+00000010 d8 87 53 14 1e 7b ff ca 19 a2 6d bc 47 6f 73 12 |..S..{....m.Gos.|
+00000020 0d 54 6e 33 21 80 01 86 f8 81 9f 20 46 f6 8c e8 |.Tn3!...... F...|
+00000030 8b 90 02 b2 da e2 83 3a 2a 0f b3 f7 96 2b f8 96 |.......:*....+..|
+00000040 56 77 39 52 9e a1 bd 74 1e 2e b1 b0 00 3c 00 00 |Vw9R...t.....<..|
+00000050 05 ff 01 00 01 00 16 03 03 02 59 0b 00 02 55 00 |..........Y...U.|
+00000060 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......|
+00000070 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..|
+00000080 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.|
+00000090 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..|
+000000a0 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..|
+000000b0 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..|
+000000c0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1|
+000000d0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.|
+000000e0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...|
+000000f0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0|
+00000100 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.|
+00000110 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6|
+00000120 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.|
+00000130 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....|
+00000140 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......|
+00000150 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$|
+00000160 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..|
+00000170 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u|
+00000180 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.|
+00000190 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........|
+000001a0 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.|
+000001b0 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......|
+000001c0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.|
+000001d0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>|
+000001e0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#|
+000001f0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..|
+00000200 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0|
+00000210 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan|
+00000220 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........|
+00000230 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...|
+00000240 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1|
+00000250 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d|
+00000260 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..|
+00000270 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....|
+00000280 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......|
+00000290 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..|
+000002a0 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.|
+000002b0 3b e9 fa e7 16 03 03 00 04 0e 00 00 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 8f d8 ac 7f ec 16 9e d8 e9 f2 |................|
+000000b0 ce 30 51 dc 87 e0 f9 80 57 66 d9 87 20 77 3a b1 |.0Q.....Wf.. w:.|
+000000c0 43 db fc 36 f5 64 6e 96 e9 b8 e2 ab bb 00 48 36 |C..6.dn.......H6|
+000000d0 60 9c 5a 7c 38 3f 13 e1 9c ef d9 15 96 91 56 e2 |`.Z|8?........V.|
+000000e0 87 2e 23 1a 98 40 |..#..@|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 50 80 01 08 cc d8 |..........P.....|
+00000010 08 a8 81 20 b2 bb 5b 50 79 74 4a b5 10 c4 7a 30 |... ..[PytJ...z0|
+00000020 6c 46 d6 e5 36 6e 4d cc e5 0c 2c ab 3b de 92 45 |lF..6nM...,.;..E|
+00000030 ee 20 58 a9 0f 03 26 3e 6c 05 a7 ef f2 7c a7 9b |. X...&>l....|..|
+00000040 57 c0 20 8d d0 69 0e b0 5a cc e6 26 5f e2 c3 24 |W. ..i..Z..&_..$|
+00000050 c4 db df 20 03 08 e1 aa 59 2b d2 |... ....Y+.|
+>>> 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 a2 dd a6 ff 57 60 80 dd 97 cf 20 |.........W`.... |
+00000020 10 04 60 80 53 17 37 ce ce 39 b6 21 f4 06 61 aa |..`.S.7..9.!..a.|
+00000030 49 7b f0 d5 e0 72 4c 6f 38 d2 ab af 1c 94 bd 5b |I{...rLo8......[|
+00000040 1b ee 8a 9b e3 15 03 03 00 40 00 00 00 00 00 00 |.........@......|
+00000050 00 00 00 00 00 00 00 00 00 00 ba 18 32 e7 6d f5 |............2.m.|
+00000060 fa 2e 61 55 cc fe 3c 4d 19 fd 84 6d c4 2a 46 92 |..aU..<M...m.*F.|
+00000070 ae b7 f3 67 c8 3c ce cd b0 66 de ee 5d 3f 07 3b |...g.<...f..]?.;|
+00000080 a9 85 a1 93 1f 98 f7 95 c9 ac |..........|
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..766bf95
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-AES256-GCM-SHA384
@@ -0,0 +1,86 @@
+>>> 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 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 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 51 02 00 00 4d 03 03 de 7a 77 5b eb |....Q...M...zw[.|
+00000010 fa 84 a0 ac ba 3b ca 25 dc b3 c0 06 44 da 31 5c |.....;.%....D.1\|
+00000020 27 e0 4e af be 47 07 5a a5 ab 20 20 72 b2 67 0c |'.N..G.Z.. r.g.|
+00000030 7e 71 5d e3 55 89 91 27 7f 65 ac 71 c6 e8 a5 4a |~q].U..'.e.q...J|
+00000040 ae e1 a2 0d 3f a6 62 08 17 7e 26 fd 00 9d 00 00 |....?.b..~&.....|
+00000050 05 ff 01 00 01 00 16 03 03 02 59 0b 00 02 55 00 |..........Y...U.|
+00000060 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......|
+00000070 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..|
+00000080 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.|
+00000090 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..|
+000000a0 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..|
+000000b0 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..|
+000000c0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1|
+000000d0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.|
+000000e0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...|
+000000f0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0|
+00000100 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.|
+00000110 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6|
+00000120 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.|
+00000130 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....|
+00000140 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......|
+00000150 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$|
+00000160 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..|
+00000170 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u|
+00000180 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.|
+00000190 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........|
+000001a0 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.|
+000001b0 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......|
+000001c0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.|
+000001d0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>|
+000001e0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#|
+000001f0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..|
+00000200 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0|
+00000210 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan|
+00000220 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........|
+00000230 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...|
+00000240 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1|
+00000250 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d|
+00000260 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..|
+00000270 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....|
+00000280 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......|
+00000290 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..|
+000002a0 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.|
+000002b0 3b e9 fa e7 16 03 03 00 04 0e 00 00 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 0b 7d |.....(.........}|
+000000a0 83 0f 79 e2 4b ef d3 0e ff 57 d2 55 cd ea e9 be |..y.K....W.U....|
+000000b0 8b 38 1e 33 b0 6a eb e3 aa 51 52 82 e6 15 |.8.3.j...QR...|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 28 1a a3 bb d4 c4 |..........(.....|
+00000010 53 c7 5c 09 8c fb e7 51 41 73 d5 76 ef e6 40 9a |S.\....QAs.v..@.|
+00000020 06 27 c6 e8 9f 1b 25 f5 d1 7b 39 b7 74 ab e8 83 |.'....%..{9.t...|
+00000030 26 f6 40 |&.@|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 1c 0d 06 |................|
+00000010 d2 25 8a 06 d9 b4 d6 76 89 1c c6 b7 22 9f 44 63 |.%.....v....".Dc|
+00000020 a3 f9 89 15 03 03 00 1a 00 00 00 00 00 00 00 02 |................|
+00000030 cb 34 e8 4b f7 b1 ab 1a 74 60 2c 2d cf a4 7d 9f |.4.K....t`,-..}.|
+00000040 f4 b4 |..|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ALPN b/src/crypto/tls/testdata/Client-TLSv12-ALPN
new file mode 100644
index 0000000..8b9a510
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ALPN
@@ -0,0 +1,93 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 01 0e 01 00 01 0a 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 8f 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 10 00 10 00 0e 06 70 72 6f 74 6f |...........proto|
+000000d0 32 06 70 72 6f 74 6f 31 00 12 00 00 00 2b 00 09 |2.proto1.....+..|
+000000e0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000f0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+00000100 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000110 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 66 02 00 00 62 03 03 2d b3 e1 a8 44 |....f...b..-...D|
+00000010 c6 3e 20 b9 50 49 ab b8 48 c3 bf d6 f3 7b 2e 0a |.> .PI..H....{..|
+00000020 8c 49 ba e5 8e 54 5e 02 59 01 75 20 f0 a0 60 c2 |.I...T^.Y.u ..`.|
+00000030 81 df 62 f9 f8 7d 3c 3c ee 1e 0c 1d c2 11 58 7f |..b..}<<......X.|
+00000040 e0 dc b1 6c 17 9e 19 60 ca c2 40 84 cc a8 00 00 |...l...`..@.....|
+00000050 1a 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 16 03 03 02 59 |.....proto1....Y|
+00000070 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 |...U..R..O0..K0.|
+00000080 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b |.............?.[|
+00000090 ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 |..0...*.H.......|
+000000a0 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |.0.1.0...U....Go|
+000000b0 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f |1.0...U....Go Ro|
+000000c0 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 |ot0...1601010000|
+000000d0 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 |00Z..25010100000|
+000000e0 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 |0Z0.1.0...U....G|
+000000f0 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 |o1.0...U....Go0.|
+00000100 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 |.0...*.H........|
+00000110 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e |....0.......F}..|
+00000120 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e |.'.H..(!.~...]..|
+00000130 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be |RE.z6G....B[....|
+00000140 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 |.y.@.Om..+.....g|
+00000150 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 |....."8.J.ts+.4.|
+00000160 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 |.....t{.X.la<..A|
+00000170 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 |..++$#w[.;.u]. T|
+00000180 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 |..c...$....P....|
+00000190 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 |C...ub...R......|
+000001a0 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff |...0..0...U.....|
+000001b0 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 |......0...U.%..0|
+000001c0 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 |...+.........+..|
+000001d0 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 |.....0...U......|
+000001e0 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 |.0.0...U........|
+000001f0 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b |..CC>I..m....`0.|
+00000200 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 |..U.#..0...H.IM.|
+00000210 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 |~.1......n{0...U|
+00000220 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e |....0...example.|
+00000230 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d |golang0...*.H...|
+00000240 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 |..........0.@+[P|
+00000250 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 |.a...SX...(.X..8|
+00000260 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 |....1Z..f=C.-...|
+00000270 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 |... d8.$:....}.@|
+00000280 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c | ._...a..v......|
+00000290 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c |\.....l..s..Cw..|
+000002a0 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 |.....@.a.Lr+...F|
+000002b0 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 |..M...>...B...=.|
+000002c0 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 ac 0c 00 |`.\!.;..........|
+000002d0 00 a8 03 00 1d 20 7b 47 ec ef 4d 39 ec 65 b9 7c |..... {G..M9.e.||
+000002e0 08 da b5 41 0d 62 0b 52 29 24 25 3d 39 21 ed d3 |...A.b.R)$%=9!..|
+000002f0 30 37 0c 15 66 49 08 04 00 80 4b 01 8e 80 78 ed |07..fI....K...x.|
+00000300 d1 44 e5 98 a4 43 9a 73 b7 dc 67 72 83 29 f3 e3 |.D...C.s..gr.)..|
+00000310 5b 72 ee d6 36 12 db bf ab d6 86 fd a8 54 a5 a0 |[r..6........T..|
+00000320 0e 76 ca ea a7 f5 f2 e1 87 94 a7 c5 d8 69 b7 58 |.v...........i.X|
+00000330 d2 f0 10 08 8c 08 ac bd aa 60 f5 45 20 15 77 71 |.........`.E .wq|
+00000340 5a bb 2a 8b 0a 4b a3 08 71 88 82 01 3c bc 54 ba |Z.*..K..q...<.T.|
+00000350 f4 42 7a 08 64 d7 57 5b dc ea 6a 72 e1 7d ca 96 |.Bz.d.W[..jr.}..|
+00000360 d9 89 eb 60 9e d2 a4 f5 cb d5 45 d1 4d 09 4e 18 |...`......E.M.N.|
+00000370 a2 4f 0f 59 97 a1 5f 7f 65 4f 16 03 03 00 04 0e |.O.Y.._.eO......|
+00000380 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 b9 f7 58 6f d3 29 b8 41 35 06 b7 |.... ..Xo.).A5..|
+00000040 55 85 c1 f0 63 fe 4f 5f 87 01 cc 67 0b f1 4c b4 |U...c.O_...g..L.|
+00000050 ca 92 bd c0 6d |....m|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 20 68 92 93 84 bd |.......... h....|
+00000010 0e de 33 1b db ca 54 b8 a0 2f 53 c5 76 de d2 c5 |..3...T../S.v...|
+00000020 7a 54 bb db 0c 08 86 79 d2 6c 58 |zT.....y.lX|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 16 79 38 07 9b be 83 44 9a 3e 11 1a |.....y8....D.>..|
+00000010 99 2f f2 4e 33 84 0b c7 8e ed c3 15 03 03 00 12 |./.N3...........|
+00000020 ca bd 7e 59 04 8c e0 52 80 1e 56 1e af c1 5f 61 |..~Y...R..V..._a|
+00000030 6c 6a |lj|
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..e1fb8a8
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-ECDSA
@@ -0,0 +1,139 @@
+>>> 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 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 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 59 02 00 00 55 03 03 36 60 84 12 26 |....Y...U..6`..&|
+00000010 51 e4 32 33 26 ef c3 31 bf ea ac 27 0f c3 fb cb |Q.23&..1...'....|
+00000020 05 89 af df 56 a9 3f 14 6e 5e 2c 20 ad 6e 60 2d |....V.?.n^, .n`-|
+00000030 94 aa e5 73 22 eb 68 92 77 1c 6c cb f4 5a 14 f2 |...s".h.w.l..Z..|
+00000040 29 85 88 aa 2e 56 2a ad 80 e1 f0 b1 c0 09 00 00 |)....V*.........|
+00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................|
+00000060 03 02 0e 0b 00 02 0a 00 02 07 00 02 04 30 82 02 |.............0..|
+00000070 00 30 82 01 62 02 09 00 b8 bf 2d 47 a0 d2 eb f4 |.0..b.....-G....|
+00000080 30 09 06 07 2a 86 48 ce 3d 04 01 30 45 31 0b 30 |0...*.H.=..0E1.0|
+00000090 09 06 03 55 04 06 13 02 41 55 31 13 30 11 06 03 |...U....AU1.0...|
+000000a0 55 04 08 13 0a 53 6f 6d 65 2d 53 74 61 74 65 31 |U....Some-State1|
+000000b0 21 30 1f 06 03 55 04 0a 13 18 49 6e 74 65 72 6e |!0...U....Intern|
+000000c0 65 74 20 57 69 64 67 69 74 73 20 50 74 79 20 4c |et Widgits Pty L|
+000000d0 74 64 30 1e 17 0d 31 32 31 31 32 32 31 35 30 36 |td0...1211221506|
+000000e0 33 32 5a 17 0d 32 32 31 31 32 30 31 35 30 36 33 |32Z..22112015063|
+000000f0 32 5a 30 45 31 0b 30 09 06 03 55 04 06 13 02 41 |2Z0E1.0...U....A|
+00000100 55 31 13 30 11 06 03 55 04 08 13 0a 53 6f 6d 65 |U1.0...U....Some|
+00000110 2d 53 74 61 74 65 31 21 30 1f 06 03 55 04 0a 13 |-State1!0...U...|
+00000120 18 49 6e 74 65 72 6e 65 74 20 57 69 64 67 69 74 |.Internet Widgit|
+00000130 73 20 50 74 79 20 4c 74 64 30 81 9b 30 10 06 07 |s Pty Ltd0..0...|
+00000140 2a 86 48 ce 3d 02 01 06 05 2b 81 04 00 23 03 81 |*.H.=....+...#..|
+00000150 86 00 04 00 c4 a1 ed be 98 f9 0b 48 73 36 7e c3 |...........Hs6~.|
+00000160 16 56 11 22 f2 3d 53 c3 3b 4d 21 3d cd 6b 75 e6 |.V.".=S.;M!=.ku.|
+00000170 f6 b0 dc 9a df 26 c1 bc b2 87 f0 72 32 7c b3 64 |.....&.....r2|.d|
+00000180 2f 1c 90 bc ea 68 23 10 7e fe e3 25 c0 48 3a 69 |/....h#.~..%.H:i|
+00000190 e0 28 6d d3 37 00 ef 04 62 dd 0d a0 9c 70 62 83 |.(m.7...b....pb.|
+000001a0 d8 81 d3 64 31 aa 9e 97 31 bd 96 b0 68 c0 9b 23 |...d1...1...h..#|
+000001b0 de 76 64 3f 1a 5c 7f e9 12 0e 58 58 b6 5f 70 dd |.vd?.\....XX._p.|
+000001c0 9b d8 ea d5 d7 f5 d5 cc b9 b6 9f 30 66 5b 66 9a |...........0f[f.|
+000001d0 20 e2 27 e5 bf fe 3b 30 09 06 07 2a 86 48 ce 3d | .'...;0...*.H.=|
+000001e0 04 01 03 81 8c 00 30 81 88 02 42 01 88 a2 4f eb |......0...B...O.|
+000001f0 e2 45 c5 48 7d 1b ac f5 ed 98 9d ae 47 70 c0 5e |.E.H}.......Gp.^|
+00000200 1b b6 2f bd f1 b6 4d b7 61 40 d3 11 a2 ce ee 0b |../...M.a@......|
+00000210 7e 92 7e ff 76 9d c3 3b 7e a5 3f ce fa 10 e2 59 |~.~.v..;~.?....Y|
+00000220 ec 47 2d 7c ac da 4e 97 0e 15 a0 6f d0 02 42 01 |.G-|..N....o..B.|
+00000230 4d fc be 67 13 9c 2d 05 0e bd 3f a3 8c 25 c1 33 |M..g..-...?..%.3|
+00000240 13 83 0d 94 06 bb d4 37 7a f6 ec 7a c9 86 2e dd |.......7z..z....|
+00000250 d7 11 69 7f 85 7c 56 de fb 31 78 2b e4 c7 78 0d |..i..|V..1x+..x.|
+00000260 ae cb be 9e 4e 36 24 31 7b 6a 0f 39 95 12 07 8f |....N6$1{j.9....|
+00000270 2a 16 03 03 00 b7 0c 00 00 b3 03 00 1d 20 87 2c |*............ .,|
+00000280 f2 fd 8e b9 3d 5f 1c c8 bb 04 f5 1e 01 a8 ba d8 |....=_..........|
+00000290 b6 8e 61 78 15 9e 3b a7 da 96 8e 77 d7 70 04 03 |..ax..;....w.p..|
+000002a0 00 8b 30 81 88 02 42 01 dc e2 26 f9 18 39 da 7d |..0...B...&..9.}|
+000002b0 bd a1 30 c6 6f dd cd aa a0 4f 71 cf 42 76 61 ba |..0.o....Oq.Bva.|
+000002c0 e7 9f 09 b5 05 f2 76 c7 db 2a 93 83 3b 0b 3a cf |......v..*..;.:.|
+000002d0 60 96 24 c8 af de 2c db 5a 29 1c 62 67 28 e9 d7 |`.$...,.Z).bg(..|
+000002e0 57 5f 54 18 cc bf ee d1 d9 02 42 01 04 cf 67 0b |W_T.......B...g.|
+000002f0 62 2c c2 17 a3 f4 f1 32 0f c5 b9 ae 3b 52 36 2b |b,.....2....;R6+|
+00000300 f0 c0 60 49 08 e0 bf f5 7c 09 13 e4 b8 ba 08 c7 |..`I....|.......|
+00000310 ea 74 a0 f5 88 45 e4 35 f1 c5 4e df fe 45 bc ca |.t...E.5..N..E..|
+00000320 9c 5f c8 84 66 13 8f b3 c9 7e b2 ba d6 16 03 03 |._..f....~......|
+00000330 00 3a 0d 00 00 36 03 01 02 40 00 2e 04 03 05 03 |.:...6...@......|
+00000340 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................|
+00000350 08 06 04 01 05 01 06 01 03 03 02 03 03 01 02 01 |................|
+00000360 03 02 02 02 04 02 05 02 06 02 00 00 16 03 03 00 |................|
+00000370 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 01 8f ff aa 8c |......0...B.....|
+00000250 bd 0c 94 39 34 e5 39 7b d2 12 26 8e 94 4a fd 68 |...94.9{..&..J.h|
+00000260 f2 f5 5b 30 69 e1 42 3a 74 cd 9a 37 75 5c d2 a6 |..[0i.B:t..7u\..|
+00000270 c9 7b b1 83 c1 d9 c5 55 1a af 3d 19 64 02 43 c0 |.{.....U..=.d.C.|
+00000280 0a 1c 0e ff f4 42 85 fb d1 aa a2 52 1a 02 41 2f |.....B.....R..A/|
+00000290 c6 23 d7 37 f1 36 75 0c 0f b4 49 14 c4 b4 d9 28 |.#.7.6u...I....(|
+000002a0 c1 00 2d e4 d6 93 fd a0 f5 59 4e 45 0c a4 28 d4 |..-......YNE..(.|
+000002b0 dc aa 7b 0b 28 29 12 94 f6 db 8c 23 af 81 7e ab |..{.().....#..~.|
+000002c0 fd 12 ba 11 27 b2 10 87 89 61 9f 5d 6d 18 79 c5 |....'....a.]m.y.|
+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 2d 3e 6e 02 fb |...........->n..|
+000002f0 50 cc 37 62 77 17 08 ef 71 e6 06 23 82 ba 97 b7 |P.7bw...q..#....|
+00000300 0f 38 f9 5e 05 63 4c c9 04 6e bd e4 78 76 32 3b |.8.^.cL..n..xv2;|
+00000310 3a a7 9b de 30 ca ed fb 17 dc 40 |:...0.....@|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 40 19 62 a8 82 26 |..........@.b..&|
+00000010 0f 0c 84 b4 31 6a 5d 12 65 dc b9 bc de 5c cb 77 |....1j].e....\.w|
+00000020 5d 04 7e a8 10 1a a5 05 e5 ca 04 68 a2 81 ef f5 |].~........h....|
+00000030 ae 4e bd f1 f3 ba 3f 6a 81 ae 71 9a 2f 31 e2 79 |.N....?j..q./1.y|
+00000040 f1 4d 6c 0e a4 be 4b f7 80 6f 97 |.Ml...K..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 e9 f4 51 fe c1 02 35 de 6e 72 c3 |.......Q...5.nr.|
+00000020 58 f3 01 4a f0 9d f2 34 df fc 0e 93 ef 46 2e 45 |X..J...4.....F.E|
+00000030 5e 60 43 52 33 15 03 03 00 30 00 00 00 00 00 00 |^`CR3....0......|
+00000040 00 00 00 00 00 00 00 00 00 00 ac 82 d6 47 42 40 |.............GB@|
+00000050 d6 6c 6d e3 b6 c6 4a b7 83 ce 6f 3f 33 ad e7 eb |.lm...J...o?3...|
+00000060 bf 59 82 50 8a 18 e3 13 46 6c |.Y.P....Fl|
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..7ae186d
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-ECDSA-RSA
@@ -0,0 +1,139 @@
+>>> 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 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 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 59 02 00 00 55 03 03 2a 52 95 57 8c |....Y...U..*R.W.|
+00000010 55 3f d7 82 f0 3f af 57 a1 82 86 00 3a 6b c0 07 |U?...?.W....:k..|
+00000020 4d c3 0e 80 cc 37 2d 51 f4 d3 e2 20 4a f6 c9 8a |M....7-Q... J...|
+00000030 d2 98 4a ff 22 66 11 da 6f 9a a0 17 b9 96 b0 86 |..J."f..o.......|
+00000040 29 e0 39 86 0a 00 42 78 30 60 61 99 c0 2f 00 00 |).9...Bx0`a../..|
+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 ac 0c 00 00 a8 03 00 1d 20 fa 3a 8f b7 50 10 38 |........ .:..P.8|
+000002d0 04 9d fb c4 e4 76 6d 93 86 b2 8a d7 5b 8f 8d 45 |.....vm.....[..E|
+000002e0 41 b7 ba 54 bc cc 7b 07 3c 08 04 00 80 a1 14 65 |A..T..{.<......e|
+000002f0 f6 48 29 ba 08 86 52 65 dd 08 ef b8 b8 77 ef fd |.H)...Re.....w..|
+00000300 8a ca dc 37 f8 69 fa 04 69 73 84 07 b2 45 f0 a2 |...7.i..is...E..|
+00000310 8c 69 f7 7c 4c 5c 95 c5 66 80 ad 93 04 67 4b 3d |.i.|L\..f....gK=|
+00000320 f8 53 a9 33 b3 c0 40 17 62 34 f0 f3 1e d2 23 93 |.S.3..@.b4....#.|
+00000330 29 52 bc f4 f0 72 58 b9 76 9c 7b 54 b0 d5 d1 ab |)R...rX.v.{T....|
+00000340 b3 1b ae f7 f3 46 6a 07 7f f4 91 ee 46 d6 85 43 |.....Fj.....F..C|
+00000350 ea c6 f9 f5 47 89 85 39 72 35 af b4 03 e9 a2 ea |....G..9r5......|
+00000360 a8 19 09 ea b3 d2 c2 38 59 65 d1 2c 18 16 03 03 |.......8Ye.,....|
+00000370 00 3a 0d 00 00 36 03 01 02 40 00 2e 04 03 05 03 |.:...6...@......|
+00000380 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................|
+00000390 08 06 04 01 05 01 06 01 03 03 02 03 03 01 02 01 |................|
+000003a0 03 02 02 02 04 02 05 02 06 02 00 00 16 03 03 00 |................|
+000003b0 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 91 0f 00 |...._X.;t.......|
+00000240 00 8d 04 03 00 89 30 81 86 02 41 63 34 72 b4 70 |......0...Ac4r.p|
+00000250 45 46 9c 3c 06 2c f5 ab d4 dd a7 91 69 9c 65 0f |EF.<.,......i.e.|
+00000260 4b d9 2d 90 3d d1 f2 4d 2a 6a 43 4f a7 fd b5 22 |K.-.=..M*jCO..."|
+00000270 83 61 e2 14 33 8c bc 8a 81 52 a1 f4 69 a7 12 c9 |.a..3....R..i...|
+00000280 c3 28 69 85 6d c1 b0 5d d3 5e ac 4e 02 41 35 cd |.(i.m..].^.N.A5.|
+00000290 3b c3 f6 ea 9e df 2a a1 ea 80 55 40 d2 13 d3 ff |;.....*...U@....|
+000002a0 b2 59 bb a0 c7 10 67 6e 9b dc 6c 3c 97 08 07 e0 |.Y....gn..l<....|
+000002b0 db da 79 6b 0e 6c a0 23 13 b1 02 32 ab ee 62 69 |..yk.l.#...2..bi|
+000002c0 f9 d5 7f 24 2e 26 94 36 a4 36 53 63 dd 90 20 14 |...$.&.6.6Sc.. .|
+000002d0 03 03 00 01 01 16 03 03 00 28 00 00 00 00 00 00 |.........(......|
+000002e0 00 00 a7 30 0e b0 f7 ba 51 35 c9 4c c2 24 90 5e |...0....Q5.L.$.^|
+000002f0 b2 59 57 5d 96 9d ad d1 1e 7d b0 35 09 9c c5 49 |.YW].....}.5...I|
+00000300 bd 82 |..|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 28 09 ff 53 e8 0f |..........(..S..|
+00000010 ad 86 30 ca 96 54 da 72 45 13 7a cd 51 f6 b3 a5 |..0..T.rE.z.Q...|
+00000020 27 4c 7c 26 81 6d 76 6f 19 8e f3 13 77 49 59 73 |'L|&.mvo....wIYs|
+00000030 4e 98 3e |N.>|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 99 7b 4c |..............{L|
+00000010 1d 0a b1 89 0d ac fa a7 39 eb 9a ff 8f 06 60 d1 |........9.....`.|
+00000020 88 e8 ef 15 03 03 00 1a 00 00 00 00 00 00 00 02 |................|
+00000030 99 42 7f c8 35 79 f3 a0 10 5c 05 25 c1 ac ab aa |.B..5y...\.%....|
+00000040 d5 9e |..|
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..9ecd8e3
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-Ed25519
@@ -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 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 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 59 02 00 00 55 03 03 5c 37 b1 d2 6c |....Y...U..\7..l|
+00000010 bc dd 26 8c 4e f7 04 80 09 3c fd 76 23 d4 52 16 |..&.N....<.v#.R.|
+00000020 df 0e 79 ab f4 cf 8c f3 61 31 c6 20 7d 7a 1d 8f |..y.....a1. }z..|
+00000030 09 3e 2b 25 04 7f 0f 0a a7 0c 03 fd 9c 09 f3 5d |.>+%...........]|
+00000040 96 75 f8 da 5b 6b 1b fb ca d7 ec 7a cc a8 00 00 |.u..[k.....z....|
+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 ac 0c 00 00 a8 03 00 1d 20 aa c7 43 e7 1e 3b 2b |........ ..C..;+|
+000002d0 28 c2 68 aa 83 cc 85 63 68 c4 b8 4d fb 18 fa b9 |(.h....ch..M....|
+000002e0 3e 9a f2 7c 04 33 7f 48 6b 08 04 00 80 28 28 c7 |>..|.3.Hk....((.|
+000002f0 84 79 65 11 07 43 7a ce f1 d6 cb 0e fe 6a 24 2c |.ye..Cz......j$,|
+00000300 f3 f0 e5 9c 80 a6 c7 41 c7 51 f2 84 be 6e 58 df |.......A.Q...nX.|
+00000310 f2 d2 d4 d9 62 08 c8 35 75 b9 8e 49 c2 98 b0 9d |....b..5u..I....|
+00000320 32 aa db bf 03 c1 61 83 f7 20 d7 ec 07 27 5e 45 |2.....a.. ...'^E|
+00000330 dc d6 92 4c a1 4f 4e 7c 53 c5 ca 42 48 40 0f 83 |...L.ON|S..BH@..|
+00000340 fc 9d 60 a1 7c 43 d1 f5 f8 3f fe 50 3f d0 03 bc |..`.|C...?.P?...|
+00000350 3e 8b ac 69 8f ae b6 9a c8 d4 98 84 30 f1 79 9b |>..i........0.y.|
+00000360 af 5d 4e 41 2a 7c 46 22 df 46 42 74 f6 16 03 03 |.]NA*|F".FBt....|
+00000370 00 3a 0d 00 00 36 03 01 02 40 00 2e 04 03 05 03 |.:...6...@......|
+00000380 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................|
+00000390 08 06 04 01 05 01 06 01 03 03 02 03 03 01 02 01 |................|
+000003a0 03 02 02 02 04 02 05 02 06 02 00 00 16 03 03 00 |................|
+000003b0 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 07 e0 a5 14 ca cf 31 d7 |...D...@......1.|
+00000180 99 96 c7 c7 d8 d8 a7 f7 82 e7 c6 c0 12 5d 91 5a |.............].Z|
+00000190 bc eb 4a c0 59 c6 5b 7b 03 df 2a ff 48 ca 55 d8 |..J.Y.[{..*.H.U.|
+000001a0 3e 10 c1 94 2c 03 b2 e7 16 83 4d e5 5a 3d 8a 48 |>...,.....M.Z=.H|
+000001b0 2f e5 c4 59 de 6f 47 05 14 03 03 00 01 01 16 03 |/..Y.oG.........|
+000001c0 03 00 20 ae 35 81 df 88 0e a3 2e 67 3f 33 02 3d |.. .5......g?3.=|
+000001d0 b8 7e 47 db cb be 05 c7 ba 43 dc 5b 52 3b 4b ca |.~G......C.[R;K.|
+000001e0 c0 dc 78 |..x|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 20 63 23 49 7c 83 |.......... c#I|.|
+00000010 1a 8b cd 48 02 e7 86 4d ab 8b 3c 4f 40 27 a6 48 |...H...M..<O@'.H|
+00000020 95 d5 80 8a 7a e0 56 0b e6 34 70 |....z.V..4p|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 16 aa b4 5b 75 04 96 c5 4a e3 2a fb |.......[u...J.*.|
+00000010 be 29 32 9e c5 e4 15 bd 38 df 69 15 03 03 00 12 |.)2.....8.i.....|
+00000020 50 4d b6 c0 95 e6 5a db f2 b7 ea 02 cb 3e 01 ea |PM....Z......>..|
+00000030 35 0d |5.|
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..35ec347
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-AES256-GCM-SHA384
@@ -0,0 +1,137 @@
+>>> 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 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 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 59 02 00 00 55 03 03 16 f7 21 0a 97 |....Y...U....!..|
+00000010 89 11 ec c3 c4 05 41 79 72 60 40 6d ec 78 90 26 |......Ayr`@m.x.&|
+00000020 0c a4 f8 5d d5 27 e9 70 bb 40 21 20 b0 bb 98 5d |...].'.p.@! ...]|
+00000030 a2 27 08 1e 4a fe f9 e1 cf a5 79 d3 eb c6 40 f7 |.'..J.....y...@.|
+00000040 ee 4f 0b fa a1 bb 09 62 07 24 30 b7 c0 30 00 00 |.O.....b.$0..0..|
+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 ac 0c 00 00 a8 03 00 1d 20 39 1f 7e 66 c8 20 24 |........ 9.~f. $|
+000002d0 cf 8e 51 f6 bf 2a 01 a9 3b 51 19 f1 9d 32 b6 fa |..Q..*..;Q...2..|
+000002e0 05 3b 90 c9 a3 8b 49 92 2a 08 04 00 80 da 65 ad |.;....I.*.....e.|
+000002f0 fa f9 d5 f6 d7 13 34 d2 ab ac ea 57 37 69 c6 b1 |......4....W7i..|
+00000300 91 ee 89 b7 04 6b 17 fb 80 23 df df ef a1 62 9b |.....k...#....b.|
+00000310 e4 0a 4e ca b0 35 b2 d3 2a cf 4f c1 e3 d9 37 78 |..N..5..*.O...7x|
+00000320 aa c8 59 f8 25 c7 43 51 19 6c c7 50 90 a4 2c 92 |..Y.%.CQ.l.P..,.|
+00000330 01 0e 8d ff f0 88 4b af 1d 03 ee 51 8b 18 e4 ee |......K....Q....|
+00000340 35 48 16 e7 4c 26 1d d8 af 91 b1 75 38 b5 65 42 |5H..L&.....u8.eB|
+00000350 8e 60 c7 f9 25 a7 85 35 72 41 6f f6 c4 61 1d c0 |.`..%..5rAo..a..|
+00000360 c8 cf da ae 31 5e 2e d6 9c ca f1 d6 31 16 03 03 |....1^......1...|
+00000370 00 3a 0d 00 00 36 03 01 02 40 00 2e 04 03 05 03 |.:...6...@......|
+00000380 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................|
+00000390 08 06 04 01 05 01 06 01 03 03 02 03 03 01 02 01 |................|
+000003a0 03 02 02 02 04 02 05 02 06 02 00 00 16 03 03 00 |................|
+000003b0 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 1c 58 51 d8 51 bc |.........V.XQ.Q.|
+00000240 8e 4b b8 24 64 85 81 d2 26 9b 38 bf 13 19 e7 0a |.K.$d...&.8.....|
+00000250 f7 94 e8 b5 94 bf 6f ae f2 07 1a 46 24 38 7b 8b |......o....F$8{.|
+00000260 2f a6 da 91 1a 5f 7d 3f cf c4 1b 14 9c 44 8e 6a |/...._}?.....D.j|
+00000270 6b c8 c4 60 c6 15 e6 f2 c0 45 e7 46 c4 32 06 b1 |k..`.....E.F.2..|
+00000280 46 5e 25 1d ba f7 d8 81 b0 6b 50 40 81 b1 93 89 |F^%......kP@....|
+00000290 cb 90 ae 10 b1 db 08 99 e6 0e 8f 17 0f 4d a7 a7 |.............M..|
+000002a0 f5 42 8a be ca d6 75 c4 32 44 22 ab df cf 22 f7 |.B....u.2D"...".|
+000002b0 58 d9 9f 52 c2 04 c0 81 59 14 03 03 00 01 01 16 |X..R....Y.......|
+000002c0 03 03 00 28 00 00 00 00 00 00 00 00 eb 5a 97 41 |...(.........Z.A|
+000002d0 1d da 2b 81 da 7a b7 9a f8 5e fe 50 75 e5 a4 6a |..+..z...^.Pu..j|
+000002e0 21 90 b7 3d 4e bc 44 cf 86 8f cd c3 |!..=N.D.....|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 28 93 a5 d4 a8 16 |..........(.....|
+00000010 4e a2 b2 c3 b9 ce dd 0e 57 49 7c eb 92 e4 e7 e3 |N.......WI|.....|
+00000020 a8 55 3a 56 54 53 92 b8 ce 15 e3 c3 c2 da 52 01 |.U:VTS........R.|
+00000030 6f 35 fd |o5.|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 5b 20 4f |.............[ O|
+00000010 e9 3f 09 28 6e 88 5d 1d 57 90 2c 35 74 37 d1 df |.?.(n.].W.,5t7..|
+00000020 aa 39 9b 15 03 03 00 1a 00 00 00 00 00 00 00 02 |.9..............|
+00000030 bb e3 77 62 e5 c9 78 f4 a5 09 93 b0 20 9a 1b a4 |..wb..x..... ...|
+00000040 48 44 |HD|
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..110f689
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-ECDSA
@@ -0,0 +1,138 @@
+>>> 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 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 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 59 02 00 00 55 03 03 68 dc 2e 5e 8e |....Y...U..h..^.|
+00000010 80 38 0e 65 a3 b0 f6 a0 c0 8f 1e 62 ef 1d 5a 54 |.8.e.......b..ZT|
+00000020 82 dc 9c 68 77 88 57 dd f3 9d c2 20 4e 56 dd 44 |...hw.W.... NV.D|
+00000030 a0 46 67 4c 09 2b d5 e6 fe 15 fb b3 8e 19 ef a3 |.FgL.+..........|
+00000040 8e 5c a9 70 00 cf 96 d7 3b 8b c9 64 c0 09 00 00 |.\.p....;..d....|
+00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................|
+00000060 03 02 0e 0b 00 02 0a 00 02 07 00 02 04 30 82 02 |.............0..|
+00000070 00 30 82 01 62 02 09 00 b8 bf 2d 47 a0 d2 eb f4 |.0..b.....-G....|
+00000080 30 09 06 07 2a 86 48 ce 3d 04 01 30 45 31 0b 30 |0...*.H.=..0E1.0|
+00000090 09 06 03 55 04 06 13 02 41 55 31 13 30 11 06 03 |...U....AU1.0...|
+000000a0 55 04 08 13 0a 53 6f 6d 65 2d 53 74 61 74 65 31 |U....Some-State1|
+000000b0 21 30 1f 06 03 55 04 0a 13 18 49 6e 74 65 72 6e |!0...U....Intern|
+000000c0 65 74 20 57 69 64 67 69 74 73 20 50 74 79 20 4c |et Widgits Pty L|
+000000d0 74 64 30 1e 17 0d 31 32 31 31 32 32 31 35 30 36 |td0...1211221506|
+000000e0 33 32 5a 17 0d 32 32 31 31 32 30 31 35 30 36 33 |32Z..22112015063|
+000000f0 32 5a 30 45 31 0b 30 09 06 03 55 04 06 13 02 41 |2Z0E1.0...U....A|
+00000100 55 31 13 30 11 06 03 55 04 08 13 0a 53 6f 6d 65 |U1.0...U....Some|
+00000110 2d 53 74 61 74 65 31 21 30 1f 06 03 55 04 0a 13 |-State1!0...U...|
+00000120 18 49 6e 74 65 72 6e 65 74 20 57 69 64 67 69 74 |.Internet Widgit|
+00000130 73 20 50 74 79 20 4c 74 64 30 81 9b 30 10 06 07 |s Pty Ltd0..0...|
+00000140 2a 86 48 ce 3d 02 01 06 05 2b 81 04 00 23 03 81 |*.H.=....+...#..|
+00000150 86 00 04 00 c4 a1 ed be 98 f9 0b 48 73 36 7e c3 |...........Hs6~.|
+00000160 16 56 11 22 f2 3d 53 c3 3b 4d 21 3d cd 6b 75 e6 |.V.".=S.;M!=.ku.|
+00000170 f6 b0 dc 9a df 26 c1 bc b2 87 f0 72 32 7c b3 64 |.....&.....r2|.d|
+00000180 2f 1c 90 bc ea 68 23 10 7e fe e3 25 c0 48 3a 69 |/....h#.~..%.H:i|
+00000190 e0 28 6d d3 37 00 ef 04 62 dd 0d a0 9c 70 62 83 |.(m.7...b....pb.|
+000001a0 d8 81 d3 64 31 aa 9e 97 31 bd 96 b0 68 c0 9b 23 |...d1...1...h..#|
+000001b0 de 76 64 3f 1a 5c 7f e9 12 0e 58 58 b6 5f 70 dd |.vd?.\....XX._p.|
+000001c0 9b d8 ea d5 d7 f5 d5 cc b9 b6 9f 30 66 5b 66 9a |...........0f[f.|
+000001d0 20 e2 27 e5 bf fe 3b 30 09 06 07 2a 86 48 ce 3d | .'...;0...*.H.=|
+000001e0 04 01 03 81 8c 00 30 81 88 02 42 01 88 a2 4f eb |......0...B...O.|
+000001f0 e2 45 c5 48 7d 1b ac f5 ed 98 9d ae 47 70 c0 5e |.E.H}.......Gp.^|
+00000200 1b b6 2f bd f1 b6 4d b7 61 40 d3 11 a2 ce ee 0b |../...M.a@......|
+00000210 7e 92 7e ff 76 9d c3 3b 7e a5 3f ce fa 10 e2 59 |~.~.v..;~.?....Y|
+00000220 ec 47 2d 7c ac da 4e 97 0e 15 a0 6f d0 02 42 01 |.G-|..N....o..B.|
+00000230 4d fc be 67 13 9c 2d 05 0e bd 3f a3 8c 25 c1 33 |M..g..-...?..%.3|
+00000240 13 83 0d 94 06 bb d4 37 7a f6 ec 7a c9 86 2e dd |.......7z..z....|
+00000250 d7 11 69 7f 85 7c 56 de fb 31 78 2b e4 c7 78 0d |..i..|V..1x+..x.|
+00000260 ae cb be 9e 4e 36 24 31 7b 6a 0f 39 95 12 07 8f |....N6$1{j.9....|
+00000270 2a 16 03 03 00 b6 0c 00 00 b2 03 00 1d 20 24 d0 |*............ $.|
+00000280 e5 11 4c 95 2c 96 58 62 01 df 20 c8 24 ce 29 a2 |..L.,.Xb.. .$.).|
+00000290 1a 3e 97 e2 df 29 49 e6 3a e8 c2 d3 72 49 04 03 |.>...)I.:...rI..|
+000002a0 00 8a 30 81 87 02 41 71 15 8d 50 f6 69 40 d7 cd |..0...Aq..P.i@..|
+000002b0 da c9 c3 ee 37 c2 5f c3 89 62 23 e0 ef 37 f9 9e |....7._..b#..7..|
+000002c0 2a 26 85 10 56 28 08 de 49 3b fa 03 f3 14 4b 3a |*&..V(..I;....K:|
+000002d0 b2 3d de 84 d2 08 8d 4e 59 3e 80 8f 6a 44 af 6f |.=.....NY>..jD.o|
+000002e0 be ee 08 ae 35 40 42 bc 02 42 00 f3 e9 89 a5 7f |....5@B..B......|
+000002f0 9c 50 7c 07 34 e4 cf f0 2b 0f cf f7 68 57 fa fd |.P|.4...+...hW..|
+00000300 2f 52 04 f8 90 7b 97 eb c3 e0 cc 68 f7 bf 22 21 |/R...{.....h.."!|
+00000310 62 b3 51 c8 a4 30 38 c5 88 46 df 55 21 21 d0 4f |b.Q..08..F.U!!.O|
+00000320 6f 95 7b 5f 5a c6 98 dd 2d d1 0a 95 16 03 03 00 |o.{_Z...-.......|
+00000330 3a 0d 00 00 36 03 01 02 40 00 2e 04 03 05 03 06 |:...6...@.......|
+00000340 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 08 |................|
+00000350 06 04 01 05 01 06 01 03 03 02 03 03 01 02 01 03 |................|
+00000360 02 02 02 04 02 05 02 06 02 00 00 16 03 03 00 04 |................|
+00000370 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 84 38 78 4d dd 9f 84 |..........8xM...|
+00000240 ae cb b8 2f e9 f3 76 66 41 56 f6 ed a5 fb 8b f2 |.../..vfAV......|
+00000250 43 0f 27 56 9e 7d a8 06 3e 8f ad b0 17 d5 d6 52 |C.'V.}..>......R|
+00000260 f4 88 e5 af 55 5b 55 fc 26 c1 a9 d5 a9 34 2b 50 |....U[U.&....4+P|
+00000270 96 09 db 59 cc f4 e8 cf 84 6f 9d b1 fd 3b a4 66 |...Y.....o...;.f|
+00000280 66 43 74 6d 4f e5 52 2c 22 2d c9 4c 67 3d ff 3d |fCtmO.R,"-.Lg=.=|
+00000290 c2 79 b3 b1 85 56 08 cc 02 7c 53 a7 be 39 04 21 |.y...V...|S..9.!|
+000002a0 fb db fe ff 1b a6 c7 7a e9 4c 11 c3 34 a6 7c 4f |.......z.L..4.|O|
+000002b0 23 61 d9 47 b0 6c ae cb 72 14 03 03 00 01 01 16 |#a.G.l..r.......|
+000002c0 03 03 00 40 00 00 00 00 00 00 00 00 00 00 00 00 |...@............|
+000002d0 00 00 00 00 d3 95 4a 65 d9 8e 3d 9c 2b 18 67 aa |......Je..=.+.g.|
+000002e0 e0 d7 a6 dd fb af 42 06 0d 56 cc 3d 12 3e 7e 95 |......B..V.=.>~.|
+000002f0 18 6e 97 d6 cc 84 eb 90 a1 c3 b6 6e 3c 42 d1 2e |.n.........n<B..|
+00000300 7a dc 41 81 |z.A.|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 40 71 ee 1d 4f 55 |..........@q..OU|
+00000010 b4 47 3d 26 52 5a 00 a5 ce 0e 31 6c 2d 09 95 df |.G=&RZ....1l-...|
+00000020 fb 74 30 89 32 3d 47 29 58 ee 61 70 74 18 8c 01 |.t0.2=G)X.apt...|
+00000030 e3 16 d7 6e 3d a1 30 75 61 b8 99 e4 c5 82 82 d5 |...n=.0ua.......|
+00000040 75 f6 e1 b4 f8 97 77 92 00 64 06 |u.....w..d.|
+>>> 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 e2 68 77 75 6a f8 3c 3d 2c 96 52 |......hwuj.<=,.R|
+00000020 2d fc d5 3b d3 17 c0 29 df 99 f1 09 23 13 9f 89 |-..;...)....#...|
+00000030 dd 21 15 23 36 15 03 03 00 30 00 00 00 00 00 00 |.!.#6....0......|
+00000040 00 00 00 00 00 00 00 00 00 00 37 4e ac 91 80 02 |..........7N....|
+00000050 4f 4a 9f b4 3c 0e 24 87 c8 d0 41 24 ce 01 e2 bb |OJ..<.$...A$....|
+00000060 18 af bc ce 09 4b 41 f6 db 08 |.....KA...|
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..cbc4bcc
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSA
@@ -0,0 +1,137 @@
+>>> 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 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 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 59 02 00 00 55 03 03 b6 96 f2 bc ed |....Y...U.......|
+00000010 1b 14 73 de 12 10 cc e9 4d f2 c7 8b 46 d8 63 55 |..s.....M...F.cU|
+00000020 8f 04 33 ec 89 b5 70 93 01 1c f2 20 72 82 e1 16 |..3...p.... r...|
+00000030 9c 0e 70 25 84 2c 09 a6 4f 19 c0 ed 44 d6 98 13 |..p%.,..O...D...|
+00000040 97 f6 19 08 d4 b6 d3 ad 82 96 ef db 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 ac 0c 00 00 a8 03 00 1d 20 21 1b d1 91 16 9c c1 |........ !......|
+000002d0 51 52 39 07 6b 6d ab 07 28 f7 d0 ae 02 13 5e 73 |QR9.km..(.....^s|
+000002e0 5b 51 30 96 27 57 56 e5 37 08 04 00 80 6a 13 82 |[Q0.'WV.7....j..|
+000002f0 97 81 ea 32 51 cb cb 8e 3b ee e5 dd 4f 80 20 50 |...2Q...;...O. P|
+00000300 c9 f0 19 9b d5 1b ae 21 f7 e6 24 4e a3 22 ec b9 |.......!..$N."..|
+00000310 25 6e 77 19 12 08 16 8a c7 c1 db 29 e9 be 05 55 |%nw........)...U|
+00000320 09 c1 6e 44 c3 d7 bd 18 80 c8 1f 42 53 3b e6 09 |..nD.......BS;..|
+00000330 00 29 20 c4 94 04 97 6f f7 e6 f4 3b 66 77 2f e5 |.) ....o...;fw/.|
+00000340 de 96 6f c3 67 c5 ce 4b 5e 4b 0e 90 02 fc 32 7f |..o.g..K^K....2.|
+00000350 71 f4 63 76 37 57 75 30 fb 1b f5 99 98 5f c3 b1 |q.cv7Wu0....._..|
+00000360 fb e3 76 ad 8e 2f 7a 72 86 ed 34 18 98 16 03 03 |..v../zr..4.....|
+00000370 00 3a 0d 00 00 36 03 01 02 40 00 2e 04 03 05 03 |.:...6...@......|
+00000380 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 |................|
+00000390 08 06 04 01 05 01 06 01 03 03 02 03 03 01 02 01 |................|
+000003a0 03 02 02 02 04 02 05 02 06 02 00 00 16 03 03 00 |................|
+000003b0 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 90 53 1e fc 7c 63 b0 |..........S..|c.|
+00000240 98 c5 19 40 fb 4f cf c3 53 51 81 68 54 c7 49 38 |...@.O..SQ.hT.I8|
+00000250 0c 41 f0 12 7d a6 e4 8a 4e 77 97 49 5a 07 7d 30 |.A..}...Nw.IZ.}0|
+00000260 fa df 77 2f 51 cf 37 65 07 0b 2c 91 15 43 1d c9 |..w/Q.7e..,..C..|
+00000270 69 46 e2 26 66 72 98 ec 62 1a 22 ae e8 3e 3a 28 |iF.&fr..b."..>:(|
+00000280 17 83 b9 74 57 59 a2 ec 31 95 17 1f c3 ec 9a 01 |...tWY..1.......|
+00000290 f2 d4 07 d5 ee d5 0e f2 f4 75 3b d6 b8 df aa ad |.........u;.....|
+000002a0 0b 87 37 30 43 7e c1 b1 e1 0d 7e 90 3d 87 9d 93 |..70C~....~.=...|
+000002b0 d7 06 57 18 5c 12 c2 32 0d 14 03 03 00 01 01 16 |..W.\..2........|
+000002c0 03 03 00 28 00 00 00 00 00 00 00 00 ff 2a ae f8 |...(.........*..|
+000002d0 c9 1c bd 3f 62 0e 68 42 e7 96 ec ee c0 fa 71 34 |...?b.hB......q4|
+000002e0 f1 e2 67 76 82 cf c3 2a fb b2 5a c1 |..gv...*..Z.|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 28 da 70 e7 aa 1b |..........(.p...|
+00000010 6c 66 cb 9b 07 d9 4e 87 6f 87 60 fb 46 f5 e9 33 |lf....N.o.`.F..3|
+00000020 48 59 ff 3e b5 bf 0b 0c b2 39 79 64 f6 3c 2e 95 |HY.>.....9yd.<..|
+00000030 04 51 87 |.Q.|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 21 29 d2 |.............!).|
+00000010 27 05 2d b4 a2 bf ea f2 96 8a 61 c9 91 75 9f 0f |'.-.......a..u..|
+00000020 50 4a 76 15 03 03 00 1a 00 00 00 00 00 00 00 02 |PJv.............|
+00000030 a9 40 eb 86 b2 f0 85 a2 75 bc 4e 09 8c c9 ca 31 |.@......u.N....1|
+00000040 e5 49 |.I|
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..b8ecfff
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSAPKCS1v15
@@ -0,0 +1,134 @@
+>>> 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 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 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 59 02 00 00 55 03 03 ad e1 a7 5e 0b |....Y...U.....^.|
+00000010 b8 bd 9d 05 c2 8e 6c f2 ea 7d a1 c8 32 cc d1 74 |......l..}..2..t|
+00000020 ba 86 75 98 33 27 39 c3 0a 6f 49 20 2b 37 9a 0f |..u.3'9..oI +7..|
+00000030 9b de 1f 1d 5f 2b 45 29 6c 9b 33 c6 bc c1 15 a4 |...._+E)l.3.....|
+00000040 19 9b 70 6c 15 eb 4a 92 92 5f b7 6b c0 2f 00 00 |..pl..J.._.k./..|
+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 ac 0c 00 00 a8 03 00 1d 20 ba ad fb 1e 28 95 96 |........ ....(..|
+000002d0 f3 62 9d 97 87 0f fd fc a9 91 a2 4b 8d 69 ec 8f |.b.........K.i..|
+000002e0 7d 49 08 6e fe 7d b3 5b 03 04 01 00 80 86 57 23 |}I.n.}.[......W#|
+000002f0 58 bb 9a 50 d8 bb 99 d9 f5 cc 66 43 38 f0 14 8a |X..P......fC8...|
+00000300 cb 6d 8b c0 83 52 f8 53 75 94 07 e3 12 2c 10 bb |.m...R.Su....,..|
+00000310 f3 9b 74 84 1f 11 f3 06 c3 f4 df db f0 1e 0a cd |..t.............|
+00000320 1b 45 18 44 88 67 79 ca 3e 6e 2b 73 c2 10 84 d8 |.E.D.gy.>n+s....|
+00000330 7b c5 2e 81 7d 53 19 46 09 35 35 8b 66 8a a8 cc |{...}S.F.55.f...|
+00000340 20 ba 20 15 9f d1 27 9c 6b 3c bb 48 79 4a 7e 11 | . ...'.k<.HyJ~.|
+00000350 da e3 26 5b 3a 95 da 4d bd 86 3e 8c 97 55 7c 22 |..&[:..M..>..U|"|
+00000360 a1 d3 88 61 ae e1 3b 51 25 c6 01 7e 10 16 03 03 |...a..;Q%..~....|
+00000370 00 0c 0d 00 00 08 01 01 00 02 04 01 00 00 16 03 |................|
+00000380 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 12 a4 42 13 85 6f 92 |...........B..o.|
+00000240 6d 26 5d 05 3c b7 80 ab a9 e0 74 3d 89 67 79 a0 |m&].<.....t=.gy.|
+00000250 9f e1 a9 20 d8 82 e2 22 99 38 03 fe 32 d9 1f c7 |... ...".8..2...|
+00000260 39 1e 27 31 59 05 eb aa bc 2c 10 eb f0 82 65 65 |9.'1Y....,....ee|
+00000270 ce b2 e9 83 67 21 43 03 19 2d 14 9f c3 db bc dc |....g!C..-......|
+00000280 59 66 95 d7 4e 09 3c f0 f2 4a 39 f7 db c4 0c 4e |Yf..N.<..J9....N|
+00000290 73 e2 d6 59 f1 bc 06 d8 75 df 32 b7 f1 b4 01 98 |s..Y....u.2.....|
+000002a0 4f 93 43 a3 a6 09 da cd 1c ee 26 65 ab d1 2a 56 |O.C.......&e..*V|
+000002b0 74 32 24 46 27 f3 d9 6a df 14 03 03 00 01 01 16 |t2$F'..j........|
+000002c0 03 03 00 28 00 00 00 00 00 00 00 00 68 27 5e 44 |...(........h'^D|
+000002d0 d7 73 26 f6 51 86 01 f5 f3 5d 61 a0 05 cd c3 00 |.s&.Q....]a.....|
+000002e0 85 6f ea 56 85 1e 7a c3 4c d3 6d 64 |.o.V..z.L.md|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 28 81 f3 33 d8 2a |..........(..3.*|
+00000010 57 45 53 2c ee 68 8b 79 ed 07 dc 90 c3 a7 84 38 |WES,.h.y.......8|
+00000020 8c 33 03 e9 c6 51 04 b2 73 8a 8b 81 12 eb 6c 5f |.3...Q..s.....l_|
+00000030 a3 8f 5e |..^|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 e5 c6 d7 |................|
+00000010 4d e0 d1 0c ff a0 66 c4 71 53 af 7e 16 01 3d 2e |M.....f.qS.~..=.|
+00000020 6c ab 90 15 03 03 00 1a 00 00 00 00 00 00 00 02 |l...............|
+00000030 92 12 87 24 c8 7e 74 23 df f7 23 49 01 9a dd 3b |...$.~t#..#I...;|
+00000040 2c 68 |,h|
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..de05fec
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ClientCert-RSA-RSAPSS
@@ -0,0 +1,142 @@
+>>> 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 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 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 59 02 00 00 55 03 03 61 fe 1e 35 33 |....Y...U..a..53|
+00000010 4b b4 dd 9b 0f 55 58 f4 0c c5 b2 73 51 7b 84 e7 |K....UX....sQ{..|
+00000020 25 f7 8f 12 5a 12 11 e1 7b e6 52 20 ad 86 a9 f9 |%...Z...{.R ....|
+00000030 7f 6a 30 da 79 23 c3 c4 dc 88 f6 19 1d cc 16 8b |.j0.y#..........|
+00000040 96 74 84 ce 53 56 65 e2 cb 94 61 0c c0 2f 00 00 |.t..SVe...a../..|
+00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................|
+00000060 03 02 66 0b 00 02 62 00 02 5f 00 02 5c 30 82 02 |..f...b.._..\0..|
+00000070 58 30 82 01 8d a0 03 02 01 02 02 11 00 f2 99 26 |X0.............&|
+00000080 eb 87 ea 8a 0d b9 fc c2 47 34 7c 11 b0 30 41 06 |........G4|..0A.|
+00000090 09 2a 86 48 86 f7 0d 01 01 0a 30 34 a0 0f 30 0d |.*.H......04..0.|
+000000a0 06 09 60 86 48 01 65 03 04 02 01 05 00 a1 1c 30 |..`.H.e........0|
+000000b0 1a 06 09 2a 86 48 86 f7 0d 01 01 08 30 0d 06 09 |...*.H......0...|
+000000c0 60 86 48 01 65 03 04 02 01 05 00 a2 03 02 01 20 |`.H.e.......... |
+000000d0 30 12 31 10 30 0e 06 03 55 04 0a 13 07 41 63 6d |0.1.0...U....Acm|
+000000e0 65 20 43 6f 30 1e 17 0d 31 37 31 31 32 33 31 36 |e Co0...17112316|
+000000f0 31 36 31 30 5a 17 0d 31 38 31 31 32 33 31 36 31 |1610Z..181123161|
+00000100 36 31 30 5a 30 12 31 10 30 0e 06 03 55 04 0a 13 |610Z0.1.0...U...|
+00000110 07 41 63 6d 65 20 43 6f 30 81 9f 30 0d 06 09 2a |.Acme Co0..0...*|
+00000120 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 81 |.H............0.|
+00000130 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc 06 |......F}...'.H..|
+00000140 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 47 |(!.~...]..RE.z6G|
+00000150 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb 4f |....B[.....y.@.O|
+00000160 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 22 |m..+.....g....."|
+00000170 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 74 |8.J.ts+.4......t|
+00000180 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 23 |{.X.la<..A..++$#|
+00000190 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d 1e |w[.;.u]. T..c...|
+000001a0 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 62 |$....P....C...ub|
+000001b0 f4 14 c8 52 d7 02 03 01 00 01 a3 46 30 44 30 0e |...R.......F0D0.|
+000001c0 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 a0 30 13 |..U...........0.|
+000001d0 06 03 55 1d 25 04 0c 30 0a 06 08 2b 06 01 05 05 |..U.%..0...+....|
+000001e0 07 03 01 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 |...0...U.......0|
+000001f0 00 30 0f 06 03 55 1d 11 04 08 30 06 87 04 7f 00 |.0...U....0.....|
+00000200 00 01 30 41 06 09 2a 86 48 86 f7 0d 01 01 0a 30 |..0A..*.H......0|
+00000210 34 a0 0f 30 0d 06 09 60 86 48 01 65 03 04 02 01 |4..0...`.H.e....|
+00000220 05 00 a1 1c 30 1a 06 09 2a 86 48 86 f7 0d 01 01 |....0...*.H.....|
+00000230 08 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 |.0...`.H.e......|
+00000240 a2 03 02 01 20 03 81 81 00 cd ac 4e f2 ce 5f 8d |.... ......N.._.|
+00000250 79 88 10 42 70 7f 7c bf 1b 5a 8a 00 ef 19 15 4b |y..Bp.|..Z.....K|
+00000260 40 15 17 71 00 6c d4 16 26 e5 49 6d 56 da 0c 1a |@..q.l..&.ImV...|
+00000270 13 9f d8 46 95 59 3c b6 7f 87 76 5e 18 aa 03 ea |...F.Y<...v^....|
+00000280 06 75 22 dd 78 d2 a5 89 b8 c9 23 64 e1 28 38 ce |.u".x.....#d.(8.|
+00000290 34 6c 6e 06 7b 51 f1 a7 e6 f4 b3 7f fa b1 3f 14 |4ln.{Q........?.|
+000002a0 11 89 66 79 d1 8e 88 0e 0b a0 9e 30 2a c0 67 ef |..fy.......0*.g.|
+000002b0 ca 46 02 88 e9 53 81 22 69 22 97 ad 80 93 d4 f7 |.F...S."i"......|
+000002c0 dd 70 14 24 d7 70 0a 46 a1 16 03 03 00 ac 0c 00 |.p.$.p.F........|
+000002d0 00 a8 03 00 1d 20 e0 90 02 58 37 69 79 d6 78 e5 |..... ...X7iy.x.|
+000002e0 1d c6 7e a0 c6 38 1b ff 47 72 d6 c2 52 cb 6c 52 |..~..8..Gr..R.lR|
+000002f0 36 7e 03 c3 35 1d 08 04 00 80 79 5f 23 fd b1 ee |6~..5.....y_#...|
+00000300 ac 62 c8 72 09 52 1f 9a 0f ac 95 3e 4e e4 97 d2 |.b.r.R.....>N...|
+00000310 a3 04 ae 19 3f 25 ad 3e b7 78 1f d9 79 5f c8 26 |....?%.>.x..y_.&|
+00000320 f0 26 e5 ee 54 46 4a 05 84 15 01 4f 7a 7e 60 bd |.&..TFJ....Oz~`.|
+00000330 86 74 78 d7 7c 86 91 2b 4f 76 b6 aa 78 27 c8 21 |.tx.|..+Ov..x'.!|
+00000340 7e df 88 2f 26 f0 9d 3c a2 e8 95 f6 9f 5a a4 5e |~../&..<.....Z.^|
+00000350 18 dc cd 0d 70 e8 85 b7 e5 57 f6 c2 f4 33 28 1c |....p....W...3(.|
+00000360 58 7b 94 b0 9e ee d8 b3 42 b5 f3 63 78 a1 30 f3 |X{......B..cx.0.|
+00000370 f7 e4 5e 72 64 6f 80 32 70 4e 16 03 03 00 0c 0d |..^rdo.2pN......|
+00000380 00 00 08 01 01 00 02 08 04 00 00 16 03 03 00 04 |................|
+00000390 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 b2 c4 60 82 75 ca be 40 dc 28 ec 6d 14 6f |....`.u..@.(.m.o|
+000002b0 6c 88 ca 9a d7 ae ce 94 26 a7 10 ad d8 c3 b9 a6 |l.......&.......|
+000002c0 48 4e 01 7d ee 6e f8 e0 15 d9 72 c4 79 8d ac 25 |HN.}.n....r.y..%|
+000002d0 37 29 83 fc e6 f1 2e 4f 76 49 6a 36 b9 1e b4 58 |7).....OvIj6...X|
+000002e0 a2 3e f7 ff 96 5e d9 17 f2 40 05 1f ec bb 5b f5 |.>...^...@....[.|
+000002f0 28 86 d2 fc 0e 7e 70 3a 3d 90 4c 46 a5 3e bc 57 |(....~p:=.LF.>.W|
+00000300 24 4c ee 35 23 99 6f 21 12 db ba d8 3a 5f 37 1f |$L.5#.o!....:_7.|
+00000310 da 3d c2 c9 bf b6 11 8b b9 b9 43 0b 52 ff 6d 2a |.=........C.R.m*|
+00000320 74 a7 14 03 03 00 01 01 16 03 03 00 28 00 00 00 |t...........(...|
+00000330 00 00 00 00 00 34 bd 90 a0 3f 1c 0c 11 5c 8a e4 |.....4...?...\..|
+00000340 28 82 c4 57 59 73 fd a4 dc a9 91 4b df 2a c6 b5 |(..WYs.....K.*..|
+00000350 f0 6e cf 41 70 |.n.Ap|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 28 e2 44 81 59 e4 |..........(.D.Y.|
+00000010 6c cf e2 e7 04 78 61 02 36 29 2c 5c c4 6f 13 0b |l....xa.6),\.o..|
+00000020 29 ba 74 b0 13 e8 8f 67 39 b5 ea d1 9d 99 d2 f6 |).t....g9.......|
+00000030 f7 32 be |.2.|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 5c 7b 38 |.............\{8|
+00000010 46 af 57 57 05 5a c5 cb 83 f3 fd 17 d4 c3 2e 93 |F.WW.Z..........|
+00000020 d7 70 52 15 03 03 00 1a 00 00 00 00 00 00 00 02 |.pR.............|
+00000030 df 2b d8 62 ec 97 c6 ab be d4 7f c9 91 f4 fe 55 |.+.b...........U|
+00000040 ac bd |..|
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..d21e9b3
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES
@@ -0,0 +1,93 @@
+>>> 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 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 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 59 02 00 00 55 03 03 ec 4a 6a f8 c5 |....Y...U...Jj..|
+00000010 42 65 f9 d3 4f 65 6f 14 6b bd ae a9 82 5d 06 9b |Be..Oeo.k....]..|
+00000020 9d 03 bb 67 eb ba 52 70 74 c3 01 20 f2 ef 69 54 |...g..Rpt.. ..iT|
+00000030 1f 4b 79 f7 5b d5 08 b4 18 4c af 8e 55 58 45 22 |.Ky.[....L..UXE"|
+00000040 c1 c9 6f cf 36 67 45 20 c7 c5 3a af c0 09 00 00 |..o.6gE ..:.....|
+00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................|
+00000060 03 02 0e 0b 00 02 0a 00 02 07 00 02 04 30 82 02 |.............0..|
+00000070 00 30 82 01 62 02 09 00 b8 bf 2d 47 a0 d2 eb f4 |.0..b.....-G....|
+00000080 30 09 06 07 2a 86 48 ce 3d 04 01 30 45 31 0b 30 |0...*.H.=..0E1.0|
+00000090 09 06 03 55 04 06 13 02 41 55 31 13 30 11 06 03 |...U....AU1.0...|
+000000a0 55 04 08 13 0a 53 6f 6d 65 2d 53 74 61 74 65 31 |U....Some-State1|
+000000b0 21 30 1f 06 03 55 04 0a 13 18 49 6e 74 65 72 6e |!0...U....Intern|
+000000c0 65 74 20 57 69 64 67 69 74 73 20 50 74 79 20 4c |et Widgits Pty L|
+000000d0 74 64 30 1e 17 0d 31 32 31 31 32 32 31 35 30 36 |td0...1211221506|
+000000e0 33 32 5a 17 0d 32 32 31 31 32 30 31 35 30 36 33 |32Z..22112015063|
+000000f0 32 5a 30 45 31 0b 30 09 06 03 55 04 06 13 02 41 |2Z0E1.0...U....A|
+00000100 55 31 13 30 11 06 03 55 04 08 13 0a 53 6f 6d 65 |U1.0...U....Some|
+00000110 2d 53 74 61 74 65 31 21 30 1f 06 03 55 04 0a 13 |-State1!0...U...|
+00000120 18 49 6e 74 65 72 6e 65 74 20 57 69 64 67 69 74 |.Internet Widgit|
+00000130 73 20 50 74 79 20 4c 74 64 30 81 9b 30 10 06 07 |s Pty Ltd0..0...|
+00000140 2a 86 48 ce 3d 02 01 06 05 2b 81 04 00 23 03 81 |*.H.=....+...#..|
+00000150 86 00 04 00 c4 a1 ed be 98 f9 0b 48 73 36 7e c3 |...........Hs6~.|
+00000160 16 56 11 22 f2 3d 53 c3 3b 4d 21 3d cd 6b 75 e6 |.V.".=S.;M!=.ku.|
+00000170 f6 b0 dc 9a df 26 c1 bc b2 87 f0 72 32 7c b3 64 |.....&.....r2|.d|
+00000180 2f 1c 90 bc ea 68 23 10 7e fe e3 25 c0 48 3a 69 |/....h#.~..%.H:i|
+00000190 e0 28 6d d3 37 00 ef 04 62 dd 0d a0 9c 70 62 83 |.(m.7...b....pb.|
+000001a0 d8 81 d3 64 31 aa 9e 97 31 bd 96 b0 68 c0 9b 23 |...d1...1...h..#|
+000001b0 de 76 64 3f 1a 5c 7f e9 12 0e 58 58 b6 5f 70 dd |.vd?.\....XX._p.|
+000001c0 9b d8 ea d5 d7 f5 d5 cc b9 b6 9f 30 66 5b 66 9a |...........0f[f.|
+000001d0 20 e2 27 e5 bf fe 3b 30 09 06 07 2a 86 48 ce 3d | .'...;0...*.H.=|
+000001e0 04 01 03 81 8c 00 30 81 88 02 42 01 88 a2 4f eb |......0...B...O.|
+000001f0 e2 45 c5 48 7d 1b ac f5 ed 98 9d ae 47 70 c0 5e |.E.H}.......Gp.^|
+00000200 1b b6 2f bd f1 b6 4d b7 61 40 d3 11 a2 ce ee 0b |../...M.a@......|
+00000210 7e 92 7e ff 76 9d c3 3b 7e a5 3f ce fa 10 e2 59 |~.~.v..;~.?....Y|
+00000220 ec 47 2d 7c ac da 4e 97 0e 15 a0 6f d0 02 42 01 |.G-|..N....o..B.|
+00000230 4d fc be 67 13 9c 2d 05 0e bd 3f a3 8c 25 c1 33 |M..g..-...?..%.3|
+00000240 13 83 0d 94 06 bb d4 37 7a f6 ec 7a c9 86 2e dd |.......7z..z....|
+00000250 d7 11 69 7f 85 7c 56 de fb 31 78 2b e4 c7 78 0d |..i..|V..1x+..x.|
+00000260 ae cb be 9e 4e 36 24 31 7b 6a 0f 39 95 12 07 8f |....N6$1{j.9....|
+00000270 2a 16 03 03 00 b7 0c 00 00 b3 03 00 1d 20 7f e5 |*............ ..|
+00000280 3b 03 9e 6a 77 11 1b 0f bc 4a db 44 7c 3b 81 1c |;..jw....J.D|;..|
+00000290 03 8b 15 a6 f3 16 a0 58 5b 13 c5 1e d2 2c 04 03 |.......X[....,..|
+000002a0 00 8b 30 81 88 02 42 00 cc 7c 76 94 81 89 8f 25 |..0...B..|v....%|
+000002b0 16 e2 a0 0d 80 4f 7a 8f 8c 83 23 53 23 45 9c c1 |.....Oz...#S#E..|
+000002c0 39 e3 0c c2 1b 4d f3 78 cd ea b9 c8 d4 b6 30 bb |9....M.x......0.|
+000002d0 ff d7 ad 6c b2 fd 62 4d 8a 05 19 cf 58 ec 81 17 |...l..bM....X...|
+000002e0 21 7c 71 a1 d7 ad 87 11 8d 02 42 01 a2 9e c8 e4 |!|q.......B.....|
+000002f0 04 7c 75 22 df 14 97 94 8a 1b a1 34 95 95 dd 4c |.|u".......4...L|
+00000300 9f 1a c7 c7 96 db ef 87 82 27 9a 27 3a 3d 75 26 |.........'.':=u&|
+00000310 04 47 66 eb 55 60 9f 93 4e b2 09 14 fa 71 5b 3f |.Gf.U`..N....q[?|
+00000320 33 37 3f 0c f2 5c 4f 1e cc fa b1 6f 70 16 03 03 |37?..\O....op...|
+00000330 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 d6 67 cb d5 7c 95 9b 16 e2 3b 86 |......g..|....;.|
+00000050 22 bd 8c c7 40 36 9b b6 7e 0a 77 78 38 14 37 3c |"...@6..~.wx8.7<|
+00000060 48 42 37 a7 07 31 bb 57 c4 e9 f5 e5 a7 58 71 f8 |HB7..1.W.....Xq.|
+00000070 82 f7 12 97 72 |....r|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 40 56 45 5c a3 b3 |..........@VE\..|
+00000010 64 43 54 7f b5 90 1a 34 ab 2b 68 25 49 41 bf 78 |dCT....4.+h%IA.x|
+00000020 50 b0 66 35 20 76 e1 d0 5c 8a 82 2e 03 83 cf c6 |P.f5 v..\.......|
+00000030 b7 48 3d 2c c4 cf f5 31 c1 ab 9a 3b 09 3a 75 e3 |.H=,...1...;.:u.|
+00000040 b2 05 fa d9 79 cc 1b 0e 30 44 e1 |....y...0D.|
+>>> 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 76 5f 1f ec 55 ec f4 87 06 91 b4 |.....v_..U......|
+00000020 ba 71 4f 7f 9c ce e1 c7 e6 3d 75 05 fd ba 98 c4 |.qO......=u.....|
+00000030 d0 39 24 b8 d4 15 03 03 00 30 00 00 00 00 00 00 |.9$......0......|
+00000040 00 00 00 00 00 00 00 00 00 00 e8 4e 09 a1 5f db |...........N.._.|
+00000050 91 d5 5b e8 6a 86 7a 6c 7d 4a e1 94 8a 7d 99 52 |..[.j.zl}J...}.R|
+00000060 e6 5d d8 35 7c a0 68 8f 09 f9 |.].5|.h...|
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..02bad39
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES-GCM
@@ -0,0 +1,88 @@
+>>> 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 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 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 59 02 00 00 55 03 03 d4 97 12 a8 e7 |....Y...U.......|
+00000010 be a9 2d 80 f0 db 01 49 07 04 f4 d1 02 db 3d 4a |..-....I......=J|
+00000020 f0 af 31 38 39 d7 4c 1a d3 74 71 20 0f a3 76 14 |..189.L..tq ..v.|
+00000030 73 ff 25 1b ef 29 b3 5e 0b 8f fe ee a6 19 d3 31 |s.%..).^.......1|
+00000040 5d 2e 71 ab 74 58 e9 d6 c5 9b f4 93 c0 2b 00 00 |].q.tX.......+..|
+00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................|
+00000060 03 02 0e 0b 00 02 0a 00 02 07 00 02 04 30 82 02 |.............0..|
+00000070 00 30 82 01 62 02 09 00 b8 bf 2d 47 a0 d2 eb f4 |.0..b.....-G....|
+00000080 30 09 06 07 2a 86 48 ce 3d 04 01 30 45 31 0b 30 |0...*.H.=..0E1.0|
+00000090 09 06 03 55 04 06 13 02 41 55 31 13 30 11 06 03 |...U....AU1.0...|
+000000a0 55 04 08 13 0a 53 6f 6d 65 2d 53 74 61 74 65 31 |U....Some-State1|
+000000b0 21 30 1f 06 03 55 04 0a 13 18 49 6e 74 65 72 6e |!0...U....Intern|
+000000c0 65 74 20 57 69 64 67 69 74 73 20 50 74 79 20 4c |et Widgits Pty L|
+000000d0 74 64 30 1e 17 0d 31 32 31 31 32 32 31 35 30 36 |td0...1211221506|
+000000e0 33 32 5a 17 0d 32 32 31 31 32 30 31 35 30 36 33 |32Z..22112015063|
+000000f0 32 5a 30 45 31 0b 30 09 06 03 55 04 06 13 02 41 |2Z0E1.0...U....A|
+00000100 55 31 13 30 11 06 03 55 04 08 13 0a 53 6f 6d 65 |U1.0...U....Some|
+00000110 2d 53 74 61 74 65 31 21 30 1f 06 03 55 04 0a 13 |-State1!0...U...|
+00000120 18 49 6e 74 65 72 6e 65 74 20 57 69 64 67 69 74 |.Internet Widgit|
+00000130 73 20 50 74 79 20 4c 74 64 30 81 9b 30 10 06 07 |s Pty Ltd0..0...|
+00000140 2a 86 48 ce 3d 02 01 06 05 2b 81 04 00 23 03 81 |*.H.=....+...#..|
+00000150 86 00 04 00 c4 a1 ed be 98 f9 0b 48 73 36 7e c3 |...........Hs6~.|
+00000160 16 56 11 22 f2 3d 53 c3 3b 4d 21 3d cd 6b 75 e6 |.V.".=S.;M!=.ku.|
+00000170 f6 b0 dc 9a df 26 c1 bc b2 87 f0 72 32 7c b3 64 |.....&.....r2|.d|
+00000180 2f 1c 90 bc ea 68 23 10 7e fe e3 25 c0 48 3a 69 |/....h#.~..%.H:i|
+00000190 e0 28 6d d3 37 00 ef 04 62 dd 0d a0 9c 70 62 83 |.(m.7...b....pb.|
+000001a0 d8 81 d3 64 31 aa 9e 97 31 bd 96 b0 68 c0 9b 23 |...d1...1...h..#|
+000001b0 de 76 64 3f 1a 5c 7f e9 12 0e 58 58 b6 5f 70 dd |.vd?.\....XX._p.|
+000001c0 9b d8 ea d5 d7 f5 d5 cc b9 b6 9f 30 66 5b 66 9a |...........0f[f.|
+000001d0 20 e2 27 e5 bf fe 3b 30 09 06 07 2a 86 48 ce 3d | .'...;0...*.H.=|
+000001e0 04 01 03 81 8c 00 30 81 88 02 42 01 88 a2 4f eb |......0...B...O.|
+000001f0 e2 45 c5 48 7d 1b ac f5 ed 98 9d ae 47 70 c0 5e |.E.H}.......Gp.^|
+00000200 1b b6 2f bd f1 b6 4d b7 61 40 d3 11 a2 ce ee 0b |../...M.a@......|
+00000210 7e 92 7e ff 76 9d c3 3b 7e a5 3f ce fa 10 e2 59 |~.~.v..;~.?....Y|
+00000220 ec 47 2d 7c ac da 4e 97 0e 15 a0 6f d0 02 42 01 |.G-|..N....o..B.|
+00000230 4d fc be 67 13 9c 2d 05 0e bd 3f a3 8c 25 c1 33 |M..g..-...?..%.3|
+00000240 13 83 0d 94 06 bb d4 37 7a f6 ec 7a c9 86 2e dd |.......7z..z....|
+00000250 d7 11 69 7f 85 7c 56 de fb 31 78 2b e4 c7 78 0d |..i..|V..1x+..x.|
+00000260 ae cb be 9e 4e 36 24 31 7b 6a 0f 39 95 12 07 8f |....N6$1{j.9....|
+00000270 2a 16 03 03 00 b7 0c 00 00 b3 03 00 1d 20 a8 15 |*............ ..|
+00000280 13 40 df f8 dc 39 f0 af 90 53 a8 34 a9 61 68 c8 |.@...9...S.4.ah.|
+00000290 ad be 4f 02 0e d2 83 fd 2e 35 bf 8c 8e 13 04 03 |..O......5......|
+000002a0 00 8b 30 81 88 02 42 00 bc 69 df 5b ec 9f 17 ff |..0...B..i.[....|
+000002b0 e6 e5 24 71 f6 2b a5 88 40 78 12 ef f3 dc 25 a9 |..$q.+..@x....%.|
+000002c0 7c 89 24 0d c7 46 b2 db ae 72 b4 2a 87 87 fe 7e ||.$..F...r.*...~|
+000002d0 22 8f e6 d4 c4 7b 61 14 c3 04 39 98 87 6f 1f 54 |"....{a...9..o.T|
+000002e0 e0 50 16 0b 52 8e d6 1e 0a 02 42 00 b7 40 26 a8 |.P..R.....B..@&.|
+000002f0 11 09 77 ec 36 e5 88 26 6d 83 6f e7 c3 b1 98 c3 |..w.6..&m.o.....|
+00000300 4b 83 92 48 65 31 87 68 ee 49 25 ec 95 59 82 b5 |K..He1.h.I%..Y..|
+00000310 93 92 c8 17 d6 d9 1c 99 60 48 1b 18 50 b4 e7 df |........`H..P...|
+00000320 ed 75 1a f2 08 e8 3d 93 99 27 ef 4d e3 16 03 03 |.u....=..'.M....|
+00000330 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 30 f1 a9 |....(........0..|
+00000040 4a 7e 86 a1 5d b7 db 2f c6 e2 ec 36 41 83 66 75 |J~..]../...6A.fu|
+00000050 a3 6c 7d e7 61 36 ac f7 76 f8 8e d8 81 |.l}.a6..v....|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 28 2c 78 86 13 dc |..........(,x...|
+00000010 a4 b9 bf ad 50 45 a3 d9 b3 df 33 a2 79 b1 1b 25 |....PE....3.y..%|
+00000020 12 94 97 99 07 6b 52 c4 52 64 ab 89 40 8c 93 4a |.....kR.Rd..@..J|
+00000030 e3 cc d9 |...|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 fa 9e 8b |................|
+00000010 92 8c f5 32 e6 d4 11 46 b4 73 62 56 f6 83 15 6f |...2...F.sbV...o|
+00000020 ce de 2d 15 03 03 00 1a 00 00 00 00 00 00 00 02 |..-.............|
+00000030 93 24 68 83 67 b6 f9 27 b5 26 52 78 5d f3 c9 d2 |.$h.g..'.&Rx]...|
+00000040 26 a0 |&.|
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..4946fe4
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES128-SHA256
@@ -0,0 +1,97 @@
+>>> 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 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 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 59 02 00 00 55 03 03 d1 af 88 61 b7 |....Y...U.....a.|
+00000010 b3 01 16 1a 44 26 1c a1 4f 2d 8a f6 9c f2 7e 1a |....D&..O-....~.|
+00000020 1f ce cb dd 5b f0 c6 2f 16 5e 4a 20 b3 c7 ae 3f |....[../.^J ...?|
+00000030 de d0 d8 9e 48 3e 87 23 f0 9d 43 10 50 3c 66 8b |....H>.#..C.P<f.|
+00000040 7f d2 9b 4f f5 e4 b3 53 db d6 65 d0 c0 23 00 00 |...O...S..e..#..|
+00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................|
+00000060 03 02 0e 0b 00 02 0a 00 02 07 00 02 04 30 82 02 |.............0..|
+00000070 00 30 82 01 62 02 09 00 b8 bf 2d 47 a0 d2 eb f4 |.0..b.....-G....|
+00000080 30 09 06 07 2a 86 48 ce 3d 04 01 30 45 31 0b 30 |0...*.H.=..0E1.0|
+00000090 09 06 03 55 04 06 13 02 41 55 31 13 30 11 06 03 |...U....AU1.0...|
+000000a0 55 04 08 13 0a 53 6f 6d 65 2d 53 74 61 74 65 31 |U....Some-State1|
+000000b0 21 30 1f 06 03 55 04 0a 13 18 49 6e 74 65 72 6e |!0...U....Intern|
+000000c0 65 74 20 57 69 64 67 69 74 73 20 50 74 79 20 4c |et Widgits Pty L|
+000000d0 74 64 30 1e 17 0d 31 32 31 31 32 32 31 35 30 36 |td0...1211221506|
+000000e0 33 32 5a 17 0d 32 32 31 31 32 30 31 35 30 36 33 |32Z..22112015063|
+000000f0 32 5a 30 45 31 0b 30 09 06 03 55 04 06 13 02 41 |2Z0E1.0...U....A|
+00000100 55 31 13 30 11 06 03 55 04 08 13 0a 53 6f 6d 65 |U1.0...U....Some|
+00000110 2d 53 74 61 74 65 31 21 30 1f 06 03 55 04 0a 13 |-State1!0...U...|
+00000120 18 49 6e 74 65 72 6e 65 74 20 57 69 64 67 69 74 |.Internet Widgit|
+00000130 73 20 50 74 79 20 4c 74 64 30 81 9b 30 10 06 07 |s Pty Ltd0..0...|
+00000140 2a 86 48 ce 3d 02 01 06 05 2b 81 04 00 23 03 81 |*.H.=....+...#..|
+00000150 86 00 04 00 c4 a1 ed be 98 f9 0b 48 73 36 7e c3 |...........Hs6~.|
+00000160 16 56 11 22 f2 3d 53 c3 3b 4d 21 3d cd 6b 75 e6 |.V.".=S.;M!=.ku.|
+00000170 f6 b0 dc 9a df 26 c1 bc b2 87 f0 72 32 7c b3 64 |.....&.....r2|.d|
+00000180 2f 1c 90 bc ea 68 23 10 7e fe e3 25 c0 48 3a 69 |/....h#.~..%.H:i|
+00000190 e0 28 6d d3 37 00 ef 04 62 dd 0d a0 9c 70 62 83 |.(m.7...b....pb.|
+000001a0 d8 81 d3 64 31 aa 9e 97 31 bd 96 b0 68 c0 9b 23 |...d1...1...h..#|
+000001b0 de 76 64 3f 1a 5c 7f e9 12 0e 58 58 b6 5f 70 dd |.vd?.\....XX._p.|
+000001c0 9b d8 ea d5 d7 f5 d5 cc b9 b6 9f 30 66 5b 66 9a |...........0f[f.|
+000001d0 20 e2 27 e5 bf fe 3b 30 09 06 07 2a 86 48 ce 3d | .'...;0...*.H.=|
+000001e0 04 01 03 81 8c 00 30 81 88 02 42 01 88 a2 4f eb |......0...B...O.|
+000001f0 e2 45 c5 48 7d 1b ac f5 ed 98 9d ae 47 70 c0 5e |.E.H}.......Gp.^|
+00000200 1b b6 2f bd f1 b6 4d b7 61 40 d3 11 a2 ce ee 0b |../...M.a@......|
+00000210 7e 92 7e ff 76 9d c3 3b 7e a5 3f ce fa 10 e2 59 |~.~.v..;~.?....Y|
+00000220 ec 47 2d 7c ac da 4e 97 0e 15 a0 6f d0 02 42 01 |.G-|..N....o..B.|
+00000230 4d fc be 67 13 9c 2d 05 0e bd 3f a3 8c 25 c1 33 |M..g..-...?..%.3|
+00000240 13 83 0d 94 06 bb d4 37 7a f6 ec 7a c9 86 2e dd |.......7z..z....|
+00000250 d7 11 69 7f 85 7c 56 de fb 31 78 2b e4 c7 78 0d |..i..|V..1x+..x.|
+00000260 ae cb be 9e 4e 36 24 31 7b 6a 0f 39 95 12 07 8f |....N6$1{j.9....|
+00000270 2a 16 03 03 00 b6 0c 00 00 b2 03 00 1d 20 dc 43 |*............ .C|
+00000280 15 b7 95 81 41 bf e2 bd 56 82 23 46 05 29 05 95 |....A...V.#F.)..|
+00000290 ae 67 08 38 9f 10 70 25 21 92 b4 a0 82 4e 04 03 |.g.8..p%!....N..|
+000002a0 00 8a 30 81 87 02 41 5d ca d6 a2 fd e3 e2 be 2f |..0...A]......./|
+000002b0 69 b5 7d 5c a3 2b 36 4c 8b 81 05 89 12 e1 30 26 |i.}\.+6L......0&|
+000002c0 fa ae 82 b9 4f 8e ba ac ee 7b 62 d5 60 f8 df a4 |....O....{b.`...|
+000002d0 c1 a1 15 73 f8 fb 0b 47 64 b3 34 4a 44 02 a6 32 |...s...Gd.4JD..2|
+000002e0 bc 0d 7b a5 c1 84 cf 77 02 42 01 f3 e5 7f d1 47 |..{....w.B.....G|
+000002f0 bc be 0a ec cd d6 4f 2c 26 5a 95 d3 0f 9b c3 c6 |......O,&Z......|
+00000300 05 b5 5e d7 f6 ca 64 17 94 aa a5 e6 b1 88 57 21 |..^...d.......W!|
+00000310 f8 da 02 de 32 8c ea 5b 7c 36 c9 93 e1 96 38 93 |....2..[|6....8.|
+00000320 9b f9 e5 44 47 a6 74 fa 0e 5f 8f 22 16 03 03 00 |...DG.t.._."....|
+00000330 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 85 db ae c1 37 85 25 3d ee 5f f5 |.........7.%=._.|
+00000050 12 95 df ee 29 4a f7 3a 80 ca bd c2 b3 d8 f3 8c |....)J.:........|
+00000060 56 62 d2 68 13 1d 73 51 09 93 a3 b9 43 4a 2c 0f |Vb.h..sQ....CJ,.|
+00000070 bf 3c 96 76 08 a9 17 68 e2 9a 3f 39 e7 04 76 f8 |.<.v...h..?9..v.|
+00000080 8f fe e8 f5 ce |.....|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 50 fa 85 cc bc dd |..........P.....|
+00000010 0e 16 86 b1 5c 51 8a b9 cc 78 cd cd 64 5d 23 ca |....\Q...x..d]#.|
+00000020 59 84 b3 42 dd ae a7 98 43 05 21 4f 35 43 75 5c |Y..B....C.!O5Cu\|
+00000030 13 c8 e0 b6 66 0f 55 32 69 7a 8b 8f cd c2 37 38 |....f.U2iz....78|
+00000040 f6 fa 0b 66 cf 46 91 3e 9f f5 43 44 f5 c7 2b e1 |...f.F.>..CD..+.|
+00000050 39 3a f7 3c f2 03 c4 85 dc 58 66 |9:.<.....Xf|
+>>> 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 44 e6 99 40 ae 12 bc d9 92 c5 ae |.....D..@.......|
+00000020 fb 4d 5f 64 7a 77 0f 80 8e a4 be d0 ba ba 41 b1 |.M_dzw........A.|
+00000030 0d 40 e9 0e 50 32 dc 35 2d 5e 5c 8a ef 20 75 80 |.@..P2.5-^\.. u.|
+00000040 a0 e5 9c 61 49 15 03 03 00 40 00 00 00 00 00 00 |...aI....@......|
+00000050 00 00 00 00 00 00 00 00 00 00 57 91 40 2a a5 f7 |..........W.@*..|
+00000060 9f 29 0f 02 8e 50 ac 4b 2e 55 9a 78 72 f0 d7 c5 |.)...P.K.U.xr...|
+00000070 3b f2 cd 28 4d 8b 49 d8 50 a6 22 96 de df 16 d6 |;..(M.I.P.".....|
+00000080 61 4b 23 5c 5d de a1 0a 5b 16 |aK#\]...[.|
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..14af5ae
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-ECDSA-AES256-GCM-SHA384
@@ -0,0 +1,88 @@
+>>> 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 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 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 59 02 00 00 55 03 03 bb 8a 66 ee 44 |....Y...U....f.D|
+00000010 42 dc 59 c7 a7 7b a8 57 8e 63 21 f0 4e 31 f4 5c |B.Y..{.W.c!.N1.\|
+00000020 1d d3 42 e5 de eb 8c 78 3a 01 01 20 9b 89 05 d6 |..B....x:.. ....|
+00000030 d2 07 38 8b 4c 5f 6d 62 9f 43 a0 cd d3 40 0f 77 |..8.L_mb.C...@.w|
+00000040 17 ff 43 4a 5c b3 8c 83 b7 4b c7 e7 c0 2c 00 00 |..CJ\....K...,..|
+00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................|
+00000060 03 02 0e 0b 00 02 0a 00 02 07 00 02 04 30 82 02 |.............0..|
+00000070 00 30 82 01 62 02 09 00 b8 bf 2d 47 a0 d2 eb f4 |.0..b.....-G....|
+00000080 30 09 06 07 2a 86 48 ce 3d 04 01 30 45 31 0b 30 |0...*.H.=..0E1.0|
+00000090 09 06 03 55 04 06 13 02 41 55 31 13 30 11 06 03 |...U....AU1.0...|
+000000a0 55 04 08 13 0a 53 6f 6d 65 2d 53 74 61 74 65 31 |U....Some-State1|
+000000b0 21 30 1f 06 03 55 04 0a 13 18 49 6e 74 65 72 6e |!0...U....Intern|
+000000c0 65 74 20 57 69 64 67 69 74 73 20 50 74 79 20 4c |et Widgits Pty L|
+000000d0 74 64 30 1e 17 0d 31 32 31 31 32 32 31 35 30 36 |td0...1211221506|
+000000e0 33 32 5a 17 0d 32 32 31 31 32 30 31 35 30 36 33 |32Z..22112015063|
+000000f0 32 5a 30 45 31 0b 30 09 06 03 55 04 06 13 02 41 |2Z0E1.0...U....A|
+00000100 55 31 13 30 11 06 03 55 04 08 13 0a 53 6f 6d 65 |U1.0...U....Some|
+00000110 2d 53 74 61 74 65 31 21 30 1f 06 03 55 04 0a 13 |-State1!0...U...|
+00000120 18 49 6e 74 65 72 6e 65 74 20 57 69 64 67 69 74 |.Internet Widgit|
+00000130 73 20 50 74 79 20 4c 74 64 30 81 9b 30 10 06 07 |s Pty Ltd0..0...|
+00000140 2a 86 48 ce 3d 02 01 06 05 2b 81 04 00 23 03 81 |*.H.=....+...#..|
+00000150 86 00 04 00 c4 a1 ed be 98 f9 0b 48 73 36 7e c3 |...........Hs6~.|
+00000160 16 56 11 22 f2 3d 53 c3 3b 4d 21 3d cd 6b 75 e6 |.V.".=S.;M!=.ku.|
+00000170 f6 b0 dc 9a df 26 c1 bc b2 87 f0 72 32 7c b3 64 |.....&.....r2|.d|
+00000180 2f 1c 90 bc ea 68 23 10 7e fe e3 25 c0 48 3a 69 |/....h#.~..%.H:i|
+00000190 e0 28 6d d3 37 00 ef 04 62 dd 0d a0 9c 70 62 83 |.(m.7...b....pb.|
+000001a0 d8 81 d3 64 31 aa 9e 97 31 bd 96 b0 68 c0 9b 23 |...d1...1...h..#|
+000001b0 de 76 64 3f 1a 5c 7f e9 12 0e 58 58 b6 5f 70 dd |.vd?.\....XX._p.|
+000001c0 9b d8 ea d5 d7 f5 d5 cc b9 b6 9f 30 66 5b 66 9a |...........0f[f.|
+000001d0 20 e2 27 e5 bf fe 3b 30 09 06 07 2a 86 48 ce 3d | .'...;0...*.H.=|
+000001e0 04 01 03 81 8c 00 30 81 88 02 42 01 88 a2 4f eb |......0...B...O.|
+000001f0 e2 45 c5 48 7d 1b ac f5 ed 98 9d ae 47 70 c0 5e |.E.H}.......Gp.^|
+00000200 1b b6 2f bd f1 b6 4d b7 61 40 d3 11 a2 ce ee 0b |../...M.a@......|
+00000210 7e 92 7e ff 76 9d c3 3b 7e a5 3f ce fa 10 e2 59 |~.~.v..;~.?....Y|
+00000220 ec 47 2d 7c ac da 4e 97 0e 15 a0 6f d0 02 42 01 |.G-|..N....o..B.|
+00000230 4d fc be 67 13 9c 2d 05 0e bd 3f a3 8c 25 c1 33 |M..g..-...?..%.3|
+00000240 13 83 0d 94 06 bb d4 37 7a f6 ec 7a c9 86 2e dd |.......7z..z....|
+00000250 d7 11 69 7f 85 7c 56 de fb 31 78 2b e4 c7 78 0d |..i..|V..1x+..x.|
+00000260 ae cb be 9e 4e 36 24 31 7b 6a 0f 39 95 12 07 8f |....N6$1{j.9....|
+00000270 2a 16 03 03 00 b7 0c 00 00 b3 03 00 1d 20 fd 71 |*............ .q|
+00000280 c1 3a 6a a3 69 6a 34 f3 02 c5 1d e5 db 63 f4 eb |.:j.ij4......c..|
+00000290 97 4c 70 bc b3 4e 9d 2c 2f b2 b9 9d ac 3f 04 03 |.Lp..N.,/....?..|
+000002a0 00 8b 30 81 88 02 42 01 bd 9d ad 24 37 b9 60 55 |..0...B....$7.`U|
+000002b0 e4 cc bc 49 c3 88 3b ed ac e4 42 8e fa 81 01 d9 |...I..;...B.....|
+000002c0 39 4c f0 1c 7d 39 a2 81 8a e1 17 0e 8d 37 76 96 |9L..}9.......7v.|
+000002d0 37 13 3a 1e 2e fd 0d 0a 3c 90 9d 43 3d 06 c0 b1 |7.:.....<..C=...|
+000002e0 4e 07 3e c3 9f f2 43 40 0b 02 42 01 d6 d0 20 ad |N.>...C@..B... .|
+000002f0 48 09 c0 9b 5d c8 84 46 3b 98 37 9b 5a 91 4a 07 |H...]..F;.7.Z.J.|
+00000300 79 68 71 92 76 dc 70 0f 5c 44 7e 81 c3 c6 3f 19 |yhq.v.p.\D~...?.|
+00000310 f4 0f 6a 0b aa cc bb 65 e7 34 b5 e9 67 2d 32 98 |..j....e.4..g-2.|
+00000320 1c f6 76 4c 96 73 df 21 d6 e1 ea 34 86 16 03 03 |..vL.s.!...4....|
+00000330 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 27 fd 98 |....(........'..|
+00000040 47 79 56 f9 e8 0e fd 18 c2 8f 2d 32 51 f7 19 b5 |GyV.......-2Q...|
+00000050 ab 2f 81 ed b6 cf 6f b5 65 81 81 f1 44 |./....o.e...D|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 28 a9 b7 63 61 57 |..........(..caW|
+00000010 54 57 f0 b2 60 58 e3 dc 6e e1 40 3e 67 b4 99 8f |TW..`X..n.@>g...|
+00000020 e9 6b 11 f1 1a 54 bd c1 d3 b9 5b 01 12 27 a4 0b |.k...T....[..'..|
+00000030 e9 ec 01 |...|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 e0 8a 6e |...............n|
+00000010 62 5d e3 db 99 10 d2 53 b6 21 2e 79 31 cf 71 1d |b].....S.!.y1.q.|
+00000020 34 71 2a 15 03 03 00 1a 00 00 00 00 00 00 00 02 |4q*.............|
+00000030 e7 4a 8d b9 2f 1b b1 70 72 da 7f d8 fa 4f 9f d6 |.J../..pr....O..|
+00000040 ca f3 |..|
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..3113b3c
--- /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 d0 01 00 00 cc 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 7b 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 12 00 00 00 2b |...............+|
+000000a0 00 09 08 03 04 03 03 03 02 03 01 00 33 00 26 00 |............3.&.|
+000000b0 24 00 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da |$... /.}.G.bC.(.|
+000000c0 ac 5f bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 |._.).0..........|
+000000d0 5f 58 cb 3b 74 |_X.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 59 02 00 00 55 03 03 e1 cc 3c 49 04 |....Y...U....<I.|
+00000010 bb 5b 18 c7 44 8f 52 62 d9 74 84 94 fa 61 3f 12 |.[..D.Rb.t...a?.|
+00000020 c8 23 50 0b 8a 5c 81 23 c2 9d 3d 20 1f b2 67 b0 |.#P..\.#..= ..g.|
+00000030 e9 2d a9 ed 35 4e ab b9 73 59 32 2f 49 ed 1e 60 |.-..5N..sY2/I..`|
+00000040 4c 31 11 6e 27 79 e0 62 e0 e4 ca 16 cc a9 00 00 |L1.n'y.b........|
+00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................|
+00000060 03 02 0e 0b 00 02 0a 00 02 07 00 02 04 30 82 02 |.............0..|
+00000070 00 30 82 01 62 02 09 00 b8 bf 2d 47 a0 d2 eb f4 |.0..b.....-G....|
+00000080 30 09 06 07 2a 86 48 ce 3d 04 01 30 45 31 0b 30 |0...*.H.=..0E1.0|
+00000090 09 06 03 55 04 06 13 02 41 55 31 13 30 11 06 03 |...U....AU1.0...|
+000000a0 55 04 08 13 0a 53 6f 6d 65 2d 53 74 61 74 65 31 |U....Some-State1|
+000000b0 21 30 1f 06 03 55 04 0a 13 18 49 6e 74 65 72 6e |!0...U....Intern|
+000000c0 65 74 20 57 69 64 67 69 74 73 20 50 74 79 20 4c |et Widgits Pty L|
+000000d0 74 64 30 1e 17 0d 31 32 31 31 32 32 31 35 30 36 |td0...1211221506|
+000000e0 33 32 5a 17 0d 32 32 31 31 32 30 31 35 30 36 33 |32Z..22112015063|
+000000f0 32 5a 30 45 31 0b 30 09 06 03 55 04 06 13 02 41 |2Z0E1.0...U....A|
+00000100 55 31 13 30 11 06 03 55 04 08 13 0a 53 6f 6d 65 |U1.0...U....Some|
+00000110 2d 53 74 61 74 65 31 21 30 1f 06 03 55 04 0a 13 |-State1!0...U...|
+00000120 18 49 6e 74 65 72 6e 65 74 20 57 69 64 67 69 74 |.Internet Widgit|
+00000130 73 20 50 74 79 20 4c 74 64 30 81 9b 30 10 06 07 |s Pty Ltd0..0...|
+00000140 2a 86 48 ce 3d 02 01 06 05 2b 81 04 00 23 03 81 |*.H.=....+...#..|
+00000150 86 00 04 00 c4 a1 ed be 98 f9 0b 48 73 36 7e c3 |...........Hs6~.|
+00000160 16 56 11 22 f2 3d 53 c3 3b 4d 21 3d cd 6b 75 e6 |.V.".=S.;M!=.ku.|
+00000170 f6 b0 dc 9a df 26 c1 bc b2 87 f0 72 32 7c b3 64 |.....&.....r2|.d|
+00000180 2f 1c 90 bc ea 68 23 10 7e fe e3 25 c0 48 3a 69 |/....h#.~..%.H:i|
+00000190 e0 28 6d d3 37 00 ef 04 62 dd 0d a0 9c 70 62 83 |.(m.7...b....pb.|
+000001a0 d8 81 d3 64 31 aa 9e 97 31 bd 96 b0 68 c0 9b 23 |...d1...1...h..#|
+000001b0 de 76 64 3f 1a 5c 7f e9 12 0e 58 58 b6 5f 70 dd |.vd?.\....XX._p.|
+000001c0 9b d8 ea d5 d7 f5 d5 cc b9 b6 9f 30 66 5b 66 9a |...........0f[f.|
+000001d0 20 e2 27 e5 bf fe 3b 30 09 06 07 2a 86 48 ce 3d | .'...;0...*.H.=|
+000001e0 04 01 03 81 8c 00 30 81 88 02 42 01 88 a2 4f eb |......0...B...O.|
+000001f0 e2 45 c5 48 7d 1b ac f5 ed 98 9d ae 47 70 c0 5e |.E.H}.......Gp.^|
+00000200 1b b6 2f bd f1 b6 4d b7 61 40 d3 11 a2 ce ee 0b |../...M.a@......|
+00000210 7e 92 7e ff 76 9d c3 3b 7e a5 3f ce fa 10 e2 59 |~.~.v..;~.?....Y|
+00000220 ec 47 2d 7c ac da 4e 97 0e 15 a0 6f d0 02 42 01 |.G-|..N....o..B.|
+00000230 4d fc be 67 13 9c 2d 05 0e bd 3f a3 8c 25 c1 33 |M..g..-...?..%.3|
+00000240 13 83 0d 94 06 bb d4 37 7a f6 ec 7a c9 86 2e dd |.......7z..z....|
+00000250 d7 11 69 7f 85 7c 56 de fb 31 78 2b e4 c7 78 0d |..i..|V..1x+..x.|
+00000260 ae cb be 9e 4e 36 24 31 7b 6a 0f 39 95 12 07 8f |....N6$1{j.9....|
+00000270 2a 16 03 03 00 b6 0c 00 00 b2 03 00 1d 20 cc a1 |*............ ..|
+00000280 4d a4 b1 22 86 e5 91 9b e2 1a 28 c6 66 06 1a 89 |M.."......(.f...|
+00000290 a9 62 23 93 09 54 ae 67 a8 ab 18 ac 67 37 04 03 |.b#..T.g....g7..|
+000002a0 00 8a 30 81 87 02 42 01 f0 46 f3 3f 13 a7 1d 84 |..0...B..F.?....|
+000002b0 73 65 9e 91 16 6c 3d 8f 21 ab 17 db 24 34 21 8c |se...l=.!...$4!.|
+000002c0 a9 e1 9b a6 17 c8 0d 7a b4 8e f0 46 cd c5 b9 b2 |.......z...F....|
+000002d0 5e 64 7f 9f 9d 03 14 7a 23 5d 55 70 ae d1 ff 08 |^d.....z#]Up....|
+000002e0 e8 70 f5 5d 55 90 74 04 0d 02 41 09 ca 7d 60 ea |.p.]U.t...A..}`.|
+000002f0 13 17 42 e8 53 e7 c5 31 15 4a 58 14 d6 54 f5 40 |..B.S..1.JX..T.@|
+00000300 a1 aa fe 4b 13 f5 29 04 05 cc 12 26 e2 b7 e5 a6 |...K..)....&....|
+00000310 90 7c 5e 66 2f ed 41 7c 97 a1 72 87 5e 46 5a 5b |.|^f/.A|..r.^FZ[|
+00000320 1b d1 7b 3c 34 ba 3f 47 7d a9 84 33 16 03 03 00 |..{<4.?G}..3....|
+00000330 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 7f ab 78 f0 a6 b6 57 bd c3 b9 32 |.... ..x...W...2|
+00000040 96 3f 7c 9d a0 4d dc 74 c9 e8 1a 88 c4 b2 10 27 |.?|..M.t.......'|
+00000050 e3 9c 1e 9b e1 |.....|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 20 0c b7 0c 47 8e |.......... ...G.|
+00000010 40 6b 9f 9c d2 cd 24 25 db 12 e8 0c 50 be f3 98 |@k....$%....P...|
+00000020 4a 6f f9 42 58 07 b9 64 d0 00 91 |Jo.BX..d...|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 16 1d 32 1c ef 0b 1f a4 ba 39 a3 63 |......2......9.c|
+00000010 04 29 e5 67 1e bb 5a 6e c7 3c c1 15 03 03 00 12 |.).g..Zn.<......|
+00000020 0e 0b 0f 49 30 fe d4 c3 35 85 e3 db 6e 65 e3 2d |...I0...5...ne.-|
+00000030 d1 1d |..|
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..ea6c787
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES
@@ -0,0 +1,97 @@
+>>> 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 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 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 59 02 00 00 55 03 03 1e 2f 6f fa 02 |....Y...U.../o..|
+00000010 44 3e 0d d0 3e b5 e6 0c a2 d6 aa 04 5b ba 93 39 |D>..>.......[..9|
+00000020 29 dd e7 7e b8 11 f9 85 97 a5 e4 20 9c 64 e9 47 |)..~....... .d.G|
+00000030 cb 7c 0c 77 9d 83 5a c4 e8 05 62 40 95 8e 8e aa |.|.w..Z...b@....|
+00000040 39 bb 24 8f b7 29 75 77 18 66 60 29 c0 13 00 00 |9.$..)uw.f`)....|
+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 ac 0c 00 00 a8 03 00 1d 20 92 ed 81 60 d9 51 c2 |........ ...`.Q.|
+000002d0 00 3d 99 84 82 c5 83 67 60 b3 11 59 0c c5 5d ff |.=.....g`..Y..].|
+000002e0 d6 28 79 68 2d 73 7f 84 40 08 04 00 80 b6 a0 4b |.(yh-s..@......K|
+000002f0 3d fb e1 e6 76 cc ae e3 59 d0 1c 50 5c 09 5d 80 |=...v...Y..P\.].|
+00000300 c2 58 0d 36 d7 1a 78 e3 c2 66 73 3a 14 06 37 6f |.X.6..x..fs:..7o|
+00000310 3a 95 2e 2a eb cc e5 e3 f7 30 eb 0d 33 04 51 6e |:..*.....0..3.Qn|
+00000320 06 86 8f 53 6d fd 97 75 b3 13 2e 4e ee 8f 03 68 |...Sm..u...N...h|
+00000330 23 32 83 96 af 01 ed b0 21 a7 13 06 47 f4 08 b9 |#2......!...G...|
+00000340 8a 47 cc 12 99 20 c6 31 77 28 2c 2e d6 a0 20 8c |.G... .1w(,... .|
+00000350 e6 67 c7 70 23 ed 98 9c c9 47 1c e0 37 95 42 aa |.g.p#....G..7.B.|
+00000360 c2 19 1b 55 09 5c 58 fb ef 67 a9 b5 65 16 03 03 |...U.\X..g..e...|
+00000370 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 dd 81 23 e0 a3 01 33 bb 87 0d 93 |.......#...3....|
+00000050 b2 61 16 01 e3 87 e0 05 cc b0 ec 15 56 df ff 9c |.a..........V...|
+00000060 e6 9c 6a 57 79 8a 0b 86 f9 fb 60 3f ca 0d ef f2 |..jWy.....`?....|
+00000070 81 c0 5e 22 bf |..^".|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 40 d4 d3 ba 7f 4c |..........@....L|
+00000010 1a ee d9 ca 66 a0 5b d7 08 78 5d 5c fd 17 32 71 |....f.[..x]\..2q|
+00000020 7f 8c 2e eb 80 bc 82 0f 0c ed 71 ac 34 59 71 d1 |..........q.4Yq.|
+00000030 aa d3 fd 0c 50 7d 4b 1b 01 5d 4c 03 9f 6c 16 8f |....P}K..]L..l..|
+00000040 5d f7 8d c0 4b 3f 01 96 23 40 22 |]...K?..#@"|
+>>> 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 36 49 0e f6 26 13 f7 69 15 54 27 |.....6I..&..i.T'|
+00000020 5a e6 f2 fb 7d ad e0 30 d3 cd ed 08 24 74 5f 77 |Z...}..0....$t_w|
+00000030 f7 8b 3f bf 94 15 03 03 00 30 00 00 00 00 00 00 |..?......0......|
+00000040 00 00 00 00 00 00 00 00 00 00 28 09 ed 2f d8 6f |..........(../.o|
+00000050 95 fc db 9e ec d8 81 7e a4 d4 8e c5 ec d3 24 bc |.......~......$.|
+00000060 ab 52 e6 01 75 98 b9 e5 9f d9 |.R..u.....|
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..88d0d01
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ECDHE-RSA-AES128-SHA256
@@ -0,0 +1,101 @@
+>>> 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 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 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 59 02 00 00 55 03 03 e6 04 5e a9 bb |....Y...U....^..|
+00000010 23 56 bd cc e7 72 9f 10 b1 fc 23 48 22 19 cb 27 |#V...r....#H"..'|
+00000020 3e c4 22 ec b9 7a 9c 81 60 c5 55 20 b9 7f 8a 0e |>."..z..`.U ....|
+00000030 6b d6 cf cb 35 85 52 f3 9f 28 00 87 22 88 6d 7c |k...5.R..(..".m||
+00000040 35 0e f6 af 7c 28 b4 71 cc 46 c1 b5 c0 27 00 00 |5...|(.q.F...'..|
+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 ac 0c 00 00 a8 03 00 1d 20 55 af 53 a0 54 77 df |........ U.S.Tw.|
+000002d0 ca 8f 49 1a 4d d0 9b 24 a6 a9 2b b2 2a 33 46 b8 |..I.M..$..+.*3F.|
+000002e0 01 d6 4e fd fb c1 e4 e6 64 08 04 00 80 5c da 2f |..N.....d....\./|
+000002f0 01 2b 10 b9 e9 35 f2 b1 2a 28 4f 78 58 7b 3d 9a |.+...5..*(OxX{=.|
+00000300 13 e4 7c 77 41 95 fa 7a 90 1f eb f5 20 55 7c 76 |..|wA..z.... U|v|
+00000310 dd c5 66 08 88 eb ba 17 f0 de f3 0c a5 a6 3c 21 |..f...........<!|
+00000320 52 89 25 b1 4d 86 e3 0b 8a 14 dc 8b a6 76 41 25 |R.%.M........vA%|
+00000330 9e d3 20 b6 61 8a 26 8b 0d b7 cb 98 ac 45 e0 3b |.. .a.&......E.;|
+00000340 6f d6 b2 52 8b a2 31 63 c8 44 1d 2a 3a c1 35 87 |o..R..1c.D.*:.5.|
+00000350 7a 7b 2a fa dd ab d3 48 9b e2 fa e1 93 7c 09 f7 |z{*....H.....|..|
+00000360 e1 72 83 f8 23 07 30 3a 4a 4f 56 97 1b 16 03 03 |.r..#.0:JOV.....|
+00000370 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 91 c1 82 23 f0 03 79 83 38 ef d0 |........#..y.8..|
+00000050 73 71 9b 7d 55 5e 53 3b d3 cf 86 48 60 2f 42 97 |sq.}U^S;...H`/B.|
+00000060 63 e8 4b 20 4c 92 3e 2f aa b3 32 46 8a 96 69 42 |c.K L.>/..2F..iB|
+00000070 96 9a 4b bd 04 f2 3d b6 5f f9 37 4f a4 3d f1 cb |..K...=._.7O.=..|
+00000080 d5 57 fc 5e 8e |.W.^.|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 50 e1 91 69 dc 7b |..........P..i.{|
+00000010 5f a4 c7 7a 8f ba bb 8d 98 c3 0e 3f 10 f1 3e 3f |_..z.......?..>?|
+00000020 37 6f 11 81 3f c5 7c 22 6f 22 a3 94 ae 3a 77 17 |7o..?.|"o"...:w.|
+00000030 a2 7b cc 8e 5e 6e 9b 4b 98 fd 16 f8 46 9e 78 19 |.{..^n.K....F.x.|
+00000040 43 e6 da e3 05 9a 0a 49 b0 09 c7 e5 4b 41 dc b4 |C......I....KA..|
+00000050 c0 81 9b 46 7e dd c3 64 2e f8 6e |...F~..d..n|
+>>> 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 65 4c 71 31 d4 47 4d 0b 81 1f 75 |.....eLq1.GM...u|
+00000020 b6 71 64 4a e6 a8 80 a1 f1 e2 0a 14 77 af a4 c6 |.qdJ........w...|
+00000030 1d 6a 7d 79 6a 15 a1 0e 86 6c 8e e1 32 64 0b 5d |.j}yj....l..2d.]|
+00000040 af e0 f5 05 91 15 03 03 00 40 00 00 00 00 00 00 |.........@......|
+00000050 00 00 00 00 00 00 00 00 00 00 ca 46 1b 95 2a 41 |...........F..*A|
+00000060 ce dc 30 d6 e0 cf 2f 2b 1f 61 81 33 a4 58 e7 af |..0.../+.a.3.X..|
+00000070 90 9c 15 42 9b ab 26 64 d1 39 46 45 6b 74 b9 c4 |...B..&d.9FEkt..|
+00000080 21 d9 ef 2d 69 51 dc e7 8a 6b |!..-iQ...k|
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..2c2cb45
--- /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 d0 01 00 00 cc 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 7b 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 12 00 00 00 2b |...............+|
+000000a0 00 09 08 03 04 03 03 03 02 03 01 00 33 00 26 00 |............3.&.|
+000000b0 24 00 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da |$... /.}.G.bC.(.|
+000000c0 ac 5f bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 |._.).0..........|
+000000d0 5f 58 cb 3b 74 |_X.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 59 02 00 00 55 03 03 2a 76 db 4b d5 |....Y...U..*v.K.|
+00000010 10 f3 21 f2 4b 29 a2 2e 7a 7d 0b 86 c4 af 60 95 |..!.K)..z}....`.|
+00000020 5b 11 84 27 8a 59 7f af a0 27 de 20 02 f7 dc 9b |[..'.Y...'. ....|
+00000030 63 8e 2e da 48 b5 73 81 8e 76 13 da dd 2e 17 2b |c...H.s..v.....+|
+00000040 ff 18 ad d7 9d f3 44 ed b6 60 0e 42 cc a8 00 00 |......D..`.B....|
+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 ac 0c 00 00 a8 03 00 1d 20 0d c3 c2 b5 73 da 39 |........ ....s.9|
+000002d0 82 e5 8c 18 0d 8d 16 c2 a5 e7 3e 39 fd 25 00 18 |..........>9.%..|
+000002e0 25 16 c0 a7 6e c6 dd bb 01 08 04 00 80 b3 bd 01 |%...n...........|
+000002f0 ae dd b1 c8 2a 5d 0e 66 6d 1e b3 92 f4 01 63 59 |....*].fm.....cY|
+00000300 0c c1 62 df 75 8f 4f 19 5a cf 2f 63 79 d0 06 31 |..b.u.O.Z./cy..1|
+00000310 c0 60 6a 4f db 70 18 bd 80 8b 30 94 40 dd 13 39 |.`jO.p....0.@..9|
+00000320 4f db 2b 54 a4 97 f7 ef a5 a3 ff f5 14 3d e2 2d |O.+T.........=.-|
+00000330 0c 0e 71 4a bd a8 59 48 ab 06 55 53 45 2a ee 3e |..qJ..YH..USE*.>|
+00000340 65 1f 47 ee 8d e3 f6 4e 2e b1 4c d0 af 50 15 02 |e.G....N..L..P..|
+00000350 5e 84 fe 76 d5 f3 c5 fb 2a 91 44 f0 92 32 ee ea |^..v....*.D..2..|
+00000360 a0 26 77 5c 94 88 24 e3 2f 75 e3 fd b7 16 03 03 |.&w\..$./u......|
+00000370 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 0b 58 fe b5 63 ac 28 f8 34 d6 72 |.... .X..c.(.4.r|
+00000040 1a a3 ec 26 91 70 07 8d 6a 3a 3b 3a 94 5e a3 fa |...&.p..j:;:.^..|
+00000050 6e 92 3a 15 65 |n.:.e|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 20 01 fa e1 2f 29 |.......... .../)|
+00000010 ee f6 d4 e8 22 b6 e0 8f 82 37 81 83 1b 03 4d 5f |...."....7....M_|
+00000020 00 80 cb eb 9a 3a 01 c7 aa e9 9a |.....:.....|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 16 43 6a e8 f2 ca f9 4f 3c 6d ff 5e |.....Cj....O<m.^|
+00000010 f3 19 eb ee 96 1c d8 68 c5 53 86 15 03 03 00 12 |.......h.S......|
+00000020 c2 72 4e 3c 33 93 fa f3 21 32 bb fd e3 c4 ef 1a |.rN<3...!2......|
+00000030 46 df |F.|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-Ed25519 b/src/crypto/tls/testdata/Client-TLSv12-Ed25519
new file mode 100644
index 0000000..72d564f
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-Ed25519
@@ -0,0 +1,68 @@
+>>> 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 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 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 59 02 00 00 55 03 03 6c 5f 04 9e a6 |....Y...U..l_...|
+00000010 c6 41 0c ee a2 2c af 45 f0 bc de 67 2d 20 1c 9c |.A...,.E...g- ..|
+00000020 82 33 fd 86 86 b3 50 04 77 ec da 20 f3 09 fb 8c |.3....P.w.. ....|
+00000030 79 83 f9 82 58 b9 76 bb d3 58 44 3d 52 0c 37 ae |y...X.v..XD=R.7.|
+00000040 18 98 84 9a 56 af 5d 2b 68 68 c7 30 cc a9 00 00 |....V.]+hh.0....|
+00000050 0d ff 01 00 01 00 00 0b 00 04 03 00 01 02 16 03 |................|
+00000060 03 01 3c 0b 00 01 38 00 01 35 00 01 32 30 82 01 |..<...8..5..20..|
+00000070 2e 30 81 e1 a0 03 02 01 02 02 10 0f 43 1c 42 57 |.0..........C.BW|
+00000080 93 94 1d e9 87 e4 f1 ad 15 00 5d 30 05 06 03 2b |..........]0...+|
+00000090 65 70 30 12 31 10 30 0e 06 03 55 04 0a 13 07 41 |ep0.1.0...U....A|
+000000a0 63 6d 65 20 43 6f 30 1e 17 0d 31 39 30 35 31 36 |cme Co0...190516|
+000000b0 32 31 33 38 30 31 5a 17 0d 32 30 30 35 31 35 32 |213801Z..2005152|
+000000c0 31 33 38 30 31 5a 30 12 31 10 30 0e 06 03 55 04 |13801Z0.1.0...U.|
+000000d0 0a 13 07 41 63 6d 65 20 43 6f 30 2a 30 05 06 03 |...Acme Co0*0...|
+000000e0 2b 65 70 03 21 00 3f e2 15 2e e6 e3 ef 3f 4e 85 |+ep.!.?......?N.|
+000000f0 4a 75 77 a3 64 9e ed e0 bf 84 2c cc 92 26 8f fa |Juw.d.....,..&..|
+00000100 6f 34 83 aa ec 8f a3 4d 30 4b 30 0e 06 03 55 1d |o4.....M0K0...U.|
+00000110 0f 01 01 ff 04 04 03 02 05 a0 30 13 06 03 55 1d |..........0...U.|
+00000120 25 04 0c 30 0a 06 08 2b 06 01 05 05 07 03 01 30 |%..0...+.......0|
+00000130 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 16 06 |...U.......0.0..|
+00000140 03 55 1d 11 04 0f 30 0d 82 0b 65 78 61 6d 70 6c |.U....0...exampl|
+00000150 65 2e 63 6f 6d 30 05 06 03 2b 65 70 03 41 00 63 |e.com0...+ep.A.c|
+00000160 44 ed 9c c4 be 53 24 53 9f d2 10 8d 9f e8 21 08 |D....S$S......!.|
+00000170 90 95 39 e5 0d c1 55 ff 2c 16 b7 1d fc ab 7d 4d |..9...U.,.....}M|
+00000180 d4 e0 93 13 d0 a9 42 e0 b6 6b fe 5d 67 48 d7 9f |......B..k.]gH..|
+00000190 50 bc 6c cd 4b 03 83 7c f2 08 58 cd ac cf 0c 16 |P.l.K..|..X.....|
+000001a0 03 03 00 6c 0c 00 00 68 03 00 1d 20 a7 28 ef 3e |...l...h... .(.>|
+000001b0 1c 65 9f 8e 9a 80 0b 7d ac 9c ce d6 1e 97 54 30 |.e.....}......T0|
+000001c0 53 9b e6 0c 61 e0 ea 9c ae 70 f2 78 08 07 00 40 |S...a....p.x...@|
+000001d0 0c 49 38 23 a0 75 28 fb ec 71 a4 89 79 45 d1 ca |.I8#.u(..q..yE..|
+000001e0 83 6f 5d dd 01 d4 c6 63 53 5d 6e 8f 06 09 80 a1 |.o]....cS]n.....|
+000001f0 f7 ef af 2d 29 af aa 10 86 1c 18 19 3f be bb 90 |...-).......?...|
+00000200 0e c3 9d 1e 6e 60 49 7f fc c8 42 61 89 c2 e3 04 |....n`I...Ba....|
+00000210 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 b2 7f b6 1b 9c ec bf 2e ae a5 70 |.... ..........p|
+00000040 d5 33 9b 63 02 66 77 7d 00 ec 86 e4 bb d4 57 68 |.3.c.fw}......Wh|
+00000050 49 2a d3 be e7 |I*...|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 20 4c 7d ef ed ea |.......... L}...|
+00000010 ab 8d 4f 38 46 6e 8f 56 b4 1d f2 1f 2c df 57 c0 |..O8Fn.V....,.W.|
+00000020 f9 8a c2 71 f8 6d df b7 c7 1e 23 |...q.m....#|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 16 26 f1 7c ee c8 3a 61 b0 f7 5a bd |.....&.|..:a..Z.|
+00000010 b7 61 61 60 69 db cd ea 10 ee 63 15 03 03 00 12 |.aa`i.....c.....|
+00000020 22 c0 65 a4 5d 0e 48 9c 56 f8 54 17 82 5f 29 97 |".e.].H.V.T.._).|
+00000030 be 6b |.k|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-ExportKeyingMaterial b/src/crypto/tls/testdata/Client-TLSv12-ExportKeyingMaterial
new file mode 100644
index 0000000..adf1f72
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-ExportKeyingMaterial
@@ -0,0 +1,90 @@
+>>> 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 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 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 59 02 00 00 55 03 03 79 92 2e 86 bc |....Y...U..y....|
+00000010 c0 b7 56 2a 25 58 75 b3 25 ac 58 1d 8d 8e d5 87 |..V*%Xu.%.X.....|
+00000020 2d 67 8e 6e d4 d4 b6 67 b1 42 96 20 91 75 0b fa |-g.n...g.B. .u..|
+00000030 d0 6f ab 91 4a c3 15 07 1d 6c 8e e5 55 f2 26 aa |.o..J....l..U.&.|
+00000040 4d 5c 57 3b 93 a6 fc 46 c9 f6 80 1e cc a8 00 00 |M\W;...F........|
+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 ac 0c 00 00 a8 03 00 1d 20 5f 3c a6 bb 4e 32 85 |........ _<..N2.|
+000002d0 69 4b 23 df 18 9c 07 ac 0b a8 dd 9b 59 33 00 02 |iK#.........Y3..|
+000002e0 99 de 4e 66 1e 04 3b ce 4b 08 04 00 80 82 41 7c |..Nf..;.K.....A||
+000002f0 7b b8 ee d4 23 08 c3 23 8d b1 ea 27 43 e7 8e f1 |{...#..#...'C...|
+00000300 7b 87 b0 88 ab f7 b1 15 2e 45 c5 50 e7 cd 05 31 |{........E.P...1|
+00000310 bf 99 30 c8 ff 6a 23 ec 9d e5 c8 09 fa ec 50 a8 |..0..j#.......P.|
+00000320 fa b3 54 b7 c5 61 99 f6 94 12 e6 34 4a 59 e3 dd |..T..a.....4JY..|
+00000330 e5 7f f4 88 c9 2a 4c 09 65 d9 75 a6 ce 12 96 82 |.....*L.e.u.....|
+00000340 a2 36 f2 5e 93 f2 4e 1c 05 91 a7 5a 67 36 e9 3d |.6.^..N....Zg6.=|
+00000350 33 cd 6a 77 9c 8d 14 95 80 41 61 bd 80 ed 7b 51 |3.jw.....Aa...{Q|
+00000360 cf 76 87 4d ac dc 5f c1 5d 52 a7 f9 51 16 03 03 |.v.M.._.]R..Q...|
+00000370 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 bc c3 7c c2 cc a4 4e 8f d0 79 7a |.... ..|...N..yz|
+00000040 a4 7d 4c 3d 17 8c 19 93 4f 49 03 50 f6 71 4d 16 |.}L=....OI.P.qM.|
+00000050 97 bb 18 88 67 |....g|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 20 00 c4 8a f9 1e |.......... .....|
+00000010 c0 66 ab ef 39 ae 41 7a 05 9c e3 06 e4 4d 00 bb |.f..9.Az.....M..|
+00000020 d4 ef 21 71 a3 54 23 fe db 4a 86 |..!q.T#..J.|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 16 0c d3 9a f5 1d f4 5f b2 45 c7 7c |..........._.E.||
+00000010 38 59 6e df 6e 59 d5 94 8b a9 bb 15 03 03 00 12 |8Yn.nY..........|
+00000020 9e 74 a5 0e c1 7f 33 52 be 17 f6 f5 4d 9f 3d d1 |.t....3R....M.=.|
+00000030 b5 65 |.e|
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..3331435
--- /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 15 01 00 01 11 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 96 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 12 |................|
+000000c0 00 00 00 2b 00 09 08 03 04 03 03 03 02 03 01 00 |...+............|
+000000d0 33 00 47 00 45 00 17 00 41 04 1e 18 37 ef 0d 19 |3.G.E...A...7...|
+000000e0 51 88 35 75 71 b5 e5 54 5b 12 2e 8f 09 67 fd a7 |Q.5uq..T[....g..|
+000000f0 24 20 3e b2 56 1c ce 97 28 5e f8 2b 2d 4f 9e f1 |$ >.V...(^.+-O..|
+00000100 07 9f 6c 4b 5b 83 56 e2 32 42 e9 58 b6 d7 49 a6 |..lK[.V.2B.X..I.|
+00000110 b5 68 1a 41 03 56 6b dc 5a 89 |.h.A.Vk.Z.|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 59 02 00 00 55 03 03 0b f0 3e a1 66 |....Y...U....>.f|
+00000010 13 35 53 83 59 3c 9e 2a 0f 0b b0 9a 42 de e4 f1 |.5S.Y<.*....B...|
+00000020 8a 2d 34 ef 15 fe 28 55 42 d8 bf 20 aa 27 5c 5f |.-4...(UB.. .'\_|
+00000030 24 59 17 ef 43 f3 18 f8 40 97 8f 1a 6a f4 e4 4a |$Y..C...@...j..J|
+00000040 a3 b7 11 39 01 bd 98 8c 61 08 d9 50 c0 2f 00 00 |...9....a..P./..|
+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 79 6a df 70 26 49 |........A.yj.p&I|
+000002d0 c0 5a 39 fc 7c 80 d1 2c cd 76 d0 4c 6f a7 7d bc |.Z9.|..,.v.Lo.}.|
+000002e0 32 c6 54 c6 76 58 e2 0f 3f 33 ad 92 61 33 11 16 |2.T.vX..?3..a3..|
+000002f0 d7 42 a8 ba 2a 8f 22 2a eb 88 3e 74 78 2a 67 de |.B..*."*..>tx*g.|
+00000300 39 75 63 2c 1d 2e da 33 77 a5 08 04 00 80 61 f5 |9uc,...3w.....a.|
+00000310 ed 56 5b f1 dd 78 a0 c4 8a 9b ac 28 c5 91 0c bd |.V[..x.....(....|
+00000320 f1 d5 c1 f6 31 2e 8c c3 d5 84 3a 15 e8 6d f1 bc |....1.....:..m..|
+00000330 9e a6 04 fd 95 2f 51 60 2f c6 ff 99 cf 38 24 bf |...../Q`/....8$.|
+00000340 a4 32 a2 1f a1 6b bd 27 98 00 14 23 0d 12 66 67 |.2...k.'...#..fg|
+00000350 48 33 92 51 e7 e7 3c f5 ef 13 ca 46 3c 39 53 70 |H3.Q..<....F<9Sp|
+00000360 41 78 4a 02 70 87 48 ce b0 31 02 33 0b 06 78 b9 |AxJ.p.H..1.3..x.|
+00000370 87 0b 07 e0 f7 15 c8 3e 27 a1 a3 20 24 9e 20 93 |.......>'.. $. .|
+00000380 7f b5 53 7b 18 88 96 87 2b df 02 ba 0c d8 16 03 |..S{....+.......|
+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 c1 90 |.....(..........|
+00000060 a0 8b 53 87 a8 e3 56 4c 5c ad 5f dc 00 af 29 5f |..S...VL\._...)_|
+00000070 11 53 7d 49 25 f8 74 16 dc 84 5f 3b c6 24 |.S}I%.t..._;.$|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 28 00 f9 b2 51 85 |..........(...Q.|
+00000010 72 7e ec 79 72 59 90 ae 69 51 79 61 10 3b 4e 4b |r~.yrY..iQya.;NK|
+00000020 45 d6 a5 9a c0 1a 69 c9 9f 1c ee cd ad 6a e8 ea |E.....i......j..|
+00000030 c4 9e f1 |...|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 86 5a 45 |..............ZE|
+00000010 24 60 90 dc bc b3 f6 61 6f db 60 02 99 f9 e2 93 |$`.....ao.`.....|
+00000020 07 85 0d 15 03 03 00 1a 00 00 00 00 00 00 00 02 |................|
+00000030 36 86 b0 60 b5 5d dd 28 64 c6 5b c7 ed 01 07 b1 |6..`.].(d.[.....|
+00000040 12 39 |.9|
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..12fb594
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-RSA-RC4
@@ -0,0 +1,84 @@
+>>> 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 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 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 51 02 00 00 4d 03 03 b0 e7 ee 09 45 |....Q...M......E|
+00000010 36 f1 7a 92 be 9e d8 9d ae cd c1 4e b2 12 94 3e |6.z........N...>|
+00000020 6c 34 71 ed 5f e0 97 7f 25 e4 dd 20 f4 43 01 03 |l4q._...%.. .C..|
+00000030 88 33 26 7f 48 c1 f2 d1 4d d3 f8 1a bd 86 4c 50 |.3&.H...M.....LP|
+00000040 18 89 dc 08 99 f1 51 c5 84 be b9 fd 00 05 00 00 |......Q.........|
+00000050 05 ff 01 00 01 00 16 03 03 02 59 0b 00 02 55 00 |..........Y...U.|
+00000060 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......|
+00000070 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..|
+00000080 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.|
+00000090 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..|
+000000a0 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..|
+000000b0 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..|
+000000c0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1|
+000000d0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.|
+000000e0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...|
+000000f0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0|
+00000100 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.|
+00000110 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6|
+00000120 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.|
+00000130 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....|
+00000140 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......|
+00000150 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$|
+00000160 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..|
+00000170 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u|
+00000180 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.|
+00000190 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........|
+000001a0 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.|
+000001b0 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......|
+000001c0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.|
+000001d0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>|
+000001e0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#|
+000001f0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..|
+00000200 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0|
+00000210 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan|
+00000220 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........|
+00000230 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...|
+00000240 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1|
+00000250 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d|
+00000260 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..|
+00000270 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....|
+00000280 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......|
+00000290 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..|
+000002a0 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.|
+000002b0 3b e9 fa e7 16 03 03 00 04 0e 00 00 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 08 65 01 80 0d 59 b8 ac 0f 09 |.....$.e...Y....|
+000000a0 bf 61 31 32 e0 74 e9 f4 72 e3 2c 79 11 4d b2 a2 |.a12.t..r.,y.M..|
+000000b0 55 65 94 c8 cd 0a 61 99 07 b8 |Ue....a...|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 24 04 20 46 cd fb |..........$. F..|
+00000010 6c 46 9c 47 21 03 fe 9b a4 c6 da 2c 71 2f db 92 |lF.G!......,q/..|
+00000020 40 da 7d 46 2e e4 9c 81 86 89 7f 53 46 91 28 |@.}F.......SF.(|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 1a 89 2b 2e 49 21 19 b7 d0 df 85 da |......+.I!......|
+00000010 b8 a7 f3 73 5f fe 44 e5 0c a1 af 16 74 93 bc 15 |...s_.D.....t...|
+00000020 03 03 00 16 5f 9e 64 d0 91 50 34 44 cf f6 1f e0 |...._.d..P4D....|
+00000030 e0 13 b9 67 da 5c 99 16 f1 b3 |...g.\....|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-RenegotiateOnce b/src/crypto/tls/testdata/Client-TLSv12-RenegotiateOnce
new file mode 100644
index 0000000..06752de
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-RenegotiateOnce
@@ -0,0 +1,244 @@
+>>> 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 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 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 59 02 00 00 55 03 03 5b 4b bb c4 39 |....Y...U..[K..9|
+00000010 fb 45 5c 54 03 30 0f 71 c3 2e 48 25 33 fd 6d 40 |.E\T.0.q..H%3.m@|
+00000020 18 6e 75 43 66 9e 08 fb 6a a1 f8 20 34 3c c4 2a |.nuCf...j.. 4<.*|
+00000030 b5 9b 65 b0 cd b9 fc ce cf 51 f8 cc a1 5d 00 ed |..e......Q...]..|
+00000040 49 5b 43 9a ff c4 cf 6b d8 2a ea e5 cc a8 00 00 |I[C....k.*......|
+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 ac 0c 00 00 a8 03 00 1d 20 76 c4 f4 ec a2 d6 c1 |........ v......|
+000002d0 b1 d8 b0 41 71 8a ee e9 8a 17 06 90 6b 0c 05 66 |...Aq.......k..f|
+000002e0 54 d8 a6 ad 50 95 11 f0 03 08 04 00 80 46 0b da |T...P........F..|
+000002f0 0b 0c 6c 1a 2e a2 7e 28 40 1b 40 9a b4 5c 36 88 |..l...~(@.@..\6.|
+00000300 c1 ad cd 45 be 23 17 a6 98 e5 11 fe a8 78 c6 21 |...E.#.......x.!|
+00000310 17 a6 a8 7d ce 28 c4 ef 51 76 f8 b1 b1 75 31 04 |...}.(..Qv...u1.|
+00000320 b9 14 bc 3b bf 59 50 b8 e1 ad c6 86 45 3c e1 70 |...;.YP.....E<.p|
+00000330 fb cd 69 8c 0a 5f f6 2d bd 10 95 30 ed 4c 9a 47 |..i.._.-...0.L.G|
+00000340 73 8b 39 72 00 0a 7e 8f a9 42 27 01 6f 3d 37 f9 |s.9r..~..B'.o=7.|
+00000350 7d d4 1b a2 6a 07 37 dc 5e 6c 8b b1 d5 75 3a 9b |}...j.7.^l...u:.|
+00000360 d1 45 c5 d8 e0 90 f0 62 3d d5 01 00 9e 16 03 03 |.E.....b=.......|
+00000370 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 bb f4 78 64 23 f7 31 50 42 3d 97 |.... ..xd#.1PB=.|
+00000040 8f 73 89 b9 90 8f 74 b6 e4 7d 58 27 65 25 59 8a |.s....t..}X'e%Y.|
+00000050 5a 8d 8f fa bd |Z....|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 20 0a 43 74 53 47 |.......... .CtSG|
+00000010 41 4b 0a f1 f7 75 51 a9 22 c9 e0 5c 53 90 6b d7 |AK...uQ."..\S.k.|
+00000020 97 18 c6 ef c3 85 32 f5 7c 26 97 |......2.|&.|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 16 8e 83 1a 32 53 02 1c fa 84 89 4f |........2S.....O|
+00000010 25 fb 5f 85 4f bd ee ae 9f 0f ea |%._.O......|
+>>> Flow 6 (server to client)
+00000000 16 03 03 00 14 96 76 32 c4 6d e6 23 bf 21 a8 09 |......v2.m.#.!..|
+00000010 a3 8b 69 98 cd c3 c9 ce 73 |..i.....s|
+>>> Flow 7 (client to server)
+00000000 16 03 03 01 16 72 5b d9 30 b2 b0 91 e2 3d 2b 12 |.....r[.0....=+.|
+00000010 2c c9 43 f1 67 ae 54 ee ce a1 15 12 12 9a 27 46 |,.C.g.T.......'F|
+00000020 7e 47 90 d4 f2 7d b9 98 ec f8 61 b8 84 52 9f 21 |~G...}....a..R.!|
+00000030 c1 83 6a ce 1a 68 fc 5b 25 42 f3 8f 55 ee 92 45 |..j..h.[%B..U..E|
+00000040 af a4 d1 c4 a6 b5 0e 58 3d 70 76 98 ec 47 af 6f |.......X=pv..G.o|
+00000050 e3 4f 9f ef 52 a3 aa 33 75 83 f6 57 33 a8 dc f5 |.O..R..3u..W3...|
+00000060 36 49 09 1c 72 31 c1 43 52 64 4a b5 ca ce 06 f5 |6I..r1.CRdJ.....|
+00000070 91 18 90 85 f0 c9 96 4f bf 4c de 9e 50 a2 1c de |.......O.L..P...|
+00000080 86 51 1f 0b 73 e1 df 1d 2d 90 6d 7f a2 f1 28 e8 |.Q..s...-.m...(.|
+00000090 5f 2a 78 2d 8e ab f2 05 19 85 4e 92 a8 cf cd 16 |_*x-......N.....|
+000000a0 1e df 1d 51 ee 8b ba 72 cd ac d2 01 4b 84 46 62 |...Q...r....K.Fb|
+000000b0 1c 28 4d 3f 44 c1 62 12 13 4f f8 73 f4 da c0 98 |.(M?D.b..O.s....|
+000000c0 14 da 31 6a 48 0d 1d bb 24 6c ef 0f 98 c0 3c 86 |..1jH...$l....<.|
+000000d0 c6 d6 8e ab bd 20 bd 06 e9 ba aa ce 3a 88 25 95 |..... ......:.%.|
+000000e0 54 15 fb c6 49 c7 98 ff 27 92 c0 60 6a 3c f8 26 |T...I...'..`j<.&|
+000000f0 fd 28 ac c4 8f 5c 4f 15 24 10 45 3c 07 3d 3f 50 |.(...\O.$.E<.=?P|
+00000100 e5 db cf 78 bd b0 d2 24 a2 4b 3e a6 9c 2d 3b 0d |...x...$.K>..-;.|
+00000110 d8 1b 86 88 dc 0c 3c 9c 16 cf ea |......<....|
+>>> Flow 8 (server to client)
+00000000 16 03 03 00 81 2e c9 cd ad df 75 cf b6 8d 7f 8c |..........u.....|
+00000010 c6 bb 5b e6 2b 40 a0 36 45 13 ae 93 f1 04 bf f3 |..[.+@.6E.......|
+00000020 62 bd c8 62 d9 cf 05 a3 4c e9 37 af 35 a6 83 8e |b..b....L.7.5...|
+00000030 71 46 b8 2a 5b 02 3b 81 d5 15 b8 17 72 c4 1e 00 |qF.*[.;.....r...|
+00000040 78 d9 4a 04 a7 b3 5b 80 bd 1f 88 ba fa 22 b5 0e |x.J...[......"..|
+00000050 ca 44 55 27 c0 67 ce 37 4c 9a 9a d7 77 da 58 35 |.DU'.g.7L...w.X5|
+00000060 83 b3 39 90 8d e2 7f 08 2e cc 5a 8e 5e a8 c3 bb |..9.......Z.^...|
+00000070 db e5 a2 56 56 04 37 13 f3 b1 71 2d ea 0a 56 00 |...VV.7...q-..V.|
+00000080 6e 8d 8b 20 79 30 16 03 03 02 69 76 4b a4 c6 5e |n.. y0....ivK..^|
+00000090 0a a2 3c 89 24 f6 93 94 25 4e 0b 8a d2 33 2f 03 |..<.$...%N...3/.|
+000000a0 ab 20 22 33 ad 84 6d aa 31 6b 5a 10 0e 42 1b dd |. "3..m.1kZ..B..|
+000000b0 35 9b a0 dc 31 f8 65 91 c4 14 78 2e 74 2e 1d 46 |5...1.e...x.t..F|
+000000c0 3a 66 41 f0 a3 9a 4e ae bc 9b 55 f9 d1 9c c5 6e |:fA...N...U....n|
+000000d0 38 24 19 15 fb e6 c3 85 de ef f0 97 a2 a1 db ed |8$..............|
+000000e0 b8 d0 05 ae 93 77 d7 45 50 a5 4e 8a 83 84 07 fb |.....w.EP.N.....|
+000000f0 3a 80 c6 69 3c 6e b2 e3 e0 97 f7 03 93 76 dd 32 |:..i<n.......v.2|
+00000100 0c 5d a2 e6 1f 82 90 8b dd 93 06 ef eb b7 e0 74 |.].............t|
+00000110 1a 7d 8f 37 c2 c1 41 9c 30 74 ca 37 17 5e 71 a0 |.}.7..A.0t.7.^q.|
+00000120 cb d6 00 47 9d 14 93 aa fe 57 56 10 ae 88 13 65 |...G.....WV....e|
+00000130 f4 6c 20 4e f9 14 87 73 36 5e d5 20 93 34 db 87 |.l N...s6^. .4..|
+00000140 e7 f8 84 6e 36 9d 60 20 b5 8f 47 33 84 94 22 e1 |...n6.` ..G3..".|
+00000150 5d c6 1c 35 39 61 71 47 90 a9 b4 c6 5e 31 58 d1 |]..59aqG....^1X.|
+00000160 40 d8 22 22 23 c2 53 e3 75 1f 98 1c cc 7f 2d 11 |@.""#.S.u.....-.|
+00000170 31 5e 49 a1 2c d9 c8 db 6e 4e 9d da 57 e1 c9 32 |1^I.,...nN..W..2|
+00000180 03 6c f0 9b df c2 03 d5 b7 e2 04 77 e8 87 bc 14 |.l.........w....|
+00000190 73 66 b0 fb d1 d6 26 0c 36 90 2c 20 43 16 c6 68 |sf....&.6., C..h|
+000001a0 6c c0 ee be 2c da 6f 4f 95 1e cf a0 31 e8 40 48 |l...,.oO....1.@H|
+000001b0 88 61 26 7b 53 5b 42 14 2a 89 a3 1e 03 01 16 9d |.a&{S[B.*.......|
+000001c0 41 6d de 60 75 1d 36 12 cd 16 8b 1c 93 da 17 79 |Am.`u.6........y|
+000001d0 4b d2 1d 78 64 da 6c cc 5c 7c e3 f9 4d 70 a2 07 |K..xd.l.\|..Mp..|
+000001e0 b4 24 33 de 19 bc d2 1a 43 42 f4 26 8b c0 81 e4 |.$3.....CB.&....|
+000001f0 a3 32 97 09 ec 6f 39 d7 ca c9 c5 ee 38 fd 91 dd |.2...o9.....8...|
+00000200 c4 dc 3c 53 38 60 c7 b6 60 c6 a9 ff ae 81 e9 8c |..<S8`..`.......|
+00000210 ea 49 19 3f fe 0e 8e b8 e6 7c ec 4b 63 66 d8 7a |.I.?.....|.Kcf.z|
+00000220 82 51 7f 24 51 ae ad 91 5d 0e 2c aa ee fa 9f d3 |.Q.$Q...].,.....|
+00000230 22 1a 8b 8d 12 48 bb 3a 7c ea f0 09 af 1a 7e 7e |"....H.:|.....~~|
+00000240 47 74 b9 b9 1f 97 8e 64 62 52 ae 08 d5 f1 13 cb |Gt.....dbR......|
+00000250 51 64 b0 6a 33 1f 48 78 c1 91 91 91 a7 75 29 cb |Qd.j3.Hx.....u).|
+00000260 32 60 96 d4 27 3f a4 8f 12 e9 5d 79 4d fd f9 19 |2`..'?....]yM...|
+00000270 b8 f7 39 d8 53 e5 45 96 0f c6 4f f2 27 c6 e6 07 |..9.S.E...O.'...|
+00000280 40 47 29 94 b9 6a 38 9e 24 bf 9e 92 f6 67 3f e3 |@G)..j8.$....g?.|
+00000290 48 0f 3b 3a d7 7b 14 4e 34 a3 8a 25 b4 a2 d6 15 |H.;:.{.N4..%....|
+000002a0 3f 38 9e ba fa 7e 33 fd a4 4c ed e7 58 93 65 7d |?8...~3..L..X.e}|
+000002b0 90 48 fc 70 7e 10 a5 d0 0a ec 96 c4 cf 26 ae 94 |.H.p~........&..|
+000002c0 d7 3f 92 40 2f ad ed c8 bb 69 b1 3e 0b ab 4f 4e |.?.@/....i.>..ON|
+000002d0 73 91 a6 05 2b a7 89 e8 63 28 39 51 53 8d 2c 5e |s...+...c(9QS.,^|
+000002e0 c8 64 90 c3 b7 2d ee 00 aa 7f 38 ca 57 ab b8 aa |.d...-....8.W...|
+000002f0 93 12 af c5 16 03 03 00 bc 0e 58 31 64 e6 68 e6 |..........X1d.h.|
+00000300 10 81 2f 79 e3 49 3a d9 cc 70 09 7e b6 b5 61 c4 |../y.I:..p.~..a.|
+00000310 92 16 22 d0 e5 af b8 b8 91 2e 72 7c cf 95 cb ef |..".......r|....|
+00000320 14 81 73 33 34 98 65 1b 69 db 2c 9d eb 1c ce be |..s34.e.i.,.....|
+00000330 1f ce 48 b4 22 8d f0 6e 48 21 8e aa af 83 43 d2 |..H."..nH!....C.|
+00000340 65 54 0f 57 6b ce b1 24 ef 09 bf 7f 23 92 35 07 |eT.Wk..$....#.5.|
+00000350 55 2f 2f e7 b7 d7 72 d2 7c 5f 71 d6 20 9a 68 e8 |U//...r.|_q. .h.|
+00000360 1b 90 0b 13 f7 37 e2 35 0d fc 04 ea 32 50 2d 04 |.....7.5....2P-.|
+00000370 72 1a db d9 71 e1 4e d1 76 7c c3 f5 22 97 92 c5 |r...q.N.v|.."...|
+00000380 61 19 e0 40 b1 14 de 37 9d 8e e7 fd fe 2b 28 97 |a..@...7.....+(.|
+00000390 91 77 8f a7 d4 b1 db bc a2 78 65 5c a8 8d 41 21 |.w.......xe\..A!|
+000003a0 0e 56 6b ac 0b da a9 dd b1 51 84 19 20 ab e5 eb |.Vk......Q.. ...|
+000003b0 f2 52 8d 48 a2 16 03 03 00 4a 69 44 32 65 c2 09 |.R.H.....JiD2e..|
+000003c0 9c c1 d6 66 06 29 c3 a6 c3 10 2e d9 9e d6 0a d3 |...f.)..........|
+000003d0 06 a3 d2 d2 67 52 bd 19 26 a8 ef 08 ed 9f 2b e8 |....gR..&.....+.|
+000003e0 96 ea 08 b7 46 a2 36 e3 c1 84 4b c2 a2 b5 34 9c |....F.6...K...4.|
+000003f0 83 ea 94 51 e6 ca 9c 0b e1 e3 86 13 b7 1b 1f 4e |...Q...........N|
+00000400 ee a1 10 70 16 03 03 00 14 5a 1c c1 14 fd d9 ff |...p.....Z......|
+00000410 e3 46 ac 89 3b b3 e1 8e 6b 90 41 44 1f |.F..;...k.AD.|
+>>> Flow 9 (client to server)
+00000000 16 03 03 02 69 c8 db 54 92 d3 ea 2f 24 47 f9 24 |....i..T.../$G.$|
+00000010 53 c1 d4 6a e8 dd 1d 71 d6 fb 2c 7e 3a 41 75 f6 |S..j...q..,~:Au.|
+00000020 0c 08 70 b6 f9 0a 12 4b 0d 3d 34 03 a9 36 9e f1 |..p....K.=4..6..|
+00000030 c7 93 dc 51 e4 15 3d fd a7 67 28 24 32 fe ff d3 |...Q..=..g($2...|
+00000040 cd 69 d6 4a 5d 11 78 3b aa 07 8d 1e c4 97 22 34 |.i.J].x;......"4|
+00000050 df 03 f2 37 fd 4f 76 c3 04 a6 a6 0f 35 1c 0f 13 |...7.Ov.....5...|
+00000060 7e 0a b9 5e 47 d2 9a 8c d8 a3 f4 7a e4 92 5f 12 |~..^G......z.._.|
+00000070 a6 20 fb 51 16 af eb 55 d0 23 4e b5 f9 e8 cc 33 |. .Q...U.#N....3|
+00000080 bd d1 52 27 21 96 06 05 67 fa 68 0e ab 2c 84 05 |..R'!...g.h..,..|
+00000090 c9 97 6a db 69 57 a8 5c 55 a9 e1 cf 33 01 28 9a |..j.iW.\U...3.(.|
+000000a0 76 09 64 a4 a3 31 36 13 72 27 0c 85 e9 59 47 27 |v.d..16.r'...YG'|
+000000b0 89 07 ee e2 e0 68 a6 f0 fa d5 c3 8b 2f 75 68 d0 |.....h....../uh.|
+000000c0 8e d8 fe ae 1d 0d af 0b 40 3d 9f ec 85 03 24 20 |........@=....$ |
+000000d0 c5 11 30 aa 25 ee 2c 86 42 ae 4f 0d 6b 18 70 1d |..0.%.,.B.O.k.p.|
+000000e0 5f ae 1e cf 99 a7 0e c8 9b b3 63 58 cd b6 7d be |_.........cX..}.|
+000000f0 01 43 96 37 87 45 5f 2f aa 9c 12 48 ef 3b c8 d9 |.C.7.E_/...H.;..|
+00000100 60 20 26 69 68 56 48 aa 64 59 9e 41 ed 7e 8d c3 |` &ihVH.dY.A.~..|
+00000110 0f cd 0e 19 7a 76 89 95 f8 20 68 cd f9 81 e9 a0 |....zv... h.....|
+00000120 21 ff 60 e5 0f 6d dd 73 d2 19 1e 2a 76 f7 9a 46 |!.`..m.s...*v..F|
+00000130 5d d5 6b b2 19 28 c2 ac 9c e0 35 c8 d2 2a 53 fa |].k..(....5..*S.|
+00000140 3e 58 9e f2 05 7e 6b ce 51 6d 3d 2a ce 2e 9b 59 |>X...~k.Qm=*...Y|
+00000150 aa d4 8d cc ad 1f 82 e7 ca 5a ef a6 87 d5 41 0b |.........Z....A.|
+00000160 8d 27 6d 09 4d 40 c3 26 a3 a9 91 dd 1b 37 5d ff |.'m.M@.&.....7].|
+00000170 8f c3 c7 b1 bf be f5 d1 19 4d 93 86 a7 5f 5e 8f |.........M..._^.|
+00000180 14 34 82 50 76 25 42 04 b8 4b d3 da 15 ee 60 d1 |.4.Pv%B..K....`.|
+00000190 35 56 4c 63 0d ba 64 13 4f 3d 12 87 84 5a 45 41 |5VLc..d.O=...ZEA|
+000001a0 14 b6 6f 91 c4 b9 4f 97 c1 10 d6 3e b3 99 21 18 |..o...O....>..!.|
+000001b0 c3 91 82 e4 b6 91 3e bb 01 89 9a f0 60 ac 8e 7d |......>.....`..}|
+000001c0 cf c2 f9 b4 4f da 40 e3 5e 83 a1 8f b4 fa 28 aa |....O.@.^.....(.|
+000001d0 c9 ae 7b 8f 7d c9 d1 f8 7b b2 b5 3f 0a 9b 00 9e |..{.}...{..?....|
+000001e0 1d fa 59 ff 39 b7 85 4d 2a b9 b8 67 03 df a0 f9 |..Y.9..M*..g....|
+000001f0 f1 7e 9d 27 1c 55 a9 76 44 9e f1 13 78 7d 34 4d |.~.'.U.vD...x}4M|
+00000200 c9 23 07 e6 db 93 d7 70 3c 1b 5d 89 ed 8d 3d 43 |.#.....p<.]...=C|
+00000210 2e 89 f6 14 83 ff 87 db 26 a5 9a cd 98 5d 32 24 |........&....]2$|
+00000220 70 d2 e0 72 a7 6f a4 b4 2b 37 db 7e 39 4f d7 37 |p..r.o..+7.~9O.7|
+00000230 ea 68 b5 98 33 0e 23 21 3f 43 b3 ff 18 8e df 85 |.h..3.#!?C......|
+00000240 ba 15 48 3a fe 09 9b b6 27 40 d4 60 a8 3e 55 a3 |..H:....'@.`.>U.|
+00000250 75 c9 32 38 b5 21 46 ab 41 99 24 e6 09 3f 64 e6 |u.28.!F.A.$..?d.|
+00000260 09 40 cb 93 25 ab 1a 90 c7 d5 a6 40 36 a0 16 03 |.@..%......@6...|
+00000270 03 00 35 0f c7 e4 c3 16 c0 4f 7f 25 04 06 63 e7 |..5......O.%..c.|
+00000280 79 79 f9 4f c9 66 ca cd ba e3 af 4a 50 a3 3d c3 |yy.O.f.....JP.=.|
+00000290 79 0c 71 d9 2f df 93 79 30 8f 6b 0f 54 f9 be 07 |y.q./..y0.k.T...|
+000002a0 f3 d6 9b c0 2a 3a 0a a1 16 03 03 00 98 b8 f1 fc |....*:..........|
+000002b0 87 62 e9 6b 40 fd 50 ac b7 fa 52 69 51 66 ae 9b |.b.k@.P...RiQf..|
+000002c0 05 7e f2 38 73 27 d8 0c 2a 53 37 30 62 76 5d e9 |.~.8s'..*S70bv].|
+000002d0 fd 95 c6 14 d2 9d 34 13 e9 4c a5 7c c0 b6 e0 c4 |......4..L.|....|
+000002e0 97 ef 01 c0 f9 38 39 ee 17 c0 20 01 76 4f a7 10 |.....89... .vO..|
+000002f0 b0 45 9d c7 c3 cd a9 47 14 4a ed 00 1f 06 70 5b |.E.....G.J....p[|
+00000300 f5 04 8b 77 ad af 1e 77 7a 9d cc fc a4 1f d2 8d |...w...wz.......|
+00000310 8f e3 31 d3 3c de e6 85 f3 3d c0 ae 78 f7 22 c6 |..1.<....=..x.".|
+00000320 ec 2e a2 f0 5f ed 95 33 54 8c 89 35 c9 e4 25 4b |...._..3T..5..%K|
+00000330 84 5e 31 83 04 d0 f1 67 69 73 8b 7f 24 ae e0 87 |.^1....gis..$...|
+00000340 6b f7 ba f0 23 14 03 03 00 11 7a c7 6a 32 2b 9b |k...#.....z.j2+.|
+00000350 25 c2 d2 ee 37 b2 8d 7b f2 90 6d 16 03 03 00 20 |%...7..{..m.... |
+00000360 c1 1c 9d 18 a9 41 92 fc 05 19 93 7c 7e 2f b2 39 |.....A.....|~/.9|
+00000370 8c 76 4b 29 5a 67 cc f5 55 9f c0 e3 8f ad ee 3c |.vK)Zg..U......<|
+>>> Flow 10 (server to client)
+00000000 14 03 03 00 11 49 66 13 ec 09 83 0d 47 82 45 61 |.....If.....G.Ea|
+00000010 06 14 cc f5 da 41 16 03 03 00 20 34 d4 0c bd 86 |.....A.... 4....|
+00000020 6d ef a9 b6 97 68 e6 88 84 ed 1c 9d a1 8d 2b c9 |m....h........+.|
+00000030 2f 45 75 5b e5 6a 08 72 71 a9 c6 17 03 03 00 19 |/Eu[.j.rq.......|
+00000040 e8 83 4c f5 19 ea d1 ef e3 27 25 f9 af d2 f0 a6 |..L......'%.....|
+00000050 b3 62 15 66 ec 72 ce 4e e2 |.b.f.r.N.|
+>>> Flow 11 (client to server)
+00000000 15 03 03 00 12 2e 39 ba ca ad 7c a9 ae 3f 6a 78 |......9...|..?jx|
+00000010 b6 31 d2 d0 4e 1f dc |.1..N..|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwice b/src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwice
new file mode 100644
index 0000000..20aa6c9
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwice
@@ -0,0 +1,343 @@
+>>> 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 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 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 59 02 00 00 55 03 03 68 39 1d 0e 5a |....Y...U..h9..Z|
+00000010 22 ba 13 5f b6 c1 52 5d 13 e5 07 18 aa ec 24 0f |".._..R]......$.|
+00000020 c9 56 3a 83 a1 32 a1 7f 02 e8 7b 20 31 e2 f8 c4 |.V:..2....{ 1...|
+00000030 5b c2 57 9a 1d a4 6f a7 9c 1c 93 b1 9f 19 c3 cb |[.W...o.........|
+00000040 e1 73 87 1b a8 88 d9 4c 67 2f 44 aa cc a8 00 00 |.s.....Lg/D.....|
+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 ac 0c 00 00 a8 03 00 1d 20 57 22 18 98 ed 7f 12 |........ W".....|
+000002d0 e7 e3 83 6b 42 82 ff 49 54 f8 0b 7d 93 3d 11 42 |...kB..IT..}.=.B|
+000002e0 67 cf 89 47 77 31 c5 59 4a 08 04 00 80 69 d4 13 |g..Gw1.YJ....i..|
+000002f0 f8 1c 68 9d 40 10 c8 aa e6 44 0e 14 b9 38 6e ca |..h.@....D...8n.|
+00000300 a9 50 05 4a ce a0 03 ea 02 92 e4 5a ed 42 6f 70 |.P.J.......Z.Bop|
+00000310 e1 c1 99 49 a4 34 20 6b 5e 14 e8 a1 d3 27 ff 0d |...I.4 k^....'..|
+00000320 0c d7 47 49 1e 8f 8a 3a 62 1d c9 81 3c 5f a3 16 |..GI...:b...<_..|
+00000330 16 34 a0 53 a7 01 1d 09 f7 d9 d4 62 b2 0a 1c 1f |.4.S.......b....|
+00000340 b2 e5 24 1b 7e 78 35 43 ed 47 f8 62 53 2d 04 ec |..$.~x5C.G.bS-..|
+00000350 81 b5 68 11 3a 2d ee 88 ef 86 eb 71 d0 5e 31 42 |..h.:-.....q.^1B|
+00000360 57 6d b6 f2 be 32 4c 38 f8 2a 93 2f db 16 03 03 |Wm...2L8.*./....|
+00000370 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 2a 03 0a 58 36 31 ec 26 df e5 7c |.... *..X61.&..||
+00000040 88 b5 d1 f7 6d fc 4b 0a 91 54 4a e7 8c 83 a3 54 |....m.K..TJ....T|
+00000050 0a 10 5b ff 69 |..[.i|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 20 27 b0 69 0c 67 |.......... '.i.g|
+00000010 c7 3a ec c1 aa 02 20 cf f9 e8 22 86 3b d3 e1 4f |.:.... ...".;..O|
+00000020 bc fd 04 40 19 77 bf bd 38 28 56 |...@.w..8(V|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 16 8a 2c 24 1b b8 53 01 54 c8 bd f3 |......,$..S.T...|
+00000010 e1 ec a9 ab 83 a0 66 a9 29 1c 4e |......f.).N|
+>>> Flow 6 (server to client)
+00000000 16 03 03 00 14 c5 e3 03 06 89 d8 47 1a 66 18 0e |...........G.f..|
+00000010 8d 36 c5 f4 30 80 7e 72 a2 |.6..0.~r.|
+>>> Flow 7 (client to server)
+00000000 16 03 03 01 16 7e eb a3 b5 ea 58 e3 4a 26 35 7d |.....~....X.J&5}|
+00000010 54 15 93 74 e8 e4 63 34 38 d9 e0 02 3d 28 f8 98 |T..t..c48...=(..|
+00000020 0f 24 6b ca 08 7f b6 77 68 ec 85 c3 4a 6b 69 c3 |.$k....wh...Jki.|
+00000030 8d 8e 1b 8b 41 11 9b 0d d1 c8 99 2b c9 d2 4c f1 |....A......+..L.|
+00000040 fd 82 e5 35 ba a3 3b f3 6d 47 82 45 08 e7 02 bb |...5..;.mG.E....|
+00000050 10 a6 7b 76 83 78 e0 aa 5a 78 24 59 1c db ae a3 |..{v.x..Zx$Y....|
+00000060 37 20 b3 12 98 48 68 d3 b3 72 9f 4f d4 de 50 b4 |7 ...Hh..r.O..P.|
+00000070 4a c1 37 93 e0 55 ae e8 37 2a 40 de ac 30 e1 1d |J.7..U..7*@..0..|
+00000080 f0 03 19 8c af 77 f5 26 98 af a8 a8 d2 72 6c 68 |.....w.&.....rlh|
+00000090 75 00 32 10 e6 3f 91 a8 24 a7 d8 05 23 04 52 23 |u.2..?..$...#.R#|
+000000a0 e7 e6 83 ac 37 1b 36 a7 ca d4 7e d5 21 4c ab 38 |....7.6...~.!L.8|
+000000b0 23 cb 7c a9 f4 66 26 5e 7f 3e d6 ab 7a ac 34 38 |#.|..f&^.>..z.48|
+000000c0 95 16 df e2 e4 cf 3a 62 82 78 cb 71 32 06 6d 07 |......:b.x.q2.m.|
+000000d0 84 91 0c e9 d0 63 88 9e d1 b5 f0 fb 43 2b 07 0b |.....c......C+..|
+000000e0 32 d7 20 af b8 76 17 da ee cc e6 03 bb 7a 0b f2 |2. ..v.......z..|
+000000f0 61 4f db 7f a3 66 b0 05 a8 88 b8 0b b3 6e 9c df |aO...f.......n..|
+00000100 48 8b 7e eb 42 cd ea eb 1d bb 63 a0 e4 ee df 21 |H.~.B.....c....!|
+00000110 20 67 11 26 dd f1 47 1b 15 2b a0 | g.&..G..+.|
+>>> Flow 8 (server to client)
+00000000 16 03 03 00 81 60 70 d6 32 5a 0a 8f df ed cd f2 |.....`p.2Z......|
+00000010 d7 bf d0 da fd 53 63 65 bf f5 26 83 0c f5 6e e9 |.....Sce..&...n.|
+00000020 78 9b 03 7b 17 5f f4 d2 af 2a a3 85 13 92 be 00 |x..{._...*......|
+00000030 93 3f b3 f1 cb 04 aa 55 f8 ed c8 e6 9c 32 08 79 |.?.....U.....2.y|
+00000040 86 84 ef ac 72 bd 93 07 9c ca d2 e7 74 dd 51 a0 |....r.......t.Q.|
+00000050 6d 0e d3 32 3c 33 9d 58 aa 46 a9 ff 22 08 bc 2c |m..2<3.X.F.."..,|
+00000060 de 81 aa a8 5a 3c f8 36 93 d3 12 06 79 61 1f 71 |....Z<.6....ya.q|
+00000070 5f 45 d7 99 b2 55 10 22 db 56 d9 39 64 57 ad c3 |_E...U.".V.9dW..|
+00000080 59 a9 bd cb f2 22 16 03 03 02 69 34 e7 f2 7a bc |Y...."....i4..z.|
+00000090 0b 90 72 a3 3b 6b 38 a3 f8 7a 19 39 ff b4 d6 8c |..r.;k8..z.9....|
+000000a0 c9 92 4f a3 23 1a f0 89 bb 01 e4 b2 24 f7 db 3d |..O.#.......$..=|
+000000b0 f4 4b 02 75 d0 ca 3c ed e8 d9 13 61 c5 61 4e 7c |.K.u..<....a.aN||
+000000c0 fe b9 49 69 63 cc 23 5f 9b 23 85 ec 86 e5 17 28 |..Iic.#_.#.....(|
+000000d0 8a 1e 0c 45 e5 4d c2 be 66 92 47 88 28 ec 52 eb |...E.M..f.G.(.R.|
+000000e0 72 e5 30 89 58 8d 15 2b 98 eb cd e2 18 7c 53 f2 |r.0.X..+.....|S.|
+000000f0 89 ba 71 a5 91 20 64 17 7c 56 f1 01 8a 52 17 66 |..q.. d.|V...R.f|
+00000100 ef d7 bc 5b ff 54 53 13 2e 80 53 4c 84 6d a2 20 |...[.TS...SL.m. |
+00000110 0f e6 3d 33 90 7a 5b 1a 50 29 ce 1e af 74 a5 b3 |..=3.z[.P)...t..|
+00000120 0e 29 c8 e5 c1 50 b6 5d c8 bb e4 b5 f5 6b 04 a8 |.)...P.].....k..|
+00000130 24 a6 a8 cc 77 7c 72 d5 b1 f3 6a 1c 2e d7 7e e0 |$...w|r...j...~.|
+00000140 4c 46 3f 26 61 2e 54 7d ab d8 d6 ec 1e b0 0d d1 |LF?&a.T}........|
+00000150 02 57 00 7f 29 aa d3 1d a4 40 73 d7 21 12 76 58 |.W..)....@s.!.vX|
+00000160 7d 79 a5 c1 d2 57 63 48 0e 63 5f 24 49 8a 57 ba |}y...WcH.c_$I.W.|
+00000170 26 1c 39 4a f8 b3 89 79 e2 be 4e 8e 37 ae 16 75 |&.9J...y..N.7..u|
+00000180 42 5e 2e 9b 14 d5 b3 06 5f b9 c8 f7 16 8f eb 1c |B^......_.......|
+00000190 48 0a da 1e b3 4a 78 f7 f8 b4 35 bf 7d 3f c5 8d |H....Jx...5.}?..|
+000001a0 fa 7d c0 b7 52 af d3 13 de 96 39 76 fd 49 80 55 |.}..R.....9v.I.U|
+000001b0 bb b3 0f 5b 0c 84 4d 8b da 62 8a 20 4b a1 28 28 |...[..M..b. K.((|
+000001c0 3d 74 cc 34 9d 95 8e af c0 05 a2 5c 73 9d 73 d8 |=t.4.......\s.s.|
+000001d0 6c 4e 77 25 c5 8c 22 07 c6 b9 55 47 0c b2 12 73 |lNw%.."...UG...s|
+000001e0 2e f5 95 f7 28 c3 e4 24 2c fd 05 ac e2 3e df 93 |....(..$,....>..|
+000001f0 5a 28 66 aa d4 86 8a 48 e2 c8 69 01 18 90 54 10 |Z(f....H..i...T.|
+00000200 67 80 a1 be a8 9a 7f f3 17 ee dc 83 06 7a 70 6c |g............zpl|
+00000210 59 c2 2d 8f ff 79 a7 e5 e2 f2 f3 f3 5b 44 42 25 |Y.-..y......[DB%|
+00000220 a3 8c a0 83 07 5c f6 73 e9 bd f5 6b 86 89 b4 11 |.....\.s...k....|
+00000230 7b 9a 28 52 4f 55 70 4a 75 00 73 cc 84 fa 4a ef |{.(ROUpJu.s...J.|
+00000240 f8 8a 8d f9 18 e2 bc 13 48 cb 80 4d 6f fc d7 23 |........H..Mo..#|
+00000250 3a 9c 6c fd 46 27 94 8a 3d 9d fb 17 f5 06 4d a1 |:.l.F'..=.....M.|
+00000260 18 75 a7 9b 08 f8 47 b5 52 b4 19 4b b7 0f a4 e0 |.u....G.R..K....|
+00000270 78 f8 8b a4 cc eb d3 85 e1 ad 21 29 0f c7 09 28 |x.........!)...(|
+00000280 3f 21 12 6c fd 76 05 13 10 a0 c1 ce ba 7c e8 6f |?!.l.v.......|.o|
+00000290 e9 99 67 0a 9d 3a 7f f1 a6 8a 53 56 f1 09 22 21 |..g..:....SV.."!|
+000002a0 24 23 6e bc 77 fc 56 3b 31 15 58 1b e9 03 a1 bf |$#n.w.V;1.X.....|
+000002b0 0a 06 a0 fb 47 77 b7 ad 01 db ee 6a bc a4 a1 77 |....Gw.....j...w|
+000002c0 6f 3e 70 84 4c a6 21 ec ff fa f0 f0 68 ee 7d b1 |o>p.L.!.....h.}.|
+000002d0 e6 37 f1 1c aa 43 c7 b9 0e c4 52 7d 54 d8 f7 c5 |.7...C....R}T...|
+000002e0 16 21 99 89 cb 02 d0 54 b8 0e 91 2e 58 25 32 6e |.!.....T....X%2n|
+000002f0 fa ae 62 c9 16 03 03 00 bc 0c 2f 7e 22 d8 7f 21 |..b......./~"..!|
+00000300 0c 1a ec e1 37 72 3f 03 1d cc 73 f9 63 95 cd 47 |....7r?...s.c..G|
+00000310 66 17 60 8c da b4 35 a2 44 b1 d8 d1 1c 98 5b 8b |f.`...5.D.....[.|
+00000320 c8 9b c8 cb c4 15 0d 8d 08 1e 7c 3a 6b 20 3a f1 |..........|:k :.|
+00000330 d1 86 ae 08 bb fd 74 c5 62 9a 50 74 07 96 10 0e |......t.b.Pt....|
+00000340 e0 e4 a4 da c4 9d d1 f4 15 97 7d 21 0f 6f cb 39 |..........}!.o.9|
+00000350 8e 4e 40 1a 2a 7f 15 88 94 52 bc fd 61 b8 37 d1 |.N@.*....R..a.7.|
+00000360 48 62 bc 53 a3 a6 62 ec 0e c3 1f 82 67 19 71 fa |Hb.S..b.....g.q.|
+00000370 99 16 c3 cf d6 82 44 36 9e 0b f0 41 12 ca 7b 67 |......D6...A..{g|
+00000380 c3 a6 2d f7 13 14 0f d1 16 f9 2a 5a dd 43 45 c6 |..-.......*Z.CE.|
+00000390 c0 f4 17 36 64 11 fc ed e6 66 b6 0c e2 3d fb 72 |...6d....f...=.r|
+000003a0 93 27 46 20 db 1b 24 f9 69 a0 c7 71 e2 27 6a 93 |.'F ..$.i..q.'j.|
+000003b0 36 73 71 10 bd 16 03 03 00 4a cb 15 91 9c 22 96 |6sq......J....".|
+000003c0 f0 c8 b9 4d 9a 6c b0 eb 1a c5 d4 06 12 89 44 1b |...M.l........D.|
+000003d0 52 cd fb 32 3f 2c 25 f4 d3 88 0f e4 9c 18 91 59 |R..2?,%........Y|
+000003e0 42 98 a8 65 35 62 f7 ce fa a3 56 46 c5 b1 da ac |B..e5b....VF....|
+000003f0 9e 4e de 8d 14 fc 3c f3 94 74 50 99 1d 65 6b a6 |.N....<..tP..ek.|
+00000400 a9 38 93 9f 16 03 03 00 14 d7 5b 68 ca 4c 80 92 |.8........[h.L..|
+00000410 f8 13 5d fe 14 22 6f 9a 42 3a 27 de c8 |..].."o.B:'..|
+>>> Flow 9 (client to server)
+00000000 16 03 03 02 69 aa 39 9e c8 e7 89 97 7f 22 3c 28 |....i.9......"<(|
+00000010 76 ac d9 48 51 e0 cd 22 53 a1 6d e7 b4 00 27 7d |v..HQ.."S.m...'}|
+00000020 89 4b f0 54 d8 39 d0 a3 fc 35 a6 36 4b 3c eb 3a |.K.T.9...5.6K<.:|
+00000030 00 b0 c1 17 9d c8 13 a5 58 ba 16 9e cb 21 50 dd |........X....!P.|
+00000040 8a e0 2d 57 dd a6 bf 4d 6e b3 21 3b 46 f4 c3 77 |..-W...Mn.!;F..w|
+00000050 a1 86 07 c7 db e9 0a cb 2d 0f ff b5 1b ad 6b c4 |........-.....k.|
+00000060 c4 a4 4e 14 cf cb b2 6c 07 65 17 d2 db 30 e9 ec |..N....l.e...0..|
+00000070 41 4e 78 26 12 27 08 a6 a7 84 39 c0 4b e7 4b 23 |ANx&.'....9.K.K#|
+00000080 2f ca ff 1e 41 9a e8 44 fc 5d a0 34 4e ca a8 6d |/...A..D.].4N..m|
+00000090 31 51 57 c9 7e d1 0a 42 22 f2 b4 f9 a7 f9 28 d8 |1QW.~..B".....(.|
+000000a0 2a dd 19 0d 90 8b e1 78 b1 1c da 3a bb 5e 05 54 |*......x...:.^.T|
+000000b0 0d 0e f8 73 ed 01 e2 e4 d4 c1 f8 fa c3 d6 6f 42 |...s..........oB|
+000000c0 cc cb 99 99 97 18 b0 fb ab 51 42 66 45 67 b6 29 |.........QBfEg.)|
+000000d0 02 60 ab 74 30 db f6 16 8a 8f 8e 9c cc d5 47 fa |.`.t0.........G.|
+000000e0 f5 af 94 4f b1 94 40 57 ab 85 59 e4 3e cc c5 a0 |...O..@W..Y.>...|
+000000f0 61 b7 64 f9 dc 96 40 ae fb 4c 57 39 9e 9a 23 8e |a.d...@..LW9..#.|
+00000100 c9 36 6c 75 11 c7 6e 54 c3 1c e9 25 6a a0 f8 bb |.6lu..nT...%j...|
+00000110 6b 5c ca 5c 06 6c 03 88 01 27 4c 89 02 e6 b6 1a |k\.\.l...'L.....|
+00000120 92 99 4d 15 c1 1a aa 58 20 49 d7 4a f9 09 34 1e |..M....X I.J..4.|
+00000130 d7 d8 31 79 9f d8 b3 a0 76 ba 96 77 77 77 5b 80 |..1y....v..www[.|
+00000140 88 ab a0 90 c7 5f 3d 82 e1 23 29 6e 3a 4d 9b f0 |....._=..#)n:M..|
+00000150 7b 6a b1 9d 78 ba 4c 7e 02 1f a0 73 3e 91 cf 75 |{j..x.L~...s>..u|
+00000160 c6 52 2d c6 79 be 85 65 0e e4 73 39 fe 53 6d e0 |.R-.y..e..s9.Sm.|
+00000170 a3 18 d5 69 80 ca f1 c8 ad f5 f4 fb b5 40 2e f8 |...i.........@..|
+00000180 30 82 ca 2c 46 6a ab a6 b2 83 9f a8 95 95 30 e3 |0..,Fj........0.|
+00000190 e3 30 6d f5 7c 83 96 af 12 d8 d6 d6 f9 6a ad bd |.0m.|........j..|
+000001a0 bb 96 83 99 99 d8 6d 20 0e e1 be da 58 05 44 88 |......m ....X.D.|
+000001b0 a6 07 47 84 d4 77 fc 9b fb d7 ac 60 70 0b e7 76 |..G..w.....`p..v|
+000001c0 13 c7 38 d9 3d 60 eb a6 9f a5 6d fc 5c d5 f6 2f |..8.=`....m.\../|
+000001d0 31 02 38 65 8d be 04 06 84 95 86 b1 84 d9 ce c7 |1.8e............|
+000001e0 30 b9 d3 85 9f 1b 12 0f 5c 0e d6 8d e3 a0 15 04 |0.......\.......|
+000001f0 03 62 9d 52 7b e7 f4 13 aa 02 64 d9 d4 4b fd 6f |.b.R{.....d..K.o|
+00000200 de ea 4a aa 91 60 e7 78 af 84 b5 9d c3 d2 c6 3a |..J..`.x.......:|
+00000210 2a 9f 9b c6 8d 9e 5e 2c 90 6c d3 9d c1 be 96 5a |*.....^,.l.....Z|
+00000220 60 d8 73 6c 49 50 c8 03 ec 58 73 bc b3 8c 30 c1 |`.slIP...Xs...0.|
+00000230 f4 a2 7d 74 3d 8d 7e 64 c1 a7 b6 24 13 06 72 1b |..}t=.~d...$..r.|
+00000240 d0 87 22 af df 2a e7 fe 57 fa db e7 00 ba 74 35 |.."..*..W.....t5|
+00000250 16 34 20 3f 75 69 35 5f 64 7e 26 56 7c 93 05 4e |.4 ?ui5_d~&V|..N|
+00000260 42 65 b8 bf 59 8e 82 13 f1 d0 05 95 c2 3d 16 03 |Be..Y........=..|
+00000270 03 00 35 99 1d 52 84 73 d6 e7 90 f6 41 9e 69 07 |..5..R.s....A.i.|
+00000280 39 0b bc b6 c7 f4 f2 a0 93 80 b9 c7 bb b4 a6 06 |9...............|
+00000290 50 5b 5d 75 97 cf c5 dc 2d 07 3d 8f 9e ae fa bf |P[]u....-.=.....|
+000002a0 5b 6b 3e 98 02 fd e4 7d 16 03 03 00 98 80 ac e9 |[k>....}........|
+000002b0 4e e0 f8 b5 8c c2 2e 84 ec e0 3b eb b7 a0 14 2d |N.........;....-|
+000002c0 ff d2 bf 35 14 20 06 00 2e 48 c7 f8 a3 fd 4f 50 |...5. ...H....OP|
+000002d0 4a 04 3e c7 07 50 90 72 29 f0 5c ac e1 fd 9d 3f |J.>..P.r).\....?|
+000002e0 42 99 77 32 a9 79 24 7f 9e cc 84 1c d0 db 87 1c |B.w2.y$.........|
+000002f0 3c 9a ae e3 45 e5 67 83 5f 75 e9 27 f3 ef 8a 15 |<...E.g._u.'....|
+00000300 88 2b 3f cc 6f 6f a4 78 d5 b2 96 3e 72 d4 c8 43 |.+?.oo.x...>r..C|
+00000310 98 a7 60 ae 38 8e fe 21 49 5b c2 80 d6 ef 6f 9b |..`.8..!I[....o.|
+00000320 08 18 07 c2 64 00 a1 a0 09 8b b4 b7 eb 0c 68 30 |....d.........h0|
+00000330 26 87 f9 99 85 63 35 81 5a e4 31 19 9e f8 b8 7b |&....c5.Z.1....{|
+00000340 81 aa 24 ff cd 14 03 03 00 11 84 c7 e1 8f 74 66 |..$...........tf|
+00000350 e6 bd 14 55 a8 d3 67 30 2d c4 fb 16 03 03 00 20 |...U..g0-...... |
+00000360 3a 63 a5 86 f3 78 f1 62 18 77 f7 25 71 52 56 17 |:c...x.b.w.%qRV.|
+00000370 d2 a5 e4 fa bc bb 44 07 85 37 cb 36 84 c7 6a 97 |......D..7.6..j.|
+>>> Flow 10 (server to client)
+00000000 14 03 03 00 11 9e 99 89 2d 10 21 a1 38 04 77 1a |........-.!.8.w.|
+00000010 f8 1d b4 01 d1 9f 16 03 03 00 20 2a cb 67 8b 1b |.......... *.g..|
+00000020 44 26 41 7b c4 6d a1 f4 cb ee 15 87 01 65 18 5a |D&A{.m.......e.Z|
+00000030 c7 2d 10 e4 91 01 cb 22 e8 92 1a 17 03 03 00 19 |.-....."........|
+00000040 1a 46 a0 9a c5 1a 27 0c e2 f9 03 55 3a e8 43 a7 |.F....'....U:.C.|
+00000050 d7 47 a5 95 6a e7 a1 12 69 16 03 03 00 14 d6 e0 |.G..j...i.......|
+00000060 1d 89 e0 c2 9a 52 d5 bc d4 08 3e f6 81 dd 57 a2 |.....R....>...W.|
+00000070 25 f6 |%.|
+>>> Flow 11 (client to server)
+00000000 16 03 03 01 16 27 50 ce c0 8e 5a e2 54 55 cb c0 |.....'P...Z.TU..|
+00000010 08 c7 20 87 7e 78 c6 da a6 7a 62 fd 7f f5 87 b3 |.. .~x...zb.....|
+00000020 83 a0 c8 70 ab 57 9b ca bf 4c 07 06 f1 89 b9 b6 |...p.W...L......|
+00000030 24 f0 ae 72 e1 36 31 9f 74 ed 06 ad 44 3b 51 2c |$..r.61.t...D;Q,|
+00000040 ed f0 c2 d8 9b 27 d2 9a ec 44 88 80 7c 5a d0 66 |.....'...D..|Z.f|
+00000050 3d 84 e3 7c 24 89 b9 dd 8c eb 86 cd ce 69 0d e3 |=..|$........i..|
+00000060 97 ee ad 74 53 7f 9c f0 05 31 43 2a 8c 09 c4 11 |...tS....1C*....|
+00000070 46 3e 82 2c 3c 69 91 d1 eb 4b 8a ab a9 cb 24 00 |F>.,<i...K....$.|
+00000080 00 25 bd 26 d3 85 19 ff 3b 2b 92 3f 43 b0 9f 24 |.%.&....;+.?C..$|
+00000090 59 4f 3d a6 ce 65 27 5c 75 47 92 7b 4a d3 ca 55 |YO=..e'\uG.{J..U|
+000000a0 38 00 ac 37 0c 6e 2d 04 bc 6e fe 3a 9a 43 b6 7f |8..7.n-..n.:.C..|
+000000b0 18 c1 a6 ce 49 b4 61 d3 97 8d a2 c9 fb fb cd 23 |....I.a........#|
+000000c0 f6 2f 0c 0b 2a b8 31 9e fd ff 9f 44 1e 33 c3 23 |./..*.1....D.3.#|
+000000d0 bf 09 d2 de 90 b6 61 9c 33 33 33 46 bc 00 7e 16 |......a.333F..~.|
+000000e0 3c bd 82 2d 31 51 5b 11 87 ec 7f 25 d8 95 f9 9c |<..-1Q[....%....|
+000000f0 df 00 54 40 f3 c1 08 fa ef ba bc 5d b1 96 ae 8f |..T@.......]....|
+00000100 35 0e 43 b2 50 c7 7e c4 b2 71 2e 40 3a b7 90 2b |5.C.P.~..q.@:..+|
+00000110 81 ac 00 14 9d da d8 ca 5e 25 62 |........^%b|
+>>> Flow 12 (server to client)
+00000000 16 03 03 00 81 37 3a f4 1b 6a 43 d2 6a 02 02 33 |.....7:..jC.j..3|
+00000010 b9 d5 9a 5c d1 3b 52 73 f2 27 a6 c0 f0 9b dd f3 |...\.;Rs.'......|
+00000020 d7 cd 89 ec 21 e0 d3 2f 4d 6c b0 cf 50 a7 39 43 |....!../Ml..P.9C|
+00000030 c2 56 d2 f8 45 d7 3c a6 b6 b9 06 3f ca a7 f8 37 |.V..E.<....?...7|
+00000040 4c 89 01 49 82 5f 27 15 3c bf f0 86 7c 1a 84 03 |L..I._'.<...|...|
+00000050 5a 90 77 03 01 fd b8 60 2a be cc 60 c6 54 b5 ec |Z.w....`*..`.T..|
+00000060 c1 5d 6b e6 f0 2c 8c e6 7e e3 b6 c3 8b 63 3c 69 |.]k..,..~....c<i|
+00000070 ac 2c 9a 24 a7 77 5f 0c 36 08 68 6c 8b 76 f1 80 |.,.$.w_.6.hl.v..|
+00000080 4a bf f7 e6 15 5b 16 03 03 02 69 a1 ce a6 de 44 |J....[....i....D|
+00000090 cf d6 f7 88 f4 da 01 06 2b e5 cf 54 8d f6 78 ab |........+..T..x.|
+000000a0 53 c5 ea d9 97 4b 94 22 24 9b 98 ba ba ee 42 9d |S....K."$.....B.|
+000000b0 c3 e4 12 e3 be 35 24 86 3d 38 a0 6e b7 e6 cf dc |.....5$.=8.n....|
+000000c0 e7 5c e1 0d 7c 05 bb 63 7c 8b c4 a4 db 9a 85 a4 |.\..|..c|.......|
+000000d0 ba d6 d4 79 38 79 01 52 2d cf c1 c7 6e 09 64 ff |...y8y.R-...n.d.|
+000000e0 e9 b6 3e f2 a0 2b 4c 91 3f e2 fe 1a 40 4b 14 ea |..>..+L.?...@K..|
+000000f0 77 8f 40 1c a2 96 7c d3 ce 34 5e d8 13 5a 82 33 |w.@...|..4^..Z.3|
+00000100 41 59 fa d9 81 1c 85 41 9c 61 b9 ca d5 46 e2 77 |AY.....A.a...F.w|
+00000110 3d a9 50 4f 11 b1 34 aa ae fd e5 ec fe 12 e6 10 |=.PO..4.........|
+00000120 36 84 fb 25 f8 a4 6f 44 e3 ac 89 67 e4 9a 02 c4 |6..%..oD...g....|
+00000130 8f a9 4a d0 f4 64 e2 de da 80 02 60 cb a9 2d e0 |..J..d.....`..-.|
+00000140 fa d9 b9 ee 43 e1 3e ed 79 79 6b 21 62 3d 6f b0 |....C.>.yyk!b=o.|
+00000150 77 53 db 26 60 e1 d6 ff a7 01 2b b7 f0 49 df b8 |wS.&`.....+..I..|
+00000160 bc d9 ac 77 80 f8 53 66 16 8d 3a 8d 63 fa 12 e1 |...w..Sf..:.c...|
+00000170 ed f7 8b c0 40 46 16 70 e3 db f3 38 87 9f 11 eb |....@F.p...8....|
+00000180 0b f5 b3 44 e4 16 e1 ed 85 e6 67 d5 35 60 20 99 |...D......g.5` .|
+00000190 7d bd 9f 65 b9 52 68 6c 6b 83 f9 06 e3 a7 3e 0f |}..e.Rhlk.....>.|
+000001a0 9e 7c a5 ac 87 7a 45 53 a5 3f 27 5b 99 a9 34 c2 |.|...zES.?'[..4.|
+000001b0 5a 44 9a 30 08 30 c6 ff 60 8a a5 72 f7 49 d3 7c |ZD.0.0..`..r.I.||
+000001c0 1f f9 8b 74 a0 b1 c8 65 84 6d 91 86 ab 1e 82 3b |...t...e.m.....;|
+000001d0 d5 c4 bb 06 b3 31 61 bb 0e 65 3e 18 4d 0c c1 c1 |.....1a..e>.M...|
+000001e0 9d 7f ea ad cf 53 2e 9c 1c 7e aa c8 84 9e 0d ce |.....S...~......|
+000001f0 91 53 3c d4 05 7e 57 d1 8b 55 ea e4 6e 57 90 4c |.S<..~W..U..nW.L|
+00000200 bb 74 9c 87 1c 6a 89 cf 2c 50 8d 04 04 e6 18 c8 |.t...j..,P......|
+00000210 0c 9f 38 84 f4 f4 94 8d 33 2b a1 27 0b 5c 6a 2a |..8.....3+.'.\j*|
+00000220 0c 13 b7 07 b7 a0 c9 e5 3c 9d 5a 7e 96 c9 53 fc |........<.Z~..S.|
+00000230 ff c4 3a 8f 16 1f 2d 64 50 1d 13 c3 55 fb af d2 |..:...-dP...U...|
+00000240 0e f9 e6 18 e3 62 ce 6a 8f 96 ff 00 0e fe 27 53 |.....b.j......'S|
+00000250 70 57 53 2d fd f3 02 c7 fe b3 19 49 88 27 7e a2 |pWS-.......I.'~.|
+00000260 42 7b 22 d0 77 4e e5 04 aa 0d b6 9d b9 48 97 ab |B{".wN.......H..|
+00000270 33 e7 14 97 65 82 f9 2c dc 71 9e 4b eb ed 42 73 |3...e..,.q.K..Bs|
+00000280 c6 c8 93 8a 3a 24 bd f9 b4 6a 95 c1 1b 22 1d f5 |....:$...j..."..|
+00000290 c8 33 c5 38 1e a7 2e 91 68 35 4c 0a 37 57 ac e2 |.3.8....h5L.7W..|
+000002a0 c9 37 9e d9 1c b8 76 73 c2 d2 0c d0 c4 a1 c0 d5 |.7....vs........|
+000002b0 72 39 bf 03 f7 8d db e0 8f fe e2 d6 d0 d4 cc bb |r9..............|
+000002c0 7d 78 c6 c5 13 a8 4e 45 1e 66 60 77 fe 26 4d 18 |}x....NE.f`w.&M.|
+000002d0 90 e8 e1 0c 5b 2b 25 9b ee 6d 76 3f f6 23 a2 26 |....[+%..mv?.#.&|
+000002e0 52 8d a9 4e 7f ed 8e e2 6d 7c b4 eb 25 46 54 27 |R..N....m|..%FT'|
+000002f0 e2 2d 2c 59 16 03 03 00 bc 6e c1 fb 66 55 ca ea |.-,Y.....n..fU..|
+00000300 56 62 78 2f fd c4 ff da 78 dd e7 4d 34 59 a5 8f |Vbx/....x..M4Y..|
+00000310 05 ab ac 7f 80 35 f6 de 9d 3f fe 4b d4 79 07 3b |.....5...?.K.y.;|
+00000320 c0 8d 02 b8 1a 28 b5 eb 9b 55 6c 26 12 8d 38 01 |.....(...Ul&..8.|
+00000330 55 ed 28 68 aa 48 13 61 d3 fe 29 f0 fe 18 4e ae |U.(h.H.a..)...N.|
+00000340 6e f9 47 7c 65 91 f9 5e 17 80 68 fd 19 4d ed 17 |n.G|e..^..h..M..|
+00000350 7f 11 c4 15 5d 4b fc ea a7 5c df 76 a0 08 2e 15 |....]K...\.v....|
+00000360 d1 c6 ae 7b 0d 1f 79 d7 0c 59 6b 53 46 b6 c0 2b |...{..y..YkSF..+|
+00000370 ce 09 39 12 7a df f6 7d a2 4b 86 2a df ab b8 7c |..9.z..}.K.*...||
+00000380 07 10 3c 34 cd 15 4c ac 68 a4 28 8a f8 fc 30 a4 |..<4..L.h.(...0.|
+00000390 4f 15 77 b4 91 ca 02 ee bb 64 36 90 1b 4b 9d 2b |O.w......d6..K.+|
+000003a0 72 e7 dc 10 bd 83 97 18 3c 56 68 58 c9 e3 22 df |r.......<VhX..".|
+000003b0 33 43 81 7d 5f 16 03 03 00 14 a8 eb 40 73 19 19 |3C.}_.......@s..|
+000003c0 22 10 63 ed f0 6d 73 8c f4 bd f9 ba ad 2e |".c..ms.......|
+>>> Flow 13 (client to server)
+00000000 16 03 03 00 35 67 14 4b ca 21 7f d2 82 1d 2e b3 |....5g.K.!......|
+00000010 1a 82 ae 2d d9 d6 7c 76 94 78 d4 ec 0e 4d fe 5c |...-..|v.x...M.\|
+00000020 d5 56 5e 6d 32 f4 a0 64 50 1e f6 e4 32 28 92 80 |.V^m2..dP...2(..|
+00000030 d4 15 1c d5 f6 52 fc ca c0 e7 14 03 03 00 11 df |.....R..........|
+00000040 9d f3 d1 64 92 92 7e 11 77 64 e5 67 01 33 49 17 |...d..~.wd.g.3I.|
+00000050 16 03 03 00 20 c8 0f d9 d2 c8 b7 d6 a5 ac 2c 33 |.... .........,3|
+00000060 f8 77 8f b1 df db 16 de 43 6c e6 5a eb a0 6e ff |.w......Cl.Z..n.|
+00000070 be 1d 69 ab 30 |..i.0|
+>>> Flow 14 (server to client)
+00000000 14 03 03 00 11 6e 2c 51 c5 dd fa 70 2a 34 e0 cc |.....n,Q...p*4..|
+00000010 3c 9f b8 66 15 e6 16 03 03 00 20 78 02 96 c6 24 |<..f...... x...$|
+00000020 57 ca 4a 60 47 68 f6 5a 13 8b 3b ce 90 60 d2 e3 |W.J`Gh.Z..;..`..|
+00000030 1b d8 ab 1c df d4 5e c2 8d 5c 5b 17 03 03 00 19 |......^..\[.....|
+00000040 b7 15 fb 91 10 48 ae 25 0c cd 4f 06 fa 2a 59 49 |.....H.%..O..*YI|
+00000050 2f 18 5e 7e 36 1b 2e cb 3a |/.^~6...:|
+>>> Flow 15 (client to server)
+00000000 15 03 03 00 12 c3 ff f7 b3 dc d4 b3 f5 d4 7c a3 |..............|.|
+00000010 18 db 08 a2 50 ad 75 |....P.u|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwiceRejected b/src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwiceRejected
new file mode 100644
index 0000000..784bcef
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-RenegotiateTwiceRejected
@@ -0,0 +1,247 @@
+>>> 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 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 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 59 02 00 00 55 03 03 96 8a 79 30 8b |....Y...U....y0.|
+00000010 13 f5 d3 1c 09 45 76 83 d7 2e e5 ad e3 ee e1 c4 |.....Ev.........|
+00000020 d4 b4 4c 37 93 cb 90 e1 9a 5e 52 20 fb 25 91 ea |..L7.....^R .%..|
+00000030 1a 96 b6 fb 1f 0c a8 62 06 a0 fe 51 68 c0 fb a5 |.......b...Qh...|
+00000040 f1 05 28 02 be dc 87 31 e6 ff 90 1a cc a8 00 00 |..(....1........|
+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 ac 0c 00 00 a8 03 00 1d 20 ad 8e 56 2a c0 d0 7c |........ ..V*..||
+000002d0 e1 cb 6b 20 0b 3e 53 33 28 25 37 42 5b 13 3c d5 |..k .>S3(%7B[.<.|
+000002e0 26 98 9e 0f df 45 6d 27 67 08 04 00 80 72 49 21 |&....Em'g....rI!|
+000002f0 f0 02 02 a3 7c e1 2a 18 d0 d0 21 8e 50 17 ad 0c |....|.*...!.P...|
+00000300 3c a2 6d 65 b5 cb bc 7f 9e 7d 7f e2 36 3d b6 c8 |<.me.....}..6=..|
+00000310 df 7e b9 28 ab 01 99 2a 68 a4 be 46 11 94 9f 8c |.~.(...*h..F....|
+00000320 67 02 92 1e 3c 51 78 f3 7a 35 ed f4 bb 8b fe b3 |g...<Qx.z5......|
+00000330 8c 32 aa c1 05 4f 99 68 b0 8a 75 65 1d e6 d6 6a |.2...O.h..ue...j|
+00000340 61 65 aa 00 01 6b 29 06 99 d4 5b c7 c3 d2 0c 17 |ae...k)...[.....|
+00000350 74 59 d4 ee 99 b8 ef 5b 53 ff 33 df 9e 05 49 4f |tY.....[S.3...IO|
+00000360 31 c6 95 81 67 c2 52 8a 0c e9 6a 46 22 16 03 03 |1...g.R...jF"...|
+00000370 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 b8 c8 5d 3d b8 b8 2b c7 06 94 ec |.... ..]=..+....|
+00000040 cc 92 01 22 3d cd 38 d8 aa 9f 1f 18 ef a0 ee 59 |..."=.8........Y|
+00000050 c0 3b 04 56 49 |.;.VI|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 20 be 6c dd f4 ef |.......... .l...|
+00000010 71 1d 9c a7 24 ef 74 81 c4 01 1e e0 ef ac 78 90 |q...$.t.......x.|
+00000020 4e 51 fd 8a ca 83 e7 57 95 07 fa |NQ.....W...|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 16 35 96 43 38 06 49 b1 3f 01 ae 85 |.....5.C8.I.?...|
+00000010 1a ee 4b 2b fe c0 75 76 b6 4a b0 |..K+..uv.J.|
+>>> Flow 6 (server to client)
+00000000 16 03 03 00 14 df 6c d7 78 02 f5 a7 cb d8 2f fb |......l.x...../.|
+00000010 04 dc 30 bc 28 51 f9 ec b8 |..0.(Q...|
+>>> Flow 7 (client to server)
+00000000 16 03 03 01 16 8c 2a 91 5b 60 aa 44 e7 b7 7e b8 |......*.[`.D..~.|
+00000010 ee c2 3e f3 c4 2f 6a 75 8e 25 07 5a 5c 42 81 fd |..>../ju.%.Z\B..|
+00000020 65 4c 2a fb a9 80 f0 ba 33 1b 06 a8 79 a8 15 8e |eL*.....3...y...|
+00000030 3a c4 08 95 a5 23 f0 ba fb 43 58 26 84 b5 9d 17 |:....#...CX&....|
+00000040 03 e5 e7 08 ce 8b 79 9c 5e fb c6 6e a6 b8 12 cf |......y.^..n....|
+00000050 b9 6e 4a 2a 90 d0 6b 65 93 bf 41 31 25 7f 3a 7c |.nJ*..ke..A1%.:||
+00000060 75 1f d6 4e 22 d3 90 7b 71 14 57 c6 b6 89 ef 79 |u..N"..{q.W....y|
+00000070 74 7e 63 79 b9 63 d6 ef 02 b7 54 4b 53 0e 7f 70 |t~cy.c....TKS..p|
+00000080 8a 34 b1 85 98 ae a7 05 b8 41 9d 49 a3 ca eb 7d |.4.......A.I...}|
+00000090 8b 64 e7 5d ca 11 71 93 e0 ff 6e 43 37 b4 e9 ec |.d.]..q...nC7...|
+000000a0 23 6f d6 c6 bc cb ef a2 0b d0 4b ba 4f 40 b0 4b |#o........K.O@.K|
+000000b0 ec 57 cb 8a 10 ae fe cd 14 70 42 a0 b9 1c 81 f6 |.W.......pB.....|
+000000c0 d2 79 47 31 4a b8 aa ac 89 98 cf ae 4e 8f 3d 36 |.yG1J.......N.=6|
+000000d0 c5 41 0e d8 e6 f3 88 2a 19 e5 e7 71 e2 2f 32 93 |.A.....*...q./2.|
+000000e0 ae 05 95 25 8f ec 4e 10 25 7e 53 60 6e c2 f2 72 |...%..N.%~S`n..r|
+000000f0 fc 7a 69 c1 93 e9 b8 2e 94 f3 19 31 5b 23 7c fd |.zi........1[#|.|
+00000100 04 5d 59 ca 00 cc 37 0b 05 0d 50 10 50 3f b0 86 |.]Y...7...P.P?..|
+00000110 84 d4 fc 6a 0a 94 dc ba 88 fe ad |...j.......|
+>>> Flow 8 (server to client)
+00000000 16 03 03 00 81 41 25 27 5b 76 24 a0 4f f0 bf ca |.....A%'[v$.O...|
+00000010 c4 4f f8 7c c6 e8 2a d4 d1 ed f1 b8 34 84 d6 d5 |.O.|..*.....4...|
+00000020 93 20 70 7d 8e 75 c5 16 a8 ff 5c e6 de 16 ea 96 |. p}.u....\.....|
+00000030 3f 86 3b bd 6d fa 96 3d 27 18 34 b8 18 86 ee 65 |?.;.m..='.4....e|
+00000040 7f f2 cc 7a b9 f8 2e 5a 32 f3 16 e2 a2 27 fd 4b |...z...Z2....'.K|
+00000050 31 19 e6 81 d9 ef 02 10 ac b6 55 d3 0b e2 b0 09 |1.........U.....|
+00000060 56 ea 50 5a 96 b3 ff 07 78 48 df 77 3f 15 c9 ff |V.PZ....xH.w?...|
+00000070 a7 24 af 28 ec 99 1a c9 36 09 16 9c 7c 5a c0 85 |.$.(....6...|Z..|
+00000080 7c 93 e4 61 2e 5b 16 03 03 02 69 ef 17 31 d5 9c ||..a.[....i..1..|
+00000090 bc 09 f9 b7 75 e2 c8 ea 93 6f b7 49 e3 0e af bb |....u....o.I....|
+000000a0 84 d6 3b 20 e2 89 13 6f 7a d1 73 a7 cb d5 03 b2 |..; ...oz.s.....|
+000000b0 20 40 40 76 d9 5d 3b 23 cb 48 ba 3c 1b e7 5d de | @@v.];#.H.<..].|
+000000c0 16 be 82 91 39 d0 b4 83 3e 4c b8 a0 66 56 47 6c |....9...>L..fVGl|
+000000d0 08 03 b1 0f be 3f d3 5e 7e b4 40 db db 5b ce 61 |.....?.^~.@..[.a|
+000000e0 d9 dc 02 7d ea df ea 43 08 2c b0 1c af 76 8f d3 |...}...C.,...v..|
+000000f0 cd af 51 cd 17 df 70 58 90 bd 83 aa 4b e5 fe cd |..Q...pX....K...|
+00000100 90 30 e0 b5 d0 95 49 c2 10 06 8c 5a dd a2 37 ad |.0....I....Z..7.|
+00000110 d5 d1 0e 73 c7 92 a9 ab 67 51 da 9d a4 62 6d a6 |...s....gQ...bm.|
+00000120 d7 89 22 2b 97 59 ad 02 65 e9 1d 48 44 07 c9 c0 |.."+.Y..e..HD...|
+00000130 c4 1f 7f da 64 0c 35 19 16 b3 70 41 d8 61 c3 47 |....d.5...pA.a.G|
+00000140 59 4d c2 e6 07 86 55 92 b9 98 8e 5c 86 d2 d5 51 |YM....U....\...Q|
+00000150 6a 50 19 99 75 0a cf 6e 49 cc 8a 76 b5 2b 20 48 |jP..u..nI..v.+ H|
+00000160 2b 11 d4 54 a2 ea 98 ce d8 56 22 c8 f8 eb e5 25 |+..T.....V"....%|
+00000170 c8 cf ec 86 95 09 51 7e 18 89 bb 8f d4 66 b8 44 |......Q~.....f.D|
+00000180 c2 78 f4 4d ad eb 2d 79 f8 f6 02 4f d2 35 d4 71 |.x.M..-y...O.5.q|
+00000190 b3 ae e6 7d f6 45 6c 99 07 57 3c 01 bb c1 fb f1 |...}.El..W<.....|
+000001a0 1a ac ba 92 b6 60 52 63 8b 21 eb bf 77 02 c6 29 |.....`Rc.!..w..)|
+000001b0 7f 10 f7 11 ac a2 90 a9 8b 47 da c1 2c 41 c9 da |.........G..,A..|
+000001c0 3f 18 ab be f0 eb 20 98 80 c6 d2 14 9e 8e d3 41 |?..... ........A|
+000001d0 c3 37 ab 12 5b cc d0 25 bd af 16 49 4e 89 a1 92 |.7..[..%...IN...|
+000001e0 d1 09 49 59 dc cf f8 6c 73 02 cb 72 6d 28 6e 28 |..IY...ls..rm(n(|
+000001f0 c5 a8 84 20 e6 f8 1b ad c1 6c 8f b0 30 b2 49 84 |... .....l..0.I.|
+00000200 22 42 7d ec e1 c7 ab 29 de 1c 84 1f cf 59 c6 80 |"B}....).....Y..|
+00000210 7e 13 13 d7 c5 e5 f2 e0 3b 9d 81 c9 3f 86 21 27 |~.......;...?.!'|
+00000220 d7 c8 45 c1 25 f6 19 8d 0a f6 e9 5a 9b d5 64 a1 |..E.%......Z..d.|
+00000230 e4 6d fe 6a cf d1 c3 1b d4 ea d9 1f 6b dc f9 a7 |.m.j........k...|
+00000240 e9 d2 6c 31 19 db e1 f4 f8 82 6e 8b da fd b1 fd |..l1......n.....|
+00000250 0a 56 84 73 db 25 5f bb 12 61 70 de 67 34 28 1c |.V.s.%_..ap.g4(.|
+00000260 c3 e6 eb 81 c8 94 55 ca 52 25 e8 72 bf a1 c5 88 |......U.R%.r....|
+00000270 b8 ce 72 8d 64 6c 38 d9 19 07 f3 51 51 91 84 f2 |..r.dl8....QQ...|
+00000280 c4 76 7f 8b 57 09 71 94 38 aa f1 64 51 6f 62 50 |.v..W.q.8..dQobP|
+00000290 c8 50 68 82 b9 54 b1 28 54 99 21 26 7d 75 c7 c7 |.Ph..T.(T.!&}u..|
+000002a0 79 e7 65 93 72 a4 39 2d 4c ec ba b2 4c 92 ae ee |y.e.r.9-L...L...|
+000002b0 34 a2 22 2f f9 b9 75 a9 27 77 63 2d ac 27 87 ce |4."/..u.'wc-.'..|
+000002c0 ee 37 c0 c7 c1 b6 4c 13 d7 78 97 64 dc af ea 0d |.7....L..x.d....|
+000002d0 7c 12 0e 7b 0b 26 77 01 e4 1c 24 e8 9f fc 19 2f ||..{.&w...$..../|
+000002e0 46 a2 81 3d 0d c7 16 7e 49 25 b4 c1 0f 0a 71 05 |F..=...~I%....q.|
+000002f0 25 eb 53 e4 16 03 03 00 bc 0b 79 2d c6 0a 63 68 |%.S.......y-..ch|
+00000300 f0 21 37 d0 42 4a 0f 2f 7d 2f a0 7d 3d c3 94 c4 |.!7.BJ./}/.}=...|
+00000310 36 f5 a6 db e1 ad 0f 94 07 67 57 54 d4 57 86 50 |6........gWT.W.P|
+00000320 a2 e1 78 09 f2 e3 7b bc 6d 1b c0 fe 16 eb d3 ef |..x...{.m.......|
+00000330 fb ec 22 44 ee 2f 78 99 84 e2 c1 4c f7 0d 4f bc |.."D./x....L..O.|
+00000340 ca 57 be de 5f 52 08 33 b0 e1 1d 7b 45 9e 5d 17 |.W.._R.3...{E.].|
+00000350 41 2c 10 43 44 18 84 38 f3 0b 6a a1 76 bf 75 c9 |A,.CD..8..j.v.u.|
+00000360 56 b2 53 4c 98 39 c0 6f 30 13 96 8a 27 59 12 03 |V.SL.9.o0...'Y..|
+00000370 60 64 ce 28 54 c0 03 f4 c4 d1 df 94 e3 6e 43 61 |`d.(T........nCa|
+00000380 fa 43 40 e5 05 3b 26 dc c4 41 bd 73 c3 9e a0 db |.C@..;&..A.s....|
+00000390 fb c9 50 b4 4a d9 2d 71 cf e8 ff 3d 17 9e 29 35 |..P.J.-q...=..)5|
+000003a0 61 6c ab 11 ac 21 fa 90 6b 75 1f 0a 9d 30 3f 13 |al...!..ku...0?.|
+000003b0 fa c3 97 7a 74 16 03 03 00 4a 3d ca 3b 3d c8 6f |...zt....J=.;=.o|
+000003c0 44 4e 53 3d 05 27 97 aa bd 58 33 d6 ad 4a 34 71 |DNS=.'...X3..J4q|
+000003d0 22 d9 36 96 17 a5 ba 6b b3 20 2e da 64 65 14 c7 |".6....k. ..de..|
+000003e0 6a c7 07 39 55 db bb ad e2 49 84 09 5e 78 88 b5 |j..9U....I..^x..|
+000003f0 4b d5 23 fa 17 c5 f2 b8 2a c6 e5 1e 15 47 01 36 |K.#.....*....G.6|
+00000400 ef 7f 0a 14 16 03 03 00 14 28 e3 58 7e b9 36 d6 |.........(.X~.6.|
+00000410 ef 65 c8 bc fb 10 57 3d 48 70 7f 68 7d |.e....W=Hp.h}|
+>>> Flow 9 (client to server)
+00000000 16 03 03 02 69 d8 c1 81 7e a9 d7 70 97 62 c7 68 |....i...~..p.b.h|
+00000010 df 02 01 9d cc dc 38 d0 d6 bb 48 03 1d 0b be 73 |......8...H....s|
+00000020 b3 1a 88 91 a0 1b 55 91 51 a5 d7 54 58 c4 ea 50 |......U.Q..TX..P|
+00000030 e5 67 b1 60 78 b6 e2 7f d7 6c b4 76 d7 24 fd af |.g.`x....l.v.$..|
+00000040 f6 68 90 8c de 71 cd 15 4f d0 c8 f6 ba 89 ce 05 |.h...q..O.......|
+00000050 be 35 e8 9e 7a 8b 8d 0d 23 d4 5a bd 3a 9e d0 bf |.5..z...#.Z.:...|
+00000060 80 08 f5 ad 7d 84 f1 8a 16 de 97 6b b2 75 8e 49 |....}......k.u.I|
+00000070 0f d7 8b 10 57 f7 21 1f c0 87 de 06 c5 ae ae dd |....W.!.........|
+00000080 9c 22 92 a1 6c c7 46 8d e2 be 43 32 9c be 47 6b |."..l.F...C2..Gk|
+00000090 4d 2a 60 f0 b6 3a 09 16 d6 16 a1 92 4a 2d 2d 72 |M*`..:......J--r|
+000000a0 00 8f 40 7c 3e a9 61 be 35 c8 f8 48 b4 1c 90 61 |..@|>.a.5..H...a|
+000000b0 90 c5 aa f8 ae aa d4 8a 15 74 b2 5d aa 24 cf 45 |.........t.].$.E|
+000000c0 ef 02 bd 29 b9 50 b4 fe 83 05 fa 4a a5 82 10 28 |...).P.....J...(|
+000000d0 b7 ab c3 ca c3 65 bb 51 a4 7c ac 57 03 78 28 e3 |.....e.Q.|.W.x(.|
+000000e0 91 9f c1 ce 02 08 70 84 8c 11 1f ae 35 a5 06 12 |......p.....5...|
+000000f0 f8 78 5b 38 0a 11 c8 1c 2d 1b 0c 21 66 d9 41 b2 |.x[8....-..!f.A.|
+00000100 ed 66 3c 47 f2 dc ab c1 59 7d 65 df bb 80 37 1c |.f<G....Y}e...7.|
+00000110 5e 9b 41 e1 1d 5f b5 24 e4 77 61 3b e8 36 93 03 |^.A.._.$.wa;.6..|
+00000120 6d 87 17 e9 d7 77 35 b1 83 a3 b9 80 4d 40 20 82 |m....w5.....M@ .|
+00000130 94 36 53 94 ad 6b b3 ad 0a 70 fd 11 ce 81 56 ca |.6S..k...p....V.|
+00000140 c2 5d 16 69 e3 59 7e 37 3b cd f3 54 1e b8 5e 1a |.].i.Y~7;..T..^.|
+00000150 64 3f bf c6 ba ff fa b5 bf 4b c2 8e 5a 4d 43 1f |d?.......K..ZMC.|
+00000160 8e 50 bc 7a 82 13 c7 25 aa b4 a8 97 45 49 12 25 |.P.z...%....EI.%|
+00000170 f5 4d 52 df 90 e5 74 0f a0 d2 fd c3 6f bd 41 ed |.MR...t.....o.A.|
+00000180 ff 78 e8 97 f2 e2 d1 5b 7c e6 27 01 16 27 1d b6 |.x.....[|.'..'..|
+00000190 8a cf c6 5b 8d b3 d8 8e 0c ee 2a d5 21 f6 4b d3 |...[......*.!.K.|
+000001a0 5a 74 7e 3d c6 fb 0e 35 97 de e7 52 c0 b2 c3 37 |Zt~=...5...R...7|
+000001b0 94 28 41 e0 3b 65 56 f1 4f 60 03 48 88 1d db fc |.(A.;eV.O`.H....|
+000001c0 60 9f 33 e1 4d 37 eb 22 36 b2 76 ae 1c 3d 1c 5e |`.3.M7."6.v..=.^|
+000001d0 3a c5 5b 00 eb 72 8b 54 ba 76 d1 71 77 5f 76 54 |:.[..r.T.v.qw_vT|
+000001e0 5f fd 0e d1 3a 50 ad b1 55 4a db 6d bf 2f 33 90 |_...:P..UJ.m./3.|
+000001f0 fc 42 de cd e4 a9 dd 11 25 d1 9f 56 1e 8a 2b 5c |.B......%..V..+\|
+00000200 6c ed e7 51 84 42 6b ab 7d 77 b4 95 c3 75 b3 24 |l..Q.Bk.}w...u.$|
+00000210 ce 70 b0 e1 63 7f ec b0 ea 6a a4 a1 d5 e8 3e 96 |.p..c....j....>.|
+00000220 65 99 40 46 73 c8 e1 6e 86 65 92 bf 3d 92 a3 4f |e.@Fs..n.e..=..O|
+00000230 37 6d bb 80 33 a5 7d aa d3 a9 37 77 a6 4e 5b d6 |7m..3.}...7w.N[.|
+00000240 f3 f9 b2 42 75 18 1f 5a 58 f3 08 35 bc f4 2b 93 |...Bu..ZX..5..+.|
+00000250 62 0b 8a 83 f9 44 d0 e1 1a 44 b2 66 45 6f de b3 |b....D...D.fEo..|
+00000260 d2 ec 34 ac 15 89 76 b4 da dd 95 ca 44 5b 16 03 |..4...v.....D[..|
+00000270 03 00 35 39 e8 06 21 47 85 b5 53 96 03 0b 08 3b |..59..!G..S....;|
+00000280 d2 9d 55 1f 23 4f 3a c0 be 4f e0 e0 0a f1 65 6f |..U.#O:..O....eo|
+00000290 78 22 c4 10 6b d0 96 dc 04 78 e8 d3 95 f6 9a 78 |x"..k....x.....x|
+000002a0 09 f2 42 d3 79 57 99 c4 16 03 03 00 98 37 6b 75 |..B.yW.......7ku|
+000002b0 79 17 fa 67 7f 94 2e aa 88 61 91 97 dc 10 1e e6 |y..g.....a......|
+000002c0 6d 6d fa d5 64 17 f4 ec ba 01 43 99 88 e2 a7 13 |mm..d.....C.....|
+000002d0 e0 9e 6a e9 97 c7 b3 ec b9 c9 72 51 3d 01 eb c0 |..j.......rQ=...|
+000002e0 03 0f 08 48 90 27 36 6b bd e7 0d 4e 41 6a ef 11 |...H.'6k...NAj..|
+000002f0 42 5b ae d1 16 ec 8f b7 47 a2 f5 b4 6a d4 32 bb |B[......G...j.2.|
+00000300 0c cc 4f 2a e0 be 44 47 c8 77 09 f5 78 4b d6 ec |..O*..DG.w..xK..|
+00000310 87 95 dc e1 74 75 54 af 45 bb 7a f5 2e f7 ac 3d |....tuT.E.z....=|
+00000320 d1 b2 31 5a c0 24 c7 7c 25 36 62 a7 48 73 66 44 |..1Z.$.|%6b.HsfD|
+00000330 c1 78 47 f3 48 c5 a0 f7 66 3e 78 27 2c 3c dc 83 |.xG.H...f>x',<..|
+00000340 f5 6c e1 09 31 14 03 03 00 11 79 32 99 fd 2d 8d |.l..1.....y2..-.|
+00000350 14 33 fd 1b 1b a8 3d 99 4b 0a b7 16 03 03 00 20 |.3....=.K...... |
+00000360 76 25 53 83 f2 c5 bf a6 fa 2e d3 5a 62 67 5b 1d |v%S........Zbg[.|
+00000370 23 9a 9c b3 16 01 3f 6a e9 4c ea e1 d4 d1 09 42 |#.....?j.L.....B|
+>>> Flow 10 (server to client)
+00000000 14 03 03 00 11 a7 38 2a 4e 04 a5 b7 df d6 05 bb |......8*N.......|
+00000010 b5 93 38 bc 9e 62 16 03 03 00 20 f3 d3 e1 7d 80 |..8..b.... ...}.|
+00000020 41 ce 05 99 92 c7 47 fe b5 08 3b 78 9d ae b0 5f |A.....G...;x..._|
+00000030 2c ed bd 0b 90 e0 94 9e 0b b0 a5 17 03 03 00 19 |,...............|
+00000040 27 f0 6a 55 af 3f c1 82 85 1a 6b 28 e1 cd dc 59 |'.jU.?....k(...Y|
+00000050 43 be c7 18 16 30 08 b2 9e 16 03 03 00 14 c1 c5 |C....0..........|
+00000060 64 ef 72 4f 6c 96 f1 f6 5b 70 29 e4 59 36 0a cd |d.rOl...[p).Y6..|
+00000070 d2 a3 |..|
+>>> Flow 11 (client to server)
+00000000 15 03 03 00 12 af 73 0e 40 39 dd 1e 04 99 3e 10 |......s.@9....>.|
+00000010 c9 62 b3 78 77 9b 56 15 03 03 00 12 25 8b 87 29 |.b.xw.V.....%..)|
+00000020 82 d0 9f 5e 9a 27 bd c1 bf b7 a2 f0 92 ac |...^.'........|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-RenegotiationRejected b/src/crypto/tls/testdata/Client-TLSv12-RenegotiationRejected
new file mode 100644
index 0000000..f7a7668
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-RenegotiationRejected
@@ -0,0 +1,95 @@
+>>> 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 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 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 59 02 00 00 55 03 03 a3 55 d2 e2 bd |....Y...U...U...|
+00000010 94 8f 04 51 26 1c a6 61 b1 ed 05 e2 39 44 33 05 |...Q&..a....9D3.|
+00000020 79 14 b7 1f 89 1e bb ba 53 0d 12 20 09 29 6d 26 |y.......S.. .)m&|
+00000030 04 70 4a 5d 01 90 f2 c6 28 df 11 6a 64 23 ec 9e |.pJ]....(..jd#..|
+00000040 9f 2b 15 33 dc 88 26 35 3a b0 86 92 cc a8 00 00 |.+.3..&5:.......|
+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 ac 0c 00 00 a8 03 00 1d 20 43 6b 44 5b 79 c9 38 |........ CkD[y.8|
+000002d0 dc e4 ab fa 88 fa e6 06 89 b1 4e ff ab 8d d6 f7 |..........N.....|
+000002e0 21 b4 ff 9d a0 c8 54 cc 63 08 04 00 80 cd f4 d6 |!.....T.c.......|
+000002f0 c8 ad 03 e7 f0 e8 f4 c9 f0 e6 28 db cd 3b 7c bf |..........(..;|.|
+00000300 05 af 3d fe c1 f9 f1 7a ec 41 bf 1f a8 95 6d ee |..=....z.A....m.|
+00000310 e6 92 cb c0 ff fd c1 ed 86 b0 59 45 3e 2d 1d 66 |..........YE>-.f|
+00000320 56 d1 9f e2 b7 79 ac aa 81 6d b0 42 36 96 80 4d |V....y...m.B6..M|
+00000330 ca 36 29 1b 65 03 73 3f 85 ec 59 cb b4 a5 a0 c0 |.6).e.s?..Y.....|
+00000340 0c 16 ad e2 6b 35 3c ab 1e da 69 19 7d a2 63 a7 |....k5<...i.}.c.|
+00000350 69 2a d2 3f 12 17 bf 4c ed 8a f7 75 fe ce d4 2b |i*.?...L...u...+|
+00000360 4d 35 bf 65 d6 9e 01 69 a8 0a 73 26 34 16 03 03 |M5.e...i..s&4...|
+00000370 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 b8 d8 22 20 8d 69 23 05 34 eb 69 |.... .." .i#.4.i|
+00000040 92 a0 a9 6c cd 94 3b 72 49 91 72 8e 65 79 ca 62 |...l..;rI.r.ey.b|
+00000050 14 cf da 2e b6 |.....|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 20 31 25 d4 c7 92 |.......... 1%...|
+00000010 16 0b 92 2d a2 20 8b b2 c7 96 a6 b7 b6 b3 82 3a |...-. .........:|
+00000020 4d a1 a8 96 29 fb 99 e9 ea 04 6c |M...).....l|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 16 8b 92 f3 f8 99 bf a3 7c c4 03 d8 |............|...|
+00000010 4d e7 1b ad 50 e1 99 17 33 68 e2 |M...P...3h.|
+>>> Flow 6 (server to client)
+00000000 16 03 03 00 14 91 99 15 68 ae 92 52 bd 13 75 45 |........h..R..uE|
+00000010 6d a9 f0 2d ee f5 c3 9b e7 |m..-.....|
+>>> Flow 7 (client to server)
+00000000 15 03 03 00 12 be 8b 4b a6 a7 7a 62 45 32 ff db |.......K..zbE2..|
+00000010 07 ad a0 1b 46 9d c9 15 03 03 00 12 16 da d4 86 |....F...........|
+00000020 4f c8 26 5a d0 34 82 fe 47 34 ae 31 db a7 |O.&Z.4..G4.1..|
diff --git a/src/crypto/tls/testdata/Client-TLSv12-SCT b/src/crypto/tls/testdata/Client-TLSv12-SCT
new file mode 100644
index 0000000..8492ee9
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv12-SCT
@@ -0,0 +1,113 @@
+>>> 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 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 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 01 c6 02 00 01 c2 03 03 b0 59 eb bc ae |............Y...|
+00000010 f3 42 03 d1 fe 2c 7d 6f 0e ff e4 0c 9e 13 00 b9 |.B...,}o........|
+00000020 46 99 e2 84 49 64 a9 05 05 8a fb 20 16 12 dc b7 |F...Id..... ....|
+00000030 e0 09 a2 a6 56 83 43 54 de 40 53 47 43 f0 2f c9 |....V.CT.@SGC./.|
+00000040 2d 92 5e a0 9d a3 6a c4 55 17 01 cb cc a8 00 01 |-.^...j.U.......|
+00000050 7a 00 12 01 69 01 67 00 75 00 a4 b9 09 90 b4 18 |z...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 16 03 03 02 59 |...............Y|
+000001d0 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 82 |...U..R..O0..K0.|
+000001e0 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 5b |.............?.[|
+000001f0 ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 |..0...*.H.......|
+00000200 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 6f |.0.1.0...U....Go|
+00000210 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 6f |1.0...U....Go Ro|
+00000220 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 30 |ot0...1601010000|
+00000230 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 30 |00Z..25010100000|
+00000240 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 47 |0Z0.1.0...U....G|
+00000250 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 81 |o1.0...U....Go0.|
+00000260 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 |.0...*.H........|
+00000270 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 2e |....0.......F}..|
+00000280 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe 1e |.'.H..(!.~...]..|
+00000290 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 be |RE.z6G....B[....|
+000002a0 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 |.y.@.Om..+.....g|
+000002b0 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 f1 |....."8.J.ts+.4.|
+000002c0 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 41 |.....t{.X.la<..A|
+000002d0 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 54 |..++$#w[.;.u]. T|
+000002e0 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 14 |..c...$....P....|
+000002f0 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 01 |C...ub...R......|
+00000300 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 ff |...0..0...U.....|
+00000310 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 30 |......0...U.%..0|
+00000320 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 01 |...+.........+..|
+00000330 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff 04 |.....0...U......|
+00000340 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f 91 |.0.0...U........|
+00000350 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 1b |..CC>I..m....`0.|
+00000360 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d 13 |..U.#..0...H.IM.|
+00000370 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 55 |~.1......n{0...U|
+00000380 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 2e |....0...example.|
+00000390 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 0d |golang0...*.H...|
+000003a0 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b 50 |..........0.@+[P|
+000003b0 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 38 |.a...SX...(.X..8|
+000003c0 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b f2 |....1Z..f=C.-...|
+000003d0 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 40 |... d8.$:....}.@|
+000003e0 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 0c | ._...a..v......|
+000003f0 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d 0c |\.....l..s..Cw..|
+00000400 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db 46 |.....@.a.Lr+...F|
+00000410 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d 13 |..M...>...B...=.|
+00000420 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 ac 0c 00 |`.\!.;..........|
+00000430 00 a8 03 00 1d 20 4c 46 c9 9f ed 2e 81 0f 8c 4b |..... LF.......K|
+00000440 bc 05 53 74 c6 c8 76 99 21 94 1b 8f 93 c6 64 ce |..St..v.!.....d.|
+00000450 e9 9d 6b 1d 66 51 08 04 00 80 09 9e c2 21 89 93 |..k.fQ.......!..|
+00000460 1f c5 2e 2c fa 67 7b 42 23 e1 e0 67 5c 6d e9 1e |...,.g{B#..g\m..|
+00000470 e8 a2 ac d7 cf f4 12 98 f6 e6 3d 51 0c 2c 29 ad |..........=Q.,).|
+00000480 f8 8e 24 2a a3 99 2e f3 b2 a7 fe a9 6c e9 00 d8 |..$*........l...|
+00000490 6a 7f 41 12 84 a0 d6 19 38 b1 5a 13 b6 71 cf bd |j.A.....8.Z..q..|
+000004a0 e2 6e 04 01 c8 cd 83 12 71 85 ae bc 94 b1 e4 4d |.n......q......M|
+000004b0 a5 5f 9e a5 5d 95 76 fe f5 d6 a9 f0 4c 07 c9 6e |._..].v.....L..n|
+000004c0 fc 4a 56 2b 56 4e 9c ec 2c fe bc 9c 9e 57 f3 90 |.JV+VN..,....W..|
+000004d0 c6 6e 77 5a cf 8c 1a 15 cd 90 16 03 03 00 04 0e |.nwZ............|
+000004e0 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 19 bf ac 05 d4 bb 8a 6d 11 f4 98 |.... .......m...|
+00000040 0d af 78 57 49 74 5c 44 45 9e 2c 92 26 b9 10 b5 |..xWIt\DE.,.&...|
+00000050 6d 5f 24 bc a6 |m_$..|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 20 69 3a c4 9c ee |.......... i:...|
+00000010 91 6b bc 33 39 82 64 c2 0a f0 a4 dd 85 16 3c ce |.k.39.d.......<.|
+00000020 39 c4 98 37 77 47 1e c2 c6 d8 f6 |9..7wG.....|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 16 92 25 9b 97 11 08 71 63 b2 c1 35 |......%....qc..5|
+00000010 14 3b e7 15 f6 05 67 51 46 db ba 15 03 03 00 12 |.;....gQF.......|
+00000020 b2 53 a1 ec a8 cf 79 7d f8 86 70 05 e5 81 a1 6c |.S....y}..p....l|
+00000030 41 ab |A.|
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..3d3de61
--- /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 f4 01 00 00 f0 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 75 00 05 00 05 01 00 00 00 00 00 0a 00 |...u............|
+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 12 |................|
+000000c0 00 00 00 2b 00 09 08 03 04 03 03 03 02 03 01 00 |...+............|
+000000d0 33 00 26 00 24 00 1d 00 20 2f e5 7d a3 47 cd 62 |3.&.$... /.}.G.b|
+000000e0 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 cf |C.(.._.).0......|
+000000f0 c2 ed 90 99 5f 58 cb 3b 74 |...._X.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 59 02 00 00 55 03 03 f7 79 97 18 3c |....Y...U...y..<|
+00000010 fa 52 c6 d2 6b 1e de a5 60 da d5 e2 0b f6 23 a8 |.R..k...`.....#.|
+00000020 48 94 e8 1f fb b9 76 43 94 e8 98 20 31 a5 85 d5 |H.....vC... 1...|
+00000030 2f c4 93 b1 ae aa 50 bc 14 9e 57 79 18 85 cd ef |/.....P...Wy....|
+00000040 b4 f0 42 c9 6c b1 86 c1 03 27 ca df c0 2f 00 00 |..B.l....'.../..|
+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 ac 0c 00 00 a8 03 00 1d 20 90 95 bd 82 cf 8a cc |........ .......|
+000002d0 08 b4 09 09 8d 59 2d 03 7a bb 92 4a c4 5c 08 4d |.....Y-.z..J.\.M|
+000002e0 42 a3 ba cb 9a 43 ae f0 22 08 04 00 80 a0 97 ac |B....C..".......|
+000002f0 01 a5 c8 7b 4c 73 7e 70 7a 9a fc 9d 71 2f fe 67 |...{Ls~pz...q/.g|
+00000300 ca dd 6b 43 db 64 0f 64 52 e7 d3 5d 6d b2 7c 50 |..kC.d.dR..]m.|P|
+00000310 74 7e 80 d5 22 77 3f fb c2 e8 dc 92 37 4f 1e 1e |t~.."w?.....7O..|
+00000320 e7 13 f2 01 33 80 32 66 4f c2 17 8e ec 4f ed 4a |....3.2fO....O.J|
+00000330 15 6c e8 86 ec df d5 46 6c a5 43 0d 40 fe a0 c8 |.l.....Fl.C.@...|
+00000340 65 b4 76 46 b8 36 2c da 87 7c 60 87 db 39 4c 2e |e.vF.6,..|`..9L.|
+00000350 0f e4 72 32 11 26 99 7e c8 7a c0 bc 9c a7 29 57 |..r2.&.~.z....)W|
+00000360 9d 27 37 4e ec c5 bb fd a1 3c f3 66 63 16 03 03 |.'7N.....<.fc...|
+00000370 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 81 b1 2c |....(..........,|
+00000040 a2 3b 38 34 a6 66 57 02 e3 67 1b ee 73 95 50 de |.;84.fW..g..s.P.|
+00000050 dd 5a fd 4e 0d ee b7 a6 46 1a 34 61 73 |.Z.N....F.4as|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 28 2f a9 80 36 d8 |..........(/..6.|
+00000010 d0 74 e4 39 46 04 88 8e 91 ea fd 96 ed 1f 89 9f |.t.9F...........|
+00000020 a4 e9 24 0e ca 48 2b 5c 5d f1 cc 57 ce 92 1a ad |..$..H+\]..W....|
+00000030 b9 10 11 |...|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 1e 00 00 00 00 00 00 00 01 da be 68 |...............h|
+00000010 97 b4 a4 72 d0 ed 75 66 6a a9 6f 39 8a 08 a9 db |...r..ufj.o9....|
+00000020 de 4d e1 15 03 03 00 1a 00 00 00 00 00 00 00 02 |.M..............|
+00000030 14 90 0e 1d 26 5c 18 c6 5c 93 66 c4 90 78 a8 91 |....&\..\.f..x..|
+00000040 cb fd |..|
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..f8a733e
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv13-AES128-SHA256
@@ -0,0 +1,90 @@
+>>> 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 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 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 7a 02 00 00 76 03 03 f1 4c f4 16 24 |....z...v...L..$|
+00000010 e5 c6 b5 ce 72 08 3b 33 9f 1f 1f 80 2c 10 0b 34 |....r.;3....,..4|
+00000020 01 99 85 ba b0 3c 85 50 3d bf 73 20 00 00 00 00 |.....<.P=.s ....|
+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 69 |..+.....3.$... i|
+00000060 94 3b 83 cd 1f 93 53 53 82 de 14 cb 76 2a 19 62 |.;....SS....v*.b|
+00000070 0f f8 9e d1 e3 e0 a9 d5 23 ac 07 64 53 27 4b 14 |........#..dS'K.|
+00000080 03 03 00 01 01 17 03 03 00 17 ef 24 2c ea 6f 05 |...........$,.o.|
+00000090 c2 07 7a d2 12 30 ce 01 f4 96 b8 dc e6 c2 27 02 |..z..0........'.|
+000000a0 bd 17 03 03 02 6d 99 2b cb 79 43 01 66 24 eb f1 |.....m.+.yC.f$..|
+000000b0 14 d2 ea 1e 57 67 81 e3 a0 9c 99 1b 1f d5 f0 c7 |....Wg..........|
+000000c0 78 48 61 01 42 25 85 0b cd a1 b1 75 3c 50 01 cc |xHa.B%.....u<P..|
+000000d0 69 09 22 a5 fb db 43 76 2f 4e 34 4e 14 a3 e4 89 |i."...Cv/N4N....|
+000000e0 f7 d7 cd 66 da b3 1d fd f0 98 60 18 41 09 a5 22 |...f......`.A.."|
+000000f0 6d c9 21 bc c3 cd 53 ca c3 a5 d7 24 57 b4 f5 bc |m.!...S....$W...|
+00000100 ec b1 48 70 12 55 a5 a6 01 10 68 0f c4 e5 de 89 |..Hp.U....h.....|
+00000110 f9 0d ab 48 92 d4 12 d7 75 77 c3 2f ae 2f 6f 58 |...H....uw././oX|
+00000120 2d 6e ad 72 43 dc ce 4b c9 74 3d eb db da 37 2c |-n.rC..K.t=...7,|
+00000130 1e a2 86 c4 b3 64 69 f6 84 ce 52 b5 32 c6 b9 c2 |.....di...R.2...|
+00000140 49 2d 08 f9 d4 9a 29 09 5b 71 09 81 a3 19 c2 4d |I-....).[q.....M|
+00000150 8c 48 2c e3 c6 cb 81 d4 7f 10 b3 c8 2b 21 ad 83 |.H,.........+!..|
+00000160 97 d2 bd 11 90 39 1e f4 de 65 e2 e8 e8 c7 ce f9 |.....9...e......|
+00000170 6d ad b0 60 5c 4b 59 c4 96 ce b3 a1 83 b2 7c 71 |m..`\KY.......|q|
+00000180 74 e6 a9 a7 89 bf 8d 0d 6c 8d b5 04 33 38 ff 68 |t.......l...38.h|
+00000190 42 0e 84 da d2 b2 16 29 83 66 82 a9 2a d2 67 1b |B......).f..*.g.|
+000001a0 18 a6 7d e3 f1 d3 f1 b4 cc 6c 14 e2 cd 2d 96 7b |..}......l...-.{|
+000001b0 76 dd b0 1d 24 7f ea c0 14 24 d7 37 00 7c cd e3 |v...$....$.7.|..|
+000001c0 20 33 a4 3a 22 2a be 3e e8 f8 7c 0d 3e 51 f7 6b | 3.:"*.>..|.>Q.k|
+000001d0 ce f3 51 cf 7e ae 55 40 bb ab 0e 40 6b d9 8a 3b |..Q.~.U@...@k..;|
+000001e0 d5 f2 1f 76 6a 05 9b 87 e2 3b db fa cc e8 93 8a |...vj....;......|
+000001f0 d9 ba 2b 63 77 77 62 f1 22 ce 11 a9 26 b5 e8 a2 |..+cwwb."...&...|
+00000200 ec 3f 98 44 01 27 d7 e1 39 26 33 e3 86 00 60 f7 |.?.D.'..9&3...`.|
+00000210 a7 91 07 45 f8 3f 78 dc 88 71 30 26 0c f9 0d 51 |...E.?x..q0&...Q|
+00000220 2a c5 ce 33 ac b7 91 a9 74 2e 46 68 80 6e 62 cd |*..3....t.Fh.nb.|
+00000230 2d 5e 43 fe bd d1 37 07 71 85 5d c7 38 17 50 3a |-^C...7.q.].8.P:|
+00000240 1c 5e 9f cf 1e 3c 96 d0 26 5d 4c 82 78 a8 69 e7 |.^...<..&]L.x.i.|
+00000250 d3 9a 81 e5 85 66 c3 d9 74 a1 82 9d fb 24 81 13 |.....f..t....$..|
+00000260 0d ce cb 43 61 3c 3a a7 d1 80 7f 1d 41 d8 62 43 |...Ca<:.....A.bC|
+00000270 c6 08 5d 91 05 ed 2c 50 04 42 8c db 2a 11 61 96 |..]...,P.B..*.a.|
+00000280 9b d2 1d 40 af 83 ed 93 06 ba 65 22 0a a5 e8 a6 |...@......e"....|
+00000290 b9 4a 63 6f c0 ac da 72 10 24 c6 ed 08 86 c8 a1 |.Jco...r.$......|
+000002a0 92 5e d0 d8 8b 04 b7 43 50 0b 03 41 3f f9 96 16 |.^.....CP..A?...|
+000002b0 a3 c8 09 e8 ac 91 b2 45 d5 58 5f 41 05 7c b3 88 |.......E.X_A.|..|
+000002c0 7a 59 cd 1a 00 86 29 72 77 a5 19 43 32 79 fc d6 |zY....)rw..C2y..|
+000002d0 d7 e9 81 08 e3 d9 d9 56 39 59 7c 1e d3 10 3e a4 |.......V9Y|...>.|
+000002e0 c6 80 d3 8b 9b 36 51 c5 d3 14 64 a6 65 e2 1a 26 |.....6Q...d.e..&|
+000002f0 c4 a8 31 07 bb 58 8c 9b d8 7d 86 fd 54 6c c9 ae |..1..X...}..Tl..|
+00000300 7d 88 4b 13 0f 52 10 41 d6 be 01 32 f2 42 47 0f |}.K..R.A...2.BG.|
+00000310 7a 8c 7e 17 03 03 00 99 8b ce c4 db 9c 9c 88 e3 |z.~.............|
+00000320 88 58 de 8f 10 e9 fb 4a c7 26 96 60 48 84 2c b1 |.X.....J.&.`H.,.|
+00000330 2b 6c 35 70 8a d7 39 91 51 d7 3f db 81 f0 41 07 |+l5p..9.Q.?...A.|
+00000340 a2 c9 c1 74 76 62 58 f1 cb e2 50 48 57 bb 6e 3d |...tvbX...PHW.n=|
+00000350 ee ee 4a 53 e7 3c 66 aa e3 d9 c1 f1 74 1a 93 b9 |..JS.<f.....t...|
+00000360 44 90 f6 a5 a4 da f5 6b 75 01 38 52 8f 9c ab 01 |D......ku.8R....|
+00000370 78 88 a6 cc 65 15 61 a8 8c cc 14 59 07 ea 6f 25 |x...e.a....Y..o%|
+00000380 5c 86 89 16 eb e7 da 20 82 d7 96 e4 78 7a c3 36 |\...... ....xz.6|
+00000390 b3 5c e7 17 1b 07 30 a2 72 ca a2 f3 dc 7e 45 c9 |.\....0.r....~E.|
+000003a0 7f 94 f8 a1 7b bb 2a 30 d7 bc 51 03 fb e6 2a fa |....{.*0..Q...*.|
+000003b0 17 17 03 03 00 35 c1 a0 76 b6 35 4b 5c 26 94 c6 |.....5..v.5K\&..|
+000003c0 ba b1 7b b1 13 00 f2 2c 17 ed ac ab 47 9a a1 8d |..{....,....G...|
+000003d0 3a 1c 78 44 14 a1 04 31 3d eb 9a 8d bb 2f 73 46 |:.xD...1=..../sF|
+000003e0 cb 5c f6 86 81 fa 56 fb 39 8c 55 |.\....V.9.U|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 97 2c 39 3a a5 |..........5.,9:.|
+00000010 32 33 e5 74 43 97 98 ef ef 30 de 27 8b f7 b5 ab |23.tC....0.'....|
+00000020 dd af 87 7c a5 5e 76 cf 50 2a 03 f8 94 a4 7a df |...|.^v.P*....z.|
+00000030 14 0a 2d 39 57 3b 02 97 c5 d7 63 85 21 3f 55 27 |..-9W;....c.!?U'|
+00000040 17 03 03 00 17 7c b4 8b 82 f0 0a ec 6f fa 60 ef |.....|......o.`.|
+00000050 4c 0a 1c 0b ad 99 c3 89 fb a4 40 2c 17 03 03 00 |L.........@,....|
+00000060 13 f2 d5 58 ba 6b ca e8 f4 14 4c 66 23 38 f2 e8 |...X.k....Lf#8..|
+00000070 ea a9 ba c1 |....|
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..8ea3ed6
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv13-AES256-SHA384
@@ -0,0 +1,92 @@
+>>> 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 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 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 7a 02 00 00 76 03 03 71 00 90 30 07 |....z...v..q..0.|
+00000010 24 01 ae 33 b2 e8 4f 1f 9a 2c 83 e5 7b 30 1e a2 |$..3..O..,..{0..|
+00000020 8e 4a d0 df d1 ec 23 b5 ba aa 75 20 00 00 00 00 |.J....#...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 02 00 00 |................|
+00000050 2e 00 2b 00 02 03 04 00 33 00 24 00 1d 00 20 06 |..+.....3.$... .|
+00000060 2a 26 bd 81 c2 90 9b 17 6e d0 b5 ab 72 e6 93 ce |*&......n...r...|
+00000070 53 6d 8c 54 b5 a4 50 91 93 32 6e 88 e6 b2 69 14 |Sm.T..P..2n...i.|
+00000080 03 03 00 01 01 17 03 03 00 17 7d 11 37 f0 18 b1 |..........}.7...|
+00000090 53 55 38 bb 12 7c e8 b3 89 bc 35 fb 2a 36 d1 0f |SU8..|....5.*6..|
+000000a0 3a 17 03 03 02 6d a0 fa dc 8e ac a6 90 5a 20 0e |:....m.......Z .|
+000000b0 ee 22 89 7b 69 5b c9 1a a1 c6 43 b9 40 f6 85 78 |.".{i[....C.@..x|
+000000c0 61 0b 14 c6 e6 3b a9 ac 4c 7a 96 9b 7b 87 d0 ce |a....;..Lz..{...|
+000000d0 42 cc 75 9d fc 06 44 3e e8 12 3a 94 b7 de 86 c4 |B.u...D>..:.....|
+000000e0 b5 66 e1 f5 48 21 f7 f1 58 7f 23 6c 3f 76 a0 cb |.f..H!..X.#l?v..|
+000000f0 a7 f6 72 34 07 fa c1 55 3e 61 cf 72 c4 6c f1 ca |..r4...U>a.r.l..|
+00000100 dd dc ec 66 3d 7b f6 cf 53 3b 28 bd 27 1b aa a6 |...f={..S;(.'...|
+00000110 28 2a ab fa 48 a5 08 67 b5 49 c7 c7 5d f8 2c ec |(*..H..g.I..].,.|
+00000120 83 af 58 33 42 6c c1 4c 94 17 7e 36 1c a9 48 34 |..X3Bl.L..~6..H4|
+00000130 5f 26 78 f6 69 88 3a a5 1b d1 76 ad 88 63 25 33 |_&x.i.:...v..c%3|
+00000140 0d e3 d0 34 6b 7f fc 96 2b 8d 22 6f 3f 21 8a 14 |...4k...+."o?!..|
+00000150 01 e0 5c 54 6c c3 b8 12 f9 17 f5 4c ce e0 bd 10 |..\Tl......L....|
+00000160 e7 e1 29 24 73 94 c2 5e b0 ad d3 91 9e 87 ea 23 |..)$s..^.......#|
+00000170 4d fd 8f 12 ca 87 ff 2e 93 9f 16 a8 18 e1 66 8f |M.............f.|
+00000180 50 76 15 cd 70 5c a2 1d 91 51 e5 54 13 5f 73 d3 |Pv..p\...Q.T._s.|
+00000190 b2 6e b1 27 80 0b 3d 64 d5 fa f3 a4 fb 77 33 cb |.n.'..=d.....w3.|
+000001a0 ac 93 54 36 2d 71 c3 9e dd 37 02 a9 9d b0 9b ac |..T6-q...7......|
+000001b0 f8 c5 dc 43 9b d8 db c7 d0 fb cf 69 fa 62 e4 9d |...C.......i.b..|
+000001c0 b7 04 f8 49 d3 a7 8d bd cf 8a e3 4a 62 cb bb 29 |...I.......Jb..)|
+000001d0 b5 db 21 80 76 eb 28 67 34 1e 40 0b 83 83 19 10 |..!.v.(g4.@.....|
+000001e0 46 8f bd 78 d6 7c 05 c2 19 82 1c e8 7d 84 f2 79 |F..x.|......}..y|
+000001f0 c4 a6 e0 f7 7e df 70 7f 42 48 9f e4 99 03 7f 9e |....~.p.BH......|
+00000200 e8 fd 75 c3 8a 55 55 8e 08 2e 62 28 a5 16 b7 11 |..u..UU...b(....|
+00000210 d8 9a 11 48 46 ad d3 ba 4f 91 c8 fd 72 d9 df 98 |...HF...O...r...|
+00000220 1a 59 51 55 af ab 73 b9 f3 bf fe 7d 55 7d 44 54 |.YQU..s....}U}DT|
+00000230 cd bb f3 eb 6e ff 5a 09 e9 b9 c1 66 97 8e a5 7c |....n.Z....f...||
+00000240 89 4a 51 1d 8b e4 40 fb 97 ce ef 9d 7c 02 e4 db |.JQ...@.....|...|
+00000250 f1 ca 01 d9 05 b4 de 10 23 33 92 ff 26 3b 09 8f |........#3..&;..|
+00000260 11 7c 37 ad fb 58 ed 7a 10 08 fd df 98 dd d6 c5 |.|7..X.z........|
+00000270 b8 fd 59 37 21 1d 6e 27 8a 56 24 45 e7 64 61 0b |..Y7!.n'.V$E.da.|
+00000280 20 2d bc 79 89 fa 6d 7a 06 77 61 0c 60 25 e2 79 | -.y..mz.wa.`%.y|
+00000290 6a 54 9e 5b 4b 33 68 17 da 63 ba a7 f9 ad 2c 84 |jT.[K3h..c....,.|
+000002a0 52 e9 27 85 71 74 d2 5f c9 f8 8e 67 f7 47 58 f5 |R.'.qt._...g.GX.|
+000002b0 e4 72 a7 bd 1c 94 4b 4d 13 5a 62 69 d9 6f 3a 51 |.r....KM.Zbi.o:Q|
+000002c0 f0 18 90 e5 b6 21 23 97 70 74 93 ba 9b bc dc e4 |.....!#.pt......|
+000002d0 3d 9c 52 3f 93 f0 48 05 e8 50 d0 b4 98 92 7a 18 |=.R?..H..P....z.|
+000002e0 3f 39 ba f8 f7 ee 19 b0 ce ac d0 ab 9e 83 ee 0e |?9..............|
+000002f0 5d 2a 72 74 a8 8b 4d de 6b a9 91 ad b4 a4 26 99 |]*rt..M.k.....&.|
+00000300 4e aa 6d 48 77 83 78 78 be 96 f1 17 d6 96 74 4a |N.mHw.xx......tJ|
+00000310 80 d1 5b 17 03 03 00 99 d9 40 96 5c fb 5d 65 69 |..[......@.\.]ei|
+00000320 db 54 a8 f6 8c b7 d3 25 8d 2d c5 f1 40 5b f2 26 |.T.....%.-..@[.&|
+00000330 f3 86 9e 61 6a a5 b9 66 b1 27 b1 20 6b 2c 64 84 |...aj..f.'. k,d.|
+00000340 3f 48 24 5d d9 90 4b d1 ed 1b 0e 05 84 7f ad 0e |?H$]..K.........|
+00000350 e6 75 f6 f9 33 90 73 7c 88 10 d7 e9 74 41 4b c3 |.u..3.s|....tAK.|
+00000360 19 8e e1 a8 a6 7c 3c 9a bc 69 a7 e7 bb d6 af 98 |.....|<..i......|
+00000370 f1 49 53 14 95 80 d6 95 81 5a 5e 88 2c 29 70 df |.IS......Z^.,)p.|
+00000380 b2 df fe f3 17 03 e7 de af 12 57 c5 7a ef 70 eb |..........W.z.p.|
+00000390 8a c6 c3 05 de 5b 15 af 5f 54 8c 7b 23 b7 e1 f1 |.....[.._T.{#...|
+000003a0 30 b1 ed 34 4c 59 f5 68 c2 50 e8 c3 83 78 1d 1f |0..4LY.h.P...x..|
+000003b0 eb 17 03 03 00 45 1a d4 61 ba 4a a5 1e 02 80 04 |.....E..a.J.....|
+000003c0 2a 19 11 af 8c e9 bd ab 22 6b 75 41 a8 40 de 57 |*......."kuA.@.W|
+000003d0 54 8c dc 09 cc 57 76 82 27 5e 59 0c 30 f7 9d c4 |T....Wv.'^Y.0...|
+000003e0 fe 1c 09 f2 f4 5f e0 79 ac 02 06 80 f3 60 c4 92 |....._.y.....`..|
+000003f0 cd 6a df b6 46 7c de 90 8d bb 94 |.j..F|.....|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 45 8c 37 d5 7e 3e |..........E.7.~>|
+00000010 c4 24 64 8b fa fc 8d 03 a7 92 34 35 c3 2c f2 54 |.$d.......45.,.T|
+00000020 43 06 5d 8a c9 c0 e8 7d 22 d3 99 58 01 0e 44 aa |C.]....}"..X..D.|
+00000030 3c 26 eb 68 45 14 cd bf 6c 61 bb 31 91 9d b4 57 |<&.hE...la.1...W|
+00000040 42 79 14 8c 67 c6 65 52 15 07 c8 f3 c3 9f 23 ef |By..g.eR......#.|
+00000050 17 03 03 00 17 21 51 dd 67 e4 be f8 7c 7b 84 0d |.....!Q.g...|{..|
+00000060 78 3c 7f ac 50 f8 34 7b fb 38 09 d0 17 03 03 00 |x<..P.4{.8......|
+00000070 13 35 1a 52 9d de 4a 74 1f 01 70 de 05 c5 c3 b9 |.5.R..Jt..p.....|
+00000080 e6 de 9c 0f |....|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-ALPN b/src/crypto/tls/testdata/Client-TLSv13-ALPN
new file mode 100644
index 0000000..1d8da26
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv13-ALPN
@@ -0,0 +1,93 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 01 0e 01 00 01 0a 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 8f 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 10 00 10 00 0e 06 70 72 6f 74 6f |...........proto|
+000000d0 32 06 70 72 6f 74 6f 31 00 12 00 00 00 2b 00 09 |2.proto1.....+..|
+000000e0 08 03 04 03 03 03 02 03 01 00 33 00 26 00 24 00 |..........3.&.$.|
+000000f0 1d 00 20 2f e5 7d a3 47 cd 62 43 15 28 da ac 5f |.. /.}.G.bC.(.._|
+00000100 bb 29 07 30 ff f6 84 af c4 cf c2 ed 90 99 5f 58 |.).0.........._X|
+00000110 cb 3b 74 |.;t|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 7a 02 00 00 76 03 03 c2 91 70 7a 7a |....z...v....pzz|
+00000010 d4 c9 46 7a e9 44 d1 c0 92 a6 0a 43 34 08 b2 ce |..Fz.D.....C4...|
+00000020 14 99 8f 6c f7 37 fb a1 28 00 ae 20 00 00 00 00 |...l.7..(.. ....|
+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 60 |..+.....3.$... `|
+00000060 96 62 c2 30 4e ae b6 89 f2 06 e0 4e 8e 32 27 04 |.b.0N......N.2'.|
+00000070 b5 74 80 d8 c3 f5 76 7d 0e 0e e1 8d bc 2c 2c 14 |.t....v}.....,,.|
+00000080 03 03 00 01 01 17 03 03 00 24 45 c7 50 3e a9 63 |.........$E.P>.c|
+00000090 24 0b e9 80 3f 59 bb be 23 8a 5d 46 eb ee 17 9c |$...?Y..#.]F....|
+000000a0 70 6f 52 1f 18 f3 9f 72 d6 35 44 55 91 d2 17 03 |poR....r.5DU....|
+000000b0 03 02 6d c2 c0 1f 53 2a 0c 3c 7f 08 c3 cb 53 4e |..m...S*.<....SN|
+000000c0 b2 f5 b3 2d a5 10 e1 97 00 89 67 db 4e df ad 75 |...-......g.N..u|
+000000d0 94 b4 56 c4 8a a3 49 41 43 a1 3f aa 9b 8e e1 8d |..V...IAC.?.....|
+000000e0 4c 9c 36 f6 80 da 4e 7f 00 10 c0 81 3e 45 1b a0 |L.6...N.....>E..|
+000000f0 b7 7f 2c bd eb 2a 8b c4 e6 fa c8 b3 59 28 f6 b8 |..,..*......Y(..|
+00000100 0a 93 cb b3 bf 28 e7 1a ae a0 f5 ff 3a 42 f5 64 |.....(......:B.d|
+00000110 92 2c dd c2 24 77 2f a6 7e 23 63 3f 24 16 b3 d5 |.,..$w/.~#c?$...|
+00000120 b7 df 3f 30 23 a4 aa c9 14 78 6c f2 82 45 52 df |..?0#....xl..ER.|
+00000130 cf a1 1d 35 fd 2a 30 89 14 38 5a 23 b1 63 2c c1 |...5.*0..8Z#.c,.|
+00000140 6d 6b 07 d0 41 38 4f 4c 87 d3 bd f1 ec ed 29 52 |mk..A8OL......)R|
+00000150 3d c7 74 3d e9 d3 ce 47 1c 24 d5 78 19 c9 5e 01 |=.t=...G.$.x..^.|
+00000160 66 a0 f1 8f ea a6 c1 e4 b4 e0 c2 2e d7 d6 64 36 |f.............d6|
+00000170 c9 bc d1 27 33 6f 26 a8 c6 aa 0d bc ae f9 2e bc |...'3o&.........|
+00000180 f1 a7 82 42 09 83 62 88 c0 9f 20 95 a9 38 50 b4 |...B..b... ..8P.|
+00000190 55 d6 e9 f4 c6 a1 e6 67 a9 5f e4 15 97 44 13 ef |U......g._...D..|
+000001a0 d3 50 8b 61 38 5e 89 75 b1 cf 6a 6f 0c c5 26 13 |.P.a8^.u..jo..&.|
+000001b0 2c 5a 26 c9 81 98 88 cd ec 8c 2c 99 a0 ff 55 8f |,Z&.......,...U.|
+000001c0 3f 9b c3 3b 52 d0 a3 3a f9 b8 f0 17 81 53 00 f3 |?..;R..:.....S..|
+000001d0 ef 72 b3 4e b9 65 28 8f a2 48 dc dd 6b 16 61 c3 |.r.N.e(..H..k.a.|
+000001e0 4e 0e c0 1c ac 8c 40 28 27 63 66 c7 74 40 8d 93 |N.....@('cf.t@..|
+000001f0 71 e9 f6 3f d8 8d 5d c6 28 11 4f ac 55 6f 80 1b |q..?..].(.O.Uo..|
+00000200 2e 84 05 94 e0 4f e7 63 62 65 c7 52 99 49 2f 5d |.....O.cbe.R.I/]|
+00000210 b4 99 d3 c3 fa b9 f5 83 aa 28 2e 9d ce af 72 7f |.........(....r.|
+00000220 57 ea 81 f3 bf b5 d7 93 3a 1f a0 83 4d 8a 91 85 |W.......:...M...|
+00000230 fe b7 a1 b3 cb 1d b1 85 9b bb 36 1b 12 9f ed 13 |..........6.....|
+00000240 09 55 31 bd ee 61 06 57 b4 07 4d c6 1e fa b9 7f |.U1..a.W..M.....|
+00000250 c7 b6 60 70 92 b7 9a ff 80 7d da 7f 2a 62 89 be |..`p.....}..*b..|
+00000260 79 43 d3 ae 9c f1 00 6d 68 6c a3 f6 48 6e e0 48 |yC.....mhl..Hn.H|
+00000270 97 0f 5c 44 43 9f a8 88 27 96 fc 53 a0 e1 f2 7a |..\DC...'..S...z|
+00000280 a6 a7 d9 96 2e 3d c4 e0 d9 18 79 ec 83 c2 9b da |.....=....y.....|
+00000290 0b d4 8b 87 c5 98 f5 8b e7 e3 d1 bd 2b 2b 42 e2 |............++B.|
+000002a0 4b 3e 64 88 4b 72 d0 35 cc c3 e6 68 c6 f6 4f 23 |K>d.Kr.5...h..O#|
+000002b0 39 a7 94 8d f3 e6 bd cd d5 e9 8c 53 83 a7 87 09 |9..........S....|
+000002c0 15 fe ea eb 2e 56 da 6b d9 5b b7 b1 c5 c4 ba 65 |.....V.k.[.....e|
+000002d0 39 89 16 f5 f6 4e e6 3a 63 34 1b 5d f5 fa 6b 8d |9....N.:c4.]..k.|
+000002e0 c3 49 07 88 12 ca 18 c5 50 da 74 44 c0 c0 33 bd |.I......P.tD..3.|
+000002f0 2e 45 94 af e1 40 90 00 11 2d 08 7b fc e4 3b f0 |.E...@...-.{..;.|
+00000300 94 fd 5a 0c 3a f9 76 df 3b 5e a3 0d 0f e7 2d df |..Z.:.v.;^....-.|
+00000310 fd e9 ce 45 5a 13 36 a6 18 ae 46 30 00 fc d5 e3 |...EZ.6...F0....|
+00000320 17 03 03 00 99 0e 35 b6 91 ad cd a6 62 6e 79 12 |......5.....bny.|
+00000330 53 d5 f0 78 72 c5 dd 94 00 e3 75 2c 11 a3 72 f6 |S..xr.....u,..r.|
+00000340 b7 b3 5e d9 51 79 d5 a9 1e 21 2f df 0d 53 9a c8 |..^.Qy...!/..S..|
+00000350 43 a9 58 e2 a9 3d 9a b4 b4 72 bb 62 65 4b 83 f8 |C.X..=...r.beK..|
+00000360 cd 1b 58 e0 69 d9 87 3b 8d 05 42 e1 22 23 e9 5b |..X.i..;..B."#.[|
+00000370 3a 5a 38 17 17 fb 3a 56 de fc 56 f8 77 12 31 4a |:Z8...:V..V.w.1J|
+00000380 c5 38 ec 69 72 54 e5 63 2a a0 1e b4 7d 86 43 29 |.8.irT.c*...}.C)|
+00000390 21 ba 56 c2 d9 1b 9f a4 c1 02 f3 83 c1 9a 56 69 |!.V...........Vi|
+000003a0 5c 9e 5f ae 94 9d 6f 03 ec 75 7a 19 98 cd a9 dd |\._...o..uz.....|
+000003b0 4a 01 41 72 2e 60 9f ca 4c d2 27 d9 0f 4f 17 03 |J.Ar.`..L.'..O..|
+000003c0 03 00 35 5d 61 3c 07 70 2f 35 ba d0 93 44 16 bd |..5]a<.p/5...D..|
+000003d0 73 4b a0 fb 05 52 6a cc 5a 2e f2 94 d6 77 98 03 |sK...Rj.Z....w..|
+000003e0 c3 2e 8e a9 d1 38 14 d2 cd e6 e3 b6 ad ec d6 a0 |.....8..........|
+000003f0 cf b0 58 5f 8f d3 43 4b |..X_..CK|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 3d 0a fd 33 39 |..........5=..39|
+00000010 b6 94 43 53 ae ee 3f 4e c6 2d a2 3a f0 ef 94 7d |..CS..?N.-.:...}|
+00000020 32 0a b6 90 cd a1 6f 29 88 ff 3c 91 c1 e5 e5 ae |2.....o)..<.....|
+00000030 b7 a0 0b b3 c0 e6 37 9d 06 8b d8 ae 06 c0 0e 7b |......7........{|
+00000040 17 03 03 00 17 c2 a1 82 db df fa 54 28 79 a0 0c |...........T(y..|
+00000050 97 8c 82 ee 22 c9 b9 35 32 7a 21 4b 17 03 03 00 |...."..52z!K....|
+00000060 13 87 2b f8 38 81 df fa e5 2e ff e2 d2 51 3e bc |..+.8........Q>.|
+00000070 dd d3 e8 62 |...b|
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..69749f0
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv13-CHACHA20-SHA256
@@ -0,0 +1,90 @@
+>>> 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 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 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 7a 02 00 00 76 03 03 39 b2 74 80 d8 |....z...v..9.t..|
+00000010 49 72 79 63 9b 7b da d7 cf b4 29 20 f8 80 ed d9 |Iryc.{....) ....|
+00000020 66 09 65 22 b6 27 16 c5 a7 6f 8b 20 00 00 00 00 |f.e".'...o. ....|
+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 42 |..+.....3.$... B|
+00000060 80 fb 4a d3 49 53 a5 9f f6 da ca 64 f8 5d 2c f5 |..J.IS.....d.],.|
+00000070 45 4d f1 a5 ec c3 c6 fc d2 ff 56 b1 63 53 1a 14 |EM........V.cS..|
+00000080 03 03 00 01 01 17 03 03 00 17 f8 d8 e1 1a e0 c8 |................|
+00000090 75 f9 40 90 da 16 a0 41 4f 8c 23 e7 47 43 89 cf |u.@....AO.#.GC..|
+000000a0 d4 17 03 03 02 6d d6 23 1d c6 c0 d4 5e a3 fe 2b |.....m.#....^..+|
+000000b0 03 04 6c 88 d1 4a ac 9b dd 90 e5 18 c5 35 9c 4a |..l..J.......5.J|
+000000c0 f3 c4 64 e2 c2 40 62 fb 68 b3 22 37 9f f4 eb ae |..d..@b.h."7....|
+000000d0 45 d9 a8 be f4 1e 89 16 88 b5 10 e3 5c 2e 42 15 |E...........\.B.|
+000000e0 34 24 f3 bd dd 73 6d 6b d1 db 3e 69 b0 0a 54 e6 |4$...smk..>i..T.|
+000000f0 b7 2c b7 80 86 93 91 d5 26 02 77 bf 10 38 ee 40 |.,......&.w..8.@|
+00000100 22 4d 3f 67 02 6b f8 1c 4a ad 2b c7 f6 19 d4 36 |"M?g.k..J.+....6|
+00000110 9b ff c4 08 73 e1 48 0a a6 e8 80 3b 88 8a c2 e8 |....s.H....;....|
+00000120 c6 4a ae da a1 4f 3b 9e fb 80 3b 78 ca 80 42 00 |.J...O;...;x..B.|
+00000130 a4 5c 9d a0 6c 63 a7 66 e6 26 b7 14 d8 8b ba 1a |.\..lc.f.&......|
+00000140 4b 13 81 3c e4 76 4e ac 6c 2f b4 71 e9 dc c4 c8 |K..<.vN.l/.q....|
+00000150 ef f0 61 22 f4 6b 83 ae d8 d0 a7 c6 d9 ea 95 85 |..a".k..........|
+00000160 77 90 0f 22 a0 50 cb ff 50 a5 98 ee de e4 89 f3 |w..".P..P.......|
+00000170 20 f2 63 a2 45 3a 48 33 d5 b9 ff 5e f8 7d c5 2d | .c.E:H3...^.}.-|
+00000180 b9 9c b2 65 bf d5 13 36 46 a5 96 9f f4 de 7c 1c |...e...6F.....|.|
+00000190 78 3f 1a 0a 62 14 13 8e 55 7e cd 47 87 1b 7e a8 |x?..b...U~.G..~.|
+000001a0 7f 03 ec 1c d3 72 eb e5 94 d9 9d 95 d6 f5 ad 2c |.....r.........,|
+000001b0 e9 7d 0f 2c ea 7b 1e 8e d7 b4 f1 5d 12 be d7 cf |.}.,.{.....]....|
+000001c0 b7 43 89 65 e9 04 0e f8 b4 b4 4d 9c 9c 42 3c 50 |.C.e......M..B<P|
+000001d0 a7 91 d0 7f c0 de fb 99 08 ce 5c fd 67 3a cb 1a |..........\.g:..|
+000001e0 d3 1a 4c a2 2e 7d 73 01 2b 5f bb a2 86 7d 0e e0 |..L..}s.+_...}..|
+000001f0 a1 c9 06 c0 4a 0a f6 c6 c4 b5 53 51 3e 2f f4 60 |....J.....SQ>/.`|
+00000200 1d 41 55 9d c4 88 f3 76 4f 92 b5 03 98 23 6b c4 |.AU....vO....#k.|
+00000210 c3 62 bd 12 dd 3a bc 37 d0 18 64 c6 e1 2c cb 62 |.b...:.7..d..,.b|
+00000220 f6 d3 24 35 47 e7 cf 15 d3 53 9d ac 3f 97 48 c1 |..$5G....S..?.H.|
+00000230 b8 d3 a3 2c 9f cd 2b 72 bc bd a6 8a b1 54 48 7b |...,..+r.....TH{|
+00000240 e0 b7 a2 2e 46 04 cc e5 29 1d 73 c7 67 f8 f0 d8 |....F...).s.g...|
+00000250 e0 88 f0 7b 11 ff e1 1d 95 6c 85 c4 08 72 3e 94 |...{.....l...r>.|
+00000260 92 4b 8a 58 62 04 10 83 7c 5e 65 20 a7 5d 6d 16 |.K.Xb...|^e .]m.|
+00000270 30 64 fc aa 7f 8f 06 ed 4e 3c 86 c8 10 92 fb 0d |0d......N<......|
+00000280 7b 81 10 07 cf 30 7f 6b 11 63 60 2a 61 92 cb 74 |{....0.k.c`*a..t|
+00000290 82 a4 04 cf 23 43 21 55 45 2a 29 93 42 0f 0c f6 |....#C!UE*).B...|
+000002a0 9b 14 b5 96 09 25 1b bc b0 7b 72 e2 6f b8 55 74 |.....%...{r.o.Ut|
+000002b0 00 bb 1c 7c b1 9b 58 63 97 bb 6d c5 fb a4 da 24 |...|..Xc..m....$|
+000002c0 1e b2 97 18 75 ab 8b a2 77 50 38 4d f8 a0 39 58 |....u...wP8M..9X|
+000002d0 8c 2d 3e ba 27 03 e9 51 87 0a 95 e0 08 40 5d e6 |.->.'..Q.....@].|
+000002e0 6a dd 10 1d 6d 8c 32 88 a8 32 ee dd 44 9c 9b b0 |j...m.2..2..D...|
+000002f0 6f f5 4b 08 60 9d 83 1e ab 83 c0 92 10 c7 aa 90 |o.K.`...........|
+00000300 d2 b2 61 5e 12 b5 e8 ea a7 68 59 17 a4 f4 15 f7 |..a^.....hY.....|
+00000310 dc 10 81 17 03 03 00 99 8a 61 79 8f 33 51 7b a9 |.........ay.3Q{.|
+00000320 ce 3f 82 2b bb da 40 2e 73 c8 d9 6e 7d 72 ba 94 |.?.+..@.s..n}r..|
+00000330 7d ad fb b7 ba 9c 74 00 0b c9 1d b6 8d 54 b9 48 |}.....t......T.H|
+00000340 eb 49 78 c3 1a 75 b8 16 22 5d 50 f5 4a 81 59 d3 |.Ix..u.."]P.J.Y.|
+00000350 38 79 38 c1 35 11 55 69 6b d2 86 3c 0f 12 26 57 |8y8.5.Uik..<..&W|
+00000360 f5 84 d7 dd 74 61 6f b8 08 66 e9 3c f7 43 29 a5 |....tao..f.<.C).|
+00000370 94 9e ab af 68 04 c1 6a ae 9d 12 2d 57 e9 ff 30 |....h..j...-W..0|
+00000380 7d 80 35 65 cc df c8 65 0b a1 f9 6d 6b a5 0b df |}.5e...e...mk...|
+00000390 0c 1a 04 0a 00 8f ac 2b 29 60 92 4e 91 d3 42 25 |.......+)`.N..B%|
+000003a0 b4 a5 0a 1a 5f 83 ec 9a f0 0a 2c 6d 65 00 24 d3 |...._.....,me.$.|
+000003b0 e1 17 03 03 00 35 e4 72 aa 9e 6c a8 93 7b e4 49 |.....5.r..l..{.I|
+000003c0 1e 23 7c 50 18 59 00 08 3b f1 c1 5f 20 ba 51 56 |.#|P.Y..;.._ .QV|
+000003d0 fe bb 93 99 52 e6 5e 6d 26 cc 60 11 c2 a1 c8 18 |....R.^m&.`.....|
+000003e0 2e 72 bd ee 36 ca 41 25 73 f2 30 |.r..6.A%s.0|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 b6 c3 b9 b1 52 |..........5....R|
+00000010 88 d2 78 2b ec 1c 63 e8 d5 08 0e 4e d6 51 b9 02 |..x+..c....N.Q..|
+00000020 ba cc a8 ca b6 da 45 a9 7c 1a 18 39 47 84 db 34 |......E.|..9G..4|
+00000030 d6 05 6f e5 16 19 57 6f 65 0b 7a e7 37 b5 d3 28 |..o...Woe.z.7..(|
+00000040 17 03 03 00 17 dc b8 e2 1c aa b8 f5 cb b6 fd ba |................|
+00000050 29 34 73 bb c6 e0 3a fc 3e fb d3 01 17 03 03 00 |)4s...:.>.......|
+00000060 13 eb 66 ab 47 38 1b 01 96 6c 59 46 c2 ad bf 2d |..f.G8...lYF...-|
+00000070 36 22 97 19 |6"..|
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..251e339
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv13-ClientCert-ECDSA-RSA
@@ -0,0 +1,139 @@
+>>> 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 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 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 7a 02 00 00 76 03 03 ce 38 98 c9 b7 |....z...v...8...|
+00000010 f8 67 af 0d 29 52 88 a4 d0 c2 a8 10 c4 8e 80 26 |.g..)R.........&|
+00000020 43 84 0e 60 06 ce f0 b7 b1 cd 29 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 aa |..+.....3.$... .|
+00000060 00 03 6d 16 04 54 48 55 4d f9 04 e8 29 ca 9c 5d |..m..THUM...)..]|
+00000070 14 94 a2 7a 2e 0a 4e 75 12 2d 63 cf 19 81 21 14 |...z..Nu.-c...!.|
+00000080 03 03 00 01 01 17 03 03 00 17 7b 90 e1 af 77 ca |..........{...w.|
+00000090 a1 3b a6 e0 9f ea 4b f6 3f 45 a0 78 1c fb af 51 |.;....K.?E.x...Q|
+000000a0 30 17 03 03 00 42 ff 27 8b 9c fd 65 d7 b1 d4 43 |0....B.'...e...C|
+000000b0 eb 8f c3 ca b4 57 be 35 35 75 35 cf 43 73 d6 14 |.....W.55u5.Cs..|
+000000c0 7e 2d b4 f8 31 60 1b 35 2a 38 91 32 40 8b f0 ab |~-..1`.5*8.2@...|
+000000d0 a8 b0 dc 2b db b9 63 92 28 dc f2 c2 95 d3 4a 63 |...+..c.(.....Jc|
+000000e0 69 e7 58 0c e5 9c d5 22 17 03 03 02 6d 7c 70 9b |i.X...."....m|p.|
+000000f0 e1 81 3a 0d 6e 7f 5c 30 2e 09 1d 82 ac 48 a6 7e |..:.n.\0.....H.~|
+00000100 03 ce d0 ce e2 e8 9e 8b 2b ee af 1a b1 6a 3a 27 |........+....j:'|
+00000110 04 53 73 d2 d4 28 68 19 96 3a 3d 89 df 2c e3 2b |.Ss..(h..:=..,.+|
+00000120 45 c8 5e 60 42 b0 4d f2 9c 8a 8d 83 f6 97 e0 b0 |E.^`B.M.........|
+00000130 02 39 37 46 2b 07 28 8b e8 d8 c2 e3 ba 58 9b dc |.97F+.(......X..|
+00000140 62 c4 e6 cb b4 97 f0 67 2b b3 40 4b 64 3e 73 3f |b......g+.@Kd>s?|
+00000150 a1 1f 6e fe 7f ba af 7d bd c4 7c 37 60 c0 94 d6 |..n....}..|7`...|
+00000160 bc 14 70 a9 95 a6 b7 88 9d 50 cf 9f 36 0c 38 c4 |..p......P..6.8.|
+00000170 97 ba ea 43 16 e8 fd 72 22 3c 09 4a 97 1c 97 70 |...C...r"<.J...p|
+00000180 88 6d d4 f3 9d b9 5a f3 67 f5 7b da 3e ed 1a 66 |.m....Z.g.{.>..f|
+00000190 4c 62 50 ff cd 92 08 d8 5c 2e 11 de ea 44 16 91 |LbP.....\....D..|
+000001a0 3e 44 d7 8c dd 2a b4 c7 2b 4d 40 a2 f9 7e 49 a9 |>D...*..+M@..~I.|
+000001b0 d8 51 a1 27 b3 34 75 59 04 04 cd 52 d6 37 34 e6 |.Q.'.4uY...R.74.|
+000001c0 41 32 36 45 c0 65 fb 5c e2 21 77 7f 35 db 9d 34 |A26E.e.\.!w.5..4|
+000001d0 0d 6e 9d a7 9e 00 ec e3 3e 9c 50 50 13 5b ad b9 |.n......>.PP.[..|
+000001e0 b3 47 44 f8 9b 12 ab 50 7f a7 df 35 c5 d6 78 3c |.GD....P...5..x<|
+000001f0 c1 04 41 db 99 18 cd 8c 05 3f 08 ae 2b 41 c9 46 |..A......?..+A.F|
+00000200 16 9a e3 a9 5b d3 9c 00 56 0e e2 d1 da 6d 6b 20 |....[...V....mk |
+00000210 65 1b 55 1f 4f b1 eb 94 c6 48 e3 50 d6 14 c5 62 |e.U.O....H.P...b|
+00000220 5e fc d2 cf df f4 68 90 c9 bb 80 54 f3 f3 a3 78 |^.....h....T...x|
+00000230 af 1f 6f ef e1 d5 64 24 04 e5 d4 59 bc 4d 7b a0 |..o...d$...Y.M{.|
+00000240 1a 23 e1 81 b7 c4 bb 52 86 f4 2a 85 d2 d0 7a ed |.#.....R..*...z.|
+00000250 c0 5d 27 07 4b df 52 c4 ea c8 c9 9c f0 48 35 71 |.]'.K.R......H5q|
+00000260 bd 04 65 65 47 e3 21 88 ff 08 6c 6a f3 6c dd 81 |..eeG.!...lj.l..|
+00000270 3f 50 21 66 34 49 07 a0 e0 6d 80 54 77 8b 27 81 |?P!f4I...m.Tw.'.|
+00000280 4f b9 59 60 0a b0 c7 00 6a 7b 26 33 f6 5e ad 37 |O.Y`....j{&3.^.7|
+00000290 bf ea 87 e4 3c e7 b8 20 b0 89 88 ac 5a a4 af f7 |....<.. ....Z...|
+000002a0 23 3c 0a d0 ab 74 fc 49 d2 e5 51 a7 a5 4e 21 5f |#<...t.I..Q..N!_|
+000002b0 90 9a 65 36 9f e1 e3 9e 3d 67 d6 93 f1 b8 f0 4b |..e6....=g.....K|
+000002c0 c6 d8 ca 50 fb cc 92 ab 47 b5 8c 21 02 4a ee 42 |...P....G..!.J.B|
+000002d0 35 a3 52 41 04 94 19 cd 23 c6 33 b0 84 0d 88 97 |5.RA....#.3.....|
+000002e0 5a e0 3e 4c 6d 99 ec 6d 11 3f 19 e7 77 60 3b de |Z.>Lm..m.?..w`;.|
+000002f0 6d 04 b8 ab bc 83 4f 51 a5 ba 56 56 d6 e3 ff 0e |m.....OQ..VV....|
+00000300 d5 4b 75 29 6a f9 4b c6 ef fd 62 25 89 76 f1 fd |.Ku)j.K...b%.v..|
+00000310 84 3f e9 93 63 cf eb 47 85 b1 aa a2 4c 94 6b 99 |.?..c..G....L.k.|
+00000320 98 6e 1a 19 85 0b 90 d2 9f 0f ec d4 36 1e 22 a0 |.n..........6.".|
+00000330 4e 7f a1 ae 90 15 68 8a 48 c5 06 01 aa b9 56 cb |N.....h.H.....V.|
+00000340 e0 62 53 d8 96 56 61 1d 81 96 b8 66 ae 94 c8 5f |.bS..Va....f..._|
+00000350 86 47 fe ca 27 8d 7f 8e f8 74 17 03 03 00 99 ac |.G..'....t......|
+00000360 2b 09 0b 44 a5 33 27 19 86 59 ca 75 5c df 59 fc |+..D.3'..Y.u\.Y.|
+00000370 34 57 08 11 4f d8 1a c6 7c 76 d5 0a 36 91 f2 3a |4W..O...|v..6..:|
+00000380 d1 96 58 64 29 3a d1 05 e3 cb 6f ea 92 4a f6 3b |..Xd):....o..J.;|
+00000390 54 4c 16 41 99 6e 0f e9 c3 9a ac a3 59 ee fa c9 |TL.A.n......Y...|
+000003a0 4d 58 ae 23 58 58 b5 b5 d6 6a dd b4 0c 24 bf e1 |MX.#XX...j...$..|
+000003b0 d4 16 53 f2 2d e1 78 d0 ea 70 59 ac a3 e4 e4 6f |..S.-.x..pY....o|
+000003c0 65 93 28 ad e1 64 83 11 05 42 a3 a0 11 d5 f2 af |e.(..d...B......|
+000003d0 7e 03 93 80 82 48 e0 84 2e 1c 50 98 65 22 49 f1 |~....H....P.e"I.|
+000003e0 df 41 03 83 b2 5c 1c 56 cb b7 f3 72 04 d6 09 cf |.A...\.V...r....|
+000003f0 f9 3a 5d e8 35 80 b6 a2 17 03 03 00 35 b4 b5 c3 |.:].5.......5...|
+00000400 43 78 3d e8 eb 66 7d 1c 36 8e a1 9f 26 ab 5a aa |Cx=..f}.6...&.Z.|
+00000410 63 b6 2f 7a a5 f6 7d 89 1e 5d c5 a1 bf b4 3b 4a |c./z..}..]....;J|
+00000420 89 1f 96 74 e3 c4 d8 72 57 a5 c7 99 a9 f3 77 16 |...t...rW.....w.|
+00000430 f3 25 |.%|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 02 1e 2e 1c 18 ac 6e |...............n|
+00000010 bd d7 35 f8 21 6f 36 d7 13 94 53 3b 56 5d 03 8e |..5.!o6...S;V]..|
+00000020 2d 92 fa cb 17 d3 75 55 13 84 9c aa be f7 34 9e |-.....uU......4.|
+00000030 35 67 9b 90 bc 76 5d 65 c0 23 b0 04 d0 ba 15 b5 |5g...v]e.#......|
+00000040 30 70 4d 8d d2 38 73 0a 3a 58 c3 bc da a4 f5 ae |0pM..8s.:X......|
+00000050 05 ee 0c 06 bd 06 fe ab 1b 31 cf 4d 46 63 cc ee |.........1.MFc..|
+00000060 8f 8a 0d e9 32 50 4d a0 f6 f2 ce c5 be 41 c2 16 |....2PM......A..|
+00000070 a7 c3 b3 8a 5c 27 4a fd 37 2d 32 d9 76 25 27 12 |....\'J.7-2.v%'.|
+00000080 03 b9 e7 ef bc c8 59 e1 16 80 dc b2 16 ae 05 b6 |......Y.........|
+00000090 cf 8e 99 0d f8 ed 5a b1 bb c1 05 d5 35 fe fd 2d |......Z.....5..-|
+000000a0 97 c6 19 d8 2d 1a a9 30 d1 4a 6d 27 45 93 5f 5d |....-..0.Jm'E._]|
+000000b0 45 f4 98 a8 d8 88 27 8f f2 ad 1e 24 6e c8 8f 12 |E.....'....$n...|
+000000c0 f7 32 b5 3d 3c e3 e0 32 56 4e 80 a8 5f 27 f0 d0 |.2.=<..2VN.._'..|
+000000d0 a1 c2 d0 22 2d 3a 36 0f bd 7b 94 9f ca 8d c1 ea |..."-:6..{......|
+000000e0 c6 1f d8 87 4a 75 bd 3e 0f ae 2f e1 78 ae 3f 00 |....Ju.>../.x.?.|
+000000f0 f4 3a 82 dd ec 3f 61 43 bf 4b f8 01 a3 32 df 13 |.:...?aC.K...2..|
+00000100 61 45 ca bb e0 9a 17 85 45 90 c6 fb 5d 79 1b 58 |aE......E...]y.X|
+00000110 54 ca 84 e9 a9 11 c4 74 82 f7 da e4 b3 4f 05 a1 |T......t.....O..|
+00000120 23 72 9f 63 b8 4c 55 e6 da 33 b9 1c b0 fe 28 72 |#r.c.LU..3....(r|
+00000130 f0 02 b6 ec 70 ae 27 d4 21 51 32 56 32 4e e7 7d |....p.'.!Q2V2N.}|
+00000140 b8 0d 75 25 45 5c 68 83 4f e3 3e 8a 87 7c 06 81 |..u%E\h.O.>..|..|
+00000150 ac ff 23 44 0e bd e7 0a 76 64 45 c4 04 df 35 db |..#D....vdE...5.|
+00000160 ab 8a 38 87 f5 e5 35 75 7a 92 85 3d 14 9e aa 19 |..8...5uz..=....|
+00000170 4d 94 25 8f c0 c3 37 ca 63 f3 dd 48 4a 6a 6b f5 |M.%...7.c..HJjk.|
+00000180 fa 52 67 30 ab ff 56 9f 58 bd cd 66 d4 83 85 d8 |.Rg0..V.X..f....|
+00000190 85 6c 6d 3c 56 e5 17 75 fc dc a7 3d ed 18 a1 3b |.lm<V..u...=...;|
+000001a0 6c e6 54 95 75 38 77 77 90 34 81 cb 1c cb e9 04 |l.T.u8ww.4......|
+000001b0 c8 d2 12 04 36 a8 9b f6 9b 6a 81 8d f5 b1 e2 ca |....6....j......|
+000001c0 31 37 27 f2 84 bd 5c 3a 1c 6c 64 83 35 94 89 ee |17'...\:.ld.5...|
+000001d0 08 42 1d 05 52 67 e6 4d 7f bb d2 21 82 8c 15 6b |.B..Rg.M...!...k|
+000001e0 e9 f9 6d bc b3 1f 5a df b8 55 aa 9d f6 aa d2 7c |..m...Z..U.....||
+000001f0 41 76 3b 1b b2 f5 b8 49 32 be bb f8 0e d3 74 be |Av;....I2.....t.|
+00000200 eb 0d 9b e2 57 b6 ec e5 61 d7 09 80 a8 63 b4 cf |....W...a....c..|
+00000210 bb 0a 14 9d 39 1c 08 58 22 c4 ae d5 4f 42 97 14 |....9..X"...OB..|
+00000220 71 e1 c0 a5 5e 8e 2f 89 27 17 03 03 00 a3 f0 96 |q...^./.'.......|
+00000230 d3 9e 8c 19 84 9a 42 d3 84 64 a6 89 40 6f d6 c9 |......B..d..@o..|
+00000240 50 90 bb 9d 16 90 9d fb aa 85 28 ab 25 63 78 a9 |P.........(.%cx.|
+00000250 dd dc 35 03 73 08 26 2b 30 53 84 f8 74 66 f2 6f |..5.s.&+0S..tf.o|
+00000260 d7 0a f0 e2 c4 10 a4 46 cf 77 ea cb b7 b7 a9 81 |.......F.w......|
+00000270 5f 09 4a 6a a5 16 a4 79 dc b0 c9 ae 5a ff 2a 7b |_.Jj...y....Z.*{|
+00000280 3f bd 7a 15 b3 02 ad 3e 90 37 46 51 71 fc 6d d0 |?.z....>.7FQq.m.|
+00000290 9f 38 42 95 1a 88 ac 5f 83 a1 8a 59 59 62 cc 4a |.8B...._...YYb.J|
+000002a0 57 d2 3e 1e 7e 1d c0 4d 41 23 85 5f 92 f4 63 16 |W.>.~..MA#._..c.|
+000002b0 df df 6e 3d d7 c1 e6 21 22 0f e1 13 82 29 a6 e3 |..n=...!"....)..|
+000002c0 f8 8c a4 a3 72 1d 61 c1 2a 9d a8 2d 13 8a 4f 87 |....r.a.*..-..O.|
+000002d0 91 17 03 03 00 35 9d 35 c8 ac 1e c6 46 8d e1 42 |.....5.5....F..B|
+000002e0 68 e5 79 77 64 15 e2 13 c0 70 1a 47 59 d0 1e c3 |h.ywd....p.GY...|
+000002f0 68 f7 5a fe 11 a2 3d e4 6e 2c b5 7d ea 98 e7 75 |h.Z...=.n,.}...u|
+00000300 7c 54 a4 35 9b 1f c9 ba 72 b1 94 17 03 03 00 17 ||T.5....r.......|
+00000310 a3 81 17 ac 97 a9 f0 91 b5 7a 04 38 ff fd 8e d3 |.........z.8....|
+00000320 d8 7b c4 40 7e d3 ea 17 03 03 00 13 a8 b1 06 94 |.{.@~...........|
+00000330 90 83 62 d5 be a8 23 d5 8b af 77 0d 90 13 98 |..b...#...w....|
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..689c287
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv13-ClientCert-Ed25519
@@ -0,0 +1,122 @@
+>>> 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 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 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 7a 02 00 00 76 03 03 4e 4c 01 f1 4e |....z...v..NL..N|
+00000010 49 97 ec eb df ce 50 4d 1c 9c d0 35 92 10 97 0a |I.....PM...5....|
+00000020 dd fb a8 4f 39 c6 14 21 d6 42 ac 20 00 00 00 00 |...O9..!.B. ....|
+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 c1 |..+.....3.$... .|
+00000060 c2 ca 32 aa 48 d8 52 bc c8 23 6d 98 18 3e 15 b6 |..2.H.R..#m..>..|
+00000070 0b 25 db f9 6f a7 e1 75 95 a1 46 d3 47 4a 0e 14 |.%..o..u..F.GJ..|
+00000080 03 03 00 01 01 17 03 03 00 17 87 10 92 da b4 9a |................|
+00000090 03 a5 0f 73 e6 93 cb 71 1d 58 6e 5d 27 eb ee b6 |...s...q.Xn]'...|
+000000a0 c7 17 03 03 00 42 89 8d 57 16 95 5b f0 98 ad c7 |.....B..W..[....|
+000000b0 d7 94 ba 4d 7e 88 b9 8d 13 26 a6 6c 81 90 a6 1e |...M~....&.l....|
+000000c0 2b 4e 91 70 e2 da 9d a2 0d 6f 9b 5b ee 69 58 a1 |+N.p.....o.[.iX.|
+000000d0 4c c3 59 57 28 62 b3 ed 26 15 79 db 01 8c 88 e3 |L.YW(b..&.y.....|
+000000e0 63 1f bc b0 01 c9 82 ca 17 03 03 02 6d e5 d6 77 |c...........m..w|
+000000f0 4e d3 af c3 5e 01 e9 1b 31 63 a4 84 d3 cc 2d f8 |N...^...1c....-.|
+00000100 5d 73 f9 3e 83 03 c5 c5 cd 95 00 7b f2 b5 79 fa |]s.>.......{..y.|
+00000110 47 e5 07 89 a9 22 49 7a 7e 7e 6e d2 3b 68 e8 9c |G...."Iz~~n.;h..|
+00000120 40 1c 86 2a 48 ee 59 8e 1c 04 8b 91 20 68 65 31 |@..*H.Y..... he1|
+00000130 e7 76 dc 6c 5a ce cb 32 d3 e8 71 7f 93 08 b5 01 |.v.lZ..2..q.....|
+00000140 84 0a b4 ec 80 68 69 9b b3 4a 4a 4d 56 16 eb 42 |.....hi..JJMV..B|
+00000150 29 93 4d b4 76 f6 e0 15 fe 25 b1 cb 5a da 22 4b |).M.v....%..Z."K|
+00000160 88 4c ec 66 48 09 e1 d1 0f 3e 3a ad 65 d7 d7 85 |.L.fH....>:.e...|
+00000170 1d cb 35 2c 84 60 ec a1 6d f1 60 cf c6 c7 82 1a |..5,.`..m.`.....|
+00000180 7c 91 40 2e 3e 88 1f ff 79 2e 6e 97 c5 45 9f e1 ||.@.>...y.n..E..|
+00000190 bf 33 ad 65 df f3 ce 1a d7 57 7e db f2 28 79 a9 |.3.e.....W~..(y.|
+000001a0 9e 4f 9e 8a ce 02 5a 18 bb f1 ac 72 5b 3f 4c 6b |.O....Z....r[?Lk|
+000001b0 97 14 14 f9 82 8a 4f 99 21 98 db af 3e 08 ab 4f |......O.!...>..O|
+000001c0 d8 3f f6 cc da 76 77 eb 02 39 0a 00 23 a5 e0 92 |.?...vw..9..#...|
+000001d0 01 10 3f 76 ab 1a 38 8e f9 a1 d0 25 c3 9d 50 a4 |..?v..8....%..P.|
+000001e0 ef a5 8c f8 5d bc d9 fd dd 25 cd 42 38 52 d1 cd |....]....%.B8R..|
+000001f0 d2 1b fc ba 7d 8b bd 82 05 23 c3 9d 02 ff 1b 4e |....}....#.....N|
+00000200 08 e1 f3 7c 35 15 0f e8 0e b7 8a e5 4a 2b da 45 |...|5.......J+.E|
+00000210 4a 72 9a 32 7e 55 52 65 d2 a8 32 90 53 bf 25 29 |Jr.2~URe..2.S.%)|
+00000220 1e 8d d7 a3 22 d6 40 19 95 58 a8 37 af a8 52 e7 |....".@..X.7..R.|
+00000230 79 b9 4e 61 d8 f0 7d d2 69 25 99 28 3f 31 f6 b2 |y.Na..}.i%.(?1..|
+00000240 44 65 1f 9c 41 08 17 c9 01 5d 20 ea ab fe 06 64 |De..A....] ....d|
+00000250 9a f4 d0 24 e0 b5 88 0a 2b 96 e9 71 11 a8 49 b4 |...$....+..q..I.|
+00000260 40 62 1b 45 15 47 cb a5 fc 4f 07 58 2b ef d4 5d |@b.E.G...O.X+..]|
+00000270 df 40 38 6c 6e ca 63 c5 95 2d 79 26 86 ff 33 02 |.@8ln.c..-y&..3.|
+00000280 da 5a 85 0c 8f 7f 58 ba ea 88 cf bc 51 92 12 86 |.Z....X.....Q...|
+00000290 f1 c1 f9 0a d0 6e cc b4 2b 16 98 ad f8 11 ad 63 |.....n..+......c|
+000002a0 82 d7 4e ea a5 ee 78 a2 9a 35 b6 b3 d9 24 cf 66 |..N...x..5...$.f|
+000002b0 03 d2 25 1f 15 37 c7 b5 8e bb 0a 40 0f 28 c2 16 |..%..7.....@.(..|
+000002c0 90 a4 61 9e dd fd b5 ad 97 39 0d 66 e7 fa 5b e2 |..a......9.f..[.|
+000002d0 c2 ef 44 5d 44 07 d6 c3 ed e2 89 6e 4c ed 79 42 |..D]D......nL.yB|
+000002e0 86 3b f4 94 0c 82 5e 52 ce 00 ab 5c 20 b4 18 db |.;....^R...\ ...|
+000002f0 c9 fe 8b be 8d da e9 86 13 62 6b 8d 0d 57 c8 fe |.........bk..W..|
+00000300 a6 4b 82 52 d5 d8 05 18 2f a0 43 d6 c8 89 fb e7 |.K.R..../.C.....|
+00000310 72 17 61 89 36 5b e0 aa 4d 6c 20 ee 68 db 32 e4 |r.a.6[..Ml .h.2.|
+00000320 97 9f 18 26 7c 1a cd e8 b9 05 ae fd 86 bf 0e 47 |...&|..........G|
+00000330 09 06 bd de 2d b9 50 6a 0c a6 27 04 5e aa e0 ce |....-.Pj..'.^...|
+00000340 e7 cf 98 f9 7e 7d b9 4d 77 9a 88 3a d4 41 07 cc |....~}.Mw..:.A..|
+00000350 87 b6 41 53 8b 8c 79 8e 07 b9 17 03 03 00 99 0b |..AS..y.........|
+00000360 63 4e d8 79 d7 11 f2 46 00 6c 5d d2 9e 49 df 7e |cN.y...F.l]..I.~|
+00000370 f2 96 1a 68 9d 6a 05 dc 61 45 47 a4 18 5c 65 04 |...h.j..aEG..\e.|
+00000380 00 38 d1 25 0c ff a3 a2 c0 c2 82 7f b1 1b a1 c6 |.8.%............|
+00000390 7b ac fb 71 48 b6 e4 e2 7b c4 d0 44 8e 22 d6 91 |{..qH...{..D."..|
+000003a0 99 87 a2 88 3d bb b4 80 13 57 2a 6a b0 2d 52 16 |....=....W*j.-R.|
+000003b0 d3 f2 e4 cd d0 79 9a 31 ce 68 65 b3 61 67 a0 b9 |.....y.1.he.ag..|
+000003c0 1e 6b 9f 73 dc 46 be 5e df d7 c2 30 d5 60 b5 e5 |.k.s.F.^...0.`..|
+000003d0 60 cc 10 ae 9a f9 b6 9a fd 14 b9 1e b7 3c 1d 3e |`............<.>|
+000003e0 34 a6 49 d2 48 f7 24 56 29 c9 98 f1 33 b1 e5 5e |4.I.H.$V)...3..^|
+000003f0 2c 7b bb 5f b6 53 6a c8 17 03 03 00 35 d9 af 32 |,{._.Sj.....5..2|
+00000400 1f a5 09 3f 8a 10 df a7 34 9b f8 ec 07 81 80 73 |...?....4......s|
+00000410 dc ba 09 fc 40 e4 1e df f6 de 02 54 3c 7d ea 49 |....@......T<}.I|
+00000420 91 16 72 70 8e 1a 21 76 c6 00 0e 03 9f 0a 82 fe |..rp..!v........|
+00000430 4c 18 |L.|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 01 50 1d 6e 16 0d 4e |..........P.n..N|
+00000010 c0 a2 41 c3 a2 84 c9 80 c0 f0 ef c0 5d 3a 3b f2 |..A.........]:;.|
+00000020 bf 1c 9e 79 d7 d3 94 0b 41 2d bc 50 eb 0f 60 f4 |...y....A-.P..`.|
+00000030 bd cd f6 03 22 7b 68 68 44 34 c9 0f 23 ca 76 6f |...."{hhD4..#.vo|
+00000040 f2 97 38 07 43 56 7e b7 ce 67 68 67 37 34 d0 f7 |..8.CV~..ghg74..|
+00000050 c5 92 fd 65 98 b8 7e 5f 48 a8 a3 aa a8 96 65 b5 |...e..~_H.....e.|
+00000060 48 be 91 99 67 0a 37 c7 31 b4 43 ba 26 bb 87 98 |H...g.7.1.C.&...|
+00000070 3c 55 e4 63 b0 33 ca ee 0a a5 fe 36 88 ef cf f0 |<U.c.3.....6....|
+00000080 ab 6b 7d e8 f6 1f 14 12 49 f7 14 b7 12 bb d8 1e |.k}.....I.......|
+00000090 e0 be ed 56 75 b9 ab 8a 20 75 d9 6f 45 2d 71 b3 |...Vu... u.oE-q.|
+000000a0 2f b7 cd 9c c5 16 ed 37 0e 08 15 a5 49 18 7c 13 |/......7....I.|.|
+000000b0 8e 0b 66 01 b1 8c 1d 89 d4 91 9e 5a 6b 94 f6 fa |..f........Zk...|
+000000c0 7b a8 14 1c a7 20 55 c5 e4 0e 9d e0 5b d6 d4 b7 |{.... U.....[...|
+000000d0 1d 93 2b 7c 25 46 28 11 06 57 a3 cb 2f 4b 39 cf |..+|%F(..W../K9.|
+000000e0 61 be 60 9a fd f1 6e e1 a2 a7 20 f2 fd 50 a2 d2 |a.`...n... ..P..|
+000000f0 17 db 16 4f 3f 8c 20 e4 4d 56 37 3b c2 42 17 cc |...O?. .MV7;.B..|
+00000100 5d 99 06 fc 18 0d 1a 88 e8 f9 6f cf 7d 2e 57 73 |].........o.}.Ws|
+00000110 85 47 ed d0 2d b3 9a 05 cf 0c 7d e6 ed 29 95 f4 |.G..-.....}..)..|
+00000120 d5 e0 96 6a 1d 67 3e 5f 43 9f b5 f6 66 f5 84 63 |...j.g>_C...f..c|
+00000130 bd 42 a6 f8 ef 38 42 8a d8 28 dc 55 e5 88 03 76 |.B...8B..(.U...v|
+00000140 96 ba 89 35 63 7e 6c da 39 d8 9a 27 04 ab d5 0e |...5c~l.9..'....|
+00000150 48 89 cc 81 25 44 61 16 2c b2 69 17 03 03 00 59 |H...%Da.,.i....Y|
+00000160 81 8f 94 30 8d fc 47 13 7e 84 06 9b 4a 85 2c bb |...0..G.~...J.,.|
+00000170 b3 a0 0d 4f 50 6a cb 0b 9b 40 ef cc 84 70 1f 69 |...OPj...@...p.i|
+00000180 b9 3e a6 c4 ba 66 eb a9 6f 78 83 7f d4 1f d8 c4 |.>...f..ox......|
+00000190 b0 f6 9b 03 29 7f b1 f8 60 40 0b 28 91 32 2c 03 |....)...`@.(.2,.|
+000001a0 aa 9e 7b fb 99 c2 11 51 1f a7 81 69 16 39 f4 52 |..{....Q...i.9.R|
+000001b0 ca d8 d0 f3 87 6f 58 ab 9a 17 03 03 00 35 de 03 |.....oX......5..|
+000001c0 88 61 50 5c 08 88 77 28 6a 1d 28 44 3d 49 8b 79 |.aP\..w(j.(D=I.y|
+000001d0 d1 a2 13 67 95 0f 7c 18 fe e2 e0 07 f1 ce b9 be |...g..|.........|
+000001e0 79 aa 40 d6 cf 66 53 ac 15 ae 2a 14 a9 63 98 55 |y.@..fS...*..c.U|
+000001f0 96 16 6f 17 03 03 00 17 a8 ac 17 c5 eb d9 8e 77 |..o............w|
+00000200 9e 4b e0 20 c6 0c 34 b6 c3 ab c4 b6 8b b2 77 17 |.K. ..4.......w.|
+00000210 03 03 00 13 58 d4 7b 8f ca 20 41 e3 3f d1 ae cf |....X.{.. A.?...|
+00000220 3d e1 86 91 c0 a1 08 |=......|
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..8e361ea
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv13-ClientCert-RSA-ECDSA
@@ -0,0 +1,134 @@
+>>> 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 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 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 7a 02 00 00 76 03 03 30 0a c5 df b0 |....z...v..0....|
+00000010 90 3a 48 4b 20 f1 89 62 be 1f 1b 64 c2 7e 69 25 |.:HK ..b...d.~i%|
+00000020 9f b7 f9 2c 86 e7 40 e7 e8 10 fa 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 13 03 00 00 |................|
+00000050 2e 00 2b 00 02 03 04 00 33 00 24 00 1d 00 20 94 |..+.....3.$... .|
+00000060 e8 ab 87 65 c8 dd 6f ee b4 d6 0b bb fd 18 9a 2d |...e..o........-|
+00000070 e4 bc c6 20 98 09 71 65 7d 54 35 73 22 99 1b 14 |... ..qe}T5s"...|
+00000080 03 03 00 01 01 17 03 03 00 17 37 b7 eb eb a2 9f |..........7.....|
+00000090 7f 00 8c 9d a9 50 7c 0c 15 31 63 71 45 7a 3d ee |.....P|..1cqEz=.|
+000000a0 5e 17 03 03 00 42 9f 23 07 cf d0 bc e8 bb 95 01 |^....B.#........|
+000000b0 37 94 18 2e 05 02 8a eb 0a 37 10 79 51 a9 d4 43 |7........7.yQ..C|
+000000c0 18 18 e6 00 9d 68 ff 74 f3 9c 19 bf 5e 51 0c 47 |.....h.t....^Q.G|
+000000d0 61 35 8c b2 58 5f 32 bc 88 c4 fb 5a 22 61 14 98 |a5..X_2....Z"a..|
+000000e0 28 26 8c 75 9d 1d 19 05 17 03 03 02 22 d2 2c 1a |(&.u........".,.|
+000000f0 e5 58 0d d7 0b c4 66 b2 06 90 bc 92 0f 05 34 5d |.X....f.......4]|
+00000100 2b 20 26 02 cc ac 90 40 a0 f1 5f 0e b9 99 7c 0f |+ &....@.._...|.|
+00000110 c9 3e 60 0b 39 ec 6c 94 3a d4 f7 b7 49 5e c7 6e |.>`.9.l.:...I^.n|
+00000120 df 3b cc 33 cb 32 41 53 dd 09 8e 91 97 d2 e0 06 |.;.3.2AS........|
+00000130 5e 0c 4c 49 46 18 83 fc ac b4 f8 76 2d 18 ee 0b |^.LIF......v-...|
+00000140 b6 4a b9 aa eb ee db 7a aa 6d 04 84 ed 8e 15 bc |.J.....z.m......|
+00000150 bf 6f a1 29 bc 0b 9f ba 05 a5 42 82 fd 1c 30 c9 |.o.)......B...0.|
+00000160 20 df 8e ba 28 ab 0b a2 42 09 5e e8 c1 61 d2 25 | ...(...B.^..a.%|
+00000170 fc 05 53 62 91 45 29 54 60 31 b8 4f 01 9c 7b 6a |..Sb.E)T`1.O..{j|
+00000180 04 27 df bc e0 a0 3d b3 80 73 22 ca 9b 41 be b6 |.'....=..s"..A..|
+00000190 09 22 67 1e 54 52 ce 14 b5 56 7a ca 3f a8 3e 01 |."g.TR...Vz.?.>.|
+000001a0 d2 e4 36 18 87 f6 08 19 55 d2 ba 3c a3 c5 11 84 |..6.....U..<....|
+000001b0 62 2a 09 c6 67 de cd ab 66 12 dd 0a 23 77 18 b7 |b*..g...f...#w..|
+000001c0 73 c1 29 61 52 32 95 eb a0 db 72 ae b7 ff 2a b2 |s.)aR2....r...*.|
+000001d0 08 f6 d7 69 32 c2 f8 8b e1 40 a9 d0 fe 11 64 a2 |...i2....@....d.|
+000001e0 a2 dd a7 e6 a6 dd 5d 79 49 df bb c0 83 da 56 7a |......]yI.....Vz|
+000001f0 a5 22 8e 60 df 89 48 e0 e2 e9 5f d5 fe dd ba 34 |.".`..H..._....4|
+00000200 ad 91 52 d8 2f 7e a4 73 50 e8 b7 83 e2 d9 5e 05 |..R./~.sP.....^.|
+00000210 96 08 e4 d4 bb 01 39 99 aa 1d fd 74 1b dc ca c2 |......9....t....|
+00000220 8f bb b8 bf c4 eb 00 6f cc 70 eb 7c c7 29 e4 64 |.......o.p.|.).d|
+00000230 8c 76 a7 b5 79 ea b6 96 fe eb 8f e7 81 9b d1 d0 |.v..y...........|
+00000240 41 16 db ef 9e 55 2a 77 6c 34 54 22 48 6a ca 78 |A....U*wl4T"Hj.x|
+00000250 31 6e d2 00 7f 54 93 65 ec 28 42 66 7b 74 4d 58 |1n...T.e.(Bf{tMX|
+00000260 fe 25 74 bd 9f a4 ff f2 45 06 c6 63 1f 11 68 a4 |.%t.....E..c..h.|
+00000270 fb fe 62 2b f8 19 e3 32 2c cc 5d 71 37 21 05 82 |..b+...2,.]q7!..|
+00000280 c9 c7 30 c7 74 64 d9 f9 6b c2 ae d8 15 2b 2a 79 |..0.td..k....+*y|
+00000290 a0 2d a3 18 1f d7 20 99 96 86 52 32 cf 84 bd 73 |.-.... ...R2...s|
+000002a0 63 85 82 a3 64 fb e3 ea 1b 31 f5 df 1c 74 06 48 |c...d....1...t.H|
+000002b0 69 8a e3 f0 72 8c 59 8b de 0b 06 02 47 54 4c 2d |i...r.Y.....GTL-|
+000002c0 46 ac d4 f5 4d 5c fe 0d bf af d0 37 58 82 3e d2 |F...M\.....7X.>.|
+000002d0 4e c1 7e 0f b0 21 f7 8e 2c 88 db 83 43 ed ad 5b |N.~..!..,...C..[|
+000002e0 0f a2 ce 47 e4 3f dd 1b 71 fe f0 a7 a1 8d 8c dc |...G.?..q.......|
+000002f0 75 e0 7a 89 f7 14 5b 37 9d 35 f6 23 91 a8 d2 1a |u.z...[7.5.#....|
+00000300 96 07 1b 5b 9c 35 27 b8 b9 0c 92 1e cf 1b 3c 17 |...[.5'.......<.|
+00000310 03 03 00 a4 f0 59 e1 1d 62 39 69 c5 53 ae 66 85 |.....Y..b9i.S.f.|
+00000320 df ea 32 73 ca 94 e2 b5 14 d4 30 07 dd fd 2f 9a |..2s......0.../.|
+00000330 16 fc e9 71 4a 20 b8 d2 7e 17 26 ff a9 55 56 24 |...qJ ..~.&..UV$|
+00000340 31 85 bc ea 19 1c 37 b7 fe 8b 47 5f a3 99 0f 5d |1.....7...G_...]|
+00000350 17 92 4b 2a 4c b5 6c db 8f bb 46 ee 89 31 53 79 |..K*L.l...F..1Sy|
+00000360 aa 34 9d 9b e8 9b e7 82 55 a3 92 f6 53 53 d3 72 |.4......U...SS.r|
+00000370 17 23 33 01 e8 75 7e 8d 63 91 a0 67 8f a5 f0 15 |.#3..u~.c..g....|
+00000380 8c f5 81 e2 c4 08 ff 14 1d 96 cf ef 4e 09 18 a1 |............N...|
+00000390 2c 38 0a f7 33 f0 1d ef 9d 12 4d 8c 25 f0 80 a2 |,8..3.....M.%...|
+000003a0 aa a7 cf e4 7c e6 44 58 6d 30 70 48 55 3b b5 79 |....|.DXm0pHU;.y|
+000003b0 55 aa 03 ed 14 ea e5 ee 17 03 03 00 35 72 1a ca |U...........5r..|
+000003c0 5c 3d 3b 75 29 cc a9 09 85 67 89 37 18 91 c0 af |\=;u)....g.7....|
+000003d0 28 d2 0c c9 8b 05 94 04 3a 68 38 f0 c3 db 95 89 |(.......:h8.....|
+000003e0 c8 28 fc 07 4b 49 7d b6 25 36 05 53 96 e0 d9 35 |.(..KI}.%6.S...5|
+000003f0 e5 7c |.||
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 02 11 6a 55 c4 ff 7a |...........jU..z|
+00000010 5b c4 b7 cb 8d ad ae 53 53 3d 41 3a fc 16 44 fd |[......SS=A:..D.|
+00000020 c8 5f 39 c3 5e 6b ee 7d ea 88 9c a9 78 f9 dc 51 |._9.^k.}....x..Q|
+00000030 b2 90 68 7d ae 2c b7 90 6e 79 cf f4 97 50 95 87 |..h}.,..ny...P..|
+00000040 f1 f6 2c 14 bc 2b a3 68 0d e6 c8 66 2f 3b 89 72 |..,..+.h...f/;.r|
+00000050 67 4d d8 e9 8d 6a 89 2a f9 e4 c1 b5 c0 92 16 25 |gM...j.*.......%|
+00000060 61 a6 98 ec b6 6b 52 8b a5 80 5a 9e 6d 03 ad 42 |a....kR...Z.m..B|
+00000070 a9 46 2f d8 e5 67 c9 8d 89 f7 34 93 82 7c a3 bb |.F/..g....4..|..|
+00000080 48 62 06 90 5c 5a aa fd 7c 71 88 24 22 f9 6a 2c |Hb..\Z..|q.$".j,|
+00000090 d1 d9 7e 0a 4c 39 11 e8 c0 17 1d 83 64 f2 2b c6 |..~.L9......d.+.|
+000000a0 c0 81 8c 6a 39 a9 09 aa 1e 58 eb 30 88 59 4d f2 |...j9....X.0.YM.|
+000000b0 d2 64 9f 4c 90 29 c0 66 94 e3 df 12 9c 75 33 24 |.d.L.).f.....u3$|
+000000c0 fb 14 bc 70 e1 b5 de 54 28 b0 3f 01 2c 2e 5f 35 |...p...T(.?.,._5|
+000000d0 e3 01 59 2a 3f ce ca 11 bb 29 97 03 f6 f4 30 b9 |..Y*?....)....0.|
+000000e0 66 db 3c f7 06 41 7b e8 f8 af 3e 03 65 2f 5f 88 |f.<..A{...>.e/_.|
+000000f0 fd 30 45 7a c9 b4 9f bf 03 eb c9 dd 06 ac 82 06 |.0Ez............|
+00000100 e8 81 8e ea 29 45 78 5c 0f 8e 21 8a fb 0b 95 c1 |....)Ex\..!.....|
+00000110 63 e9 18 c1 9a a4 c6 7d 56 4b 9a de 96 dd 37 54 |c......}VK....7T|
+00000120 92 ef 71 42 a8 66 e7 df e7 ea ec 4e 3c b3 8e 7d |..qB.f.....N<..}|
+00000130 ed 92 da 86 e5 fa 51 f8 e4 b0 09 f3 06 4d 38 f1 |......Q......M8.|
+00000140 d5 5f d2 72 1e 5f c3 1e 1d fd 96 70 e7 9c ae ea |._.r._.....p....|
+00000150 62 ce e4 a9 31 34 47 bc f0 9f 1c c7 b6 66 f0 70 |b...14G......f.p|
+00000160 7a e1 c5 a9 76 64 d4 25 0f 56 cd 36 17 67 bd 4d |z...vd.%.V.6.g.M|
+00000170 c7 78 d8 23 46 4b ac 46 34 1a d2 2d c5 e6 67 55 |.x.#FK.F4..-..gU|
+00000180 11 ec 8c f0 67 84 bf 89 ce 3c 71 4e 3a ab ff 22 |....g....<qN:.."|
+00000190 59 23 00 54 4b b6 9e c4 01 a1 9f e1 46 a6 a6 f3 |Y#.TK.......F...|
+000001a0 24 58 0c b4 6e 85 4c c1 8a d6 f8 02 c9 54 fb 85 |$X..n.L......T..|
+000001b0 c7 63 9b 47 28 10 a0 2d b6 c2 83 16 71 ae a7 c2 |.c.G(..-....q...|
+000001c0 e0 dc 8b 6d 57 e0 4b a2 a8 5d 4d 8b ed 72 31 d6 |...mW.K..]M..r1.|
+000001d0 54 33 78 df bb 4a f9 58 9f 8c 2b 11 36 29 a0 f0 |T3x..J.X..+.6)..|
+000001e0 8a 95 20 d8 f1 8c 08 e1 54 0a 81 79 33 20 23 de |.. .....T..y3 #.|
+000001f0 34 c8 2b 45 3a 59 c5 78 39 65 ea 70 e2 fe 59 4c |4.+E:Y.x9e.p..YL|
+00000200 ed 7f 07 07 25 a7 ff fa c9 c3 1f 33 55 c4 16 bb |....%......3U...|
+00000210 c9 b9 e0 2e ff 94 7c de 84 30 60 d6 17 03 03 00 |......|..0`.....|
+00000220 99 53 44 d2 12 38 c4 a7 7e f5 f5 67 b3 79 cf 8a |.SD..8..~..g.y..|
+00000230 34 0f 5d 49 0f bb 5f 30 c8 36 13 61 8d b5 b1 b0 |4.]I.._0.6.a....|
+00000240 dc 73 2f 1a 51 2f d4 8e 25 71 e1 46 af 11 96 19 |.s/.Q/..%q.F....|
+00000250 f7 fe 09 d9 6e 70 d5 fc b9 5b 1c ae ed 06 37 af |....np...[....7.|
+00000260 a1 bf 35 c6 6b 30 33 a2 c4 f6 c8 d4 73 34 73 8e |..5.k03.....s4s.|
+00000270 69 08 be 91 2c 8d 01 52 30 14 b3 d3 a0 7d 8a 9d |i...,..R0....}..|
+00000280 e9 af b2 77 64 eb 16 c1 8e 19 72 ad 4a fd d4 c9 |...wd.....r.J...|
+00000290 08 d0 54 6c f1 06 8c 70 2f e6 ef 23 23 67 96 db |..Tl...p/..##g..|
+000002a0 5f aa 81 6c 41 17 6b f4 30 ce 00 d6 a2 d8 28 f8 |_..lA.k.0.....(.|
+000002b0 be 9f 04 94 fa e3 fa 76 d0 30 17 03 03 00 35 9b |.......v.0....5.|
+000002c0 43 c4 8f dc b7 a1 44 4e 00 66 0a 95 a6 d7 46 79 |C.....DN.f....Fy|
+000002d0 30 2d 57 51 4e 21 a7 ed 43 e7 22 2d eb 07 9b 7d |0-WQN!..C."-...}|
+000002e0 ea a4 ff 14 5d 97 1f d5 e8 f1 3d 8d e3 13 b6 79 |....].....=....y|
+000002f0 36 ce 83 e8 17 03 03 00 17 d5 98 a6 a3 b7 40 2b |6.............@+|
+00000300 26 87 2f 4f 64 95 f1 2d e0 7b e3 98 c2 81 dc 7b |&./Od..-.{.....{|
+00000310 17 03 03 00 13 5b ab 65 e4 b1 d0 bd e9 c6 b2 3a |.....[.e.......:|
+00000320 4b 66 ce eb 25 0c bc 7d |Kf..%..}|
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..2367a39
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv13-ClientCert-RSA-RSAPSS
@@ -0,0 +1,143 @@
+>>> 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 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 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 7a 02 00 00 76 03 03 a9 f1 13 c3 3c |....z...v......<|
+00000010 1c dd c9 3a a1 ad 92 92 f1 f4 16 39 be 14 64 9c |...:.......9..d.|
+00000020 66 d8 28 cd b7 bb 40 43 ec f4 67 20 00 00 00 00 |f.(...@C..g ....|
+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 ff |..+.....3.$... .|
+00000060 53 ac b3 b0 48 47 d0 1e b1 70 eb dd 02 e5 e8 07 |S...HG...p......|
+00000070 ce c7 e0 af d7 e0 46 c7 ff f5 97 30 e5 80 5b 14 |......F....0..[.|
+00000080 03 03 00 01 01 17 03 03 00 17 0b 12 ef 6d ea 5e |.............m.^|
+00000090 71 41 83 d6 35 9f 39 2c f0 ab 01 e9 03 54 c6 9e |qA..5.9,.....T..|
+000000a0 37 17 03 03 00 20 15 7a 35 f4 a6 6e 65 89 10 ae |7.... .z5..ne...|
+000000b0 18 31 c0 0c 15 1c b8 c5 5d f3 54 0c 98 32 a4 5e |.1......].T..2.^|
+000000c0 91 f7 03 8a 80 b9 17 03 03 02 7a fa 93 7f c6 d1 |..........z.....|
+000000d0 2f 7e 2d d6 1b b7 ff fd 96 6e a1 f7 0e 98 dc 77 |/~-......n.....w|
+000000e0 cc 6a 4e 91 3d c1 ad 4b 5c 28 ee ea a7 0a ce 8f |.jN.=..K\(......|
+000000f0 51 dd 89 fd 5a 81 6d 21 d6 0d 35 70 84 73 8c fa |Q...Z.m!..5p.s..|
+00000100 2e 7a e0 af ab 79 79 aa 67 2b 80 a8 b3 a8 fb 0d |.z...yy.g+......|
+00000110 eb 87 66 d5 be 33 0b f0 80 b8 5e 21 84 be 25 fe |..f..3....^!..%.|
+00000120 47 98 5a 26 5d c3 96 2e c5 b8 da 9f a6 d4 ca bb |G.Z&]...........|
+00000130 de 7f 2c 0a 28 a8 f3 41 bc a2 2e 70 f2 b3 6f a3 |..,.(..A...p..o.|
+00000140 10 0e 1f 11 af 11 50 2b 22 84 97 d7 80 f5 62 77 |......P+".....bw|
+00000150 a6 94 47 22 ef 24 c6 0e dc 5c f5 40 08 f7 21 78 |..G".$...\.@..!x|
+00000160 ae 11 f3 d8 a5 d8 20 ac 90 73 d7 a2 e3 f0 08 57 |...... ..s.....W|
+00000170 fc 74 70 66 fd 3d 49 c7 99 37 98 5e b1 1c c4 38 |.tpf.=I..7.^...8|
+00000180 64 09 e6 70 b6 8b 00 72 2d 5b b4 70 39 d6 e9 d5 |d..p...r-[.p9...|
+00000190 dc cd 8e 01 eb 5f 34 61 d0 97 62 0b 4f 81 ed 30 |....._4a..b.O..0|
+000001a0 64 56 f2 6e 31 5e 24 e8 56 2b d6 31 54 c4 48 47 |dV.n1^$.V+.1T.HG|
+000001b0 16 00 a7 65 c1 fa ea 12 30 78 41 e7 30 2d 71 cf |...e....0xA.0-q.|
+000001c0 b0 e9 be e4 a2 33 38 87 2d 37 14 2d 03 cf ae 87 |.....38.-7.-....|
+000001d0 9a 09 f2 ed f3 44 66 c3 8a 56 8e e4 c4 aa e9 f7 |.....Df..V......|
+000001e0 cd 75 52 1b d9 ed 66 04 13 dd dd cf 0f 44 cd 18 |.uR...f......D..|
+000001f0 68 c5 2c 4c f9 e3 d3 02 12 78 38 5c f6 96 d7 80 |h.,L.....x8\....|
+00000200 f0 83 03 fe 7a e0 35 7e a3 ad 99 52 ec fc ee 74 |....z.5~...R...t|
+00000210 f5 09 0f ca 69 f0 fb d0 40 90 1b 46 9e 2d 62 c9 |....i...@..F.-b.|
+00000220 0f 59 b2 cc a0 4a 9b 84 14 3a 1b 51 fc e7 e8 a1 |.Y...J...:.Q....|
+00000230 26 fd 20 8c 88 6f 87 11 ae 97 76 f8 4b cc 67 1a |&. ..o....v.K.g.|
+00000240 3e 58 65 77 77 82 06 c0 d4 41 4e 66 d2 5a 83 b1 |>Xeww....ANf.Z..|
+00000250 ee 19 5d 7b 99 34 d3 2f 6c bd 30 a3 8c 75 89 ec |..]{.4./l.0..u..|
+00000260 cb 90 8b 89 05 b8 e4 6e 3b 60 5d 0e 19 8f d6 c7 |.......n;`].....|
+00000270 86 f0 a9 2b c7 12 4a 4c d8 a5 e8 64 49 1d 49 99 |...+..JL...dI.I.|
+00000280 a7 80 01 f0 77 57 4a 78 3c ac 38 40 bb d2 10 24 |....wWJx<.8@...$|
+00000290 9d e2 29 b2 1e 4b 50 66 64 07 79 80 c7 81 9d e2 |..)..KPfd.y.....|
+000002a0 f5 a9 10 9a 8d 3b de 0e 21 85 13 ac 26 30 f9 e4 |.....;..!...&0..|
+000002b0 a6 f9 8f e0 3c c1 69 7e 11 4c d1 a8 4e 88 30 fc |....<.i~.L..N.0.|
+000002c0 52 6e b0 4f b6 7e 15 9e a5 8a 46 ca 1f ac 8e 2a |Rn.O.~....F....*|
+000002d0 07 34 d7 c2 14 c6 c1 ed a1 f9 1e 59 b4 b4 86 3e |.4.........Y...>|
+000002e0 d3 d0 78 a6 07 62 d3 88 80 54 a8 2a e9 38 2e 58 |..x..b...T.*.8.X|
+000002f0 43 94 cc ed f0 46 f6 cc 4b 7a b8 f5 a2 d6 a8 36 |C....F..Kz.....6|
+00000300 e2 8e 11 fb e7 21 19 c5 fa c9 90 98 72 43 88 ac |.....!......rC..|
+00000310 c0 56 84 9e cd b7 e5 26 d6 49 19 88 a5 12 ac 49 |.V.....&.I.....I|
+00000320 5d 77 37 2a ff 38 5a 7a 5b c8 74 5d 74 fc 22 7f |]w7*.8Zz[.t]t.".|
+00000330 46 97 2b 34 32 fb 83 65 75 b6 8b 5c 8a b1 d4 a2 |F.+42..eu..\....|
+00000340 14 7f 46 0d 63 17 03 03 00 99 c7 79 bb 4f 88 a0 |..F.c......y.O..|
+00000350 78 be 04 ca 39 1f 1f a8 82 59 b5 dd 96 93 0d c4 |x...9....Y......|
+00000360 30 f4 22 4c e2 52 51 d4 33 b8 35 7b ed 01 19 25 |0."L.RQ.3.5{...%|
+00000370 b5 31 36 25 23 a2 51 d9 7a a9 00 72 05 34 81 62 |.16%#.Q.z..r.4.b|
+00000380 d0 df 8b 3a 65 98 4e 87 e2 29 9b 44 77 8c dd c9 |...:e.N..).Dw...|
+00000390 4c a5 de 14 97 e0 f1 2c e8 5d 0e 8f d0 fd f6 77 |L......,.].....w|
+000003a0 c1 1f ac 79 4d 32 19 09 98 a8 f0 2f 3e d5 7e f7 |...yM2...../>.~.|
+000003b0 aa c1 f0 36 b1 8e c7 0b ce 09 00 ac 28 64 c0 33 |...6........(d.3|
+000003c0 58 cc 48 3a 15 a4 77 24 50 67 f2 39 53 4d 63 23 |X.H:..w$Pg.9SMc#|
+000003d0 48 74 bd 0a c8 02 17 be e4 64 af 6e 02 a9 22 92 |Ht.......d.n..".|
+000003e0 65 04 c6 17 03 03 00 35 e0 4e 15 4b 9d 53 57 c6 |e......5.N.K.SW.|
+000003f0 97 b4 9d 1a 03 39 26 b9 ca 5b 04 50 af db 52 99 |.....9&..[.P..R.|
+00000400 d9 13 40 6a 89 23 99 42 9a 91 1d d1 6c 07 a0 aa |..@j.#.B....l...|
+00000410 05 6e 60 0b fd e7 de 32 c3 97 18 0d 9b |.n`....2.....|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 02 7a 94 78 2d 5d 5a |..........z.x-]Z|
+00000010 3e 96 7f 19 29 51 99 f3 6e d3 a4 d5 3c 9a 3d d5 |>...)Q..n...<.=.|
+00000020 37 bc 3b 71 b3 54 83 d9 5e 9d 64 76 f9 74 7a 24 |7.;q.T..^.dv.tz$|
+00000030 e3 cb ea aa 17 f4 44 41 73 71 39 d6 9b d5 a6 a2 |......DAsq9.....|
+00000040 6a 1e 1c 02 a1 d5 e3 e8 f5 f7 07 9d 3b ea f8 6d |j...........;..m|
+00000050 80 cf 6b 14 71 b8 bd c4 8a 07 49 31 e7 bd d5 91 |..k.q.....I1....|
+00000060 ac 80 70 25 5e f4 db 07 ed 36 c2 3a 1d ad 86 6e |..p%^....6.:...n|
+00000070 68 1a ca 4f a1 ba c3 2f de 49 01 fa a9 39 a6 51 |h..O.../.I...9.Q|
+00000080 3a e6 9f cf 6b 02 4e 1e 70 dd f2 10 c2 62 9b 1f |:...k.N.p....b..|
+00000090 83 10 fa 85 52 a8 a7 08 37 9c 92 b0 9c fe 00 78 |....R...7......x|
+000000a0 0b a4 7b b5 f9 9f 87 d2 d3 07 72 b2 ab 96 9e 73 |..{.......r....s|
+000000b0 55 3c 1e 65 99 89 36 78 7e 42 8f 05 de b6 fb fc |U<.e..6x~B......|
+000000c0 1b 34 18 e6 4d 15 6c d1 2f 2c b0 ef 00 e9 07 89 |.4..M.l./,......|
+000000d0 ca 91 d9 c1 73 bf 8f a5 a4 7d 7e cc f5 85 fb af |....s....}~.....|
+000000e0 57 70 35 63 71 d6 78 57 13 48 27 ba a4 42 22 c2 |Wp5cq.xW.H'..B".|
+000000f0 56 f4 ae 38 39 a0 1f 57 44 57 c4 8a 70 90 30 70 |V..89..WDW..p.0p|
+00000100 ba 4a 98 29 0f aa e2 33 27 24 ee d9 e9 02 80 68 |.J.)...3'$.....h|
+00000110 4c 55 08 fb 3d 25 d6 d4 9d 83 ea 14 99 c2 77 94 |LU..=%........w.|
+00000120 f9 70 34 a8 ed 35 e6 4f c2 75 50 63 d5 9d 9a 89 |.p4..5.O.uPc....|
+00000130 8f 2e 5b ca 6b b3 ad e7 a2 c6 f7 0c 45 08 b7 f4 |..[.k.......E...|
+00000140 58 d3 d5 54 c2 67 f3 76 fb fc 9d fe 42 43 ea 90 |X..T.g.v....BC..|
+00000150 2b 29 e7 10 2f d7 9c 04 c4 cc 89 8f a9 36 14 f6 |+)../........6..|
+00000160 fc f1 25 6c 90 12 bf c6 cd ad 46 ce 17 3b 26 fb |..%l......F..;&.|
+00000170 c6 98 cb 6c f2 2c fd b9 2f 52 3e 56 42 78 0b 92 |...l.,../R>VBx..|
+00000180 a5 27 56 18 3d d6 26 3f e4 a1 6f ce c8 f1 f1 7a |.'V.=.&?..o....z|
+00000190 1f 84 66 c9 d9 8a 5c 0e 34 80 ba 58 b3 8b 7f f3 |..f...\.4..X....|
+000001a0 8a c9 6b c4 99 94 2c b7 e8 e8 9a a5 43 75 f8 e0 |..k...,.....Cu..|
+000001b0 29 1f 70 77 c7 4a 9f de ca 92 88 7c 37 12 d9 ef |).pw.J.....|7...|
+000001c0 2f 94 de ea d1 d9 69 6a 93 06 36 e0 68 02 53 ae |/.....ij..6.h.S.|
+000001d0 0e 00 cd ad d3 10 a7 89 2c 53 a7 03 d9 07 3c e9 |........,S....<.|
+000001e0 0b b0 18 2e 03 88 03 5c f4 b2 7e 59 f4 22 8c f7 |.......\..~Y."..|
+000001f0 5e d7 c7 ea ac 0f bc f7 3e 3f 75 fd 6d 9c 4c 3c |^.......>?u.m.L<|
+00000200 41 8d f5 30 17 20 83 c3 27 83 ce 84 6a e3 75 2b |A..0. ..'...j.u+|
+00000210 9d 7d de 2a bf 5a fb e1 2f 80 74 74 f6 09 bc 1f |.}.*.Z../.tt....|
+00000220 be f0 59 9e ce a1 62 46 54 a4 9a 25 97 b7 cd 1a |..Y...bFT..%....|
+00000230 0a d0 44 f6 ea a4 ed 63 e7 49 9a 4b f4 1a 39 91 |..D....c.I.K..9.|
+00000240 e6 34 e1 7b dd e7 53 ab 83 56 57 b2 89 3f 90 1f |.4.{..S..VW..?..|
+00000250 98 c4 64 27 b5 f5 f6 57 16 ca d9 0a 33 de 24 c3 |..d'...W....3.$.|
+00000260 f3 7c 23 37 94 93 c5 1a 42 da 18 6b 24 dd 37 54 |.|#7....B..k$.7T|
+00000270 ae f3 8a 3e 10 42 20 6e 49 23 1a 0f bd 65 7e 45 |...>.B nI#...e~E|
+00000280 12 7a 64 9a 30 17 03 03 00 99 af 41 cf 95 21 1f |.zd.0......A..!.|
+00000290 34 df 1c c7 a8 b6 ee 31 8d b3 9e 5a 59 8e c4 37 |4......1...ZY..7|
+000002a0 79 a4 d8 75 22 da 12 21 e5 de d4 ad 98 17 e2 ae |y..u"..!........|
+000002b0 ae 9f f6 e8 29 66 d0 ac b4 08 16 24 40 67 9d d5 |....)f.....$@g..|
+000002c0 bf a4 64 91 a1 17 82 c0 e7 77 b6 20 26 4a 70 1d |..d......w. &Jp.|
+000002d0 c8 f8 ec 18 b7 c6 3c 81 b9 c6 04 9c 0d 37 a6 39 |......<......7.9|
+000002e0 fd 2d 99 d7 ba 41 a4 91 60 f1 1f d2 76 76 aa 47 |.-...A..`...vv.G|
+000002f0 89 0a d1 97 0b 91 20 a9 43 c9 ce 2c 84 ba 81 7a |...... .C..,...z|
+00000300 39 91 7d 12 75 05 8e 87 b1 3f 80 8d 12 ca 8f 91 |9.}.u....?......|
+00000310 23 84 28 11 c3 81 ed 09 05 16 6e 50 57 76 ad 5c |#.(.......nPWv.\|
+00000320 c5 92 77 17 03 03 00 35 5a d9 15 29 1f a3 f0 cf |..w....5Z..)....|
+00000330 74 c4 1d 0c c3 fa 54 59 1e 54 06 0d 1b ce 07 00 |t.....TY.T......|
+00000340 f9 66 3d e1 75 10 cf de cb 7d 0d d6 d1 4d 87 81 |.f=.u....}...M..|
+00000350 13 ec 2c 28 13 a5 b3 01 c7 86 3a 84 65 17 03 03 |..,(......:.e...|
+00000360 00 17 b4 e4 18 61 62 04 b3 ca 98 36 93 42 a2 be |.....ab....6.B..|
+00000370 2c f5 18 11 bd 7d 64 70 bc 17 03 03 00 13 32 65 |,....}dp......2e|
+00000380 fa 07 3e 3c ed 9d 85 31 ba 8e 92 ea de 17 59 cd |..><...1......Y.|
+00000390 db |.|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-ECDSA b/src/crypto/tls/testdata/Client-TLSv13-ECDSA
new file mode 100644
index 0000000..dac9ef7
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv13-ECDSA
@@ -0,0 +1,86 @@
+>>> 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 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 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 7a 02 00 00 76 03 03 e3 21 e8 24 fb |....z...v...!.$.|
+00000010 e8 fe 46 e2 54 a7 db 98 ae a4 b2 fc f8 17 99 b4 |..F.T...........|
+00000020 ed 6a aa 9c f9 ce e2 0f f8 88 05 20 00 00 00 00 |.j......... ....|
+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 a9 |..+.....3.$... .|
+00000060 5a 5c e9 b1 71 e8 a8 64 97 65 02 6b 3d 25 6f 6f |Z\..q..d.e.k=%oo|
+00000070 9a 47 cb 4a 81 ac 89 23 22 c1 f4 3d db 77 1e 14 |.G.J...#"..=.w..|
+00000080 03 03 00 01 01 17 03 03 00 17 12 15 75 15 9f 10 |............u...|
+00000090 90 07 34 9c eb 05 d0 a1 4b 36 5b 4c 7b 26 2a 00 |..4.....K6[L{&*.|
+000000a0 29 17 03 03 02 22 85 a0 67 d7 72 57 83 19 79 12 |)...."..g.rW..y.|
+000000b0 b7 bd 37 ed ab 49 5d 15 49 2b 4f a1 b2 25 08 22 |..7..I].I+O..%."|
+000000c0 88 83 70 07 bc 8f 69 45 1b 21 36 99 f4 99 40 f8 |..p...iE.!6...@.|
+000000d0 0d 30 13 87 70 68 f6 9d ce c7 9e 25 2c 1e 7a b5 |.0..ph.....%,.z.|
+000000e0 52 ed f8 0f f7 d9 e5 15 fc a3 47 83 0d 18 c4 de |R.........G.....|
+000000f0 a1 a6 24 35 aa 56 d1 8b 95 07 5f 0f ba 1f 96 c3 |..$5.V...._.....|
+00000100 5b 36 cc d2 15 e6 b4 88 8f e3 7f 79 c2 24 d5 f3 |[6.........y.$..|
+00000110 a7 35 69 4e d2 2a f7 5c 08 8a c0 26 dd b9 77 5b |.5iN.*.\...&..w[|
+00000120 96 1b 5f 03 89 07 a0 6a b1 14 1d 02 46 08 eb 80 |.._....j....F...|
+00000130 d5 4c dc 69 63 8f 14 a1 e5 02 95 05 8a 8b c8 68 |.L.ic..........h|
+00000140 c3 d8 75 56 47 94 32 ba 67 71 ed 4b b4 62 ba 6a |..uVG.2.gq.K.b.j|
+00000150 31 20 a7 d6 f8 8c a0 e9 e8 d2 1a 6b 85 6b b7 ee |1 .........k.k..|
+00000160 78 e1 2e 4c 14 f0 b3 3e b8 dc 7d af f0 9d 29 f3 |x..L...>..}...).|
+00000170 54 1d 9d dc 9e a3 9f 29 5b 33 1d f7 00 98 85 bd |T......)[3......|
+00000180 42 39 85 75 cf fa dc f3 7e 80 14 4e a5 90 80 b6 |B9.u....~..N....|
+00000190 e3 37 d3 27 c6 7b b9 ee 32 61 a5 72 e5 2f a6 ab |.7.'.{..2a.r./..|
+000001a0 cb 8e ac 53 4b 86 24 92 4b 77 d6 8d aa b4 37 d5 |...SK.$.Kw....7.|
+000001b0 2b b2 2f 07 23 37 4a d9 1f cc 6c 72 c6 21 5b 38 |+./.#7J...lr.![8|
+000001c0 a3 33 5c 86 50 69 34 8f 5a b8 cc 5e 82 7d 5b b2 |.3\.Pi4.Z..^.}[.|
+000001d0 5b f5 58 7f 2c 61 08 4b 3d 8b 67 09 19 01 d2 4f |[.X.,a.K=.g....O|
+000001e0 06 62 17 4e d4 bf 88 89 bb c4 6e 14 2b 3a 50 c9 |.b.N......n.+:P.|
+000001f0 56 8a c1 0a 45 e6 67 32 f3 96 37 4b ba c2 2a 2b |V...E.g2..7K..*+|
+00000200 84 e1 ff bb e0 ea 68 9b 98 fc 78 26 25 f6 50 25 |......h...x&%.P%|
+00000210 52 57 83 94 39 b9 a7 8d 38 43 70 a8 b7 61 a6 cf |RW..9...8Cp..a..|
+00000220 09 77 db 3d 64 94 63 73 5b a1 6d f4 06 c1 b3 fb |.w.=d.cs[.m.....|
+00000230 c6 9a 0b ea 9f 8e 6d 58 53 0e 13 e0 a6 21 69 7a |......mXS....!iz|
+00000240 d3 57 32 d4 c6 32 ef 02 8e 54 1d 72 2d d6 a7 dc |.W2..2...T.r-...|
+00000250 59 54 be 69 3f 5c 53 23 a9 f7 3e a9 e6 e7 e0 98 |YT.i?\S#..>.....|
+00000260 65 f6 74 f4 49 1c 77 0f 92 34 87 81 29 85 d1 e0 |e.t.I.w..4..)...|
+00000270 1e 4d b4 eb c2 44 43 a7 10 51 7c 5e 8e a4 b6 37 |.M...DC..Q|^...7|
+00000280 78 e8 35 02 07 3d 60 a5 01 75 01 25 f3 ff 32 ff |x.5..=`..u.%..2.|
+00000290 34 ab a4 c3 4c ad 21 b8 91 0a d6 54 4b 7d cf c5 |4...L.!....TK}..|
+000002a0 ec 0f e5 4a 4d 75 4c ec fc 37 2b 26 5a 73 93 70 |...JMuL..7+&Zs.p|
+000002b0 88 c7 9c cf 32 f9 ee a7 27 6e 1d 9e 36 a2 31 9e |....2...'n..6.1.|
+000002c0 cd 0e c2 89 ef 2b 40 1a 17 03 03 00 a4 ad 19 05 |.....+@.........|
+000002d0 e6 40 5e b1 ec 69 6b 47 ef 5d d3 ee a6 94 51 85 |.@^..ikG.]....Q.|
+000002e0 d8 28 d9 df 8b d0 df 23 7e bd 98 6c 33 26 45 fa |.(.....#~..l3&E.|
+000002f0 60 71 8b f5 71 5c 22 4e b3 a7 01 fe 17 39 89 67 |`q..q\"N.....9.g|
+00000300 0b 70 ff 52 b9 10 9c e9 02 c0 1c 56 9d c8 45 51 |.p.R.......V..EQ|
+00000310 5a dd 86 79 6d a7 7d eb 16 c2 1a 5f 6a 3b 93 42 |Z..ym.}...._j;.B|
+00000320 13 f3 3d 8a 39 21 5f a9 7f cf 4b 1e 22 f1 a3 f8 |..=.9!_...K."...|
+00000330 5c 35 41 2a e2 91 72 4f 59 61 1c 15 be 27 6a bd |\5A*..rOYa...'j.|
+00000340 b7 16 1f 63 97 51 d6 96 dd 81 f9 e7 fd 97 33 6e |...c.Q........3n|
+00000350 da 5a 61 77 57 6e 3b 65 24 db b3 3a 18 7b dc f4 |.ZawWn;e$..:.{..|
+00000360 7c ff ab 43 7f 1b ae ae b8 73 71 9e be 91 d6 56 ||..C.....sq....V|
+00000370 13 17 03 03 00 35 39 61 a3 b7 e5 1d 3d 87 92 84 |.....59a....=...|
+00000380 11 39 7d f4 ce 29 b9 4b fd 3c 0c 5a b6 3a fa e2 |.9}..).K.<.Z.:..|
+00000390 a8 5b e6 d2 e5 7e e3 a6 33 59 e4 a8 59 95 5d b9 |.[...~..3Y..Y.].|
+000003a0 31 6d 51 90 22 be c0 3f 6e 43 f2 |1mQ."..?nC.|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 50 4f ce ae a5 |..........5PO...|
+00000010 f7 b0 7e 2b 91 86 72 da 90 65 fd 1b a5 46 c6 98 |..~+..r..e...F..|
+00000020 47 90 5a f2 b8 5a 1f 18 44 19 bd ca dd 2a 15 e7 |G.Z..Z..D....*..|
+00000030 53 f5 17 e8 7d 9b f1 9a 63 ac b0 b0 df c3 0e 4c |S...}...c......L|
+00000040 17 03 03 00 17 8b bd fb bc fd f7 af 53 9b 8b 1a |............S...|
+00000050 a3 e5 f6 e9 87 bd 4a 8a 1b 0e c9 d9 17 03 03 00 |......J.........|
+00000060 13 8e c6 d3 6e 04 8f 3b d4 76 a4 c7 c8 63 a8 a8 |....n..;.v...c..|
+00000070 9e ba e7 fd |....|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-Ed25519 b/src/crypto/tls/testdata/Client-TLSv13-Ed25519
new file mode 100644
index 0000000..d284740
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv13-Ed25519
@@ -0,0 +1,68 @@
+>>> 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 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 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 7a 02 00 00 76 03 03 6f b6 d3 79 9b |....z...v..o..y.|
+00000010 00 17 a8 46 3f e4 bc fc 08 1e 56 6c d8 63 86 f3 |...F?.....Vl.c..|
+00000020 83 1b d8 26 6d 86 d6 4c f3 4f e1 20 00 00 00 00 |...&m..L.O. ....|
+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 5b |..+.....3.$... [|
+00000060 8f 4f 5a a9 95 6b 04 07 31 d3 ed 91 8b 25 b4 7b |.OZ..k..1....%.{|
+00000070 5c a1 0a a6 26 09 92 9b b0 72 26 f9 0d 09 60 14 |\...&....r&...`.|
+00000080 03 03 00 01 01 17 03 03 00 17 a8 99 d3 76 1f 12 |.............v..|
+00000090 19 18 15 8e 4c 59 43 92 11 4a aa 50 98 7e 4c d9 |....LYC..J.P.~L.|
+000000a0 63 17 03 03 01 50 66 f5 d6 ce 35 0f 10 e5 ab 34 |c....Pf...5....4|
+000000b0 78 17 c6 b6 60 40 eb 53 34 9f ce 02 c4 36 51 18 |x...`@.S4....6Q.|
+000000c0 c2 b3 fb f3 98 92 d0 f2 b7 be 28 f5 c7 2d fa 1f |..........(..-..|
+000000d0 9b 8b aa e5 45 54 6b 0e ed 6b 44 cb d4 4d 62 b2 |....ETk..kD..Mb.|
+000000e0 30 c9 df ac cf a3 7e 43 58 1e bf 6e 5b 69 4e 48 |0.....~CX..n[iNH|
+000000f0 1c 39 49 eb 8a 0c 22 f3 70 4a 80 50 39 d6 68 29 |.9I...".pJ.P9.h)|
+00000100 d0 6d 08 20 26 39 6d 37 5a 9f 79 e9 16 e3 7e 94 |.m. &9m7Z.y...~.|
+00000110 8f 5f 9b 97 2d e1 b1 48 e4 a3 36 63 40 5a 80 93 |._..-..H..6c@Z..|
+00000120 06 27 3b 93 d9 ed 2d b1 3e 74 ed bc 38 a1 cb 17 |.';...-.>t..8...|
+00000130 06 4a 9b c1 c1 d7 7a 1c ca ff 4d ee 91 6d d0 3c |.J....z...M..m.<|
+00000140 c2 4b cc 33 c6 7c 76 8e db a2 e0 fe 15 e2 ec db |.K.3.|v.........|
+00000150 1f 5d 05 c8 5e 0e 7f 2c 7a 95 08 34 68 a2 2c 7c |.]..^..,z..4h.,||
+00000160 04 16 92 7a c8 ec 52 2d 1a c4 7a ea 12 cd 0f b9 |...z..R-..z.....|
+00000170 7c 00 51 55 02 5b 02 7d ec 89 af f5 6d 76 89 0e ||.QU.[.}....mv..|
+00000180 67 42 f0 e4 67 4d 3f 70 ff 2c 64 81 1c 4a 92 1f |gB..gM?p.,d..J..|
+00000190 26 8b a4 4f 15 18 b5 11 4a 61 df 45 53 74 fd 8d |&..O....Ja.ESt..|
+000001a0 ff 22 32 91 af c7 7f a4 7b 62 c3 3b 30 51 b6 34 |."2.....{b.;0Q.4|
+000001b0 b6 01 21 f9 86 74 be 62 27 1a 41 1f f0 0d 8b 5c |..!..t.b'.A....\|
+000001c0 4b 82 ea 76 23 9c 36 af 25 1f f6 2d 5f 9c 28 bd |K..v#.6.%..-_.(.|
+000001d0 b6 d5 1e 26 8b c1 dc ac ed 6d 10 ff 13 ed fc 08 |...&.....m......|
+000001e0 08 0a 74 1c b1 5b f8 45 e4 83 44 f2 be ce 8d ac |..t..[.E..D.....|
+000001f0 ee ae e6 21 da c7 17 03 03 00 59 d9 b3 95 0a f7 |...!......Y.....|
+00000200 1a 1a 54 fa ab 09 38 6d 6d 53 0a ef 11 73 bc a2 |..T...8mmS...s..|
+00000210 20 03 31 48 e2 0a d1 af 56 6c ca dd 88 ba 72 3a | .1H....Vl....r:|
+00000220 c1 e0 c5 60 44 74 d6 c9 18 23 96 2c e7 88 c8 3e |...`Dt...#.,...>|
+00000230 02 73 c0 38 d4 bd 85 a4 bb 78 a0 ba d3 fd f1 c4 |.s.8.....x......|
+00000240 27 08 05 fb 2c 26 20 b7 1a 41 87 a6 b7 97 19 26 |'...,& ..A.....&|
+00000250 50 ed 9a e4 17 03 03 00 35 68 36 c7 78 c3 5e ff |P.......5h6.x.^.|
+00000260 b3 92 a7 25 31 2a a2 fa 24 d9 da 69 16 03 8b db |...%1*..$..i....|
+00000270 fe b2 3f 63 88 49 f1 14 63 7a 58 a9 6f c5 64 92 |..?c.I..czX.o.d.|
+00000280 21 84 82 d8 49 98 fb f3 f1 fd 52 83 32 97 |!...I.....R.2.|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 07 7b a2 7a 4f |..........5.{.zO|
+00000010 40 e9 a2 94 9f b7 2d 91 87 1e 37 b0 ca b7 ea 91 |@.....-...7.....|
+00000020 53 f1 bf 7d 56 6a 0c 6a 9d 07 ac 93 9c db ca ac |S..}Vj.j........|
+00000030 43 7b eb 56 9d 6c 79 f2 72 f8 0b 8d 15 08 84 d5 |C{.V.ly.r.......|
+00000040 17 03 03 00 17 07 b3 7d a9 56 c4 76 e5 12 97 29 |.......}.V.v...)|
+00000050 b7 99 e6 3e 08 79 2d fb 1a 5b eb 7a 17 03 03 00 |...>.y-..[.z....|
+00000060 13 66 b7 65 57 0d 54 7b 6a 34 98 a1 4e 29 d5 92 |.f.eW.T{j4..N)..|
+00000070 1e b6 52 bc |..R.|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-ExportKeyingMaterial b/src/crypto/tls/testdata/Client-TLSv13-ExportKeyingMaterial
new file mode 100644
index 0000000..a0ede61
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv13-ExportKeyingMaterial
@@ -0,0 +1,90 @@
+>>> 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 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 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 7a 02 00 00 76 03 03 d6 7f ef 2d f6 |....z...v.....-.|
+00000010 82 d9 be 6d 33 80 73 c0 d4 d8 63 e9 95 a6 5b 1f |...m3.s...c...[.|
+00000020 ce c0 ec 13 07 f4 68 7d cc 79 18 20 00 00 00 00 |......h}.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 03 00 00 |................|
+00000050 2e 00 2b 00 02 03 04 00 33 00 24 00 1d 00 20 00 |..+.....3.$... .|
+00000060 e9 40 7a 65 78 98 47 43 aa e1 63 fd 6b c4 21 1d |.@zex.GC..c.k.!.|
+00000070 58 45 5f 64 a0 18 55 a0 c3 14 7d 4e 12 93 7c 14 |XE_d..U...}N..|.|
+00000080 03 03 00 01 01 17 03 03 00 17 4c 01 0b f7 e7 1b |..........L.....|
+00000090 a9 47 84 10 3b 50 85 6e 3d 8e 52 bc 99 bf d4 35 |.G..;P.n=.R....5|
+000000a0 45 17 03 03 02 6d 8c b3 22 04 de 8b 09 e5 e7 9f |E....m..".......|
+000000b0 d5 1f fb 8a 57 ad a7 93 4c 5f 29 46 df c3 e5 86 |....W...L_)F....|
+000000c0 66 f1 c7 6b 14 79 cf 9d cc e1 f5 3f 31 2c dc ff |f..k.y.....?1,..|
+000000d0 77 99 14 9e 56 12 4e a4 cb 56 5c d6 c0 5b 57 dc |w...V.N..V\..[W.|
+000000e0 22 72 12 2d d6 a0 8a c7 90 e6 41 66 78 1a d7 a6 |"r.-......Afx...|
+000000f0 87 db f1 e3 9b 86 8c cf 94 22 cf 81 99 20 bc 19 |........."... ..|
+00000100 50 f9 fe 6c ab ea d4 a2 ee f8 17 1d ae 37 86 2a |P..l.........7.*|
+00000110 f9 83 3c 59 d0 aa 63 22 18 d5 12 40 be f7 02 f1 |..<Y..c"...@....|
+00000120 9a bf 07 39 23 73 23 a1 66 70 b7 be 9a 24 de 30 |...9#s#.fp...$.0|
+00000130 2f 62 6e f8 d5 ee 69 a7 87 3c 73 10 4c 7c 97 42 |/bn...i..<s.L|.B|
+00000140 62 b9 d5 74 40 f0 d7 b3 74 42 73 d7 41 bc 35 43 |b..t@...tBs.A.5C|
+00000150 87 2e c5 1b e9 15 e8 5e 18 b9 6b 57 2a ee 59 7a |.......^..kW*.Yz|
+00000160 1c a6 2b cb b4 db e8 bb 99 87 74 4a ee 57 3a 87 |..+.......tJ.W:.|
+00000170 3c 2d b9 76 41 4a 7a a5 6a fa 92 e9 80 24 08 dc |<-.vAJz.j....$..|
+00000180 18 44 4b 59 7c 81 99 29 f2 c4 55 b6 58 71 0d 68 |.DKY|..)..U.Xq.h|
+00000190 6b 06 bd 13 2c a0 04 15 2e 49 cc 99 7f a6 b4 5d |k...,....I.....]|
+000001a0 d3 49 a5 21 15 d7 66 2d a2 e8 cd a7 7e 46 c4 ac |.I.!..f-....~F..|
+000001b0 89 ae cb 58 73 42 9f dc c3 c9 5a 13 2f 6f f7 ab |...XsB....Z./o..|
+000001c0 04 4b 9f f1 6c c4 ac 0f f5 eb 8d 7a ef cf 01 00 |.K..l......z....|
+000001d0 8a 02 ec 16 09 c1 e9 27 81 32 70 b1 24 d4 db 4e |.......'.2p.$..N|
+000001e0 9e 22 65 21 a7 8f 19 d5 c6 57 78 8a fa a6 41 87 |."e!.....Wx...A.|
+000001f0 52 eb 5d ef f8 7e 3b 34 a5 31 ff 33 33 fd 85 03 |R.]..~;4.1.33...|
+00000200 e4 94 56 ef 11 c0 fe 84 f6 87 94 26 de 7c bd d1 |..V........&.|..|
+00000210 1b ea 15 34 62 e5 da bd e6 c4 b0 74 b5 27 ad 21 |...4b......t.'.!|
+00000220 39 16 c8 be e8 41 50 7b de fb 71 10 4c b1 f4 5a |9....AP{..q.L..Z|
+00000230 bf ea fd 9b 86 a5 c6 e7 2f c2 13 e4 d2 cd 32 7a |......../.....2z|
+00000240 6b ad ab 43 12 3b 45 b9 5c e4 cf 2c f9 f3 44 2c |k..C.;E.\..,..D,|
+00000250 11 31 ce c5 65 dd ea e6 52 bd 8a 35 d0 31 d4 4f |.1..e...R..5.1.O|
+00000260 01 24 54 e4 d2 bf 6e 79 b2 bf a8 f0 5d 9d 72 44 |.$T...ny....].rD|
+00000270 6e df 29 8a d2 cc a8 d2 ee 0c 51 50 cd 71 a6 2a |n.).......QP.q.*|
+00000280 fe 53 2e f7 ae fa 4c 34 d0 68 31 d5 69 be 64 a5 |.S....L4.h1.i.d.|
+00000290 03 54 31 1a dc f0 9e c7 82 1f 15 d1 64 ff 79 07 |.T1.........d.y.|
+000002a0 5e 71 3a 98 3c 21 a7 8e 1e bf 2d f3 86 4b 3f 30 |^q:.<!....-..K?0|
+000002b0 73 0d 7c 5d 57 1b a9 89 2b 52 70 84 8e e6 bb fe |s.|]W...+Rp.....|
+000002c0 b7 1f 65 6a 08 63 58 16 81 51 09 b2 79 7d 84 c0 |..ej.cX..Q..y}..|
+000002d0 6f e1 ab 92 35 16 2e 8f 5c 17 2d 5e 68 7f d4 94 |o...5...\.-^h...|
+000002e0 5a 1b 1d 6c 5f e0 36 a0 ae 54 5b e9 39 1f bc 73 |Z..l_.6..T[.9..s|
+000002f0 f9 04 80 e9 36 d2 2c de 64 ca 08 95 d0 98 4b da |....6.,.d.....K.|
+00000300 7b 0d 7f 79 1b a0 56 6c dd 3c 40 52 3e 7a 8f 52 |{..y..Vl.<@R>z.R|
+00000310 3c c9 2f 17 03 03 00 99 07 91 f0 6b e0 bb 6f 0b |<./........k..o.|
+00000320 ff 08 69 bc d2 1d f1 40 d2 d7 c7 f6 c2 b3 57 d7 |..i....@......W.|
+00000330 90 00 c9 9e ef 40 b6 96 86 0d 27 8b 6f ac 54 2f |.....@....'.o.T/|
+00000340 73 b3 b4 82 1b d3 f5 e9 41 a7 fd d5 b1 67 f7 6e |s.......A....g.n|
+00000350 2e c1 06 34 ef a3 b9 97 4d a8 64 4f f8 48 24 5c |...4....M.dO.H$\|
+00000360 66 f4 d7 d4 e3 ad 45 fb 4a 42 0d 19 bb a1 cc b3 |f.....E.JB......|
+00000370 88 d2 2a d7 c3 53 c4 7b 08 a5 68 dc c4 1a f6 f3 |..*..S.{..h.....|
+00000380 a1 42 48 1c c9 2b 1f fb 5d fc 49 ed ce 16 14 34 |.BH..+..].I....4|
+00000390 34 01 c9 ef e6 29 9c 81 1a 7d 7b bd 95 eb ad 5f |4....)...}{...._|
+000003a0 ce 19 30 9c e6 ae 09 15 3c 2b 38 8b e6 97 76 4e |..0.....<+8...vN|
+000003b0 dd 17 03 03 00 35 d2 a1 3f 22 e9 2b b6 7a d1 d8 |.....5..?".+.z..|
+000003c0 7b 87 bf d1 bf 56 0b 55 52 d0 a9 cf ae 57 6e 6f |{....V.UR....Wno|
+000003d0 29 0c c3 f7 f3 d4 bf ff a4 6b 49 1a 57 57 27 89 |)........kI.WW'.|
+000003e0 e0 f5 bb d2 16 85 39 40 fd 77 a3 |......9@.w.|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 b3 39 ad 6b 24 |..........5.9.k$|
+00000010 47 e3 9f 11 f9 7e 9a cf 41 db c8 43 ce 86 ae ce |G....~..A..C....|
+00000020 0c af 17 42 d7 24 57 13 e6 ba a7 44 7c 72 38 aa |...B.$W....D|r8.|
+00000030 8f fa a2 a2 9f b0 ba 43 47 20 e8 03 3c 00 ee ad |.......CG ..<...|
+00000040 17 03 03 00 17 ff 5b 79 f8 c8 0c 7a 52 6d b0 b2 |......[y...zRm..|
+00000050 22 17 3b 5d f9 75 23 bb 27 38 35 a6 17 03 03 00 |".;].u#.'85.....|
+00000060 13 d3 94 d9 b5 8b fa dc b6 fe 26 ca b0 52 5c ef |..........&..R\.|
+00000070 84 e3 3c f9 |..<.|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-HelloRetryRequest b/src/crypto/tls/testdata/Client-TLSv13-HelloRetryRequest
new file mode 100644
index 0000000..4840339
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv13-HelloRetryRequest
@@ -0,0 +1,119 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 f6 01 00 00 f2 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 77 00 05 00 05 01 00 00 00 00 00 0a 00 |...w............|
+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 12 00 00 00 2b 00 09 08 03 04 03 03 03 02 03 |.....+..........|
+000000d0 01 00 33 00 26 00 24 00 1d 00 20 2f e5 7d a3 47 |..3.&.$... /.}.G|
+000000e0 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af |.bC.(.._.).0....|
+000000f0 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 17 01 00 01 13 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 98 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 12 00 00 00 2b 00 09 08 03 |...........+....|
+000000d0 04 03 03 03 02 03 01 00 33 00 47 00 45 00 17 00 |........3.G.E...|
+000000e0 41 04 1e 18 37 ef 0d 19 51 88 35 75 71 b5 e5 54 |A...7...Q.5uq..T|
+000000f0 5b 12 2e 8f 09 67 fd a7 24 20 3e b2 56 1c ce 97 |[....g..$ >.V...|
+00000100 28 5e f8 2b 2d 4f 9e f1 07 9f 6c 4b 5b 83 56 e2 |(^.+-O....lK[.V.|
+00000110 32 42 e9 58 b6 d7 49 a6 b5 68 1a 41 03 56 6b dc |2B.X..I..h.A.Vk.|
+00000120 5a 89 |Z.|
+>>> Flow 4 (server to client)
+00000000 16 03 03 00 9b 02 00 00 97 03 03 1d 65 62 8f 58 |............eb.X|
+00000010 2b 99 04 1d fd cc e3 0b 46 5c 55 a9 3a 80 76 60 |+.......F\U.:.v`|
+00000020 8f 52 09 6e 48 5d 5a e3 92 da a3 20 00 00 00 00 |.R.nH]Z.... ....|
+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 1c 01 c6 9e c8 49 43 49 6f 0f 17 f3 ce 87 1a 0f |.....ICIo.......|
+00000070 1f 2c 70 18 e4 29 f2 16 a2 e0 02 b7 9d 52 bc b9 |.,p..).......R..|
+00000080 d4 b0 1d 19 da 3a 38 f6 93 04 0b ae 5f 60 45 87 |.....:8....._`E.|
+00000090 57 80 20 27 c6 9c d4 eb ec c0 85 df f5 aa be de |W. '............|
+000000a0 17 03 03 00 17 d4 a9 5f 09 d3 e6 47 ad a7 7b 38 |......._...G..{8|
+000000b0 a3 b8 02 37 16 ec 03 56 df d5 8d ec 17 03 03 02 |...7...V........|
+000000c0 6d be 1b 2a 60 52 3c 01 2e 6e 7f e3 68 fa de 09 |m..*`R<..n..h...|
+000000d0 ed 5e 8f 0f a0 34 d5 0a 8b 2f 30 8f 6c 56 9e fe |.^...4.../0.lV..|
+000000e0 e6 9a a9 f1 6e 7c 63 a7 d8 88 e2 95 fa 17 ad 0c |....n|c.........|
+000000f0 49 20 93 18 3c ba db fc a1 14 60 2c 77 d4 44 5f |I ..<.....`,w.D_|
+00000100 69 9c c7 a3 b9 d0 ee e8 c5 ec 45 d3 79 d0 ee 04 |i.........E.y...|
+00000110 fd c3 6d 12 1a f2 6e 62 9f eb ff 32 88 17 4c df |..m...nb...2..L.|
+00000120 20 4f cc f9 fd d5 7c 8b 8c c2 da 7d 8a c9 f9 27 | O....|....}...'|
+00000130 32 06 75 fe 75 e2 bb bd 6c 31 5d 32 af 36 95 39 |2.u.u...l1]2.6.9|
+00000140 92 6c 32 e5 4f b5 f7 07 9f b3 1b b8 10 a8 d9 db |.l2.O...........|
+00000150 d3 b0 40 2f 1e e6 54 f5 35 73 7d 22 b3 6b b8 3c |..@/..T.5s}".k.<|
+00000160 83 82 8a 75 f4 ec 18 94 57 0c de 98 41 73 61 63 |...u....W...Asac|
+00000170 5b 95 3e 4e d4 02 c3 b7 f9 4c 6f 01 c9 52 3c b9 |[.>N.....Lo..R<.|
+00000180 ad 61 83 2c 89 6d 63 40 fd d4 67 83 36 8b 9a 1c |.a.,.mc@..g.6...|
+00000190 ca 93 16 d8 e3 91 08 d1 3f ba af cb d9 69 09 10 |........?....i..|
+000001a0 07 a7 54 9c ee a2 7d 97 ce b6 1f 31 9b 85 b0 82 |..T...}....1....|
+000001b0 fc 22 87 70 93 59 9c c9 e3 07 9b d0 c0 a4 1d d4 |.".p.Y..........|
+000001c0 2e 36 c0 72 b6 d5 2a f5 b3 fa ab fb 1a 90 05 51 |.6.r..*........Q|
+000001d0 b7 19 15 af d9 b2 5f 32 ef e6 5a 2d 4a 2c 7f a9 |......_2..Z-J,..|
+000001e0 43 cf b8 ac e4 8a f0 bf 68 90 b9 7c 1c 7e fa f0 |C.......h..|.~..|
+000001f0 bc e3 a9 4f a7 2d 3a f3 12 eb b1 93 b4 b9 1b d7 |...O.-:.........|
+00000200 81 31 db 58 c4 8e 9f 46 44 39 74 a1 a8 b0 78 0c |.1.X...FD9t...x.|
+00000210 b9 23 6d 90 bb a8 b0 7c e2 a3 a3 c4 e6 83 32 5d |.#m....|......2]|
+00000220 ea 5a a4 3d 94 ca 51 3c 71 28 cf 43 27 9f 66 9b |.Z.=..Q<q(.C'.f.|
+00000230 ec 49 0f a4 12 f5 a3 96 cd 3e 05 5b 9c d0 07 6f |.I.......>.[...o|
+00000240 8a 11 df 2f be a7 1d 0d 9f a8 04 41 3d 5e 1b f6 |.../.......A=^..|
+00000250 b0 10 9b 6a 49 da 6c f9 6c 6e 2e 6c 9b cf f1 fe |...jI.l.ln.l....|
+00000260 49 92 2b 16 3f 63 ef 87 71 9c da 0d 49 63 2a 4c |I.+.?c..q...Ic*L|
+00000270 b5 82 c8 b0 75 5b 7b 89 39 cd 9a da dc 42 d1 1f |....u[{.9....B..|
+00000280 92 61 e1 71 b9 b5 d2 40 3c 7a 4a 8d 91 1f e6 9d |.a.q...@<zJ.....|
+00000290 79 37 71 3c dc a3 98 0b b3 64 39 74 f1 8f 84 35 |y7q<.....d9t...5|
+000002a0 1d 6b b7 0a f9 aa 26 55 a8 39 7f 11 26 18 98 fe |.k....&U.9..&...|
+000002b0 94 fb 5d e4 a1 2f 0f 3b f0 b6 78 d5 87 32 73 6e |..]../.;..x..2sn|
+000002c0 3e b1 3e 3c 19 31 7a ae d8 73 67 96 56 9c 38 a6 |>.><.1z..sg.V.8.|
+000002d0 bc 39 1f 11 74 ad 69 c6 d2 40 0f 65 d8 ee aa 87 |.9..t.i..@.e....|
+000002e0 b3 4c 6c 1a 1d 62 4a 7a d9 15 05 54 0d 8a 22 68 |.Ll..bJz...T.."h|
+000002f0 8e 41 22 b0 ee 41 b3 94 5d 1a 62 d8 bb ac f2 87 |.A"..A..].b.....|
+00000300 ad 91 19 e7 e1 bc 29 3b 96 8c d1 76 99 e5 82 48 |......);...v...H|
+00000310 0b 87 6a 93 3b 2c b7 c1 73 07 53 7c 1f 9f 48 dd |..j.;,..s.S|..H.|
+00000320 71 da 55 e1 4a a3 86 d2 ff 23 b2 1d ea b0 17 03 |q.U.J....#......|
+00000330 03 00 99 75 af 84 36 54 8e 17 09 c7 2e 72 de 7d |...u..6T.....r.}|
+00000340 29 5c 94 a9 e3 d3 d0 9b 3e a0 84 e6 cf b4 48 d8 |)\......>.....H.|
+00000350 dd 7c 8a 82 96 15 aa cb 95 38 88 9e 48 c4 bf 75 |.|.......8..H..u|
+00000360 9c f4 07 ed 5d 4d 36 8b 58 7f 9c 32 0b f9 d2 44 |....]M6.X..2...D|
+00000370 3d d6 ab 3b 3d 38 1f 8d 7e e8 b6 26 57 c9 c6 98 |=..;=8..~..&W...|
+00000380 49 4f 1e ad 5d fa 8b ca bc ce 99 f2 d9 5b 14 54 |IO..]........[.T|
+00000390 56 0c 59 c8 22 9f 77 f1 db 92 43 c3 dd a5 29 ec |V.Y.".w...C...).|
+000003a0 0d 79 0d b3 04 3f 4b 6b d6 a8 da 99 64 94 78 a5 |.y...?Kk....d.x.|
+000003b0 e9 cd 7e f8 0c fb 72 d6 03 89 dd 00 13 f3 14 18 |..~...r.........|
+000003c0 ba 59 3c 04 7f 6a b5 62 37 56 2e 2d 17 03 03 00 |.Y<..j.b7V.-....|
+000003d0 35 af eb 05 4e ec ee 4b d6 6b 03 35 d8 ba a3 cf |5...N..K.k.5....|
+000003e0 50 c6 80 07 90 92 1c ed 1f d2 d5 12 e3 7f 74 1a |P.............t.|
+000003f0 2c 3b 4b 6c f4 58 af 9a 1a cd 90 f4 d8 78 97 09 |,;Kl.X.......x..|
+00000400 2f f6 35 c1 29 b8 |/.5.).|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 35 8d 07 5a 33 f5 d1 e7 6d 71 48 45 |....5..Z3...mqHE|
+00000010 3e 2a c0 7e 66 03 77 b5 69 b1 e5 13 04 0e 0d ea |>*.~f.w.i.......|
+00000020 6f 80 46 a1 9a 54 09 6f a7 be b7 a3 a1 0c d4 ba |o.F..T.o........|
+00000030 0e 7d 00 8f 1b 01 0b d4 6b 4c 17 03 03 00 17 b9 |.}......kL......|
+00000040 fd 5a 5c a1 c2 33 71 63 99 25 bd 03 a3 24 a7 b6 |.Z\..3qc.%...$..|
+00000050 e7 42 04 6a 81 c5 17 03 03 00 13 b6 4a f1 0a 26 |.B.j........J..&|
+00000060 95 e8 fb 4b d1 db 24 95 8f 65 1f 3c 5d b9 |...K..$..e.<].|
diff --git a/src/crypto/tls/testdata/Client-TLSv13-KeyUpdate b/src/crypto/tls/testdata/Client-TLSv13-KeyUpdate
new file mode 100644
index 0000000..ea10f66
--- /dev/null
+++ b/src/crypto/tls/testdata/Client-TLSv13-KeyUpdate
@@ -0,0 +1,102 @@
+>>> 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 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 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 7a 02 00 00 76 03 03 86 ed 46 3d 38 |....z...v....F=8|
+00000010 c5 47 10 b5 4e ac e5 b7 d7 ba cc 23 db f5 0a f4 |.G..N......#....|
+00000020 5e d3 62 af 47 8a 23 34 59 5c db 20 00 00 00 00 |^.b.G.#4Y\. ....|
+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 e3 |..+.....3.$... .|
+00000060 ff 35 33 31 c9 d8 5c 68 2a e5 73 98 4d 11 5b d7 |.531..\h*.s.M.[.|
+00000070 06 18 a9 dd 0e 4a 21 92 5b 15 8f bb 91 a9 6c 14 |.....J!.[.....l.|
+00000080 03 03 00 01 01 17 03 03 00 17 ea ac f8 a0 41 47 |..............AG|
+00000090 af 01 fb 51 2e ec 3b 79 f1 8a 54 2b 93 45 33 c3 |...Q..;y..T+.E3.|
+000000a0 79 17 03 03 02 6d 0e c9 a4 55 8e 8c 09 55 cd a6 |y....m...U...U..|
+000000b0 d4 dc 1e 5a de ee 56 c8 c2 ac 12 77 77 76 82 fc |...Z..V....wwv..|
+000000c0 a6 44 cb c8 c3 16 c4 5e bc 3f f3 3b 6c 33 f3 35 |.D.....^.?.;l3.5|
+000000d0 ed bd 8e 37 1a 25 de 7e b3 88 71 ce f9 e5 9b a6 |...7.%.~..q.....|
+000000e0 99 11 0f 71 6b 36 11 04 66 a2 5f 74 1c c6 6a 99 |...qk6..f._t..j.|
+000000f0 49 84 d1 36 96 df 6d 2c c5 a3 cf 5a c9 37 22 8a |I..6..m,...Z.7".|
+00000100 72 e4 d4 25 ed 4a b1 c4 85 5a 9a f7 de 0b dd 41 |r..%.J...Z.....A|
+00000110 7d 14 63 35 2e 1c 77 6c 9e 6f 41 d1 cb 29 ca 6d |}.c5..wl.oA..).m|
+00000120 88 1c 35 53 1b 14 24 79 84 ec 85 0d de e3 0f 2c |..5S..$y.......,|
+00000130 23 ae 41 72 85 fb 43 36 82 ba 8f 78 79 a2 c3 95 |#.Ar..C6...xy...|
+00000140 72 19 ea 1d 2f 29 0e d5 11 85 e4 cc 8c a5 f4 8e |r.../)..........|
+00000150 39 ba 88 8f e1 5a 54 7c 53 8b a3 1a 44 9c ae 5b |9....ZT|S...D..[|
+00000160 1f 0e ea 06 f1 8e 5f 22 d1 ef ee e1 4c b6 1a 26 |......_"....L..&|
+00000170 db 53 96 e6 bc 0b 2f ee b7 fa 47 af 1e 9c f6 7b |.S..../...G....{|
+00000180 81 97 0f c3 08 9b 2c a3 de bd f7 8a 1e 13 ad de |......,.........|
+00000190 a5 fc 5f c7 7a 53 72 e5 17 dc 0a eb 90 91 29 2e |.._.zSr.......).|
+000001a0 7a a5 09 fd be 31 ff 81 ec a3 fc 91 41 4f cb c7 |z....1......AO..|
+000001b0 27 c3 39 8f cd 77 62 72 9a e9 e9 16 da 90 b6 6b |'.9..wbr.......k|
+000001c0 05 70 c8 aa f5 cd 88 13 4d ff a5 a9 0f e7 d2 d3 |.p......M.......|
+000001d0 97 2b eb e1 d7 fe 74 da fb 1e af 94 e6 52 18 48 |.+....t......R.H|
+000001e0 5b e8 c3 10 9d 76 de 17 86 67 83 4a e9 fa 30 e8 |[....v...g.J..0.|
+000001f0 46 95 f5 81 b1 a5 76 38 57 37 3a 8d df ad e7 30 |F.....v8W7:....0|
+00000200 41 b2 94 31 da 0d d6 5c df 76 01 cd 4d c2 1b fe |A..1...\.v..M...|
+00000210 bc 69 41 ac dd d7 dd 0a 7c 5b 31 5c c8 1e b3 14 |.iA.....|[1\....|
+00000220 39 20 51 26 6d e5 55 27 a4 9a bb fc 3d 4b 6a b0 |9 Q&m.U'....=Kj.|
+00000230 54 92 ee 33 1b 9b d5 41 fd ef 21 c6 f0 f8 90 a0 |T..3...A..!.....|
+00000240 c4 f5 86 d4 d9 c7 89 6f 67 23 37 31 44 2f 8f 55 |.......og#71D/.U|
+00000250 0a aa e1 9a ec 32 26 e2 ce 96 90 c6 f5 cc 95 79 |.....2&........y|
+00000260 da 0c b4 c1 62 d3 0a 8d 7b 83 33 8e af ff 57 c0 |....b...{.3...W.|
+00000270 5b ca 0f b5 64 10 81 43 12 86 67 cf b2 0a 53 f2 |[...d..C..g...S.|
+00000280 04 46 4f 99 ee e2 cd ce 3e 82 1f 34 43 26 f9 4c |.FO.....>..4C&.L|
+00000290 57 b0 10 c0 37 40 9c 4f fb 14 fa 4e 1e 4b 40 da |W...7@.O...N.K@.|
+000002a0 cc c3 d0 d7 ee 63 18 2e 97 06 a6 49 69 07 7a 3e |.....c.....Ii.z>|
+000002b0 da 47 68 70 b0 10 bf 8d 18 d2 14 c0 18 18 b2 61 |.Ghp...........a|
+000002c0 45 54 e8 20 34 f8 a3 74 5a 8d aa c2 63 af e8 ff |ET. 4..tZ...c...|
+000002d0 f9 1b 33 d6 34 c2 f2 c2 3d d8 0e 32 7a 10 cc 21 |..3.4...=..2z..!|
+000002e0 02 22 a6 aa 7d 15 c3 7b 3f a2 50 5a 4e 53 ec f5 |."..}..{?.PZNS..|
+000002f0 11 dd 48 6e 7e e9 c5 94 2c c4 9a 6e 10 a6 c6 a5 |..Hn~...,..n....|
+00000300 9d e1 c5 43 e6 69 a1 91 65 50 eb e6 76 db f0 09 |...C.i..eP..v...|
+00000310 14 45 ef 17 03 03 00 99 e4 82 99 6b d8 57 ca 1b |.E.........k.W..|
+00000320 78 98 88 ad c7 04 b7 d2 b2 d5 00 3b a9 bf 86 66 |x..........;...f|
+00000330 a7 30 72 95 29 2a 27 9f 9a 3d bd 0b e6 a0 04 22 |.0r.)*'..=....."|
+00000340 56 3d d8 08 84 a7 e7 c5 67 74 34 7d 57 1f c9 df |V=......gt4}W...|
+00000350 71 0c 97 55 5a d9 8d 99 df 49 b5 a9 57 6d b0 c7 |q..UZ....I..Wm..|
+00000360 2d 4b 70 9d e7 e3 70 31 f0 2f 32 15 7b 67 b4 4c |-Kp...p1./2.{g.L|
+00000370 f0 f0 4a 16 a5 37 b2 ae 9b 2a 72 7c 2e d8 22 a1 |..J..7...*r|..".|
+00000380 2b 91 f2 14 fc f9 27 fd ca ad 27 dd 15 11 df b1 |+.....'...'.....|
+00000390 cc 4c 3a 45 3f b6 7c 53 c5 d0 82 49 1a f2 28 63 |.L:E?.|S...I..(c|
+000003a0 a2 be 6f 2f db d8 d3 76 0a 12 fa 87 14 00 11 e7 |..o/...v........|
+000003b0 1f 17 03 03 00 35 0c af 49 a1 ba 14 d4 e5 5c cf |.....5..I.....\.|
+000003c0 c8 f7 fb 93 e3 d5 45 ac 59 ed 56 3c 1c e6 53 6a |......E.Y.V<..Sj|
+000003d0 77 62 a3 1a 8c 55 14 b0 d8 6f dd 1c fb a4 6f 25 |wb...U...o....o%|
+000003e0 18 28 ab 9e a5 ad 6d 97 63 f4 9c |.(....m.c..|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 12 2a a7 31 42 |..........5.*.1B|
+00000010 e9 65 d6 88 9c 49 85 53 16 6c 85 bc d1 70 65 3a |.e...I.S.l...pe:|
+00000020 aa cd d3 12 ce 69 e3 3a 63 7a 8d ed 54 df 9c 97 |.....i.:cz..T...|
+00000030 4e ef 7c 20 ce 41 ac 33 a9 3b fc 5e 35 34 65 00 |N.| .A.3.;.^54e.|
+00000040 17 03 03 00 17 11 5f 88 3b 45 0e 4e 8a 26 43 a3 |......_.;E.N.&C.|
+00000050 9e 77 10 76 8c e1 ed d3 19 f4 27 5f |.w.v......'_|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 16 7d 92 67 60 95 ba fa a0 5f 03 e9 |.....}.g`...._..|
+00000010 2b e6 53 ed fb 6b 4f b9 e9 09 10 |+.S..kO....|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 16 06 17 fb 4b 33 c7 06 d5 a9 40 e8 |........K3....@.|
+00000010 c7 09 65 b2 5c 2d 45 2f bf 45 a8 |..e.\-E/.E.|
+>>> Flow 6 (server to client)
+00000000 17 03 03 00 1a 04 5e c0 bb ad 6c 2f 65 61 5c 39 |......^...l/ea\9|
+00000010 a9 e2 c4 9e 0e 4c 68 d2 a9 97 8a bf 95 39 3f |.....Lh......9?|
+>>> Flow 7 (client to server)
+00000000 17 03 03 00 1d 1f 74 d0 fb ed fa 59 81 21 7e f0 |......t....Y.!~.|
+00000010 41 c8 6e 6b 9f b6 1a 86 ad 2e ac 9e 3d 3b 66 c9 |A.nk........=;f.|
+00000020 4a 87 17 03 03 00 13 7b 76 c4 85 c1 41 47 6d 35 |J......{v...AGm5|
+00000030 98 86 02 d5 3b e4 6b 4c 3e 7a |....;.kL>z|
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..db87bef
--- /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 15 01 00 01 11 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 96 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 12 |................|
+000000c0 00 00 00 2b 00 09 08 03 04 03 03 03 02 03 01 00 |...+............|
+000000d0 33 00 47 00 45 00 17 00 41 04 1e 18 37 ef 0d 19 |3.G.E...A...7...|
+000000e0 51 88 35 75 71 b5 e5 54 5b 12 2e 8f 09 67 fd a7 |Q.5uq..T[....g..|
+000000f0 24 20 3e b2 56 1c ce 97 28 5e f8 2b 2d 4f 9e f1 |$ >.V...(^.+-O..|
+00000100 07 9f 6c 4b 5b 83 56 e2 32 42 e9 58 b6 d7 49 a6 |..lK[.V.2B.X..I.|
+00000110 b5 68 1a 41 03 56 6b dc 5a 89 |.h.A.Vk.Z.|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 9b 02 00 00 97 03 03 bb 03 f1 4e 88 |..............N.|
+00000010 23 9e 85 ee 32 13 db 0d 69 11 48 47 c6 c9 e5 b2 |#...2...i.HG....|
+00000020 25 9d 0c 27 87 05 3f 58 42 60 2d 20 00 00 00 00 |%..'..?XB`- ....|
+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 85 3c 83 1b e5 02 e9 0d 89 cc c0 f7 af 1e ba af |.<..............|
+00000070 de ad cb 8f 4d 58 04 40 c2 60 e9 41 8b 94 26 76 |....MX.@.`.A..&v|
+00000080 73 64 c3 27 e3 51 9d 5f 21 97 59 a3 02 cc 20 61 |sd.'.Q._!.Y... a|
+00000090 b7 ef cb bb d9 31 b6 b7 b1 77 ea 8d 69 13 13 48 |.....1...w..i..H|
+000000a0 14 03 03 00 01 01 17 03 03 00 17 ab ac 2e 62 de |..............b.|
+000000b0 b6 f4 c7 35 cf b4 75 fc a4 a5 2c 40 68 f5 48 80 |...5..u...,@h.H.|
+000000c0 d2 8b 17 03 03 02 6d a9 36 b5 10 78 1f af 79 65 |......m.6..x..ye|
+000000d0 dd ee 36 08 b9 96 e2 bf 09 53 c7 ee 12 19 1b de |..6......S......|
+000000e0 96 25 cb a7 55 71 28 22 16 3f 4b 3e 15 a2 2e 57 |.%..Uq(".?K>...W|
+000000f0 99 85 28 b2 01 16 3a 75 ff 5e 21 39 6c be fc bd |..(...:u.^!9l...|
+00000100 24 33 ec c7 50 83 49 91 8a ed 43 38 b5 48 cd 92 |$3..P.I...C8.H..|
+00000110 dd 9a f1 b7 90 61 3b 8f ff b9 cf 97 3d 8e 23 8e |.....a;.....=.#.|
+00000120 d1 78 52 b4 ba a1 75 97 32 52 e3 1f c8 43 ca b7 |.xR...u.2R...C..|
+00000130 89 46 e6 30 c2 c5 32 b3 5f a8 ea ea e2 31 d2 41 |.F.0..2._....1.A|
+00000140 23 5e 64 a2 b9 23 27 73 b2 df 77 cd 04 8b dd 37 |#^d..#'s..w....7|
+00000150 a5 77 df 0e 4f 9d 01 22 7b be 7a 0c 18 5c 8b 62 |.w..O.."{.z..\.b|
+00000160 7c 6b 7e a7 54 8c 69 97 50 d7 cf a0 a4 cb 3a 3b ||k~.T.i.P.....:;|
+00000170 76 7b 0a de 80 d1 40 c3 05 5e b3 4e 71 cd 03 82 |v{....@..^.Nq...|
+00000180 d5 95 d0 38 ab 65 83 24 66 d2 31 2d 9e 58 16 87 |...8.e.$f.1-.X..|
+00000190 b8 ab 4c 4e 75 40 7e 3d 33 2f f4 ed 0b a8 11 1c |..LNu@~=3/......|
+000001a0 7a a4 b0 e3 6a 73 d0 6e e6 82 39 c1 cf 57 a4 9a |z...js.n..9..W..|
+000001b0 8b fc bc 8e e8 6a c3 e1 b0 64 18 55 6d 19 30 25 |.....j...d.Um.0%|
+000001c0 34 f8 b1 ef cf 3c 04 08 69 10 ad 08 67 5b 8d 64 |4....<..i...g[.d|
+000001d0 eb 83 72 39 2e 56 e4 d2 e9 f2 da 40 3e 85 29 ab |..r9.V.....@>.).|
+000001e0 5b 83 e5 b0 d2 9b eb c3 99 6e 2a f3 78 95 d4 7a |[........n*.x..z|
+000001f0 7f bf 9c 16 55 77 43 4d 67 f7 4a 6f 40 27 a2 82 |....UwCMg.Jo@'..|
+00000200 b9 86 05 5d 90 e2 52 a2 d4 7c 7b 3e da 30 c1 aa |...]..R..|{>.0..|
+00000210 30 2e 9a 34 c5 59 dd db e9 25 67 da 22 47 f2 be |0..4.Y...%g."G..|
+00000220 cc c8 5a 4e da cf ad 86 8d bd b0 68 26 69 ea 3a |..ZN.......h&i.:|
+00000230 1c 1e 29 ae e1 09 63 88 f0 81 31 f9 70 a7 92 27 |..)...c...1.p..'|
+00000240 32 9e 3b 6f 09 5e 42 20 53 88 bf 09 8b a8 17 5c |2.;o.^B S......\|
+00000250 24 7c 18 1f 9c 99 9b db 6d 11 26 8e 92 2c a1 b4 |$|......m.&..,..|
+00000260 5c 9f d9 0a a8 af 25 f7 84 f5 65 d1 b1 6c d8 aa |\.....%...e..l..|
+00000270 49 c7 a6 13 47 2e 55 f4 2e de 3d 43 c1 15 8d 60 |I...G.U...=C...`|
+00000280 c1 27 59 7e 7b 14 ee 54 09 fc 99 79 c9 bf fb 45 |.'Y~{..T...y...E|
+00000290 2d 32 ed 1a 2c 84 bc f4 a2 b5 5f 4e cf 60 29 91 |-2..,....._N.`).|
+000002a0 90 b6 ab 06 8f 2d 43 a5 a5 54 0d 67 52 c2 1c fb |.....-C..T.gR...|
+000002b0 f3 41 b7 67 b4 50 05 86 19 75 93 8b 6c c3 bf 08 |.A.g.P...u..l...|
+000002c0 64 f2 df ff 37 6d 2f 1e 3a 28 f4 ba 27 8d 61 d5 |d...7m/.:(..'.a.|
+000002d0 79 70 19 82 99 7a e5 68 f3 c1 23 da 5d e1 98 b2 |yp...z.h..#.]...|
+000002e0 69 ca 42 83 61 29 3f d9 20 51 f2 a9 ea 1c 0b 5a |i.B.a)?. Q.....Z|
+000002f0 20 b0 af 70 cc c5 ad 72 6b 09 85 56 8a 26 86 cf | ..p...rk..V.&..|
+00000300 4e 9a 56 97 5d 63 8d 1d 46 04 48 16 c9 1e 91 47 |N.V.]c..F.H....G|
+00000310 74 53 28 51 7e 3c 84 a1 50 d6 f3 ac 31 ce 04 18 |tS(Q~<..P...1...|
+00000320 81 38 0d c5 3d f5 d5 04 2f f0 96 9b 73 49 4c d6 |.8..=.../...sIL.|
+00000330 89 d9 b9 be 17 03 03 00 99 3a 37 ed 2d 98 80 f9 |.........:7.-...|
+00000340 d0 04 14 12 8c 63 45 cc 8d cb 29 5f 0e f0 86 ef |.....cE...)_....|
+00000350 8d 6c d6 0f ef 66 99 91 e8 8c d7 7b 21 07 7e 96 |.l...f.....{!.~.|
+00000360 84 f8 f9 5b 1b 39 8b 4f 16 ec 5c 69 7b 18 09 5d |...[.9.O..\i{..]|
+00000370 95 f1 f3 73 4b 8f 84 66 ee 61 85 dd fe ea 36 df |...sK..f.a....6.|
+00000380 e5 2a 71 ec 2d 7e 47 1c b7 79 2d 87 f8 dc 44 27 |.*q.-~G..y-...D'|
+00000390 8a f1 13 6e df ca 59 79 9b 18 01 7e 31 bd 44 f7 |...n..Yy...~1.D.|
+000003a0 8d ad 1c 97 e7 e1 b9 a6 17 d1 25 d1 b8 0d 04 bb |..........%.....|
+000003b0 21 a4 08 db a2 08 87 5c 04 9a 11 fa c6 24 db 20 |!......\.....$. |
+000003c0 42 79 9c 97 dd 6c d2 e7 24 b4 79 47 be f3 43 87 |By...l..$.yG..C.|
+000003d0 0f 95 17 03 03 00 35 9e 7d 12 0e d6 0a e6 af a3 |......5.}.......|
+000003e0 83 dd eb 08 73 2d 43 7e 81 85 51 4c d1 ad d0 77 |....s-C~..QL...w|
+000003f0 8d 28 62 44 41 9c b0 e9 93 d7 3d 07 e4 e1 6e 4c |.(bDA.....=...nL|
+00000400 a8 5b 4a 3f 58 3f 97 07 73 d7 5a 62 |.[J?X?..s.Zb|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 df 31 1a 84 e2 |..........5.1...|
+00000010 93 54 01 f2 d1 e8 32 6c 32 91 e5 64 86 68 ad 5f |.T....2l2..d.h._|
+00000020 aa 24 54 86 b2 39 92 24 06 65 5c 06 67 43 7d 09 |.$T..9.$.e\.gC}.|
+00000030 79 78 c6 f3 cf 6c a9 ec 38 e3 ec 81 c4 9b c5 33 |yx...l..8......3|
+00000040 17 03 03 00 17 25 ed 98 67 8f ad e8 60 ce 5b ad |.....%..g...`.[.|
+00000050 ab 3e 67 64 e3 8d bf 98 96 a2 3d 99 17 03 03 00 |.>gd......=.....|
+00000060 13 9d 28 f2 24 fe d6 11 b0 64 d6 8a 8d c1 81 e0 |..(.$....d......|
+00000070 17 d5 a0 f3 |....|
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..4a43382
--- /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 f4 01 00 00 f0 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 75 00 05 00 05 01 00 00 00 00 00 0a 00 |...u............|
+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 12 |................|
+000000c0 00 00 00 2b 00 09 08 03 04 03 03 03 02 03 01 00 |...+............|
+000000d0 33 00 26 00 24 00 1d 00 20 2f e5 7d a3 47 cd 62 |3.&.$... /.}.G.b|
+000000e0 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 cf |C.(.._.).0......|
+000000f0 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 eb 1b 4e e5 65 |....z...v....N.e|
+00000010 54 ab 07 68 1c d9 32 0f 0e c2 ae a3 2a 89 37 50 |T..h..2.....*.7P|
+00000020 23 51 61 7d 68 60 34 0d 40 2f b8 20 00 00 00 00 |#Qa}h`4.@/. ....|
+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 7d df 14 8a ad 43 51 c3 c2 08 3a ea f7 e3 96 6a |}....CQ...:....j|
+00000070 b7 8b 61 66 d9 82 c5 7b b9 77 bc 62 6a 19 04 14 |..af...{.w.bj...|
+00000080 03 03 00 01 01 17 03 03 00 17 4e 7b b6 d1 b1 19 |..........N{....|
+00000090 0d 0c d0 d3 5a 66 44 5c 81 49 74 f3 71 3b 97 5e |....ZfD\.It.q;.^|
+000000a0 ee 17 03 03 02 6d 00 17 b1 4d b9 f5 fc ea 48 72 |.....m...M....Hr|
+000000b0 aa a5 1c 8b fe 97 08 54 ab 2d 0a 0e f7 51 41 bf |.......T.-...QA.|
+000000c0 7b 14 ba b7 d9 0a 30 44 db b9 06 e7 6b a9 0a 94 |{.....0D....k...|
+000000d0 49 a2 29 50 f2 7f 7e 68 91 41 ad a9 cb ee e2 bd |I.)P..~h.A......|
+000000e0 03 fd 95 79 ea c3 77 ee 88 3b 7a 81 15 9f 17 96 |...y..w..;z.....|
+000000f0 b2 db b9 f3 26 dd 75 69 ef 12 c0 63 b0 04 63 ae |....&.ui...c..c.|
+00000100 aa b3 67 f8 7f a5 17 cf 56 5f ee 34 2d d7 83 23 |..g.....V_.4-..#|
+00000110 84 00 4b 94 1a 76 2a 01 ce 49 0a 57 7d c8 65 7a |..K..v*..I.W}.ez|
+00000120 d7 16 34 1c a8 37 fd 71 d4 79 08 b1 44 9f 9e a7 |..4..7.q.y..D...|
+00000130 78 ab 9d 0d c4 80 0e 81 35 75 23 59 89 1b 2c d3 |x.......5u#Y..,.|
+00000140 bc c9 86 b9 7b 22 19 30 dd cc 68 93 ab d2 98 dd |....{".0..h.....|
+00000150 c2 9f 20 af c9 1a 87 b3 28 73 84 83 ca 98 1d 60 |.. .....(s.....`|
+00000160 df 12 19 70 80 f2 ff 20 64 b5 8c ef e2 e8 6a 5a |...p... d.....jZ|
+00000170 df 8e ba 95 d8 2c c4 b6 4f a1 33 8c 8d a3 fc d3 |.....,..O.3.....|
+00000180 c4 4b ba b2 6d 3a f7 da 38 23 5f 03 a7 92 13 76 |.K..m:..8#_....v|
+00000190 12 73 26 17 30 e0 21 f1 16 8f a1 e5 6d f0 21 a8 |.s&.0.!.....m.!.|
+000001a0 c6 25 64 86 95 5e 6f 4d 21 f0 f3 a3 27 23 2b 4b |.%d..^oM!...'#+K|
+000001b0 90 03 ba 6c ce 9c 20 ed 69 15 76 cb 39 bc fd 44 |...l.. .i.v.9..D|
+000001c0 10 b4 72 d5 44 9d f7 eb a4 b0 d5 07 20 a1 6b 71 |..r.D....... .kq|
+000001d0 16 e4 f7 8f a0 d8 fa 86 db e6 ef eb 63 41 a0 17 |............cA..|
+000001e0 83 71 0d 1c 4b ec 58 c3 90 9c ea 34 79 a7 91 43 |.q..K.X....4y..C|
+000001f0 ad 3d ff 28 c8 b4 3e 7a b6 83 53 f4 99 0b 86 bc |.=.(..>z..S.....|
+00000200 f2 cf ae 1d a7 5c 7f 57 d9 85 95 25 33 bb 4d 79 |.....\.W...%3.My|
+00000210 25 2e 54 6d 5d 14 32 68 7d 6e 45 bd b1 e1 24 30 |%.Tm].2h}nE...$0|
+00000220 c2 1c 45 b9 a2 42 ae b5 c6 6a 56 f9 8a 12 51 f9 |..E..B...jV...Q.|
+00000230 61 a2 9d 56 98 09 8d ea 70 17 48 d8 23 48 ca 18 |a..V....p.H.#H..|
+00000240 43 1e a2 bc 88 69 3d 45 95 89 cc f0 74 8d 88 36 |C....i=E....t..6|
+00000250 5e a8 1b be 88 41 35 8d de a9 20 23 f3 5e ab c9 |^....A5... #.^..|
+00000260 61 22 2e 86 54 2f c4 4a 60 04 c2 e3 b8 cf 1a 41 |a"..T/.J`......A|
+00000270 a6 31 ab 7a b5 07 dc 54 82 89 b1 1f 9f 62 98 bc |.1.z...T.....b..|
+00000280 bd 39 be 23 ed d5 bc 0d 8e a6 69 14 26 39 fe ed |.9.#......i.&9..|
+00000290 98 c8 48 36 6c 8e 9f 93 57 7a ba 33 03 35 c6 de |..H6l...Wz.3.5..|
+000002a0 55 03 63 e8 a4 53 08 0a b0 a7 3e a3 cb f2 df 3d |U.c..S....>....=|
+000002b0 cd 59 df ee f6 45 2d 77 39 32 4a 1f 08 21 e7 db |.Y...E-w92J..!..|
+000002c0 52 2a 06 86 e6 00 98 ca 9f a3 ad 0f 7f d3 25 6d |R*............%m|
+000002d0 56 58 21 e2 39 59 56 15 74 4d 18 37 f5 40 29 db |VX!.9YV.tM.7.@).|
+000002e0 de be 49 77 e0 2c 5c 6b ee b1 bd 4a ea 2a 07 94 |..Iw.,\k...J.*..|
+000002f0 0f 21 7c bb 1f bd 3e ad 9e b6 95 7d 16 e8 f0 4e |.!|...>....}...N|
+00000300 de e2 ca 9c 34 9f b8 e5 57 d5 b7 b5 8d 60 dd c2 |....4...W....`..|
+00000310 ce 47 2c 17 03 03 00 99 37 37 20 49 98 44 f6 b4 |.G,.....77 I.D..|
+00000320 58 54 ff 5e b0 05 22 8e c6 68 9a ae 49 51 e9 f1 |XT.^.."..h..IQ..|
+00000330 71 75 cf 1a 79 da 33 f1 5f 7e a1 02 81 05 12 8b |qu..y.3._~......|
+00000340 a3 a8 ad 87 ee f0 87 da f1 16 80 9d 2e fa 5a 22 |..............Z"|
+00000350 a5 f5 b9 14 f5 8f 9b 35 87 ba 1a f7 c4 17 c8 f6 |.......5........|
+00000360 a1 1e 28 cd fe 03 90 9f f0 81 d3 80 bb 4c 1a b1 |..(..........L..|
+00000370 c6 11 de 19 a1 5a 3c 73 77 f0 70 b8 d1 38 16 f3 |.....Z<sw.p..8..|
+00000380 64 d0 8e 9c fe 4d 83 48 dc 20 78 db 6a 65 3f f4 |d....M.H. x.je?.|
+00000390 0f a0 70 cc 30 bb cd 86 51 0c 20 ea 59 a5 ed e8 |..p.0...Q. .Y...|
+000003a0 72 d9 5e f3 c3 41 0b 19 f3 97 0f fc 77 42 6d 15 |r.^..A......wBm.|
+000003b0 92 17 03 03 00 35 ac 97 30 a0 8a d8 d2 e6 4a 5b |.....5..0.....J[|
+000003c0 f5 58 32 22 63 8e 36 2e 21 a2 30 33 ae 49 55 76 |.X2"c.6.!.03.IUv|
+000003d0 cf c8 b3 3f 82 8d c3 0e ea 22 ec 8f 65 c8 c4 0d |...?....."..e...|
+000003e0 bf cc 6a 86 e9 32 50 db 02 93 ec |..j..2P....|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 e5 27 80 72 fd |..........5.'.r.|
+00000010 6c 0d b5 a7 14 23 08 0b f5 54 70 8c 29 61 d0 2a |l....#...Tp.)a.*|
+00000020 81 2d 05 83 2a 21 1e 16 94 5b 65 0d 6a ca b6 81 |.-..*!...[e.j...|
+00000030 d9 9d 3c 5c 9c fe 2b 01 a8 3b 23 fb 9e eb 2c 56 |..<\..+..;#...,V|
+00000040 17 03 03 00 17 79 fd 43 29 72 96 e0 ad fd 7e 60 |.....y.C)r....~`|
+00000050 94 51 8d 8a 6e 6a 5d 6c f3 0d 4b 74 17 03 03 00 |.Q..nj]l..Kt....|
+00000060 13 a4 7c e1 31 71 61 82 e7 7d 28 0f 63 d7 ae 76 |..|.1qa..}(.c..v|
+00000070 9c 71 37 cd |.q7.|
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..1132b39
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv10-ECDHE-ECDSA-AES
@@ -0,0 +1,80 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 63 01 00 00 5f 03 01 38 de f5 d6 ae |....c..._..8....|
+00000010 46 71 e8 02 f2 45 88 b8 64 fb 6e 68 67 d1 7f e8 |Fq...E..d.nhg...|
+00000020 49 71 1e a9 ec 8e 54 06 bb 2b 16 00 00 04 c0 0a |Iq....T..+......|
+00000030 00 ff 01 00 00 32 00 00 00 0e 00 0c 00 00 09 31 |.....2.........1|
+00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........|
+00000050 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................|
+00000060 00 16 00 00 00 17 00 00 |........|
+>>> Flow 2 (server to client)
+00000000 16 03 01 00 37 02 00 00 33 03 01 00 00 00 00 00 |....7...3.......|
+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 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 01 02 |................|
+00000040 0e 0b 00 02 0a 00 02 07 00 02 04 30 82 02 00 30 |...........0...0|
+00000050 82 01 62 02 09 00 b8 bf 2d 47 a0 d2 eb f4 30 09 |..b.....-G....0.|
+00000060 06 07 2a 86 48 ce 3d 04 01 30 45 31 0b 30 09 06 |..*.H.=..0E1.0..|
+00000070 03 55 04 06 13 02 41 55 31 13 30 11 06 03 55 04 |.U....AU1.0...U.|
+00000080 08 13 0a 53 6f 6d 65 2d 53 74 61 74 65 31 21 30 |...Some-State1!0|
+00000090 1f 06 03 55 04 0a 13 18 49 6e 74 65 72 6e 65 74 |...U....Internet|
+000000a0 20 57 69 64 67 69 74 73 20 50 74 79 20 4c 74 64 | Widgits Pty Ltd|
+000000b0 30 1e 17 0d 31 32 31 31 32 32 31 35 30 36 33 32 |0...121122150632|
+000000c0 5a 17 0d 32 32 31 31 32 30 31 35 30 36 33 32 5a |Z..221120150632Z|
+000000d0 30 45 31 0b 30 09 06 03 55 04 06 13 02 41 55 31 |0E1.0...U....AU1|
+000000e0 13 30 11 06 03 55 04 08 13 0a 53 6f 6d 65 2d 53 |.0...U....Some-S|
+000000f0 74 61 74 65 31 21 30 1f 06 03 55 04 0a 13 18 49 |tate1!0...U....I|
+00000100 6e 74 65 72 6e 65 74 20 57 69 64 67 69 74 73 20 |nternet Widgits |
+00000110 50 74 79 20 4c 74 64 30 81 9b 30 10 06 07 2a 86 |Pty Ltd0..0...*.|
+00000120 48 ce 3d 02 01 06 05 2b 81 04 00 23 03 81 86 00 |H.=....+...#....|
+00000130 04 00 c4 a1 ed be 98 f9 0b 48 73 36 7e c3 16 56 |.........Hs6~..V|
+00000140 11 22 f2 3d 53 c3 3b 4d 21 3d cd 6b 75 e6 f6 b0 |.".=S.;M!=.ku...|
+00000150 dc 9a df 26 c1 bc b2 87 f0 72 32 7c b3 64 2f 1c |...&.....r2|.d/.|
+00000160 90 bc ea 68 23 10 7e fe e3 25 c0 48 3a 69 e0 28 |...h#.~..%.H:i.(|
+00000170 6d d3 37 00 ef 04 62 dd 0d a0 9c 70 62 83 d8 81 |m.7...b....pb...|
+00000180 d3 64 31 aa 9e 97 31 bd 96 b0 68 c0 9b 23 de 76 |.d1...1...h..#.v|
+00000190 64 3f 1a 5c 7f e9 12 0e 58 58 b6 5f 70 dd 9b d8 |d?.\....XX._p...|
+000001a0 ea d5 d7 f5 d5 cc b9 b6 9f 30 66 5b 66 9a 20 e2 |.........0f[f. .|
+000001b0 27 e5 bf fe 3b 30 09 06 07 2a 86 48 ce 3d 04 01 |'...;0...*.H.=..|
+000001c0 03 81 8c 00 30 81 88 02 42 01 88 a2 4f eb e2 45 |....0...B...O..E|
+000001d0 c5 48 7d 1b ac f5 ed 98 9d ae 47 70 c0 5e 1b b6 |.H}.......Gp.^..|
+000001e0 2f bd f1 b6 4d b7 61 40 d3 11 a2 ce ee 0b 7e 92 |/...M.a@......~.|
+000001f0 7e ff 76 9d c3 3b 7e a5 3f ce fa 10 e2 59 ec 47 |~.v..;~.?....Y.G|
+00000200 2d 7c ac da 4e 97 0e 15 a0 6f d0 02 42 01 4d fc |-|..N....o..B.M.|
+00000210 be 67 13 9c 2d 05 0e bd 3f a3 8c 25 c1 33 13 83 |.g..-...?..%.3..|
+00000220 0d 94 06 bb d4 37 7a f6 ec 7a c9 86 2e dd d7 11 |.....7z..z......|
+00000230 69 7f 85 7c 56 de fb 31 78 2b e4 c7 78 0d ae cb |i..|V..1x+..x...|
+00000240 be 9e 4e 36 24 31 7b 6a 0f 39 95 12 07 8f 2a 16 |..N6$1{j.9....*.|
+00000250 03 01 00 b5 0c 00 00 b1 03 00 1d 20 2f e5 7d a3 |........... /.}.|
+00000260 47 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 |G.bC.(.._.).0...|
+00000270 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 00 8b 30 81 |......._X.;t..0.|
+00000280 88 02 42 01 ad 26 fd 16 9a 93 5f 87 ce 29 8c d2 |..B..&...._..)..|
+00000290 56 a7 d2 59 56 bd d3 1f 90 54 bd af 91 81 25 ff |V..YV....T....%.|
+000002a0 66 74 57 16 2f 31 f2 5a 48 97 03 b9 41 4c 8e bb |ftW./1.ZH...AL..|
+000002b0 87 31 ed 71 84 37 63 78 9f 0a c7 9d 5e f3 5a 53 |.1.q.7cx....^.ZS|
+000002c0 88 89 46 ba a7 02 42 00 92 74 15 1c 0e 1f 2f 95 |..F...B..t..../.|
+000002d0 e5 79 d5 e9 90 ce d8 96 0d fd b8 42 55 00 94 08 |.y.........BU...|
+000002e0 4e 47 a9 ea bd 67 0b 02 a6 9e 8b d3 09 e5 53 ea |NG...g........S.|
+000002f0 03 22 2e 2d 78 2c 69 1d 28 ab 13 3d 0a 46 15 09 |.".-x,i.(..=.F..|
+00000300 b6 0b 74 69 2d 5a 96 bf b6 16 03 01 00 04 0e 00 |..ti-Z..........|
+00000310 00 00 |..|
+>>> Flow 3 (client to server)
+00000000 16 03 01 00 25 10 00 00 21 20 82 c0 dd 83 c2 45 |....%...! .....E|
+00000010 a2 bc 3a 2a ec ab 60 8e 02 e0 db 7c 59 83 c1 62 |..:*..`....|Y..b|
+00000020 c7 cc 61 1e de dc 40 e4 65 6c 14 03 01 00 01 01 |..a...@.el......|
+00000030 16 03 01 00 30 3e 26 56 0b a2 10 47 00 55 27 21 |....0>&V...G.U'!|
+00000040 63 33 f2 7d 4b ba 77 5f e7 a7 09 7a 1f 51 85 f2 |c3.}K.w_...z.Q..|
+00000050 46 a5 af 80 79 1a c7 72 bb 3d f9 dd 1d 83 05 22 |F...y..r.=....."|
+00000060 c9 6c dd 91 d9 |.l...|
+>>> Flow 4 (server to client)
+00000000 14 03 01 00 01 01 16 03 01 00 30 38 fa fd 42 8f |..........08..B.|
+00000010 80 5a 7c 33 d4 6c 72 f7 4e 2f 00 ab c2 86 58 9d |.Z|3.lr.N/....X.|
+00000020 fc a5 43 fa ea 5b a1 ee a9 df df 9d 90 4c c0 e3 |..C..[.......L..|
+00000030 10 09 c4 23 21 f9 e9 69 f5 f8 fa 17 03 01 00 20 |...#!..i....... |
+00000040 1e 57 17 e4 96 06 32 d4 00 a3 98 ed bd 1c 61 78 |.W....2.......ax|
+00000050 e7 0d 89 ec 84 c3 56 fa 75 73 87 6f 47 35 80 3f |......V.us.oG5.?|
+00000060 17 03 01 00 30 4d 51 0a dd 70 6d b0 c2 d1 46 5c |....0MQ..pm...F\|
+00000070 b5 03 87 de e6 65 d3 e2 83 e0 33 f8 a2 0a 29 7f |.....e....3...).|
+00000080 6c 24 2b 1f 7b 2b 53 19 21 e9 62 6c 31 75 9c be |l$+.{+S.!.bl1u..|
+00000090 5b b0 3d 5b 1a 15 03 01 00 20 19 51 64 4b 5a 9b |[.=[..... .QdKZ.|
+000000a0 c8 2a 1c e7 9e 29 d9 df ad 1d 08 09 82 a3 b1 1d |.*...)..........|
+000000b0 60 99 00 25 30 51 a1 72 b6 27 |`..%0Q.r.'|
diff --git a/src/crypto/tls/testdata/Server-TLSv10-ExportKeyingMaterial b/src/crypto/tls/testdata/Server-TLSv10-ExportKeyingMaterial
new file mode 100644
index 0000000..cb3b8da
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv10-ExportKeyingMaterial
@@ -0,0 +1,93 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 67 01 00 00 63 03 01 41 69 16 b5 d5 |....g...c..Ai...|
+00000010 c2 9d 36 2b 95 8e e5 41 9b 92 82 27 2a cc 4e 6e |..6+...A...'*.Nn|
+00000020 5d f1 1b 58 49 3c 95 1d 8b 61 35 00 00 04 c0 14 |]..XI<...a5.....|
+00000030 00 ff 01 00 00 36 00 00 00 0e 00 0c 00 00 09 31 |.....6.........1|
+00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........|
+00000050 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................|
+00000060 00 23 00 00 00 16 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 14 00 00 |...DOWNGRD......|
+00000030 0f 00 23 00 00 ff 01 00 01 00 00 0b 00 02 01 00 |..#.............|
+00000040 16 03 01 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 01 00 aa 0c 00 00 a6 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 00 80 c6 ad e2 |......_X.;t.....|
+000002d0 21 0d d7 30 42 da 08 52 d5 46 70 a3 e5 d6 40 ab |!..0B..R.Fp...@.|
+000002e0 bf 52 f8 da a5 41 86 1d 48 e6 51 91 52 8d 3c 5d |.R...A..H.Q.R.<]|
+000002f0 ca 36 4c 62 d1 6b c8 48 8c 99 50 89 a9 27 4b 21 |.6Lb.k.H..P..'K!|
+00000300 c9 9d a6 43 34 d2 47 a7 b3 1a 6d 98 b3 7f 37 94 |...C4.G...m...7.|
+00000310 60 ba 88 f1 b7 ed 34 2b 47 f4 80 27 d3 a0 74 6a |`.....4+G..'..tj|
+00000320 c6 d6 49 e3 8a e5 5d f1 a7 54 8a b4 84 8d a8 6b |..I...]..T.....k|
+00000330 3b 7a 3f eb 81 77 4b bf be 1e ac cd aa f9 4b 79 |;z?..wK.......Ky|
+00000340 24 78 6c 67 14 13 ab f8 ad 33 7c 94 38 16 03 01 |$xlg.....3|.8...|
+00000350 00 04 0e 00 00 00 |......|
+>>> Flow 3 (client to server)
+00000000 16 03 01 00 25 10 00 00 21 20 f5 be 48 cb fb 0d |....%...! ..H...|
+00000010 69 27 a8 ab 59 c4 9a ac 92 71 46 d1 17 7e 35 67 |i'..Y....qF..~5g|
+00000020 15 b1 ea 9f 53 48 a3 b5 f9 55 14 03 01 00 01 01 |....SH...U......|
+00000030 16 03 01 00 30 e1 79 95 7c ab 01 74 35 39 9b ce |....0.y.|..t59..|
+00000040 79 5f 15 21 88 fc be fc 46 a9 31 ca 82 07 0c 1f |y_.!....F.1.....|
+00000050 d8 2f 93 b5 5d 23 bf f9 10 40 bc b5 22 53 df d6 |./..]#...@.."S..|
+00000060 b1 10 b9 16 96 |.....|
+>>> Flow 4 (server to client)
+00000000 16 03 01 00 8b 04 00 00 87 00 00 00 00 00 81 50 |...............P|
+00000010 46 ad c1 db a8 38 86 7b 2b bb fd d0 c3 42 3e 00 |F....8.{+....B>.|
+00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 |................|
+00000030 6d ec a4 83 51 ed 14 ef 68 ca 42 c5 4c d2 34 08 |m...Q...h.B.L.4.|
+00000040 0b cc b9 32 8f 21 f7 50 c4 e1 28 9b 7d 5e ed de |...2.!.P..(.}^..|
+00000050 0a df 30 0d 16 34 6b 6d 22 3c d3 c8 b2 99 84 8e |..0..4km"<......|
+00000060 09 6d 3c 62 d4 0f f6 37 dc 53 ae 72 40 49 38 16 |.m<b...7.S.r@I8.|
+00000070 9c 30 34 bf 6e 34 bb 54 73 33 c0 c9 8c 12 ae bc |.04.n4.Ts3......|
+00000080 e9 a8 80 23 de d0 e5 d3 46 d8 6a 86 c7 a5 6c 61 |...#....F.j...la|
+00000090 14 03 01 00 01 01 16 03 01 00 30 27 a7 5d e7 93 |..........0'.]..|
+000000a0 54 9a 77 d5 43 aa e3 ec 21 00 fa d4 36 04 c3 82 |T.w.C...!...6...|
+000000b0 b0 b7 f5 b4 19 ce f9 58 0a b4 7f d6 bf 95 43 9d |.......X......C.|
+000000c0 26 44 46 77 48 cd 77 82 e2 48 51 17 03 01 00 20 |&DFwH.w..HQ.... |
+000000d0 c0 9b b1 d3 9f e6 4f 55 59 17 5a dc e4 2f bc 04 |......OUY.Z../..|
+000000e0 6f eb 4d d9 22 6e 97 20 33 94 d4 91 aa 70 4d ab |o.M."n. 3....pM.|
+000000f0 17 03 01 00 30 9b 0f 50 a8 95 f5 db 67 96 c2 3e |....0..P....g..>|
+00000100 46 a7 41 99 d5 e2 ab 60 b1 eb 8d 68 2f 71 30 70 |F.A....`...h/q0p|
+00000110 75 cc b8 50 1a 58 3b 96 d3 5c 99 43 27 4f b1 4a |u..P.X;..\.C'O.J|
+00000120 c8 8d 5b ab 49 15 03 01 00 20 34 a6 41 25 fd 23 |..[.I.... 4.A%.#|
+00000130 44 6d 60 7f 79 5d 27 23 f7 cb 77 d0 cd 81 c4 67 |Dm`.y]'#..w....g|
+00000140 0e 56 92 60 ac a1 32 a5 0d 94 |.V.`..2...|
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..502fd28
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv10-RSA-3DES
@@ -0,0 +1,76 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 63 01 00 00 5f 03 01 25 03 63 bf 34 |....c..._..%.c.4|
+00000010 89 c8 9e f6 e0 46 f8 30 5c e8 62 0a f7 db 68 c9 |.....F.0\.b...h.|
+00000020 50 54 0e c2 15 f1 cb 07 66 06 3d 00 00 04 00 0a |PT......f.=.....|
+00000030 00 ff 01 00 00 32 00 00 00 0e 00 0c 00 00 09 31 |.....2.........1|
+00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........|
+00000050 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................|
+00000060 00 16 00 00 00 17 00 00 |........|
+>>> Flow 2 (server to client)
+00000000 16 03 01 00 37 02 00 00 33 03 01 00 00 00 00 00 |....7...3.......|
+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 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 01 02 |................|
+00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0|
+00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.|
+00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......|
+00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G|
+00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R|
+00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000|
+000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000|
+000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....|
+000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0|
+000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......|
+000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.|
+000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].|
+00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...|
+00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....|
+00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4|
+00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..|
+00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. |
+00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...|
+00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....|
+00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....|
+00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..|
+00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.|
+000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....|
+000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......|
+000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0|
+000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM|
+000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...|
+000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example|
+00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..|
+00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[|
+00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..|
+00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..|
+00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.|
+00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....|
+00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.|
+00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...|
+00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=|
+00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 01 00 04 0e |.`.\!.;.........|
+000002a0 00 00 00 |...|
+>>> Flow 3 (client to server)
+00000000 16 03 01 00 86 10 00 00 82 00 80 0f e9 83 ca 77 |...............w|
+00000010 c8 26 16 24 00 b7 09 d2 73 aa c1 d9 77 f3 fc 38 |.&.$....s...w..8|
+00000020 1c 2e c0 26 b4 a6 40 e1 1b 93 39 8f a2 1f f2 f9 |...&..@...9.....|
+00000030 18 2a 7b 0e cd 9b 9b 9c 49 86 43 3d 48 fd 40 d7 |.*{.....I.C=H.@.|
+00000040 af f9 2b 5e c6 cc c6 2d 8d 36 fe b1 75 c1 b5 a0 |..+^...-.6..u...|
+00000050 57 97 0f 01 ee b4 6a af 0c fe f0 68 78 04 6a 3e |W.....j....hx.j>|
+00000060 83 d0 72 34 80 d8 7d cd 8b 83 06 5b 36 50 10 8e |..r4..}....[6P..|
+00000070 b4 27 3d 6a ae b7 7f 8b 2a b1 0b 51 49 05 b5 01 |.'=j....*..QI...|
+00000080 3c 27 9a 59 e3 41 18 38 d6 8f 7a 14 03 01 00 01 |<'.Y.A.8..z.....|
+00000090 01 16 03 01 00 28 c0 46 65 9f 7f d8 c3 c4 a7 33 |.....(.Fe......3|
+000000a0 50 f9 07 41 95 12 a6 f3 ca 53 b9 96 f8 a8 a6 5f |P..A.....S....._|
+000000b0 1e c8 20 e5 8b 87 4e 12 73 13 e0 e4 c6 89 |.. ...N.s.....|
+>>> Flow 4 (server to client)
+00000000 14 03 01 00 01 01 16 03 01 00 28 e2 47 2b 57 fe |..........(.G+W.|
+00000010 74 71 95 6a ee 68 2b f3 48 40 13 52 35 46 58 d4 |tq.j.h+.H@.R5FX.|
+00000020 ee aa 4c a8 53 0f 3a 19 ed 18 37 2d e4 b9 1e e6 |..L.S.:...7-....|
+00000030 28 42 a1 17 03 01 00 18 d8 7c 20 f2 03 6d a9 ed |(B.......| ..m..|
+00000040 c9 73 50 d7 56 4f 0b d8 4b 44 f6 80 e4 c1 a9 f5 |.sP.VO..KD......|
+00000050 17 03 01 00 28 f5 b2 11 6b a6 4b 22 30 42 3c cc |....(...k.K"0B<.|
+00000060 07 0d ed 10 d0 c7 7b ec b3 60 0b 2b 3c fb ec 3a |......{..`.+<..:|
+00000070 c0 be 44 e7 76 b6 9e db 17 36 92 df 88 15 03 01 |..D.v....6......|
+00000080 00 18 7a d9 2f 46 2e 0f ec c5 ee 7b ef bd fb e5 |..z./F.....{....|
+00000090 26 40 0a a2 4e eb 56 0e ca 03 |&@..N.V...|
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..7425376
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv10-RSA-AES
@@ -0,0 +1,79 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 63 01 00 00 5f 03 01 78 91 f6 ad 9e |....c..._..x....|
+00000010 79 23 92 10 d9 c5 43 52 8f f6 f4 3f f4 eb ac 6b |y#....CR...?...k|
+00000020 f3 ce a9 76 a2 bf c3 5b 9d bc 52 00 00 04 00 2f |...v...[..R..../|
+00000030 00 ff 01 00 00 32 00 00 00 0e 00 0c 00 00 09 31 |.....2.........1|
+00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........|
+00000050 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................|
+00000060 00 16 00 00 00 17 00 00 |........|
+>>> Flow 2 (server to client)
+00000000 16 03 01 00 37 02 00 00 33 03 01 00 00 00 00 00 |....7...3.......|
+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 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 01 02 |................|
+00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0|
+00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.|
+00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......|
+00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G|
+00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R|
+00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000|
+000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000|
+000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....|
+000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0|
+000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......|
+000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.|
+000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].|
+00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...|
+00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....|
+00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4|
+00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..|
+00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. |
+00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...|
+00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....|
+00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....|
+00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..|
+00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.|
+000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....|
+000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......|
+000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0|
+000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM|
+000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...|
+000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example|
+00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..|
+00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[|
+00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..|
+00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..|
+00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.|
+00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....|
+00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.|
+00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...|
+00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=|
+00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 01 00 04 0e |.`.\!.;.........|
+000002a0 00 00 00 |...|
+>>> Flow 3 (client to server)
+00000000 16 03 01 00 86 10 00 00 82 00 80 73 aa be d1 21 |...........s...!|
+00000010 67 e9 9c 20 40 cf 0a 47 31 61 e9 2b ba 06 4f aa |g.. @..G1a.+..O.|
+00000020 ce 15 6a b7 df 0d 0e b0 fe b5 f2 c0 26 81 39 6e |..j.........&.9n|
+00000030 5b 96 3c 2f 42 4f 08 92 48 a3 95 c8 ad 0d 0e 8f |[.</BO..H.......|
+00000040 9c 9e fc bf d7 25 2e c7 d1 e2 e6 66 9b bf 20 94 |.....%.....f.. .|
+00000050 6f d3 62 77 38 0f f6 96 ae 54 f1 8c 6a c2 17 bd |o.bw8....T..j...|
+00000060 c6 7c 99 f0 e5 6d 1b f2 81 c6 49 29 c2 24 db a7 |.|...m....I).$..|
+00000070 0f c0 53 15 6f 3e 9b d8 c2 32 f1 3e 16 b7 d3 b2 |..S.o>...2.>....|
+00000080 36 99 9f b7 53 ef 34 e8 d6 13 3b 14 03 01 00 01 |6...S.4...;.....|
+00000090 01 16 03 01 00 30 c6 d2 a6 85 cf 2a e4 9e 9e e1 |.....0.....*....|
+000000a0 d0 82 d0 2a f8 e5 bd f6 9a 67 0b c6 47 07 9c 14 |...*.....g..G...|
+000000b0 7e 73 9e 4c 8b d2 55 4f b2 32 9a 16 16 a5 e8 25 |~s.L..UO.2.....%|
+000000c0 62 e2 e9 88 b6 44 |b....D|
+>>> Flow 4 (server to client)
+00000000 14 03 01 00 01 01 16 03 01 00 30 21 7a ee 62 6a |..........0!z.bj|
+00000010 20 39 2a 39 d1 d3 f7 bd 53 05 4f 1a 36 71 3b b6 | 9*9....S.O.6q;.|
+00000020 c5 5a b7 3b c3 0b 3f b9 2f ac 62 1c c2 2f fa 29 |.Z.;..?./.b../.)|
+00000030 dd f3 bc ff 35 28 7f 86 b8 0f 33 17 03 01 00 20 |....5(....3.... |
+00000040 3a 6c 47 23 37 5a 15 bd 03 c6 64 c5 59 2f 91 e8 |:lG#7Z....d.Y/..|
+00000050 a6 1b d5 04 c2 a7 80 0e 94 6c 3c e4 70 2c ea 81 |.........l<.p,..|
+00000060 17 03 01 00 30 60 14 bc 6b 84 16 9f 53 b6 ee c9 |....0`..k...S...|
+00000070 43 cf f3 46 97 45 e1 2f 86 96 26 cc ef ea 09 72 |C..F.E./..&....r|
+00000080 36 92 4e 9e 2a 8e a2 d7 9a cd 5f 38 a8 07 c4 54 |6.N.*....._8...T|
+00000090 a1 4d 6e 7a 36 15 03 01 00 20 1e c2 df a3 3e 8e |.Mnz6.... ....>.|
+000000a0 15 c4 c0 90 8f 7c 5a e0 68 d7 ea 86 76 8d d1 27 |.....|Z.h...v..'|
+000000b0 c1 d9 32 55 f9 ce f5 92 e6 51 |..2U.....Q|
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..8b1de03
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv10-RSA-RC4
@@ -0,0 +1,73 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 63 01 00 00 5f 03 01 55 31 1a ed 02 |....c..._..U1...|
+00000010 35 fe 3c ea 62 08 52 96 93 bc 2a 1b 82 fe b9 8f |5.<.b.R...*.....|
+00000020 7a 47 0e 6a 9b e8 86 ca 89 a0 e6 00 00 04 00 05 |zG.j............|
+00000030 00 ff 01 00 00 32 00 00 00 0e 00 0c 00 00 09 31 |.....2.........1|
+00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........|
+00000050 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................|
+00000060 00 16 00 00 00 17 00 00 |........|
+>>> Flow 2 (server to client)
+00000000 16 03 01 00 37 02 00 00 33 03 01 00 00 00 00 00 |....7...3.......|
+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 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 01 02 |................|
+00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0|
+00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.|
+00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......|
+00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G|
+00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R|
+00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000|
+000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000|
+000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....|
+000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0|
+000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......|
+000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.|
+000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].|
+00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...|
+00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....|
+00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4|
+00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..|
+00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. |
+00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...|
+00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....|
+00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....|
+00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..|
+00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.|
+000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....|
+000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......|
+000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0|
+000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM|
+000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...|
+000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example|
+00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..|
+00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[|
+00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..|
+00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..|
+00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.|
+00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....|
+00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.|
+00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...|
+00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=|
+00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 01 00 04 0e |.`.\!.;.........|
+000002a0 00 00 00 |...|
+>>> Flow 3 (client to server)
+00000000 16 03 01 00 86 10 00 00 82 00 80 75 7d be e3 5b |...........u}..[|
+00000010 66 4b 58 09 f7 86 6a ca 93 8e ba 3c 18 11 47 5e |fKX...j....<..G^|
+00000020 7e c2 b1 0c 5e a4 c1 07 ef 25 00 d7 bf c7 b0 03 |~...^....%......|
+00000030 0d f6 ff a9 c2 73 a2 c0 dc 8d db f9 5a a9 18 7d |.....s......Z..}|
+00000040 1f 8e 0b 9c 24 6c c8 49 99 e1 42 e0 86 d5 e1 e1 |....$l.I..B.....|
+00000050 d1 ae fd d2 c4 ef 07 8c 28 95 b7 54 25 57 40 1c |........(..T%W@.|
+00000060 c6 af 85 46 a0 31 d4 39 b8 47 43 88 a0 a6 5d d7 |...F.1.9.GC...].|
+00000070 95 fb 88 64 ce 36 2b c5 56 85 56 40 f8 d4 d3 90 |...d.6+.V.V@....|
+00000080 d1 25 53 06 d8 ab a0 f2 21 8f 88 14 03 01 00 01 |.%S.....!.......|
+00000090 01 16 03 01 00 24 26 50 7a 2c ab 3f db 41 06 cf |.....$&Pz,.?.A..|
+000000a0 8b 7b f8 46 ad a4 77 b6 06 f0 44 23 04 34 88 9d |.{.F..w...D#.4..|
+000000b0 48 d7 5e cc 9e e6 46 a3 04 69 |H.^...F..i|
+>>> Flow 4 (server to client)
+00000000 14 03 01 00 01 01 16 03 01 00 24 57 fc eb dd 40 |..........$W...@|
+00000010 83 1d 9a 9a 80 a3 62 a0 08 23 c3 97 fd d5 fb d7 |......b..#......|
+00000020 98 f8 14 ae 61 c7 21 fb 8a 18 1e c8 15 05 e7 17 |....a.!.........|
+00000030 03 01 00 21 7c 2b 2d 72 2f 63 56 3a 09 51 4e ab |...!|+-r/cV:.QN.|
+00000040 31 25 c8 7e 34 5b a4 ab 30 87 50 07 ed 32 3f 79 |1%.~4[..0.P..2?y|
+00000050 f1 db c0 17 f3 15 03 01 00 16 fc ce c9 0c b6 0c |................|
+00000060 c5 2d d9 3f 2a 9e 9a 83 40 e1 a3 b9 5f 89 aa 75 |.-.?*...@..._..u|
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..dc70edf
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv11-RSA-RC4
@@ -0,0 +1,73 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 63 01 00 00 5f 03 02 2b b6 22 28 e3 |....c..._..+."(.|
+00000010 1f 42 f4 2e d0 43 4b 9a ea 2b 36 44 ca 93 6c 71 |.B...CK..+6D..lq|
+00000020 b9 4d 52 44 64 57 b2 05 9b 41 da 00 00 04 00 05 |.MRDdW...A......|
+00000030 00 ff 01 00 00 32 00 00 00 0e 00 0c 00 00 09 31 |.....2.........1|
+00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........|
+00000050 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................|
+00000060 00 16 00 00 00 17 00 00 |........|
+>>> Flow 2 (server to client)
+00000000 16 03 02 00 37 02 00 00 33 03 02 00 00 00 00 00 |....7...3.......|
+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 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 02 02 |................|
+00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0|
+00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.|
+00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......|
+00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G|
+00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R|
+00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000|
+000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000|
+000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....|
+000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0|
+000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......|
+000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.|
+000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].|
+00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...|
+00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....|
+00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4|
+00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..|
+00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. |
+00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...|
+00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....|
+00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....|
+00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..|
+00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.|
+000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....|
+000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......|
+000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0|
+000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM|
+000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...|
+000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example|
+00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..|
+00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[|
+00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..|
+00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..|
+00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.|
+00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....|
+00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.|
+00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...|
+00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=|
+00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 02 00 04 0e |.`.\!.;.........|
+000002a0 00 00 00 |...|
+>>> Flow 3 (client to server)
+00000000 16 03 02 00 86 10 00 00 82 00 80 3d 47 85 0a ef |...........=G...|
+00000010 47 7c c5 93 bb 6f 7c 57 dc 2b 3f f4 e7 da 4e fc |G|...o|W.+?...N.|
+00000020 04 52 36 71 c5 63 1f 6f e6 43 91 06 bc 5c 14 b0 |.R6q.c.o.C...\..|
+00000030 ee 83 ed 3d 7a d2 4e 2c d2 2c bb f0 0c b5 82 d5 |...=z.N,.,......|
+00000040 9d c2 5a 03 12 b6 70 20 3c 89 84 af 1b 2c 2f b7 |..Z...p <....,/.|
+00000050 9b fe dd 71 06 ac 46 30 a7 b5 9f 0b aa 6e 58 50 |...q..F0.....nXP|
+00000060 9d da 6b ba 00 51 e9 2a e9 d2 e9 0f 83 62 73 19 |..k..Q.*.....bs.|
+00000070 91 a4 46 bd 53 42 f7 15 ab ab 6b 8f f3 6f d1 07 |..F.SB....k..o..|
+00000080 44 41 97 4c 7d 89 4b 33 55 30 30 14 03 02 00 01 |DA.L}.K3U00.....|
+00000090 01 16 03 02 00 24 54 fe a0 7c 16 47 de 0b 8f 7d |.....$T..|.G...}|
+000000a0 51 68 05 da 1e 6d 96 c9 e1 94 68 fa 79 46 02 db |Qh...m....h.yF..|
+000000b0 03 4e 2e 70 9f 7e 14 85 fd 1d |.N.p.~....|
+>>> Flow 4 (server to client)
+00000000 14 03 02 00 01 01 16 03 02 00 24 4b c5 cf 20 3f |..........$K.. ?|
+00000010 0a 13 1f 55 25 26 9b 33 fd 14 61 0f 44 32 26 b3 |...U%&.3..a.D2&.|
+00000020 ab 01 ee c2 1f d3 38 08 f0 af 76 6a 0d e1 b7 17 |......8...vj....|
+00000030 03 02 00 21 97 16 df 99 06 81 f2 00 d3 fd b4 03 |...!............|
+00000040 be 16 b6 aa 74 d4 c7 25 67 94 14 34 25 ec 0d 12 |....t..%g..4%...|
+00000050 c7 43 2d a2 1d 15 03 02 00 16 94 58 af 6b 55 5f |.C-........X.kU_|
+00000060 25 0c 80 28 99 2d 75 1a ce 24 cd 75 0d 7f b9 71 |%..(.-u..$.u...q|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ALPN b/src/crypto/tls/testdata/Server-TLSv12-ALPN
new file mode 100644
index 0000000..d738662
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-ALPN
@@ -0,0 +1,92 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 9d 01 00 00 99 03 03 53 49 69 68 95 |...........SIih.|
+00000010 b9 7b 2a 84 d2 03 93 d4 33 e7 b7 7e bc b5 97 b0 |.{*.....3..~....|
+00000020 4f 4f 6c d0 96 43 aa c8 6f da 90 00 00 04 cc a8 |OOl..C..o.......|
+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 48 02 00 00 44 03 03 00 00 00 00 00 |....H...D.......|
+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 1c 00 23 00 00 ff 01 00 01 00 00 10 00 09 00 07 |..#.............|
+00000040 06 70 72 6f 74 6f 31 00 0b 00 02 01 00 16 03 03 |.proto1.........|
+00000050 02 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b |.Y...U..R..O0..K|
+00000060 30 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f |0..............?|
+00000070 e2 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 |.[..0...*.H.....|
+00000080 0b 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 |...0.1.0...U....|
+00000090 47 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 |Go1.0...U....Go |
+000000a0 52 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 |Root0...16010100|
+000000b0 30 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 |0000Z..250101000|
+000000c0 30 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 |000Z0.1.0...U...|
+000000d0 02 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f |.Go1.0...U....Go|
+000000e0 30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 |0..0...*.H......|
+000000f0 05 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d |......0.......F}|
+00000100 93 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d |...'.H..(!.~...]|
+00000110 fe 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 |..RE.z6G....B[..|
+00000120 c0 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 |...y.@.Om..+....|
+00000130 2e 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 |.g....."8.J.ts+.|
+00000140 34 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 |4......t{.X.la<.|
+00000150 b0 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce |.A..++$#w[.;.u].|
+00000160 20 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa | T..c...$....P..|
+00000170 b6 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 |..C...ub...R....|
+00000180 00 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 |.....0..0...U...|
+00000190 01 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 |........0...U.%.|
+000001a0 16 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b |.0...+.........+|
+000001b0 06 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 |.......0...U....|
+000001c0 ff 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 |...0.0...U......|
+000001d0 9f 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 |....CC>I..m....`|
+000001e0 30 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 |0...U.#..0...H.I|
+000001f0 4d 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 |M.~.1......n{0..|
+00000200 03 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c |.U....0...exampl|
+00000210 65 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 |e.golang0...*.H.|
+00000220 f7 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b |............0.@+|
+00000230 5b 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a |[P.a...SX...(.X.|
+00000240 a9 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 |.8....1Z..f=C.-.|
+00000250 0b f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d |..... d8.$:....}|
+00000260 b7 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc |.@ ._...a..v....|
+00000270 e1 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 |..\.....l..s..Cw|
+00000280 8d 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae |.......@.a.Lr+..|
+00000290 db 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe |.F..M...>...B...|
+000002a0 3d 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 ac |=.`.\!.;........|
+000002b0 0c 00 00 a8 03 00 1d 20 2f e5 7d a3 47 cd 62 43 |....... /.}.G.bC|
+000002c0 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 cf c2 |.(.._.).0.......|
+000002d0 ed 90 99 5f 58 cb 3b 74 08 04 00 80 3b cd 7a 99 |..._X.;t....;.z.|
+000002e0 3f bf 03 5a 26 21 90 db b4 8d 3b 69 14 82 1c ae |?..Z&!....;i....|
+000002f0 7d 72 8f 4e eb ff c4 f0 13 fa 6f 69 48 e7 6d 3d |}r.N......oiH.m=|
+00000300 fc b3 1c 54 60 54 cf 83 48 1d a3 50 55 28 3f 2c |...T`T..H..PU(?,|
+00000310 db d3 dc c7 d9 58 74 de eb 5e 21 26 2f 32 c6 b2 |.....Xt..^!&/2..|
+00000320 be 1b 08 fa d6 9f 3b b0 2b e8 c2 36 2f 9d c1 35 |......;.+..6/..5|
+00000330 c1 54 4b 37 5f ff 99 4f c1 e4 ad 69 a0 c8 52 d3 |.TK7_..O...i..R.|
+00000340 01 23 0d 57 17 08 7c 07 9a 3a 6d c8 87 5d 7e 09 |.#.W..|..:m..]~.|
+00000350 7b 03 f9 5e de 83 4d 13 89 08 72 96 16 03 03 00 |{..^..M...r.....|
+00000360 04 0e 00 00 00 |.....|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 fb eb 44 09 0e 62 |....%...! ..D..b|
+00000010 b0 ce d8 1f c5 f9 46 31 1e 1d e8 fb 02 5f 34 3b |......F1....._4;|
+00000020 c1 6f 9a 38 6a 46 d2 cd a0 53 14 03 03 00 01 01 |.o.8jF...S......|
+00000030 16 03 03 00 20 88 73 90 39 bc 9b 02 e4 c0 35 f0 |.... .s.9.....5.|
+00000040 ef 40 b0 08 ca b9 bd 25 6b cd 03 7d ec 58 73 65 |.@.....%k..}.Xse|
+00000050 d5 89 f2 f1 70 |....p|
+>>> Flow 4 (server to client)
+00000000 16 03 03 00 8b 04 00 00 87 00 00 00 00 00 81 50 |...............P|
+00000010 46 ad c1 db a8 38 86 7b 2b bb fd d0 c3 42 3e 00 |F....8.{+....B>.|
+00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 |................|
+00000030 6f e0 18 83 51 ed 14 ef 68 ca 42 c5 4c cd 0b 21 |o...Q...h.B.L..!|
+00000040 a5 29 ef 62 07 a5 11 b9 1f 4e 54 c3 66 4c 1e d3 |.).b.....NT.fL..|
+00000050 1a 00 52 34 67 2b af 73 02 5f c9 6c 7c 6e ba f2 |..R4g+.s._.l|n..|
+00000060 e6 38 bd 23 97 3f 80 6a 3b 8e bb 98 29 49 38 16 |.8.#.?.j;...)I8.|
+00000070 77 74 2a a1 c7 36 80 de c9 91 cd b2 7d bc 6c 64 |wt*..6......}.ld|
+00000080 6c 06 57 22 d1 f2 51 5f 84 ad 30 85 3a c0 4f e7 |l.W"..Q_..0.:.O.|
+00000090 14 03 03 00 01 01 16 03 03 00 20 32 71 5a d3 94 |.......... 2qZ..|
+000000a0 d5 17 e4 8c 3a 78 d1 48 4e 1b f5 83 36 f1 5a 38 |....:x.HN...6.Z8|
+000000b0 e4 b5 6d ab 46 89 e0 24 74 87 80 17 03 03 00 1d |..m.F..$t.......|
+000000c0 69 4c a6 24 67 79 18 59 92 4f 9a d0 2d 1d 57 e0 |iL.$gy.Y.O..-.W.|
+000000d0 ec 0c 00 25 6f 2f 3a be 8a aa 80 94 ac 15 03 03 |...%o/:.........|
+000000e0 00 12 ef 86 3e 93 42 bb 72 f1 1b 90 df 9a d3 ed |....>.B.r.......|
+000000f0 d8 74 35 23 |.t5#|
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..4fadf39
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-ALPN-Fallback
@@ -0,0 +1,91 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 a6 01 00 00 a2 03 03 b5 c9 ab 32 7f |..............2.|
+00000010 e1 af 3f f2 ac 2a 11 dd 33 f9 b5 21 88 0d e4 29 |..?..*..3..!...)|
+00000020 e2 47 49 dc c7 31 a8 a5 25 81 0c 00 00 04 cc a8 |.GI..1..%.......|
+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 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 00 23 00 00 ff 01 00 01 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 5f |......_X.;t...._|
+000002d0 37 27 84 58 1e ea 1e 40 1b de a9 8f 04 d4 94 64 |7'.X...@.......d|
+000002e0 4e 27 c7 f1 b3 30 d0 53 f5 3d 57 50 d2 17 97 c8 |N'...0.S.=WP....|
+000002f0 3d 61 af a6 21 ab 1c 34 47 70 f8 b1 3b 9c 06 86 |=a..!..4Gp..;...|
+00000300 87 00 e2 13 50 83 91 ad bc 84 bd b4 7b f3 4b ed |....P.......{.K.|
+00000310 ca 81 0c 94 37 a8 ec 67 ca 9c f3 00 f6 af c2 92 |....7..g........|
+00000320 c4 8c 78 07 18 0e 43 24 1b 98 16 50 5c 2b 75 0e |..x...C$...P\+u.|
+00000330 40 66 dc 40 cd 10 1a 51 25 f3 96 25 1a 3e 70 af |@f.@...Q%..%.>p.|
+00000340 16 24 d0 1c 0e 33 f9 c1 74 cf b7 e2 28 ac 60 16 |.$...3..t...(.`.|
+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 30 f2 bb f7 a7 ac |....%...! 0.....|
+00000010 23 20 22 ee 73 0d 49 9c b3 7b c1 9a db 2c 85 f3 |# ".s.I..{...,..|
+00000020 c0 82 31 60 bd 8b 14 4e 73 43 14 03 03 00 01 01 |..1`...NsC......|
+00000030 16 03 03 00 20 09 8d c7 86 ee cc f4 c7 36 a3 49 |.... ........6.I|
+00000040 d3 f7 a1 4a 68 a2 1e b4 fc cc a2 15 cb 01 92 d8 |...Jh...........|
+00000050 72 b0 d1 6f eb |r..o.|
+>>> Flow 4 (server to client)
+00000000 16 03 03 00 8b 04 00 00 87 00 00 00 00 00 81 50 |...............P|
+00000010 46 ad c1 db a8 38 86 7b 2b bb fd d0 c3 42 3e 00 |F....8.{+....B>.|
+00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 |................|
+00000030 6f e0 18 83 51 ed 14 ef 68 ca 42 c5 4c a2 ac 05 |o...Q...h.B.L...|
+00000040 9c 69 69 99 08 9f de a4 d4 e7 37 ab 14 38 4c 47 |.ii.......7..8LG|
+00000050 70 f0 97 1d db 2d 0a 14 c2 1e f0 16 9f 6d 37 02 |p....-.......m7.|
+00000060 4b f1 16 be 98 3f df 74 83 7c 19 85 61 49 38 16 |K....?.t.|..aI8.|
+00000070 ee 35 7a e2 3f 74 fe 8d e3 07 93 a1 5e fa f2 02 |.5z.?t......^...|
+00000080 e5 c8 60 3f 11 83 8b 0e 32 52 f1 aa 52 b7 0a 89 |..`?....2R..R...|
+00000090 14 03 03 00 01 01 16 03 03 00 20 9e 65 15 cf 45 |.......... .e..E|
+000000a0 a5 03 69 c9 b1 d8 9e 92 a3 a2 b0 df 2e 62 b1 3a |..i..........b.:|
+000000b0 17 78 cd e5 1d f3 51 42 7e 4e 25 17 03 03 00 1d |.x....QB~N%.....|
+000000c0 d9 ae d0 fa b7 90 a9 2f 28 8d 1d 6f 54 1f c0 1e |......./(..oT...|
+000000d0 4d ae b6 91 f0 e8 84 cf 86 11 22 25 ea 15 03 03 |M........."%....|
+000000e0 00 12 0e 71 f2 11 9e 9f 58 ad c0 d8 fc fa 34 bc |...q....X.....4.|
+000000f0 02 5a 60 00 |.Z`.|
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..e1c991b
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-ALPN-NotConfigured
@@ -0,0 +1,91 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 9d 01 00 00 99 03 03 92 d8 d4 4f 2e |..............O.|
+00000010 82 ad e9 4f a2 c3 f7 23 da 2e dc 23 c0 87 fc 33 |...O...#...#...3|
+00000020 14 63 f1 da 98 a8 af 70 3a 7e f3 00 00 04 cc a8 |.c.....p:~......|
+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 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 00 23 00 00 ff 01 00 01 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 8c |......_X.;t.....|
+000002d0 cb 8c f6 6c dd 02 5f c9 13 7e c2 26 26 41 7a 1a |...l.._..~.&&Az.|
+000002e0 25 c7 3e 22 11 30 32 c0 67 a5 53 32 1e 32 21 cb |%.>".02.g.S2.2!.|
+000002f0 ff 0a b7 e1 7a 98 26 e9 bf 05 30 f6 13 38 ee 1d |....z.&...0..8..|
+00000300 90 56 a6 0d e0 65 a8 02 0e 08 3e c0 31 ff dd fa |.V...e....>.1...|
+00000310 05 3a 22 7c f8 ce 65 43 0c b6 c4 9a e4 ed 22 eb |.:"|..eC......".|
+00000320 c4 46 b2 3d 1d 9c c1 e7 d4 6a 79 4f cf 8f 1c 45 |.F.=.....jyO...E|
+00000330 52 51 b3 d1 a4 0d 0d df 4e 19 15 e6 af 2e 5a d5 |RQ......N.....Z.|
+00000340 8a 2e 3c 48 8a f7 86 e5 53 0e 35 9a 8a c6 dd 16 |..<H....S.5.....|
+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 b7 d6 2f 99 8f c7 |....%...! ../...|
+00000010 bc 48 b8 4f 01 f8 2c ff 75 e5 fe 10 c6 2d 2d d5 |.H.O..,.u....--.|
+00000020 43 2b c3 14 cb d0 b2 7a e9 71 14 03 03 00 01 01 |C+.....z.q......|
+00000030 16 03 03 00 20 c9 88 f1 a0 1a 9b 8a 14 00 33 f0 |.... .........3.|
+00000040 e8 01 f3 c2 66 06 98 44 4d 35 89 8f 1b 65 d0 cf |....f..DM5...e..|
+00000050 eb 7d 9f b1 df |.}...|
+>>> Flow 4 (server to client)
+00000000 16 03 03 00 8b 04 00 00 87 00 00 00 00 00 81 50 |...............P|
+00000010 46 ad c1 db a8 38 86 7b 2b bb fd d0 c3 42 3e 00 |F....8.{+....B>.|
+00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 |................|
+00000030 6f e0 18 83 51 ed 14 ef 68 ca 42 c5 4c 76 fb ec |o...Q...h.B.Lv..|
+00000040 0d 89 48 e7 19 98 64 df 59 8f df 50 ce 28 e8 3c |..H...d.Y..P.(.<|
+00000050 b6 f8 5a ae bc 6b 2e a2 d6 23 05 f6 7f 36 ea 55 |..Z..k...#...6.U|
+00000060 13 54 9e 9c 31 df d0 56 00 1f a7 6a b2 49 38 16 |.T..1..V...j.I8.|
+00000070 7f d0 78 12 95 86 11 ca 98 63 07 4a 81 a5 d3 bd |..x......c.J....|
+00000080 dc 9e 54 9c 25 f2 55 d5 fd cf 36 94 99 e0 c5 82 |..T.%.U...6.....|
+00000090 14 03 03 00 01 01 16 03 03 00 20 e6 d9 c2 bb ca |.......... .....|
+000000a0 02 d3 79 a4 fb b0 00 7d e2 47 46 d3 e7 b4 fe be |..y....}.GF.....|
+000000b0 b3 8f c4 98 b7 f7 25 bc cc 3f a8 17 03 03 00 1d |......%..?......|
+000000c0 ad f3 27 a0 c4 a4 5b 7b 40 11 a4 35 e6 10 03 63 |..'...[{@..5...c|
+000000d0 13 d3 1c ce 75 8f 09 8b 85 6c 93 b1 9f 15 03 03 |....u....l......|
+000000e0 00 12 79 0c dd 21 72 68 b8 30 45 5d 45 39 a9 c4 |..y..!rh.0E]E9..|
+000000f0 a6 d7 12 99 |....|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndECDSAGiven b/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndECDSAGiven
new file mode 100644
index 0000000..3d1ceaf
--- /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 b0 00 44 aa 86 |....m...i....D..|
+00000010 30 87 8e 3f f1 89 9a 4a f6 4c 3b 11 f3 4f e9 9f |0..?...J.L;..O..|
+00000020 00 22 47 82 26 57 c7 d0 f9 59 6f 00 00 04 00 2f |."G.&W...Yo..../|
+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 31 02 00 00 2d 03 03 00 00 00 00 00 |....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 05 ff 01 00 01 00 16 03 03 02 59 0b 00 02 55 00 |..........Y...U.|
+00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......|
+00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..|
+00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.|
+00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..|
+00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..|
+00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..|
+000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1|
+000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.|
+000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...|
+000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0|
+000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.|
+000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6|
+00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.|
+00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....|
+00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......|
+00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$|
+00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..|
+00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u|
+00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.|
+00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........|
+00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.|
+00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......|
+000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.|
+000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>|
+000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#|
+000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..|
+000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0|
+000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan|
+00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........|
+00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...|
+00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1|
+00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d|
+00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..|
+00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....|
+00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......|
+00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..|
+00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.|
+00000290 3b e9 fa e7 16 03 03 00 23 0d 00 00 1f 02 01 40 |;.......#......@|
+000002a0 00 18 08 04 04 03 08 07 08 05 08 06 04 01 05 01 |................|
+000002b0 06 01 05 03 06 03 02 01 02 03 00 00 16 03 03 00 |................|
+000002c0 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 10 ab 2f 0f b9 29 |............/..)|
+00000220 9f 26 36 09 00 96 9a 3d 2a 01 50 03 f3 d6 ac fc |.&6....=*.P.....|
+00000230 40 76 96 d0 e6 a6 67 89 24 b0 56 80 58 5e 6d 03 |@v....g.$.V.X^m.|
+00000240 e3 0f dc 61 d1 de 25 95 8a 54 9f 5b 3e f2 31 dd |...a..%..T.[>.1.|
+00000250 14 2a e2 de 7b 70 66 b5 ed 95 d9 cc 6f c0 b3 a1 |.*..{pf.....o...|
+00000260 bb 41 b2 0f 7d e8 ce b5 11 eb 99 e2 ce c0 33 bc |.A..}.........3.|
+00000270 6a 67 10 84 d2 dd ac 15 8f 8e aa 2b 1a 7b ca d3 |jg.........+.{..|
+00000280 bb 4b 92 c4 b9 2b 08 c1 0d b2 cf 96 63 64 9d 12 |.K...+......cd..|
+00000290 a6 93 cd 21 3b bc 8e 94 72 76 16 03 03 00 93 0f |...!;...rv......|
+000002a0 00 00 8f 04 03 00 8b 30 81 88 02 42 00 d5 05 54 |.......0...B...T|
+000002b0 b2 68 a5 04 d6 3c 7b 7d c1 be e3 d1 b4 25 42 d6 |.h...<{}.....%B.|
+000002c0 2a 3a 2e ea 73 0d 57 ba 0f 96 78 66 c2 c5 d7 57 |*:..s.W...xf...W|
+000002d0 79 9c 22 8b 76 e9 45 ff ef 92 e9 43 3e b8 8b b4 |y.".v.E....C>...|
+000002e0 cf 3f 67 aa 70 d1 e8 a2 1c a8 3d 24 a2 78 02 42 |.?g.p.....=$.x.B|
+000002f0 01 b2 17 64 66 2f 2e 0d 2d b9 1d 67 45 de 48 9e |...df/..-..gE.H.|
+00000300 32 f2 1f 79 38 39 b8 bb 8b 7f 82 e9 46 fd 9b 1b |2..y89......F...|
+00000310 b3 dd a4 9c 15 b2 a2 88 4c f7 42 a2 62 92 c0 d0 |........L.B.b...|
+00000320 a1 78 aa 8b 2d 78 4f 02 5a f7 eb ca c7 34 fc b6 |.x..-xO.Z....4..|
+00000330 6c 6e 14 03 03 00 01 01 16 03 03 00 40 bd 47 9b |ln..........@.G.|
+00000340 ce 31 2c 09 d3 a8 2c bb 28 0c e8 bd 01 a9 54 34 |.1,...,.(.....T4|
+00000350 a5 74 af e0 d2 38 f3 1b fa d0 2b a6 39 24 ae de |.t...8....+.9$..|
+00000360 0a cf 4b c0 a2 3b bf 80 23 71 0a 60 ca 94 b7 23 |..K..;..#q.`...#|
+00000370 80 e3 89 89 42 74 0b a1 c6 f6 d2 c0 79 |....Bt......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 54 52 4a 33 9e |...........TRJ3.|
+00000020 bb 59 7e 21 03 a6 23 bd 68 18 43 b5 c5 c5 37 a2 |.Y~!..#.h.C...7.|
+00000030 6f ac 8c 78 c5 cf 8f e6 01 df 17 53 45 6f 1a e0 |o..x.......SEo..|
+00000040 9c 4a 3d 2c cb 0d 55 7d 32 81 ec 17 03 03 00 40 |.J=,..U}2......@|
+00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000060 ba 75 93 00 86 1c bc 66 9e 27 2f 2b 5a 68 0e 44 |.u.....f.'/+Zh.D|
+00000070 81 15 0d 67 e6 ee 7a 43 08 78 93 71 91 00 56 0e |...g..zC.x.q..V.|
+00000080 c6 e1 73 4b af 2f e6 e0 92 4d e5 35 ea 53 7c 45 |..sK./...M.5.S|E|
+00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
+000000a0 00 00 00 00 00 8d 7e 99 bb 93 bd 5d ba 31 b0 0d |......~....].1..|
+000000b0 1f 76 95 50 7c 1e 24 62 9d 05 65 3f ee b7 c2 24 |.v.P|.$b..e?...$|
+000000c0 13 60 43 69 3a |.`Ci:|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndEd25519Given b/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndEd25519Given
new file mode 100644
index 0000000..1c3b08f
--- /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 aa ad c9 dc 56 |....m...i......V|
+00000010 79 2e da 42 a6 b2 9e 0a 85 a6 1b e0 5e cd 4e f5 |y..B........^.N.|
+00000020 93 93 0c d5 62 a8 53 17 10 f7 e6 00 00 04 00 2f |....b.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 31 02 00 00 2d 03 03 00 00 00 00 00 |....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 05 ff 01 00 01 00 16 03 03 02 59 0b 00 02 55 00 |..........Y...U.|
+00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......|
+00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..|
+00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.|
+00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..|
+00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..|
+00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..|
+000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1|
+000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.|
+000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...|
+000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0|
+000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.|
+000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6|
+00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.|
+00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....|
+00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......|
+00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$|
+00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..|
+00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u|
+00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.|
+00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........|
+00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.|
+00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......|
+000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.|
+000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>|
+000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#|
+000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..|
+000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0|
+000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan|
+00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........|
+00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...|
+00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1|
+00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d|
+00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..|
+00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....|
+00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......|
+00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..|
+00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.|
+00000290 3b e9 fa e7 16 03 03 00 23 0d 00 00 1f 02 01 40 |;.......#......@|
+000002a0 00 18 08 04 04 03 08 07 08 05 08 06 04 01 05 01 |................|
+000002b0 06 01 05 03 06 03 02 01 02 03 00 00 16 03 03 00 |................|
+000002c0 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 14 f2 ac 22 |..............."|
+00000150 fb 0b f8 03 a7 cf 23 d5 ea 9f b0 f2 64 ae 41 fe |......#.....d.A.|
+00000160 33 f7 54 69 f5 41 b7 c1 91 6d 2b 3e 14 2a f6 c8 |3.Ti.A...m+>.*..|
+00000170 96 45 00 28 13 f5 2f de 35 f9 64 89 5c 99 3e 89 |.E.(../.5.d.\.>.|
+00000180 06 ff 59 56 69 db 5f 6e 02 84 dd 1c 44 7b 86 e8 |..YVi._n....D{..|
+00000190 e3 d9 03 f1 16 9e 06 23 00 43 91 ec a9 dd da a4 |.......#.C......|
+000001a0 ac fe 5b f8 62 f9 76 19 38 83 54 b4 8c 0b 02 f0 |..[.b.v.8.T.....|
+000001b0 fa 7a 8e 2e da 9d e1 4a c6 51 92 9b f6 4b a1 31 |.z.....J.Q...K.1|
+000001c0 c9 64 b2 a6 9a 01 52 86 b3 7a 43 17 16 03 03 00 |.d....R..zC.....|
+000001d0 48 0f 00 00 44 08 07 00 40 29 35 71 34 aa b1 f1 |H...D...@)5q4...|
+000001e0 64 08 4e 06 43 db 00 f7 f5 98 8e b6 51 d7 c4 b5 |d.N.C.......Q...|
+000001f0 2b fa 56 8b bd 7b 18 f2 81 e9 2f 81 82 d8 90 e7 |+.V..{..../.....|
+00000200 5b bc 72 7e f7 97 43 df cd 07 bf 7b ae 60 08 8b |[.r~..C....{.`..|
+00000210 0a 71 c5 bf f0 7a 3e cc 0b 14 03 03 00 01 01 16 |.q...z>.........|
+00000220 03 03 00 40 85 4f e0 c0 f3 3e a4 51 68 d6 ec 1b |...@.O...>.Qh...|
+00000230 f1 4b 3e 0e 13 84 87 e3 3c 9a 5f 67 75 3a ad 08 |.K>.....<._gu:..|
+00000240 be 29 15 b0 1f 62 27 fd d8 dd 58 b1 65 e7 e2 db |.)...b'...X.e...|
+00000250 fe 55 a5 2d 2e 71 59 07 ad 12 12 80 12 bb 26 36 |.U.-.qY.......&6|
+00000260 93 fb ea b1 |....|
+>>> 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 f4 ed 23 ce da |.............#..|
+00000020 73 5f ef 6b a2 82 3d a5 c6 f1 fd 8f a0 47 4e 34 |s_.k..=......GN4|
+00000030 f9 7c d0 67 49 00 11 c3 76 83 23 3f 99 41 d5 5c |.|.gI...v.#?.A.\|
+00000040 aa 9f 97 66 b7 0a 59 ba f3 40 83 17 03 03 00 40 |...f..Y..@.....@|
+00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000060 82 66 85 d7 47 a6 5a 19 4f 89 5c 56 43 cb 6a bd |.f..G.Z.O.\VC.j.|
+00000070 1b ae 46 40 7d e8 a9 7b 57 04 91 8b d5 de 24 f1 |..F@}..{W.....$.|
+00000080 c0 df 37 45 e9 af d7 c5 1c e7 ee 80 0d 61 2a 7f |..7E.........a*.|
+00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
+000000a0 00 00 00 00 00 5a 97 f3 38 e5 3a f1 07 79 b7 eb |.....Z..8.:..y..|
+000000b0 ed 85 57 3a 96 16 51 38 85 86 ec 1b 9b 48 82 9c |..W:..Q8.....H..|
+000000c0 05 bf 4d e5 fb |..M..|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndGiven b/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndGiven
new file mode 100644
index 0000000..3dec0de
--- /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 e7 7e 1f 56 df |....m...i...~.V.|
+00000010 f1 1b e5 92 47 3b fb 25 a6 57 7d 13 47 08 f0 0f |....G;.%.W}.G...|
+00000020 5b 64 64 00 d3 25 33 e5 a5 5b e3 00 00 04 00 2f |[dd..%3..[...../|
+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 31 02 00 00 2d 03 03 00 00 00 00 00 |....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 05 ff 01 00 01 00 16 03 03 02 59 0b 00 02 55 00 |..........Y...U.|
+00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......|
+00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..|
+00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.|
+00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..|
+00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..|
+00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..|
+000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1|
+000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.|
+000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...|
+000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0|
+000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.|
+000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6|
+00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.|
+00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....|
+00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......|
+00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$|
+00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..|
+00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u|
+00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.|
+00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........|
+00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.|
+00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......|
+000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.|
+000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>|
+000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#|
+000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..|
+000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0|
+000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan|
+00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........|
+00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...|
+00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1|
+00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d|
+00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..|
+00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....|
+00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......|
+00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..|
+00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.|
+00000290 3b e9 fa e7 16 03 03 00 23 0d 00 00 1f 02 01 40 |;.......#......@|
+000002a0 00 18 08 04 04 03 08 07 08 05 08 06 04 01 05 01 |................|
+000002b0 06 01 05 03 06 03 02 01 02 03 00 00 16 03 03 00 |................|
+000002c0 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 7f 38 c9 |.5............8.|
+00000210 56 ed de 7d a6 2c dc cc 24 61 ea d3 8a fc b8 18 |V..}.,..$a......|
+00000220 b8 e5 50 3e c3 d1 ca cf f7 0c d9 9b 22 d8 6d 0f |..P>........".m.|
+00000230 71 e7 dd 7c 24 84 c6 f1 6a ac a0 3d ea d7 65 24 |q..|$...j..=..e$|
+00000240 d7 3a 17 d5 b7 ec f7 03 bc 58 3a 01 d5 08 27 25 |.:.......X:...'%|
+00000250 b9 2f 3b 96 cb d5 7c 12 20 f4 f1 91 58 13 fb 50 |./;...|. ...X..P|
+00000260 f8 d5 5c e4 43 85 e8 41 37 3e ff fa a6 64 92 4d |..\.C..A7>...d.M|
+00000270 bd d4 96 59 bd 94 f1 95 21 ad 75 1e 0d a2 8d 30 |...Y....!.u....0|
+00000280 a3 82 f4 56 0f ba 5d 40 32 7f 0c 5f 5a 16 03 03 |...V..]@2.._Z...|
+00000290 00 88 0f 00 00 84 08 04 00 80 39 b4 f4 68 e9 96 |..........9..h..|
+000002a0 01 53 95 31 26 fa 3c 70 46 9f ba 62 b4 37 ea a6 |.S.1&.<pF..b.7..|
+000002b0 e4 81 d1 21 f4 1f 21 d4 6d c0 98 20 40 56 52 79 |...!..!.m.. @VRy|
+000002c0 99 18 c7 f1 6f 01 25 e1 65 71 33 9e 4b 81 11 a0 |....o.%.eq3.K...|
+000002d0 68 e2 be 39 05 86 81 44 a5 64 3d 07 e3 3b 48 70 |h..9...D.d=..;Hp|
+000002e0 14 fd 1f 75 05 23 44 57 3e dd 47 79 17 c3 5e 70 |...u.#DW>.Gy..^p|
+000002f0 30 8c 11 3f 27 43 4f 5d 81 89 83 39 9d fe 0c c3 |0..?'CO]...9....|
+00000300 af 40 8d 2a 41 bf 57 67 7a df b4 89 29 10 9a 84 |.@.*A.Wgz...)...|
+00000310 ff 8c 2f 58 1a 0a b9 62 4e 8e 14 03 03 00 01 01 |../X...bN.......|
+00000320 16 03 03 00 40 7c 7a 79 ae 84 60 b8 95 83 30 78 |....@|zy..`...0x|
+00000330 e9 6e 02 36 52 85 5a 6a a7 b5 f5 6d 4d a9 09 9d |.n.6R.Zj...mM...|
+00000340 43 9d 46 da d0 cf 75 25 49 e1 79 0b 23 2d 85 c2 |C.F...u%I.y.#-..|
+00000350 fd 5d 90 08 f5 75 81 ab 01 a0 f4 93 12 87 fb e3 |.]...u..........|
+00000360 9b 99 4d fa c5 |..M..|
+>>> 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 48 61 67 c0 1e |...........Hag..|
+00000020 09 79 82 cc 55 60 fa e5 bd 1a 1d 14 d3 25 e6 4b |.y..U`.......%.K|
+00000030 b7 a6 47 64 01 65 12 b3 37 42 1a 13 d9 90 12 7e |..Gd.e..7B.....~|
+00000040 ea d8 30 39 e2 25 5e 9a 05 61 11 17 03 03 00 40 |..09.%^..a.....@|
+00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000060 cf c5 73 08 e9 15 25 b6 d8 e3 fa 0c a1 25 33 75 |..s...%......%3u|
+00000070 8a 2e 66 03 c2 2d 50 c7 e1 10 b4 2a 0c 88 87 90 |..f..-P....*....|
+00000080 04 4a 80 26 85 4b fd 9a 4f 0e b1 2c f0 18 57 f5 |.J.&.K..O..,..W.|
+00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
+000000a0 00 00 00 00 00 ce e0 a1 71 be 3d 1e b0 bd 06 4c |........q.=....L|
+000000b0 1f 5b 10 8d 77 18 e0 c5 81 c9 4e 1b 3b 96 f6 6d |.[..w.....N.;..m|
+000000c0 88 03 53 54 30 |..ST0|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndPKCS1v15Given b/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedAndPKCS1v15Given
new file mode 100644
index 0000000..8efbc91
--- /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 4c 65 99 ab e0 |....m...i..Le...|
+00000010 4b 0a 08 f5 06 20 f9 3d 96 4f 05 e3 58 6f 41 50 |K.... .=.O..XoAP|
+00000020 c1 5f e8 a8 0a 5f 8f f2 de 7f 16 00 00 04 00 2f |._..._........./|
+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 31 02 00 00 2d 03 03 00 00 00 00 00 |....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 05 ff 01 00 01 00 16 03 03 02 59 0b 00 02 55 00 |..........Y...U.|
+00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......|
+00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..|
+00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.|
+00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..|
+00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..|
+00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..|
+000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1|
+000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.|
+000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...|
+000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0|
+000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.|
+000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6|
+00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.|
+00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....|
+00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......|
+00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$|
+00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..|
+00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u|
+00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.|
+00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........|
+00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.|
+00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......|
+000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.|
+000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>|
+000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#|
+000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..|
+000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0|
+000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan|
+00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........|
+00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...|
+00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1|
+00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d|
+00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..|
+00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....|
+00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......|
+00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..|
+00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.|
+00000290 3b e9 fa e7 16 03 03 00 23 0d 00 00 1f 02 01 40 |;.......#......@|
+000002a0 00 18 08 04 04 03 08 07 08 05 08 06 04 01 05 01 |................|
+000002b0 06 01 05 03 06 03 02 01 02 03 00 00 16 03 03 00 |................|
+000002c0 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 41 62 b4 |.5...........Ab.|
+00000210 fb 81 80 58 e3 0d c7 b2 c0 55 ee 5b 1a ba 2d 8f |...X.....U.[..-.|
+00000220 9f 79 24 0a d5 be c7 2b 55 ec 51 6d b9 78 63 85 |.y$....+U.Qm.xc.|
+00000230 82 d2 ea 02 0c 06 fe 05 fd ed 08 be 71 99 5f 53 |............q._S|
+00000240 94 85 01 ff ba 2a ee 14 cb 99 0a df 1e 67 0d 95 |.....*.......g..|
+00000250 63 8d 1f 96 41 75 f9 5d 1a 21 03 6c e3 eb 4f 5e |c...Au.].!.l..O^|
+00000260 28 c3 4d bb 6d 29 33 bc 24 75 8c 3b f2 c4 6b f5 |(.M.m)3.$u.;..k.|
+00000270 86 db 40 59 34 43 fb a9 1e ea 6f 3f 0e b4 35 39 |..@Y4C....o?..59|
+00000280 52 d8 0f 85 ed 3b 52 b6 5b 7f b0 bf c3 16 03 03 |R....;R.[.......|
+00000290 00 88 0f 00 00 84 04 01 00 80 52 85 ca 08 7d 07 |..........R...}.|
+000002a0 bc d8 0c a4 b8 36 01 c0 b8 8a 18 ba d8 d4 a3 fa |.....6..........|
+000002b0 fd 32 e2 00 72 e5 d2 c8 5a 59 6b 5e 6e df 35 da |.2..r...ZYk^n.5.|
+000002c0 c7 1e ee af 87 4b d6 30 7e 27 1c 76 70 28 79 ac |.....K.0~'.vp(y.|
+000002d0 7f 31 bc 44 55 3c 15 61 d2 0d 24 9c 48 43 9f 12 |.1.DU<.a..$.HC..|
+000002e0 a6 74 5c 2f 5b 4e 96 4a 47 b4 6b 7c fa da 37 96 |.t\/[N.JG.k|..7.|
+000002f0 ec 46 7d 05 be 24 8f cf 11 31 ab 4c 5b c7 3e 94 |.F}..$...1.L[.>.|
+00000300 9a 2a 39 e8 fe aa aa ee e3 00 a3 a8 1e 75 4a 21 |.*9..........uJ!|
+00000310 b4 ad 24 8f ee e8 30 85 b1 28 14 03 03 00 01 01 |..$...0..(......|
+00000320 16 03 03 00 40 71 47 13 68 49 74 9c 2a 81 35 94 |....@qG.hIt.*.5.|
+00000330 52 f6 44 44 67 3b 62 e1 ef 34 18 e7 8a 56 71 88 |R.DDg;b..4...Vq.|
+00000340 83 7e 67 28 20 18 b1 c5 8a c8 8b 6a fe ee bf da |.~g( ......j....|
+00000350 5f 6e cd fa a8 5c af 5c 3c 83 80 78 f3 fe 1b dc |_n...\.\<..x....|
+00000360 95 fe 22 16 82 |.."..|
+>>> 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 20 f7 51 8f 23 |........... .Q.#|
+00000020 08 8d 67 5d 12 06 b0 48 81 2d 0c ba 88 03 88 31 |..g]...H.-.....1|
+00000030 d0 ab 63 0d 9f 28 60 21 0a a3 58 47 c2 04 cc f1 |..c..(`!..XG....|
+00000040 50 0d 88 b2 e5 54 50 26 e6 6e ed 17 03 03 00 40 |P....TP&.n.....@|
+00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000060 fa 4d e5 00 14 2c 65 82 5d 1b bf 99 6a 54 16 98 |.M...,e.]...jT..|
+00000070 ef 55 15 00 f9 c4 3e 61 88 83 63 fd 60 66 f1 87 |.U....>a..c.`f..|
+00000080 fa c4 45 ae de b8 0a 36 75 f5 b2 b6 f5 d8 9b df |..E....6u.......|
+00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
+000000a0 00 00 00 00 00 54 cc c0 15 e5 6d 62 4d 13 54 e8 |.....T....mbM.T.|
+000000b0 fa cf 76 a6 de d6 48 f8 0d ef 30 b7 12 05 cf 75 |..v...H...0....u|
+000000c0 8b 00 9e d5 63 |....c|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedNotGiven b/src/crypto/tls/testdata/Server-TLSv12-ClientAuthRequestedNotGiven
new file mode 100644
index 0000000..a81c173
--- /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 be a7 a4 6c f7 |....m...i.....l.|
+00000010 f6 b4 f2 64 5d 0e 36 b6 05 f5 f1 c9 fe 3c c2 8e |...d].6......<..|
+00000020 c4 b7 18 68 b9 0c 1d 51 50 2f 1e 00 00 04 00 2f |...h...QP/...../|
+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 31 02 00 00 2d 03 03 00 00 00 00 00 |....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 05 ff 01 00 01 00 16 03 03 02 59 0b 00 02 55 00 |..........Y...U.|
+00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......|
+00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..|
+00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.|
+00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..|
+00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..|
+00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..|
+000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1|
+000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.|
+000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...|
+000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0|
+000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.|
+000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6|
+00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.|
+00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....|
+00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......|
+00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$|
+00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..|
+00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u|
+00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.|
+00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........|
+00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.|
+00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......|
+000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.|
+000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>|
+000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#|
+000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..|
+000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0|
+000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan|
+00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........|
+00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...|
+00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1|
+00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d|
+00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..|
+00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....|
+00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......|
+00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..|
+00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.|
+00000290 3b e9 fa e7 16 03 03 00 23 0d 00 00 1f 02 01 40 |;.......#......@|
+000002a0 00 18 08 04 04 03 08 07 08 05 08 06 04 01 05 01 |................|
+000002b0 06 01 05 03 06 03 02 01 02 03 00 00 16 03 03 00 |................|
+000002c0 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 a9 b6 12 e2 84 71 62 7a 20 |............qbz |
+00000020 63 80 99 c6 ee f7 61 f9 74 d6 0b ab 31 74 69 ca |c.....a.t...1ti.|
+00000030 94 20 9e 1b 0e 52 45 c4 f4 b3 cb fb a4 07 61 6f |. ...RE.......ao|
+00000040 a1 5a 84 4c 4f f6 4a e4 bc c5 c2 b0 ee 8a 30 5b |.Z.LO.J.......0[|
+00000050 10 e0 ed d3 4c b7 32 8c ed 3f 89 a7 a7 95 60 86 |....L.2..?....`.|
+00000060 97 1a ae ab 2f 5c e6 6d 1b c3 35 bd f5 c1 f0 1a |..../\.m..5.....|
+00000070 d4 70 e5 00 f2 d4 d1 20 6a 82 db e7 52 ca 88 e5 |.p..... j...R...|
+00000080 2d cc 79 0c f6 09 84 65 f0 30 41 67 10 0a 48 d1 |-.y....e.0Ag..H.|
+00000090 09 3e 56 7a aa 57 bc 14 03 03 00 01 01 16 03 03 |.>Vz.W..........|
+000000a0 00 40 e6 0a 91 5f 30 f8 52 75 94 8e ab 82 ec 1d |.@..._0.Ru......|
+000000b0 b7 a1 1c 18 1a aa 1c f8 73 93 0e 20 ad 68 a7 65 |........s.. .h.e|
+000000c0 86 c9 f5 90 f9 b2 fd d1 32 94 52 6e 82 9b b9 45 |........2.Rn...E|
+000000d0 97 52 4b 1e c2 31 a6 2e c8 b3 1a 62 22 83 8f df |.RK..1.....b"...|
+000000e0 d7 06 |..|
+>>> 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 b0 2c 61 79 87 |............,ay.|
+00000020 59 d4 9e 4d e7 56 4a 34 ba 78 d5 06 98 a2 92 35 |Y..M.VJ4.x.....5|
+00000030 a1 fc 57 5a 6e d3 0f 44 08 1c a1 7b 3c d3 f1 86 |..WZn..D...{<...|
+00000040 a2 04 04 5e 1b 7c 00 4f 51 71 73 17 03 03 00 40 |...^.|.OQqs....@|
+00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000060 aa 5c 1a 9a 70 bc b3 fb 70 07 0b 24 cb 95 84 61 |.\..p...p..$...a|
+00000070 96 ed d8 97 2f d6 79 51 ed cd 67 44 e5 d4 a3 57 |..../.yQ..gD...W|
+00000080 95 f6 c8 31 a8 95 c2 07 a4 ce 1c fc 4a dc 93 d9 |...1........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 ae dd c4 f4 04 d3 b1 1a 8a 56 f7 |..............V.|
+000000b0 73 c9 d5 aa 6c 59 d7 66 77 34 64 2d 19 79 13 80 |s...lY.fw4d-.y..|
+000000c0 98 60 6d f4 d9 |.`m..|
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..d7e6188
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-ECDHE-ECDSA-AES
@@ -0,0 +1,85 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 97 01 00 00 93 03 03 86 3b 10 1e 5f |............;.._|
+00000010 81 eb 21 bd 77 47 61 e9 3f 82 85 14 91 8c ab 7d |..!.wGa.?......}|
+00000020 84 bd b1 f0 06 20 8a 7b 06 d6 78 00 00 04 c0 0a |..... .{..x.....|
+00000030 00 ff 01 00 00 66 00 00 00 0e 00 0c 00 00 09 31 |.....f.........1|
+00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........|
+00000050 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................|
+00000060 00 16 00 00 00 17 00 00 00 0d 00 30 00 2e 04 03 |...........0....|
+00000070 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 |................|
+00000080 08 05 08 06 04 01 05 01 06 01 03 03 02 03 03 01 |................|
+00000090 02 01 03 02 02 02 04 02 05 02 06 02 |............|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......|
+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 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................|
+00000040 0e 0b 00 02 0a 00 02 07 00 02 04 30 82 02 00 30 |...........0...0|
+00000050 82 01 62 02 09 00 b8 bf 2d 47 a0 d2 eb f4 30 09 |..b.....-G....0.|
+00000060 06 07 2a 86 48 ce 3d 04 01 30 45 31 0b 30 09 06 |..*.H.=..0E1.0..|
+00000070 03 55 04 06 13 02 41 55 31 13 30 11 06 03 55 04 |.U....AU1.0...U.|
+00000080 08 13 0a 53 6f 6d 65 2d 53 74 61 74 65 31 21 30 |...Some-State1!0|
+00000090 1f 06 03 55 04 0a 13 18 49 6e 74 65 72 6e 65 74 |...U....Internet|
+000000a0 20 57 69 64 67 69 74 73 20 50 74 79 20 4c 74 64 | Widgits Pty Ltd|
+000000b0 30 1e 17 0d 31 32 31 31 32 32 31 35 30 36 33 32 |0...121122150632|
+000000c0 5a 17 0d 32 32 31 31 32 30 31 35 30 36 33 32 5a |Z..221120150632Z|
+000000d0 30 45 31 0b 30 09 06 03 55 04 06 13 02 41 55 31 |0E1.0...U....AU1|
+000000e0 13 30 11 06 03 55 04 08 13 0a 53 6f 6d 65 2d 53 |.0...U....Some-S|
+000000f0 74 61 74 65 31 21 30 1f 06 03 55 04 0a 13 18 49 |tate1!0...U....I|
+00000100 6e 74 65 72 6e 65 74 20 57 69 64 67 69 74 73 20 |nternet Widgits |
+00000110 50 74 79 20 4c 74 64 30 81 9b 30 10 06 07 2a 86 |Pty Ltd0..0...*.|
+00000120 48 ce 3d 02 01 06 05 2b 81 04 00 23 03 81 86 00 |H.=....+...#....|
+00000130 04 00 c4 a1 ed be 98 f9 0b 48 73 36 7e c3 16 56 |.........Hs6~..V|
+00000140 11 22 f2 3d 53 c3 3b 4d 21 3d cd 6b 75 e6 f6 b0 |.".=S.;M!=.ku...|
+00000150 dc 9a df 26 c1 bc b2 87 f0 72 32 7c b3 64 2f 1c |...&.....r2|.d/.|
+00000160 90 bc ea 68 23 10 7e fe e3 25 c0 48 3a 69 e0 28 |...h#.~..%.H:i.(|
+00000170 6d d3 37 00 ef 04 62 dd 0d a0 9c 70 62 83 d8 81 |m.7...b....pb...|
+00000180 d3 64 31 aa 9e 97 31 bd 96 b0 68 c0 9b 23 de 76 |.d1...1...h..#.v|
+00000190 64 3f 1a 5c 7f e9 12 0e 58 58 b6 5f 70 dd 9b d8 |d?.\....XX._p...|
+000001a0 ea d5 d7 f5 d5 cc b9 b6 9f 30 66 5b 66 9a 20 e2 |.........0f[f. .|
+000001b0 27 e5 bf fe 3b 30 09 06 07 2a 86 48 ce 3d 04 01 |'...;0...*.H.=..|
+000001c0 03 81 8c 00 30 81 88 02 42 01 88 a2 4f eb e2 45 |....0...B...O..E|
+000001d0 c5 48 7d 1b ac f5 ed 98 9d ae 47 70 c0 5e 1b b6 |.H}.......Gp.^..|
+000001e0 2f bd f1 b6 4d b7 61 40 d3 11 a2 ce ee 0b 7e 92 |/...M.a@......~.|
+000001f0 7e ff 76 9d c3 3b 7e a5 3f ce fa 10 e2 59 ec 47 |~.v..;~.?....Y.G|
+00000200 2d 7c ac da 4e 97 0e 15 a0 6f d0 02 42 01 4d fc |-|..N....o..B.M.|
+00000210 be 67 13 9c 2d 05 0e bd 3f a3 8c 25 c1 33 13 83 |.g..-...?..%.3..|
+00000220 0d 94 06 bb d4 37 7a f6 ec 7a c9 86 2e dd d7 11 |.....7z..z......|
+00000230 69 7f 85 7c 56 de fb 31 78 2b e4 c7 78 0d ae cb |i..|V..1x+..x...|
+00000240 be 9e 4e 36 24 31 7b 6a 0f 39 95 12 07 8f 2a 16 |..N6$1{j.9....*.|
+00000250 03 03 00 b7 0c 00 00 b3 03 00 1d 20 2f e5 7d a3 |........... /.}.|
+00000260 47 cd 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 |G.bC.(.._.).0...|
+00000270 af c4 cf c2 ed 90 99 5f 58 cb 3b 74 04 03 00 8b |......._X.;t....|
+00000280 30 81 88 02 42 01 c5 d1 36 97 5b 0e 5e a6 90 50 |0...B...6.[.^..P|
+00000290 a0 2e 80 b5 df d7 5a f6 95 0d a4 c6 f0 da 2e e7 |......Z.........|
+000002a0 91 79 9f 85 2e ef ca 66 3c f7 c4 7b bd 61 70 bb |.y.....f<..{.ap.|
+000002b0 16 c5 aa 00 35 33 ae 58 00 b3 f1 fe 0f 77 52 23 |....53.X.....wR#|
+000002c0 f4 40 ba 4b c7 e5 43 02 42 01 64 af ab 8a 87 38 |.@.K..C.B.d....8|
+000002d0 a1 7f b8 ae 84 0e a4 ff ad 16 09 44 0b 65 67 70 |...........D.egp|
+000002e0 12 7f 1a 37 9a 1d 5e b7 3b 63 df f9 6b f1 b9 ba |...7..^.;c..k...|
+000002f0 6b 35 8f b3 03 da 3d 61 00 3d 4e 75 b4 d0 92 d5 |k5....=a.=Nu....|
+00000300 ee 50 9d d7 f9 26 69 e6 ec cf 3b 16 03 03 00 04 |.P...&i...;.....|
+00000310 0e 00 00 00 |....|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 54 db 5b a1 4c e0 |....%...! T.[.L.|
+00000010 0e 52 a2 45 e3 b4 ac 91 3d e1 de a9 3e eb 80 9e |.R.E....=...>...|
+00000020 f5 04 7b fc 82 10 2f d9 d1 41 14 03 03 00 01 01 |..{.../..A......|
+00000030 16 03 03 00 40 47 68 cc 5e 68 3f 05 d6 f8 5c 11 |....@Gh.^h?...\.|
+00000040 08 a3 91 72 ae 4c 98 67 2f 45 ee 16 6b 8b 2d 28 |...r.L.g/E..k.-(|
+00000050 15 34 43 47 f9 46 f2 96 c2 85 d5 cc 03 e0 84 de |.4CG.F..........|
+00000060 9c 03 fe bf c9 73 23 15 d0 0f 85 3a 76 db 9f 5d |.....s#....:v..]|
+00000070 95 b7 de 9c c2 |.....|
+>>> 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 98 34 52 f3 44 |............4R.D|
+00000020 18 69 23 61 ef 8f e9 c0 88 9c ad 1f cb e4 8d 55 |.i#a...........U|
+00000030 bd bb 77 9c 65 9d 21 f0 54 4c 46 db 4f e6 e8 ab |..w.e.!.TLF.O...|
+00000040 6b 1d 60 38 7f e0 2c 38 ef e7 43 17 03 03 00 40 |k.`8..,8..C....@|
+00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000060 44 68 90 07 1e 8c 7f db 3e 3f 8c 28 e1 d7 41 38 |Dh......>?.(..A8|
+00000070 e2 78 04 e3 42 c2 a9 76 bb 0a ae b9 93 df 81 d7 |.x..B..v........|
+00000080 9b 0f 1d 44 19 79 ff 7c 21 8f 75 ca e2 82 cc c4 |...D.y.|!.u.....|
+00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
+000000a0 00 00 00 00 00 82 1f e6 2c 3f c7 55 19 01 0b 62 |........,?.U...b|
+000000b0 1a 99 fc f8 d3 b0 38 21 41 92 1a d1 e0 43 96 da |......8!A....C..|
+000000c0 80 4b 58 91 c8 |.KX..|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-Ed25519 b/src/crypto/tls/testdata/Server-TLSv12-Ed25519
new file mode 100644
index 0000000..dd34592
--- /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 f0 8d 1b 90 67 |...............g|
+00000010 3b 23 46 ac f7 79 f2 f9 e8 90 98 b3 52 b2 55 2a |;#F..y......R.U*|
+00000020 fb 0f 1e dd 4f b3 75 4b 9b 88 0e 00 00 04 cc a9 |....O.uK........|
+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 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......|
+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 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 01 |................|
+00000040 3c 0b 00 01 38 00 01 35 00 01 32 30 82 01 2e 30 |<...8..5..20...0|
+00000050 81 e1 a0 03 02 01 02 02 10 0f 43 1c 42 57 93 94 |..........C.BW..|
+00000060 1d e9 87 e4 f1 ad 15 00 5d 30 05 06 03 2b 65 70 |........]0...+ep|
+00000070 30 12 31 10 30 0e 06 03 55 04 0a 13 07 41 63 6d |0.1.0...U....Acm|
+00000080 65 20 43 6f 30 1e 17 0d 31 39 30 35 31 36 32 31 |e Co0...19051621|
+00000090 33 38 30 31 5a 17 0d 32 30 30 35 31 35 32 31 33 |3801Z..200515213|
+000000a0 38 30 31 5a 30 12 31 10 30 0e 06 03 55 04 0a 13 |801Z0.1.0...U...|
+000000b0 07 41 63 6d 65 20 43 6f 30 2a 30 05 06 03 2b 65 |.Acme Co0*0...+e|
+000000c0 70 03 21 00 3f e2 15 2e e6 e3 ef 3f 4e 85 4a 75 |p.!.?......?N.Ju|
+000000d0 77 a3 64 9e ed e0 bf 84 2c cc 92 26 8f fa 6f 34 |w.d.....,..&..o4|
+000000e0 83 aa ec 8f a3 4d 30 4b 30 0e 06 03 55 1d 0f 01 |.....M0K0...U...|
+000000f0 01 ff 04 04 03 02 05 a0 30 13 06 03 55 1d 25 04 |........0...U.%.|
+00000100 0c 30 0a 06 08 2b 06 01 05 05 07 03 01 30 0c 06 |.0...+.......0..|
+00000110 03 55 1d 13 01 01 ff 04 02 30 00 30 16 06 03 55 |.U.......0.0...U|
+00000120 1d 11 04 0f 30 0d 82 0b 65 78 61 6d 70 6c 65 2e |....0...example.|
+00000130 63 6f 6d 30 05 06 03 2b 65 70 03 41 00 63 44 ed |com0...+ep.A.cD.|
+00000140 9c c4 be 53 24 53 9f d2 10 8d 9f e8 21 08 90 95 |...S$S......!...|
+00000150 39 e5 0d c1 55 ff 2c 16 b7 1d fc ab 7d 4d d4 e0 |9...U.,.....}M..|
+00000160 93 13 d0 a9 42 e0 b6 6b fe 5d 67 48 d7 9f 50 bc |....B..k.]gH..P.|
+00000170 6c cd 4b 03 83 7c f2 08 58 cd ac cf 0c 16 03 03 |l.K..|..X.......|
+00000180 00 6c 0c 00 00 68 03 00 1d 20 2f e5 7d a3 47 cd |.l...h... /.}.G.|
+00000190 62 43 15 28 da ac 5f bb 29 07 30 ff f6 84 af c4 |bC.(.._.).0.....|
+000001a0 cf c2 ed 90 99 5f 58 cb 3b 74 08 07 00 40 1f 56 |....._X.;t...@.V|
+000001b0 21 8a 44 04 69 65 ee f8 93 52 4c f0 49 42 57 4c |!.D.ie...RL.IBWL|
+000001c0 5b f5 1a ef 43 ad 39 93 03 a3 64 84 da e5 82 32 |[...C.9...d....2|
+000001d0 fc 77 12 61 f3 f4 2c d8 61 9e 86 01 1f c0 a0 98 |.w.a..,.a.......|
+000001e0 94 a3 7f 15 75 c8 e6 2f 20 bd af 7c be 0e 16 03 |....u../ ..|....|
+000001f0 03 00 04 0e 00 00 00 |.......|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 26 b0 6c 90 e7 71 |....%...! &.l..q|
+00000010 23 78 4b a1 a1 32 7c 28 e9 df 7e 98 e9 78 be 8d |#xK..2|(..~..x..|
+00000020 0d ec fc 30 82 99 16 f0 9f 20 14 03 03 00 01 01 |...0..... ......|
+00000030 16 03 03 00 20 e9 81 b0 ea b3 f3 21 40 9a 3b 3e |.... ......!@.;>|
+00000040 71 a7 13 f5 3a 8a cd 86 34 8b 7e 41 b5 2a 1b 03 |q...:...4.~A.*..|
+00000050 29 77 b3 b2 da |)w...|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 20 54 5a ff 09 7d |.......... TZ..}|
+00000010 46 04 40 62 c5 63 71 85 c7 b4 6c 09 ee 15 71 6b |F.@b.cq...l...qk|
+00000020 60 3b 00 3d 46 47 13 a5 f7 15 16 17 03 03 00 1d |`;.=FG..........|
+00000030 13 8d 00 50 58 d0 2a 47 a8 d8 de 87 d4 3e ff ee |...PX.*G.....>..|
+00000040 f1 4d 6b 25 94 6f 01 7b 70 ee 53 d9 be 15 03 03 |.Mk%.o.{p.S.....|
+00000050 00 12 13 ea 17 69 00 0e 2b ae 21 a9 5e 0a 41 2d |.....i..+.!.^.A-|
+00000060 1b 73 f0 2d |.s.-|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ExportKeyingMaterial b/src/crypto/tls/testdata/Server-TLSv12-ExportKeyingMaterial
new file mode 100644
index 0000000..e01c32c
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-ExportKeyingMaterial
@@ -0,0 +1,89 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 89 01 00 00 85 03 03 9a d9 fe da 40 |...............@|
+00000010 cf 8b ed 11 09 8e 3f 29 4b 0d 46 ff fc f6 56 2c |......?)K.F...V,|
+00000020 a8 e7 16 84 8a a4 e9 44 89 97 0b 00 00 04 cc a8 |.......D........|
+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 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 00 23 00 00 ff 01 00 01 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 89 |......_X.;t.....|
+000002d0 f8 62 c5 1a ba 78 74 da 6f 96 76 00 0f 6b a9 fb |.b...xt.o.v..k..|
+000002e0 83 d4 52 c0 80 0b 81 02 e3 b0 07 c2 9d ff b4 cc |..R.............|
+000002f0 ea 2e c7 82 91 35 74 ef 1e 9a ba 78 3e 60 6c 86 |.....5t....x>`l.|
+00000300 1d b0 14 52 84 84 70 ce 66 22 31 66 e2 53 04 bd |...R..p.f"1f.S..|
+00000310 4d 2b 5e 86 8b 79 dc 17 7a 4f bc 62 5a 21 a1 f6 |M+^..y..zO.bZ!..|
+00000320 46 1a 12 aa 7a 98 25 02 97 a8 9c 71 a4 4a 5b 28 |F...z.%....q.J[(|
+00000330 c8 11 6a 5f f1 b3 13 a7 f2 26 12 59 02 fa 28 e2 |..j_.....&.Y..(.|
+00000340 ba 8c c0 cd 50 c6 60 db 69 9a a1 92 12 26 23 16 |....P.`.i....&#.|
+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 ba 1b c8 ae 22 78 |....%...! ...."x|
+00000010 84 ba d8 1c b3 87 52 f0 bf 13 76 2b a5 47 37 13 |......R...v+.G7.|
+00000020 30 89 01 13 1a cb 63 ea b3 37 14 03 03 00 01 01 |0.....c..7......|
+00000030 16 03 03 00 20 ac d7 79 45 e6 65 1d 20 1a 95 5e |.... ..yE.e. ..^|
+00000040 68 f7 0f ee 8c 3f 3d 0b bc 58 31 aa 46 d7 e3 00 |h....?=..X1.F...|
+00000050 7b 10 8c 01 5d |{...]|
+>>> Flow 4 (server to client)
+00000000 16 03 03 00 8b 04 00 00 87 00 00 00 00 00 81 50 |...............P|
+00000010 46 ad c1 db a8 38 86 7b 2b bb fd d0 c3 42 3e 00 |F....8.{+....B>.|
+00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 |................|
+00000030 6f e0 18 83 51 ed 14 ef 68 ca 42 c5 4c f8 79 c6 |o...Q...h.B.L.y.|
+00000040 80 85 74 9c 35 6f 4e 9d 60 0b a2 28 b0 45 b6 f6 |..t.5oN.`..(.E..|
+00000050 71 a3 f6 a6 95 71 cd 1e 53 e9 58 9f 94 18 ac d6 |q....q..S.X.....|
+00000060 6b 03 ba ac b4 4f c2 02 cc 1c 5b 88 84 49 38 16 |k....O....[..I8.|
+00000070 d9 5e b8 11 ab c6 f8 a7 9d 5d 58 99 b1 b6 8a be |.^.......]X.....|
+00000080 4e 9e 40 3d 00 22 11 25 c7 51 8e cb d2 10 d4 7d |N.@=.".%.Q.....}|
+00000090 14 03 03 00 01 01 16 03 03 00 20 ff 4b 1e 87 3e |.......... .K..>|
+000000a0 05 5c b4 3e e4 b9 5c 47 f0 a2 0b 67 47 89 c6 48 |.\.>..\G...gG..H|
+000000b0 d5 e3 73 d2 00 44 56 e4 8d b6 fb 17 03 03 00 1d |..s..DV.........|
+000000c0 58 28 94 02 c2 a9 99 3d b6 0b de 9c fd 52 61 bf |X(.....=.....Ra.|
+000000d0 55 c0 12 7f be a8 52 98 d7 99 a5 d0 60 15 03 03 |U.....R.....`...|
+000000e0 00 12 26 44 ad f0 a7 56 e5 23 6f 1b 7a 7e f8 e4 |..&D...V.#o.z~..|
+000000f0 42 49 5d 1d |BI].|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-IssueTicket b/src/crypto/tls/testdata/Server-TLSv12-IssueTicket
new file mode 100644
index 0000000..f70c759
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-IssueTicket
@@ -0,0 +1,91 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 71 01 00 00 6d 03 03 3d 21 91 3a 4e |....q...m..=!.:N|
+00000010 8e cd 65 eb 0f 1c ae 2a 58 40 4c 38 22 c9 46 2c |..e....*X@L8".F,|
+00000020 b8 cd dd 38 ad c6 4b a7 60 a9 56 00 00 04 00 2f |...8..K.`.V..../|
+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 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 00 23 00 00 ff 01 00 01 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 1d 1a 1a b8 f4 |................|
+00000010 05 77 7a 96 2b 5f 50 7f 1e 69 14 be 40 ad 0c c9 |.wz.+_P..i..@...|
+00000020 7e df 2f 1d aa 74 ee b4 a5 05 fa 05 e1 85 a4 87 |~./..t..........|
+00000030 59 6a d1 e4 98 ce df e3 a5 82 98 77 c2 c4 fc 2f |Yj.........w.../|
+00000040 ec 1d 2e 96 0c 27 12 0d 64 ba 58 90 ff 7d d1 27 |.....'..d.X..}.'|
+00000050 9a b9 b5 fb 1d 76 6f 3e af f8 70 a3 cc 53 95 98 |.....vo>..p..S..|
+00000060 2c 7e a9 42 25 e5 3a e2 55 3f 19 57 6b 83 43 6a |,~.B%.:.U?.Wk.Cj|
+00000070 93 34 2c 6e cb 4e 9d 25 8b 4d 7d d7 cc e1 16 59 |.4,n.N.%.M}....Y|
+00000080 2a 95 60 e4 31 0e df 7f cb 9d b7 14 03 03 00 01 |*.`.1...........|
+00000090 01 16 03 03 00 40 28 33 df 69 4f 4c 48 b1 fb 8d |.....@(3.iOLH...|
+000000a0 3f 3c d2 81 7c 33 cf 21 6a f7 d6 43 82 22 5b de |?<..|3.!j..C."[.|
+000000b0 46 7f 7b e2 39 23 bd 39 fa 03 bd 11 9d a8 a2 84 |F.{.9#.9........|
+000000c0 4a 90 1a ab e1 b4 23 9f 72 d0 97 9e 05 5c 47 2b |J.....#.r....\G+|
+000000d0 7a 53 bb ec a0 07 |zS....|
+>>> Flow 4 (server to client)
+00000000 16 03 03 00 8b 04 00 00 87 00 00 00 00 00 81 50 |...............P|
+00000010 46 ad c1 db a8 38 86 7b 2b bb fd d0 c3 42 3e 00 |F....8.{+....B>.|
+00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 |................|
+00000030 6f 2c 9f 83 51 ed 14 ef 68 ca 42 c5 4c 75 5e a5 |o,..Q...h.B.Lu^.|
+00000040 6f d2 49 61 e4 fb 83 46 7c 4c ab f9 c6 d1 3c 9e |o.Ia...F|L....<.|
+00000050 5b 8d d8 bc c0 a5 2d 84 db 24 dd a0 16 60 1d 87 |[.....-..$...`..|
+00000060 a0 52 88 25 6c c6 8e 5b 71 0f 74 c3 48 49 38 16 |.R.%l..[q.t.HI8.|
+00000070 92 8c de 77 bd 8a 2b 45 4d 58 86 40 b1 d6 0f 99 |...w..+EMX.@....|
+00000080 de 27 41 b2 41 27 aa fe 26 e9 24 91 2a 00 ff 08 |.'A.A'..&.$.*...|
+00000090 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....|
+000000a0 00 00 00 00 00 00 00 00 00 00 00 fc cd 6b 01 90 |.............k..|
+000000b0 7b 0c 31 54 a0 3a 8b f7 ba 45 e7 e0 df 9a 59 6d |{.1T.:...E....Ym|
+000000c0 83 b6 b2 c8 93 d8 d9 b6 fe 19 56 51 75 a3 ea 0e |..........VQu...|
+000000d0 f4 4b 64 27 66 fc 19 7b 7e 13 e7 17 03 03 00 40 |.Kd'f..{~......@|
+000000e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+000000f0 c2 1b 6f f1 1e 05 1b 8a 19 16 67 00 0f dc a8 a2 |..o.......g.....|
+00000100 00 56 49 0a bb c5 df 7e 96 0c 5c db a0 f4 3e b4 |.VI....~..\...>.|
+00000110 30 3e b6 f0 16 dd d4 ed c9 de 64 49 00 9b 51 dc |0>........dI..Q.|
+00000120 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
+00000130 00 00 00 00 00 e1 9d 08 1a 2e 9a 0f 84 6d 4e e5 |.............mN.|
+00000140 2c 50 b9 28 5d 88 ea bb 48 4d af 26 7f 82 0b 56 |,P.(]...HM.&...V|
+00000150 c5 87 71 2a e7 |..q*.|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-IssueTicketPreDisable b/src/crypto/tls/testdata/Server-TLSv12-IssueTicketPreDisable
new file mode 100644
index 0000000..8cb57f5
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-IssueTicketPreDisable
@@ -0,0 +1,91 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 71 01 00 00 6d 03 03 e1 40 35 c8 5c |....q...m...@5.\|
+00000010 71 63 3f 5a 00 42 e6 3e 64 62 b8 c4 e7 e7 ba 98 |qc?Z.B.>db......|
+00000020 d8 fa 2c b5 65 f7 50 db 43 d9 70 00 00 04 00 2f |..,.e.P.C.p..../|
+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 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 00 23 00 00 ff 01 00 01 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 4f ce 06 88 66 |...........O...f|
+00000010 dd e1 0a 55 ef fb 1b 9e 70 62 8b 3b 0d e4 19 0f |...U....pb.;....|
+00000020 4f 16 c9 79 92 9c 4d 16 21 ea 43 d7 58 7f 35 65 |O..y..M.!.C.X.5e|
+00000030 a3 15 7a 8d b5 6e 9b f6 73 19 c2 0c 58 be 9d 8a |..z..n..s...X...|
+00000040 5a a8 be f3 89 48 64 28 6a 7f be b7 4a 58 93 af |Z....Hd(j...JX..|
+00000050 c0 ff 8a ae 01 34 1f cf 7b b0 7a 5e 69 19 43 fa |.....4..{.z^i.C.|
+00000060 21 b8 dc ee 0e ab 3b 81 c9 b9 be b9 56 a0 dd 62 |!.....;.....V..b|
+00000070 02 45 14 54 4d 05 5a cc 31 68 1f 17 91 a6 0e d7 |.E.TM.Z.1h......|
+00000080 5a f3 ae bb 5e 90 1d c3 c9 56 2a 14 03 03 00 01 |Z...^....V*.....|
+00000090 01 16 03 03 00 40 a1 34 07 ef 45 42 d2 88 bb 6e |.....@.4..EB...n|
+000000a0 7f 3a 2a 39 67 3f 90 76 95 b7 cc 86 b6 1a 6c c6 |.:*9g?.v......l.|
+000000b0 da 8f 26 f3 34 6c 1f 6f 05 11 39 40 00 46 00 be |..&.4l.o..9@.F..|
+000000c0 8f 3a af 86 d6 6d 5d 00 f3 5d 22 1c 31 2c 24 ee |.:...m]..]".1,$.|
+000000d0 e5 11 ba 94 5f b1 |...._.|
+>>> Flow 4 (server to client)
+00000000 16 03 03 00 8b 04 00 00 87 00 00 00 00 00 81 50 |...............P|
+00000010 46 ad c1 db a8 38 86 7b 2b bb fd d0 c3 42 3e 00 |F....8.{+....B>.|
+00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 94 |................|
+00000030 6f 2c 9f 83 51 ed 14 ef 68 ca 42 c5 4c 20 33 6c |o,..Q...h.B.L 3l|
+00000040 01 97 a5 69 44 bf 8f ea db 83 05 fb ef cc 51 1f |...iD.........Q.|
+00000050 0b 4d 44 77 89 11 cf c8 38 16 67 ea a2 3e 8b 2a |.MDw....8.g..>.*|
+00000060 18 f2 f7 25 ce e0 d8 4c 93 31 b0 59 23 49 38 16 |...%...L.1.Y#I8.|
+00000070 3a f9 63 9e 61 21 1b ab 67 09 6a 23 07 8e d0 4a |:.c.a!..g.j#...J|
+00000080 19 78 9c 1e 60 40 a7 83 c5 9a 48 41 35 c4 e9 63 |.x..`@....HA5..c|
+00000090 14 03 03 00 01 01 16 03 03 00 40 00 00 00 00 00 |..........@.....|
+000000a0 00 00 00 00 00 00 00 00 00 00 00 b8 46 07 9e 14 |............F...|
+000000b0 85 ba 6d e0 f1 f5 99 43 80 9a 54 6b 33 1e 4f c1 |..m....C..Tk3.O.|
+000000c0 88 b7 3d 60 04 d4 e9 b0 b2 6d c4 1a ca 3b 9f 83 |..=`.....m...;..|
+000000d0 28 5f ea b2 54 e4 11 78 69 de 1a 17 03 03 00 40 |(_..T..xi......@|
+000000e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+000000f0 55 34 ad ae 9b 37 df cd 88 ae fc 6a ac c5 cf 16 |U4...7.....j....|
+00000100 ec f1 bc 22 1e d2 c1 52 5e a2 e7 d2 6e 37 7a 29 |..."...R^...n7z)|
+00000110 c8 b9 d4 7d 81 63 1a f0 53 d9 10 fd 4f 3d 1c dd |...}.c..S...O=..|
+00000120 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
+00000130 00 00 00 00 00 8f f2 11 0d 93 99 83 29 d4 10 a4 |............)...|
+00000140 7c bb 26 7b 24 f1 15 3a 9b 81 0e cb 0a 51 4b 39 ||.&{$..:.....QK9|
+00000150 69 1d e5 38 5e |i..8^|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-P256 b/src/crypto/tls/testdata/Server-TLSv12-P256
new file mode 100644
index 0000000..58b9bed
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-P256
@@ -0,0 +1,86 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 8f 01 00 00 8b 03 03 49 de 51 77 8e |...........I.Qw.|
+00000010 58 03 e9 25 0b 9a 88 ef 35 2d 35 a8 30 29 22 61 |X..%....5-5.0)"a|
+00000020 ae b4 af 8a a1 2c 45 59 40 5f aa 00 00 04 c0 2f |.....,EY@_...../|
+00000030 00 ff 01 00 00 5e 00 00 00 0e 00 0c 00 00 09 31 |.....^.........1|
+00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........|
+00000050 00 0a 00 04 00 02 00 17 00 16 00 00 00 17 00 00 |................|
+00000060 00 0d 00 30 00 2e 04 03 05 03 06 03 08 07 08 08 |...0............|
+00000070 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 |................|
+00000080 06 01 03 03 02 03 03 01 02 01 03 02 02 02 04 02 |................|
+00000090 05 02 06 02 |....|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......|
+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 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................|
+00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0|
+00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.|
+00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......|
+00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G|
+00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R|
+00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000|
+000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000|
+000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....|
+000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0|
+000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......|
+000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.|
+000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].|
+00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...|
+00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....|
+00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4|
+00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..|
+00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. |
+00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...|
+00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....|
+00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....|
+00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..|
+00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.|
+000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....|
+000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......|
+000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0|
+000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM|
+000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...|
+000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example|
+00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..|
+00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[|
+00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..|
+00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..|
+00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.|
+00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....|
+00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.|
+00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...|
+00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=|
+00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 cd 0c |.`.\!.;.........|
+000002a0 00 00 c9 03 00 17 41 04 1e 18 37 ef 0d 19 51 88 |......A...7...Q.|
+000002b0 35 75 71 b5 e5 54 5b 12 2e 8f 09 67 fd a7 24 20 |5uq..T[....g..$ |
+000002c0 3e b2 56 1c ce 97 28 5e f8 2b 2d 4f 9e f1 07 9f |>.V...(^.+-O....|
+000002d0 6c 4b 5b 83 56 e2 32 42 e9 58 b6 d7 49 a6 b5 68 |lK[.V.2B.X..I..h|
+000002e0 1a 41 03 56 6b dc 5a 89 08 04 00 80 7b bd 89 a1 |.A.Vk.Z.....{...|
+000002f0 d8 9d cf e4 75 ac 15 60 a9 49 0c c7 68 61 4e e4 |....u..`.I..haN.|
+00000300 2b 51 37 5a 65 38 a4 52 6a d0 4f 8b 76 93 a4 7c |+Q7Ze8.Rj.O.v..||
+00000310 ac 30 6b 89 f1 c7 88 8f f3 5c c7 e9 d6 7c 33 94 |.0k......\...|3.|
+00000320 f7 fc f8 69 35 f3 f7 e0 ea fc 51 5c b2 e2 dc 9e |...i5.....Q\....|
+00000330 57 03 af e6 19 0d 0d e4 25 b6 52 19 12 ad 35 fc |W.......%.R...5.|
+00000340 7f c3 6a 1f ed 06 82 34 81 13 d7 c1 67 a9 18 88 |..j....4....g...|
+00000350 2f bb 00 54 5d d9 01 16 29 dd 03 3c 69 f7 46 52 |/..T]...)..<i.FR|
+00000360 6a 95 51 81 75 68 fa 15 09 11 38 94 16 03 03 00 |j.Q.uh....8.....|
+00000370 04 0e 00 00 00 |.....|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 46 10 00 00 42 41 04 a6 c3 8d d1 32 |....F...BA.....2|
+00000010 8e b4 ac 27 75 4a 57 26 7f 6a 52 a7 82 ee c2 b1 |...'uJW&.jR.....|
+00000020 a3 68 0a 8d 09 ff 82 61 57 f3 32 5e ec 1a 2f 20 |.h.....aW.2^../ |
+00000030 8c c1 d4 cf 27 7b f0 1d f9 5d f6 24 80 6a 45 d2 |....'{...].$.jE.|
+00000040 97 cf f1 5d a2 e3 b0 15 7d e6 a4 14 03 03 00 01 |...]....}.......|
+00000050 01 16 03 03 00 28 21 36 fe 82 d2 4a b4 da f8 14 |.....(!6...J....|
+00000060 d6 d6 8c be 56 1f ca 82 7f 20 bb 01 be fb 2a 0d |....V.... ....*.|
+00000070 a8 31 ee 79 f7 8a 8b 4a 1b a7 66 3a 89 67 |.1.y...J..f:.g|
+>>> 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 00 0a 97 89 c3 74 09 63 25 2a fc e1 29 |........t.c%*..)|
+00000020 18 b1 bc d6 75 2e 3b 2a fb 90 17 b9 b8 ea e2 c4 |....u.;*........|
+00000030 29 94 16 17 03 03 00 25 00 00 00 00 00 00 00 01 |)......%........|
+00000040 8c 30 76 b7 fd b1 96 0b 2a 8f f3 e1 b3 38 16 15 |.0v.....*....8..|
+00000050 10 3d 32 ee 29 b5 12 cb cb cf 98 a3 c5 15 03 03 |.=2.)...........|
+00000060 00 1a 00 00 00 00 00 00 00 02 9e 4a 55 8e 91 ff |...........JU...|
+00000070 13 0b 56 be 3c 5d b8 26 42 f1 c8 28 |..V.<].&B..(|
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..17a5ad0
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-RSA-3DES
@@ -0,0 +1,80 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 97 01 00 00 93 03 03 e2 8f 43 82 4c |.............C.L|
+00000010 13 33 88 d2 53 5d b6 02 d2 b6 b2 a1 11 f0 30 14 |.3..S]........0.|
+00000020 41 1e 8c 79 85 38 75 cd e8 a6 a7 00 00 04 00 0a |A..y.8u.........|
+00000030 00 ff 01 00 00 66 00 00 00 0e 00 0c 00 00 09 31 |.....f.........1|
+00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........|
+00000050 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................|
+00000060 00 16 00 00 00 17 00 00 00 0d 00 30 00 2e 04 03 |...........0....|
+00000070 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 |................|
+00000080 08 05 08 06 04 01 05 01 06 01 03 03 02 03 03 01 |................|
+00000090 02 01 03 02 02 02 04 02 05 02 06 02 |............|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......|
+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 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................|
+00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0|
+00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.|
+00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......|
+00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G|
+00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R|
+00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000|
+000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000|
+000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....|
+000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0|
+000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......|
+000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.|
+000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].|
+00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...|
+00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....|
+00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4|
+00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..|
+00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. |
+00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...|
+00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....|
+00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....|
+00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..|
+00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.|
+000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....|
+000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......|
+000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0|
+000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM|
+000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...|
+000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example|
+00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..|
+00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[|
+00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..|
+00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..|
+00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.|
+00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....|
+00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.|
+00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...|
+00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=|
+00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e |.`.\!.;.........|
+000002a0 00 00 00 |...|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 86 10 00 00 82 00 80 57 ce 41 c0 4d |...........W.A.M|
+00000010 b1 69 27 6e cb 92 a5 71 52 85 e7 a8 69 b0 31 d1 |.i'n...qR...i.1.|
+00000020 0a b0 3d a6 9d ab 04 e8 a2 4c d8 67 95 97 da 63 |..=......L.g...c|
+00000030 f7 0b 6e 62 29 5b 8b cf 77 f1 80 a5 1f 67 08 71 |..nb)[..w....g.q|
+00000040 50 c3 a9 90 ea b8 11 3d 5d c9 f5 1c 37 fa 67 b1 |P......=]...7.g.|
+00000050 64 b0 04 3e c1 0d db 77 fe b9 a0 ea f2 0f 1d af |d..>...w........|
+00000060 9a 77 b3 96 4f 3f 3c 52 a7 ed c4 3f 48 ef ff f8 |.w..O?<R...?H...|
+00000070 38 f6 34 60 5a 29 12 37 85 23 1c 39 8e 1a a7 2f |8.4`Z).7.#.9.../|
+00000080 68 39 1f 37 ed 08 a8 a5 b2 c1 f0 14 03 03 00 01 |h9.7............|
+00000090 01 16 03 03 00 30 8d 64 b1 cb 97 76 8a 78 08 d1 |.....0.d...v.x..|
+000000a0 c0 af 60 9c 0d f0 ae 41 93 f4 97 2b 46 f7 65 52 |..`....A...+F.eR|
+000000b0 55 a7 90 4a 83 47 cc e4 51 29 0d 6e 0b 42 52 c2 |U..J.G..Q).n.BR.|
+000000c0 bf 13 b8 01 72 d3 |....r.|
+>>> 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 0d 0f 3c 6a 28 f0 97 90 1a c3 7e c8 63 |.....<j(.....~.c|
+00000020 15 75 1b 71 c8 bb 7d 83 b0 9b a6 73 3d 3d 51 7a |.u.q..}....s==Qz|
+00000030 52 5b e4 33 16 93 40 23 43 7c a2 17 03 03 00 30 |R[.3..@#C|.....0|
+00000040 00 00 00 00 00 00 00 00 be db 1d 03 aa 15 53 49 |..............SI|
+00000050 a3 57 00 24 75 3a b1 48 71 ec d9 7d e1 40 5c dc |.W.$u:.Hq..}.@\.|
+00000060 fd f5 33 6f 6b c7 3e 9e 2e 05 af 1b 12 73 75 8c |..3ok.>......su.|
+00000070 15 03 03 00 20 00 00 00 00 00 00 00 00 5c 30 63 |.... ........\0c|
+00000080 23 55 26 ee 8d 81 9a 2e b4 e7 38 6b 04 e7 42 43 |#U&.......8k..BC|
+00000090 50 de 1e 40 2d |P..@-|
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..0196e21
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-RSA-AES
@@ -0,0 +1,84 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 97 01 00 00 93 03 03 dd 28 eb 68 4a |............(.hJ|
+00000010 8a 71 d2 98 d0 2d 21 c7 e9 19 19 de c8 13 0b 67 |.q...-!........g|
+00000020 f4 ff 4c d0 37 f5 72 9f 2d fb b3 00 00 04 00 2f |..L.7.r.-....../|
+00000030 00 ff 01 00 00 66 00 00 00 0e 00 0c 00 00 09 31 |.....f.........1|
+00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........|
+00000050 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................|
+00000060 00 16 00 00 00 17 00 00 00 0d 00 30 00 2e 04 03 |...........0....|
+00000070 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 |................|
+00000080 08 05 08 06 04 01 05 01 06 01 03 03 02 03 03 01 |................|
+00000090 02 01 03 02 02 02 04 02 05 02 06 02 |............|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......|
+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 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................|
+00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0|
+00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.|
+00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......|
+00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G|
+00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R|
+00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000|
+000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000|
+000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....|
+000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0|
+000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......|
+000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.|
+000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].|
+00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...|
+00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....|
+00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4|
+00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..|
+00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. |
+00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...|
+00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....|
+00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....|
+00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..|
+00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.|
+000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....|
+000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......|
+000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0|
+000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM|
+000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...|
+000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example|
+00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..|
+00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[|
+00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..|
+00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..|
+00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.|
+00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....|
+00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.|
+00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...|
+00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=|
+00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e |.`.\!.;.........|
+000002a0 00 00 00 |...|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 86 10 00 00 82 00 80 c0 37 ef f3 d9 |............7...|
+00000010 6b 7b 3f c4 9f 46 d2 6b 8f 7f 8d ce 89 cf 8e 2b |k{?..F.k.......+|
+00000020 1f 0d 86 f9 90 5a 23 28 6c d3 14 ce 2a 0b f1 0e |.....Z#(l...*...|
+00000030 96 1c 11 7d c0 b8 fb 4b 2e cb 07 1c fe b9 e1 62 |...}...K.......b|
+00000040 2c 38 1c 46 21 74 23 a9 f2 0b 15 36 ef 88 32 e8 |,8.F!t#....6..2.|
+00000050 28 66 8e ab 14 be e9 02 04 9d 92 99 cc 6e 28 d0 |(f...........n(.|
+00000060 f9 3d dc 61 7f f7 17 59 ab 1c 86 94 9a 28 7b 46 |.=.a...Y.....({F|
+00000070 3c 36 ff d3 26 3c ad 2d 33 ef 99 83 09 a5 a8 2f |<6..&<.-3....../|
+00000080 b3 a3 74 7f 49 a3 f1 47 7d 8c 12 14 03 03 00 01 |..t.I..G}.......|
+00000090 01 16 03 03 00 40 32 68 cb ea 32 cb f2 7a 0e 4b |.....@2h..2..z.K|
+000000a0 63 72 96 93 e8 2d 5b 22 a6 3a 05 9d 60 50 e5 d0 |cr...-[".:..`P..|
+000000b0 f3 f8 14 ed 81 fe 17 a0 ee 3f 7b aa ca dc 06 bc |.........?{.....|
+000000c0 28 90 73 33 84 0c 92 39 b7 cb da 06 08 05 0b 03 |(.s3...9........|
+000000d0 86 be cc 70 0e c2 |...p..|
+>>> 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 10 a0 48 48 86 |.............HH.|
+00000020 ac 1f f4 05 4d 12 9d 90 54 26 ec c8 1f 6d e7 d5 |....M...T&...m..|
+00000030 0c 92 61 88 2f 43 77 75 0c 08 0f 33 ac c3 d3 b0 |..a./Cwu...3....|
+00000040 94 68 e3 3f 9f c9 43 a5 8b ee ed 17 03 03 00 40 |.h.?..C........@|
+00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000060 fd 7d d3 d6 3f a5 10 37 a1 93 20 ca c8 8c 9d c3 |.}..?..7.. .....|
+00000070 90 df 2f 40 e6 83 af b6 be e4 3d 07 ff 0d 24 97 |../@......=...$.|
+00000080 c2 ff af 81 eb b5 91 72 6b 6d 70 8c af 3f 9f 76 |.......rkmp..?.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 6b 80 aa 88 45 8c 39 a8 4c ca 33 |.....k...E.9.L.3|
+000000b0 f2 33 85 a0 74 6a 64 a3 43 17 4c 5c 9b 50 e5 8d |.3..tjd.C.L\.P..|
+000000c0 ff 26 03 e1 07 |.&...|
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..fa4b47b
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-RSA-AES-GCM
@@ -0,0 +1,82 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 97 01 00 00 93 03 03 8a ca f1 8f ad |................|
+00000010 fe 0b a3 e1 b8 08 10 1a 40 57 b6 f7 f7 e3 72 c4 |........@W....r.|
+00000020 57 4a 71 f8 30 cd 62 62 c7 0f 2d 00 00 04 c0 2f |WJq.0.bb..-..../|
+00000030 00 ff 01 00 00 66 00 00 00 0e 00 0c 00 00 09 31 |.....f.........1|
+00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........|
+00000050 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................|
+00000060 00 16 00 00 00 17 00 00 00 0d 00 30 00 2e 04 03 |...........0....|
+00000070 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 |................|
+00000080 08 05 08 06 04 01 05 01 06 01 03 03 02 03 03 01 |................|
+00000090 02 01 03 02 02 02 04 02 05 02 06 02 |............|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......|
+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 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................|
+00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0|
+00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.|
+00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......|
+00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G|
+00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R|
+00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000|
+000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000|
+000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....|
+000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0|
+000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......|
+000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.|
+000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].|
+00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...|
+00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....|
+00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4|
+00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..|
+00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. |
+00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...|
+00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....|
+00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....|
+00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..|
+00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.|
+000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....|
+000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......|
+000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0|
+000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM|
+000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...|
+000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example|
+00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..|
+00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[|
+00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..|
+00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..|
+00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.|
+00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....|
+00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.|
+00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...|
+00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=|
+00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 ac 0c |.`.\!.;.........|
+000002a0 00 00 a8 03 00 1d 20 2f e5 7d a3 47 cd 62 43 15 |...... /.}.G.bC.|
+000002b0 28 da ac 5f bb 29 07 30 ff f6 84 af c4 cf c2 ed |(.._.).0........|
+000002c0 90 99 5f 58 cb 3b 74 08 04 00 80 50 0b d9 1c 03 |.._X.;t....P....|
+000002d0 6f 08 05 a6 39 cc 9f 7e 3d f1 fb af 8e 0b 9a ef |o...9..~=.......|
+000002e0 39 d3 b6 e3 71 9c 5a 37 a1 86 f2 f0 59 01 fc b2 |9...q.Z7....Y...|
+000002f0 51 1c 0e 22 42 24 3e c6 db fb a1 39 9d 75 f4 79 |Q.."B$>....9.u.y|
+00000300 55 dd e5 99 0b 22 5b ed c7 19 ac db ed d3 ee 23 |U...."[........#|
+00000310 b9 37 2b 51 ea 7f 39 4d 8b 0a bc a2 2e f2 ef 9e |.7+Q..9M........|
+00000320 a5 8c 99 77 ff d2 fb 46 e4 10 4e a9 b2 a9 ce b6 |...w...F..N.....|
+00000330 50 d4 0a 28 a5 3f 0e 2c 60 cd 0f 07 9c 7e 60 c3 |P..(.?.,`....~`.|
+00000340 79 a5 cf f3 cd 77 5a 16 8d fc 14 16 03 03 00 04 |y....wZ.........|
+00000350 0e 00 00 00 |....|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 ef 3b b1 d2 a3 f6 |....%...! .;....|
+00000010 be f2 fc 2e b5 ed d3 ec 6a fb 2f 0d 5a 04 98 61 |........j./.Z..a|
+00000020 92 26 59 ba 17 26 1b 60 27 2b 14 03 03 00 01 01 |.&Y..&.`'+......|
+00000030 16 03 03 00 28 e2 94 22 bb 71 70 c8 a6 63 e5 6f |....(..".qp..c.o|
+00000040 2e 00 0f b9 bf 6b 54 34 dc ce b0 12 0b 16 e5 ac |.....kT4........|
+00000050 8f 6b 1e 96 a1 e3 86 b7 6f 8c 76 09 da |.k......o.v..|
+>>> 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 f5 dc 00 28 06 03 50 9b b2 db 4d 89 25 |......(..P...M.%|
+00000020 3a 94 04 85 5b 7a 3f 16 fb 55 8f e0 c3 a3 33 21 |:...[z?..U....3!|
+00000030 65 84 c5 17 03 03 00 25 00 00 00 00 00 00 00 01 |e......%........|
+00000040 a9 35 62 24 4b 63 6e 62 1c 8f 99 e4 e0 3e f0 a2 |.5b$Kcnb.....>..|
+00000050 e3 02 34 6f 10 71 9c 6b b3 4a 2d 7f 71 15 03 03 |..4o.q.k.J-.q...|
+00000060 00 1a 00 00 00 00 00 00 00 02 91 43 07 98 b1 ba |...........C....|
+00000070 06 1b dd 21 46 82 63 67 8b bb 1f b5 |...!F.cg....|
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..2cc2c28
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-RSA-AES256-GCM-SHA384
@@ -0,0 +1,82 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 97 01 00 00 93 03 03 0f 13 d8 49 94 |..............I.|
+00000010 b9 cc 41 1d d4 3d bb d2 c9 a3 2c 74 11 ca 01 e8 |..A..=....,t....|
+00000020 5b b0 2e 57 60 b5 30 37 2d b9 f0 00 00 04 c0 30 |[..W`.07-......0|
+00000030 00 ff 01 00 00 66 00 00 00 0e 00 0c 00 00 09 31 |.....f.........1|
+00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........|
+00000050 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................|
+00000060 00 16 00 00 00 17 00 00 00 0d 00 30 00 2e 04 03 |...........0....|
+00000070 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 |................|
+00000080 08 05 08 06 04 01 05 01 06 01 03 03 02 03 03 01 |................|
+00000090 02 01 03 02 02 02 04 02 05 02 06 02 |............|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......|
+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 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................|
+00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0|
+00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.|
+00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......|
+00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G|
+00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R|
+00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000|
+000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000|
+000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....|
+000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0|
+000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......|
+000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.|
+000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].|
+00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...|
+00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....|
+00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4|
+00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..|
+00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. |
+00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...|
+00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....|
+00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....|
+00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..|
+00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.|
+000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....|
+000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......|
+000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0|
+000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM|
+000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...|
+000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example|
+00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..|
+00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[|
+00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..|
+00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..|
+00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.|
+00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....|
+00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.|
+00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...|
+00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=|
+00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 ac 0c |.`.\!.;.........|
+000002a0 00 00 a8 03 00 1d 20 2f e5 7d a3 47 cd 62 43 15 |...... /.}.G.bC.|
+000002b0 28 da ac 5f bb 29 07 30 ff f6 84 af c4 cf c2 ed |(.._.).0........|
+000002c0 90 99 5f 58 cb 3b 74 08 04 00 80 40 f3 67 86 41 |.._X.;t....@.g.A|
+000002d0 93 17 f7 db b2 80 ca 73 f9 f8 45 24 cc 46 57 47 |.......s..E$.FWG|
+000002e0 28 83 19 df e8 63 e7 19 c4 a2 04 85 25 7d ec 55 |(....c......%}.U|
+000002f0 91 d4 df eb 77 53 c2 3b d5 71 1a f7 39 d2 ee b4 |....wS.;.q..9...|
+00000300 06 4b e4 07 b7 fa 8a 8e fa 64 22 83 dd 22 8b b8 |.K.......d".."..|
+00000310 4d a5 1a f5 e3 81 01 81 6a a1 6e 62 54 3a 3a 09 |M.......j.nbT::.|
+00000320 ed 76 f2 5a d3 4e 4b 74 be 46 50 0d 51 77 34 f6 |.v.Z.NKt.FP.Qw4.|
+00000330 02 ef 57 39 29 bf d9 64 ad 65 06 ae a6 8d 94 86 |..W9)..d.e......|
+00000340 84 76 cf 2c 36 98 04 5b a1 59 6c 16 03 03 00 04 |.v.,6..[.Yl.....|
+00000350 0e 00 00 00 |....|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 d5 2b 0e 3c e9 3e |....%...! .+.<.>|
+00000010 e9 b0 3d 86 a9 85 b5 68 af cf 27 cf 4b d4 49 2e |..=....h..'.K.I.|
+00000020 68 f2 9e 3c 32 7c cb fb dc 57 14 03 03 00 01 01 |h..<2|...W......|
+00000030 16 03 03 00 28 5a cc f4 77 38 94 46 7b 39 5d 81 |....(Z..w8.F{9].|
+00000040 be 77 a5 4a 76 c9 46 62 17 0b 2b ea 89 c2 29 bd |.w.Jv.Fb..+...).|
+00000050 4b b0 dd 51 1e b8 7b a9 55 f5 fb b3 6a |K..Q..{.U...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 b9 9b c0 b1 2b 71 af 0b 44 4e 4a cd e8 |.......+q..DNJ..|
+00000020 c6 68 b8 2a d9 67 6f 7f 18 12 22 5c 4b 5c ca 43 |.h.*.go..."\K\.C|
+00000030 ff c1 9d 17 03 03 00 25 00 00 00 00 00 00 00 01 |.......%........|
+00000040 3c ae 33 dd 69 6c 01 a0 d2 a7 91 52 43 f3 78 38 |<.3.il.....RC.x8|
+00000050 94 f4 24 0b 3d c9 bb 5f 02 27 89 bb 9b 15 03 03 |..$.=.._.'......|
+00000060 00 1a 00 00 00 00 00 00 00 02 68 8d d7 d8 2f 95 |..........h.../.|
+00000070 61 09 59 52 0d b8 12 fc 6a 07 28 37 |a.YR....j.(7|
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..47a4ef2
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-RSA-RC4
@@ -0,0 +1,76 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 97 01 00 00 93 03 03 2c 3c 18 04 94 |...........,<...|
+00000010 e0 bb 10 99 7c 0c cd 0e e7 72 bc 83 4d f0 cf d7 |....|....r..M...|
+00000020 4b 8e 2c 8b 52 bf ed 86 65 d2 a3 00 00 04 00 05 |K.,.R...e.......|
+00000030 00 ff 01 00 00 66 00 00 00 0e 00 0c 00 00 09 31 |.....f.........1|
+00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........|
+00000050 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................|
+00000060 00 16 00 00 00 17 00 00 00 0d 00 30 00 2e 04 03 |...........0....|
+00000070 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 |................|
+00000080 08 05 08 06 04 01 05 01 06 01 03 03 02 03 03 01 |................|
+00000090 02 01 03 02 02 02 04 02 05 02 06 02 |............|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......|
+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 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................|
+00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0|
+00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.|
+00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......|
+00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G|
+00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R|
+00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000|
+000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000|
+000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....|
+000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0|
+000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......|
+000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.|
+000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].|
+00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...|
+00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....|
+00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4|
+00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..|
+00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. |
+00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...|
+00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....|
+00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....|
+00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..|
+00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.|
+000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....|
+000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......|
+000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0|
+000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM|
+000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...|
+000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example|
+00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..|
+00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[|
+00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..|
+00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..|
+00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.|
+00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....|
+00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.|
+00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...|
+00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=|
+00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e |.`.\!.;.........|
+000002a0 00 00 00 |...|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 86 10 00 00 82 00 80 a2 43 45 e6 1e |............CE..|
+00000010 08 d3 29 62 0b 40 75 98 a3 f6 68 d7 78 31 b0 c9 |..)b.@u...h.x1..|
+00000020 f4 f8 a6 98 dc d8 72 c1 2a 68 80 26 54 1c 16 af |......r.*h.&T...|
+00000030 9f 67 cf ee 74 de 9e 29 b6 cd 0d eb df aa ea 44 |.g..t..).......D|
+00000040 72 c9 aa fc ff c9 2d 9d bf bc f0 9b c1 7b 0d 5c |r.....-......{.\|
+00000050 69 0c 75 d8 23 09 29 97 f6 38 9c f9 4f 1b 4a d5 |i.u.#.)..8..O.J.|
+00000060 bd 04 d4 15 b3 a6 80 02 a4 11 32 d7 c0 cf 89 1f |..........2.....|
+00000070 93 80 2b 48 49 51 44 b7 77 3c bf b1 a6 87 a3 ff |..+HIQD.w<......|
+00000080 39 37 4a 42 49 92 93 25 0a 51 9a 14 03 03 00 01 |97JBI..%.Q......|
+00000090 01 16 03 03 00 24 b5 c9 d6 9c ec 77 38 d2 30 79 |.....$.....w8.0y|
+000000a0 f1 00 77 31 78 9b e6 ab ed 46 7c c6 e5 26 0b 44 |..w1x....F|..&.D|
+000000b0 fd 30 b0 fe 0c 84 6f 9a cf 57 |.0....o..W|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 24 58 cc 9f 3f ac |..........$X..?.|
+00000010 2e 20 73 c9 5e 13 d3 12 3a 63 1e a9 ee 13 3d 0d |. s.^...:c....=.|
+00000020 51 e9 15 5b 7b 33 92 85 6c fa d6 8a 15 16 dc 17 |Q..[{3..l.......|
+00000030 03 03 00 21 bc af 01 72 48 0c 16 c9 7a c0 3c 27 |...!...rH...z.<'|
+00000040 63 0a f8 34 e4 54 6a 39 39 61 02 bc c2 a0 07 03 |c..4.Tj99a......|
+00000050 fb 2c d0 1b 6a 15 03 03 00 16 98 71 13 a6 5d f5 |.,..j......q..].|
+00000060 7d aa 6d 05 2d a2 dc c0 7b 41 88 36 a2 49 a4 8b |}.m.-...{A.6.I..|
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..b193771
--- /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 60 c3 e9 6a 99 |....Y...U..`..j.|
+00000010 72 7a 1c b9 1e 10 4b 9a 82 d5 ea b9 b0 6f 1e 05 |rz....K......o..|
+00000020 74 a4 35 bb 71 c7 d2 56 87 b8 69 00 00 04 cc a8 |t.5.q..V..i.....|
+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 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......|
+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 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................|
+00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0|
+00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.|
+00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......|
+00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G|
+00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R|
+00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000|
+000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000|
+000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....|
+000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0|
+000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......|
+000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.|
+000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].|
+00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...|
+00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....|
+00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4|
+00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..|
+00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. |
+00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...|
+00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....|
+00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....|
+00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..|
+00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.|
+000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....|
+000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......|
+000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0|
+000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM|
+000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...|
+000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example|
+00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..|
+00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[|
+00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..|
+00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..|
+00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.|
+00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....|
+00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.|
+00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...|
+00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=|
+00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 ac 0c |.`.\!.;.........|
+000002a0 00 00 a8 03 00 1d 20 2f e5 7d a3 47 cd 62 43 15 |...... /.}.G.bC.|
+000002b0 28 da ac 5f bb 29 07 30 ff f6 84 af c4 cf c2 ed |(.._.).0........|
+000002c0 90 99 5f 58 cb 3b 74 04 01 00 80 4e c9 fd 39 89 |.._X.;t....N..9.|
+000002d0 52 c1 6b ba 3b c9 02 35 89 e8 e3 f8 41 15 ee 6d |R.k.;..5....A..m|
+000002e0 f6 08 6d 1a 47 aa 3b 5c 1d 9b 42 9b 50 85 af 56 |..m.G.;\..B.P..V|
+000002f0 a3 99 78 84 7f 06 91 97 e9 33 0d 1d 9b 17 ce 3b |..x......3.....;|
+00000300 30 f2 d0 10 1c b6 e2 7d fd b3 e1 bc 14 7a 1a 96 |0......}.....z..|
+00000310 be b9 dc 0d 29 33 84 5f d1 77 91 0a a1 f2 2b cc |....)3._.w....+.|
+00000320 dc 5e 9b f9 8b e3 34 d2 bd f3 46 b4 0d 97 de 44 |.^....4...F....D|
+00000330 aa 83 10 82 bd ca 83 27 d0 40 a7 b1 64 15 dd 84 |.......'.@..d...|
+00000340 5f 3c d9 62 42 0d 8f a6 19 0f b1 16 03 03 00 04 |_<.bB...........|
+00000350 0e 00 00 00 |....|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 82 3a 50 41 f7 b1 |....%...! .:PA..|
+00000010 0f 97 ba 38 04 db f3 a6 ec 8b d1 db 06 c1 84 89 |...8............|
+00000020 a0 53 84 92 27 a2 53 e8 5d 21 14 03 03 00 01 01 |.S..'.S.]!......|
+00000030 16 03 03 00 20 7d 80 6d 7f a9 28 d6 0d 50 d6 b4 |.... }.m..(..P..|
+00000040 24 d3 92 f8 0b 8e 6b d8 7c 64 9e 6c 87 a9 8e 37 |$.....k.|d.l...7|
+00000050 9e 1b 0b 2d a5 |...-.|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 20 e4 58 cf fb 81 |.......... .X...|
+00000010 be dd 5b 98 97 bd bd 6a f0 76 92 b6 bb 2c 8f a3 |..[....j.v...,..|
+00000020 e5 52 5b 1d f4 17 7b 2a a8 40 26 17 03 03 00 1d |.R[...{*.@&.....|
+00000030 58 ef 4f 1d 98 0f 3d 59 88 df 6e ac c9 37 43 d5 |X.O...=Y..n..7C.|
+00000040 f5 58 b3 7a 62 a3 7d 26 a2 a2 80 23 ef 15 03 03 |.X.zb.}&...#....|
+00000050 00 12 05 b8 57 6a 80 71 b6 a4 58 94 15 f4 2f 0c |....Wj.q..X.../.|
+00000060 8e 76 b2 aa |.v..|
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..af4c069
--- /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 e0 83 fd ef f8 |....[...W.......|
+00000010 cb 41 23 14 36 21 07 eb 4e 01 7d 80 63 e4 b9 45 |.A#.6!..N.}.c..E|
+00000020 f0 84 72 71 9b ac 60 49 6c 70 74 00 00 04 cc a8 |..rq..`Ilpt.....|
+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 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......|
+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 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................|
+00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0|
+00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.|
+00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......|
+00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G|
+00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R|
+00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000|
+000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000|
+000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....|
+000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0|
+000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......|
+000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.|
+000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].|
+00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...|
+00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....|
+00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4|
+00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..|
+00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. |
+00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...|
+00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....|
+00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....|
+00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..|
+00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.|
+000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....|
+000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......|
+000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0|
+000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM|
+000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...|
+000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example|
+00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..|
+00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[|
+00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..|
+00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..|
+00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.|
+00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....|
+00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.|
+00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...|
+00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=|
+00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 ac 0c |.`.\!.;.........|
+000002a0 00 00 a8 03 00 1d 20 2f e5 7d a3 47 cd 62 43 15 |...... /.}.G.bC.|
+000002b0 28 da ac 5f bb 29 07 30 ff f6 84 af c4 cf c2 ed |(.._.).0........|
+000002c0 90 99 5f 58 cb 3b 74 08 04 00 80 58 d3 5f 28 bc |.._X.;t....X._(.|
+000002d0 50 79 b9 3d f1 ac a1 af 52 cd d3 fd e7 75 47 c3 |Py.=....R....uG.|
+000002e0 65 3a 6f 62 22 c2 b5 cc 2b 22 f3 5d 3f b5 b6 9e |e:ob"...+".]?...|
+000002f0 57 bf c7 4e 08 bd fb 5a 17 13 09 1a e9 6c b6 ce |W..N...Z.....l..|
+00000300 b2 0e 88 ae ba a3 a0 b5 2c ff 51 b5 87 95 14 09 |........,.Q.....|
+00000310 6d 9c 73 3f f0 c7 40 6b 4c ca 40 96 d6 44 96 d0 |m.s?..@kL.@..D..|
+00000320 6f b1 a0 1c 4f 66 cc 9b 4f 85 98 3c 03 68 e3 a8 |o...Of..O..<.h..|
+00000330 5b 28 04 fb 1e be 9e 2a 66 c1 6e f1 2e a4 20 08 |[(.....*f.n... .|
+00000340 7e 11 78 7b fc c4 43 af 2a b4 8b 16 03 03 00 04 |~.x{..C.*.......|
+00000350 0e 00 00 00 |....|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 e2 54 7d 82 d2 8d |....%...! .T}...|
+00000010 b8 d6 87 17 ec 2a 64 4e 15 6b b0 b3 01 66 b0 7d |.....*dN.k...f.}|
+00000020 73 20 9f cb 30 9d 3c 27 ac 13 14 03 03 00 01 01 |s ..0.<'........|
+00000030 16 03 03 00 20 fa a0 b7 eb ef 49 97 d5 da f0 9d |.... .....I.....|
+00000040 85 a6 e6 67 f3 30 e8 f0 82 3a 7a c4 3f 76 f6 c5 |...g.0...:z.?v..|
+00000050 8f d3 a5 65 f3 |...e.|
+>>> Flow 4 (server to client)
+00000000 14 03 03 00 01 01 16 03 03 00 20 6b cf 58 e1 52 |.......... k.X.R|
+00000010 e3 2c 05 e6 a3 05 c1 36 02 f0 90 63 bb 86 0f 54 |.,.....6...c...T|
+00000020 61 d7 1a 31 7d bd 08 00 22 71 09 17 03 03 00 1d |a..1}..."q......|
+00000030 4a 8e 05 28 e3 77 31 43 be ac 32 c6 af f2 7b 1c |J..(.w1C..2...{.|
+00000040 ab 11 7f 32 5a 6a eb 76 ac c6 eb f1 dc 15 03 03 |...2Zj.v........|
+00000050 00 12 3a f1 ee a3 6f bf 9b 9e 5e b8 20 76 84 bc |..:...o...^. v..|
+00000060 1e 2e a0 87 |....|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-Resume b/src/crypto/tls/testdata/Server-TLSv12-Resume
new file mode 100644
index 0000000..456fe2a
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-Resume
@@ -0,0 +1,46 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 01 12 01 00 01 0e 03 03 90 27 78 df 71 |............'x.q|
+00000010 d3 0e ce 1d de ec d2 1b 70 e0 89 da 98 a9 45 3e |........p.....E>|
+00000020 9c ee 93 90 8f 61 d0 a3 b4 a4 5a 20 9d cd d4 81 |.....a....Z ....|
+00000030 e2 c0 59 81 21 bc 9f 2a 84 3e 91 15 3e b9 c0 a1 |..Y.!..*.>..>...|
+00000040 e0 6b 73 9c 45 53 03 ad b9 e6 c2 77 00 04 00 2f |.ks.ES.....w.../|
+00000050 00 ff 01 00 00 c1 00 23 00 81 50 46 ad c1 db a8 |.......#..PF....|
+00000060 38 86 7b 2b bb fd d0 c3 42 3e 00 00 00 00 00 00 |8.{+....B>......|
+00000070 00 00 00 00 00 00 00 00 00 00 94 6f 2c 9f 83 51 |...........o,..Q|
+00000080 ed 14 ef 68 ca 42 c5 4c 75 5e a5 6f d2 49 61 e4 |...h.B.Lu^.o.Ia.|
+00000090 fb 83 46 7c 4c ab f9 c6 d1 3c 9e 5b 8d d8 bc c0 |..F|L....<.[....|
+000000a0 a5 2d 84 db 24 dd a0 16 60 1d 87 a0 52 88 25 6c |.-..$...`...R.%l|
+000000b0 c6 8e 5b 71 0f 74 c3 48 49 38 16 92 8c de 77 bd |..[q.t.HI8....w.|
+000000c0 8a 2b 45 4d 58 86 40 b1 d6 0f 99 de 27 41 b2 41 |.+EMX.@.....'A.A|
+000000d0 27 aa fe 26 e9 24 91 2a 00 ff 08 00 16 00 00 00 |'..&.$.*........|
+000000e0 17 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 08 |......0.........|
+000000f0 07 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 04 |................|
+00000100 01 05 01 06 01 03 03 02 03 03 01 02 01 03 02 02 |................|
+00000110 02 04 02 05 02 06 02 |.......|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 51 02 00 00 4d 03 03 00 00 00 00 00 |....Q...M.......|
+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 9d cd d4 81 |...DOWNGRD. ....|
+00000030 e2 c0 59 81 21 bc 9f 2a 84 3e 91 15 3e b9 c0 a1 |..Y.!..*.>..>...|
+00000040 e0 6b 73 9c 45 53 03 ad b9 e6 c2 77 00 2f 00 00 |.ks.ES.....w./..|
+00000050 05 ff 01 00 01 00 14 03 03 00 01 01 16 03 03 00 |................|
+00000060 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |@...............|
+00000070 00 57 8e 5f 0a f6 3f 3b 43 f1 33 bc ef 5e c6 8d |.W._..?;C.3..^..|
+00000080 86 92 58 58 71 51 e8 54 57 96 5f bd 36 3a 9f d3 |..XXqQ.TW._.6:..|
+00000090 e9 27 01 bf fb 6a 05 57 de 2d db b2 79 38 72 95 |.'...j.W.-..y8r.|
+000000a0 fd |.|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 16 03 03 00 40 6d 3c 76 31 a4 |..........@m<v1.|
+00000010 c5 41 d4 67 9f 20 7d 3e f4 35 76 02 ef a2 4b 18 |.A.g. }>.5v...K.|
+00000020 01 f8 a8 83 0c eb 58 f7 d6 93 c6 b6 40 0e c8 24 |......X.....@..$|
+00000030 46 58 0c 79 4a c6 b4 15 65 1e 9c bd ff 51 4d d0 |FX.yJ...e....QM.|
+00000040 44 66 fe c0 98 d5 26 11 98 cf 52 |Df....&...R|
+>>> 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 4e 8e bd e5 c8 d4 1a 14 00 f1 ed |.....N..........|
+00000020 c4 88 b3 5c 92 b9 ad 8a 68 d4 f3 85 1b 02 25 aa |...\....h.....%.|
+00000030 a0 65 49 08 0d 2a b4 0a 64 eb ea ab 06 73 08 ca |.eI..*..d....s..|
+00000040 62 c9 56 45 a9 15 03 03 00 30 00 00 00 00 00 00 |b.VE.....0......|
+00000050 00 00 00 00 00 00 00 00 00 00 60 51 ae 81 79 6d |..........`Q..ym|
+00000060 91 95 02 42 30 3f c4 3c 2b fc 74 47 a7 a9 17 22 |...B0?.<+.tG..."|
+00000070 88 26 6d 18 b9 8f ad 43 e3 b0 |.&m....C..|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-ResumeDisabled b/src/crypto/tls/testdata/Server-TLSv12-ResumeDisabled
new file mode 100644
index 0000000..339fd9a
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-ResumeDisabled
@@ -0,0 +1,91 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 01 12 01 00 01 0e 03 03 b8 aa 9b e6 98 |................|
+00000010 be 93 d6 03 f2 cd 62 23 76 dd 74 6c 48 ac 9a f6 |......b#v.tlH...|
+00000020 f3 27 62 93 6e 99 b2 0d 54 af b7 20 2d 20 97 9a |.'b.n...T.. - ..|
+00000030 c8 88 50 65 95 2a 02 8f 7b 47 77 6d 3c 49 ba a9 |..Pe.*..{Gwm<I..|
+00000040 0c 8a 68 0d b9 30 64 c9 c1 f0 d4 61 00 04 00 2f |..h..0d....a.../|
+00000050 00 ff 01 00 00 c1 00 23 00 81 50 46 ad c1 db a8 |.......#..PF....|
+00000060 38 86 7b 2b bb fd d0 c3 42 3e 00 00 00 00 00 00 |8.{+....B>......|
+00000070 00 00 00 00 00 00 00 00 00 00 94 6f 2c 9f 83 51 |...........o,..Q|
+00000080 ed 14 ef 68 ca 42 c5 4c 20 33 6c 01 97 a5 69 44 |...h.B.L 3l...iD|
+00000090 bf 8f ea db 83 05 fb ef cc 51 1f 0b 4d 44 77 89 |.........Q..MDw.|
+000000a0 11 cf c8 38 16 67 ea a2 3e 8b 2a 18 f2 f7 25 ce |...8.g..>.*...%.|
+000000b0 e0 d8 4c 93 31 b0 59 23 49 38 16 3a f9 63 9e 61 |..L.1.Y#I8.:.c.a|
+000000c0 21 1b ab 67 09 6a 23 07 8e d0 4a 19 78 9c 1e 60 |!..g.j#...J.x..`|
+000000d0 40 a7 83 c5 9a 48 41 35 c4 e9 63 00 16 00 00 00 |@....HA5..c.....|
+000000e0 17 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 08 |......0.........|
+000000f0 07 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 04 |................|
+00000100 01 05 01 06 01 03 03 02 03 03 01 02 01 03 02 02 |................|
+00000110 02 04 02 05 02 06 02 |.......|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 31 02 00 00 2d 03 03 00 00 00 00 00 |....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 05 ff 01 00 01 00 16 03 03 02 59 0b 00 02 55 00 |..........Y...U.|
+00000040 02 52 00 02 4f 30 82 02 4b 30 82 01 b4 a0 03 02 |.R..O0..K0......|
+00000050 01 02 02 09 00 e8 f0 9d 3f e2 5b ea a6 30 0d 06 |........?.[..0..|
+00000060 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 1f 31 0b |.*.H........0.1.|
+00000070 30 09 06 03 55 04 0a 13 02 47 6f 31 10 30 0e 06 |0...U....Go1.0..|
+00000080 03 55 04 03 13 07 47 6f 20 52 6f 6f 74 30 1e 17 |.U....Go Root0..|
+00000090 0d 31 36 30 31 30 31 30 30 30 30 30 30 5a 17 0d |.160101000000Z..|
+000000a0 32 35 30 31 30 31 30 30 30 30 30 30 5a 30 1a 31 |250101000000Z0.1|
+000000b0 0b 30 09 06 03 55 04 0a 13 02 47 6f 31 0b 30 09 |.0...U....Go1.0.|
+000000c0 06 03 55 04 03 13 02 47 6f 30 81 9f 30 0d 06 09 |..U....Go0..0...|
+000000d0 2a 86 48 86 f7 0d 01 01 01 05 00 03 81 8d 00 30 |*.H............0|
+000000e0 81 89 02 81 81 00 db 46 7d 93 2e 12 27 06 48 bc |.......F}...'.H.|
+000000f0 06 28 21 ab 7e c4 b6 a2 5d fe 1e 52 45 88 7a 36 |.(!.~...]..RE.z6|
+00000100 47 a5 08 0d 92 42 5b c2 81 c0 be 97 79 98 40 fb |G....B[.....y.@.|
+00000110 4f 6d 14 fd 2b 13 8b c2 a5 2e 67 d8 d4 09 9e d6 |Om..+.....g.....|
+00000120 22 38 b7 4a 0b 74 73 2b c2 34 f1 d1 93 e5 96 d9 |"8.J.ts+.4......|
+00000130 74 7b f3 58 9f 6c 61 3c c0 b0 41 d4 d9 2b 2b 24 |t{.X.la<..A..++$|
+00000140 23 77 5b 1c 3b bd 75 5d ce 20 54 cf a1 63 87 1d |#w[.;.u]. T..c..|
+00000150 1e 24 c4 f3 1d 1a 50 8b aa b6 14 43 ed 97 a7 75 |.$....P....C...u|
+00000160 62 f4 14 c8 52 d7 02 03 01 00 01 a3 81 93 30 81 |b...R.........0.|
+00000170 90 30 0e 06 03 55 1d 0f 01 01 ff 04 04 03 02 05 |.0...U..........|
+00000180 a0 30 1d 06 03 55 1d 25 04 16 30 14 06 08 2b 06 |.0...U.%..0...+.|
+00000190 01 05 05 07 03 01 06 08 2b 06 01 05 05 07 03 02 |........+.......|
+000001a0 30 0c 06 03 55 1d 13 01 01 ff 04 02 30 00 30 19 |0...U.......0.0.|
+000001b0 06 03 55 1d 0e 04 12 04 10 9f 91 16 1f 43 43 3e |..U..........CC>|
+000001c0 49 a6 de 6d b6 80 d7 9f 60 30 1b 06 03 55 1d 23 |I..m....`0...U.#|
+000001d0 04 14 30 12 80 10 48 13 49 4d 13 7e 16 31 bb a3 |..0...H.IM.~.1..|
+000001e0 01 d5 ac ab 6e 7b 30 19 06 03 55 1d 11 04 12 30 |....n{0...U....0|
+000001f0 10 82 0e 65 78 61 6d 70 6c 65 2e 67 6f 6c 61 6e |...example.golan|
+00000200 67 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 |g0...*.H........|
+00000210 03 81 81 00 9d 30 cc 40 2b 5b 50 a0 61 cb ba e5 |.....0.@+[P.a...|
+00000220 53 58 e1 ed 83 28 a9 58 1a a9 38 a4 95 a1 ac 31 |SX...(.X..8....1|
+00000230 5a 1a 84 66 3d 43 d3 2d d9 0b f2 97 df d3 20 64 |Z..f=C.-...... d|
+00000240 38 92 24 3a 00 bc cf 9c 7d b7 40 20 01 5f aa d3 |8.$:....}.@ ._..|
+00000250 16 61 09 a2 76 fd 13 c3 cc e1 0c 5c ee b1 87 82 |.a..v......\....|
+00000260 f1 6c 04 ed 73 bb b3 43 77 8d 0c 1c f1 0f a1 d8 |.l..s..Cw.......|
+00000270 40 83 61 c9 4c 72 2b 9d ae db 46 06 06 4d f4 c1 |@.a.Lr+...F..M..|
+00000280 b3 3e c0 d1 bd 42 d4 db fe 3d 13 60 84 5c 21 d3 |.>...B...=.`.\!.|
+00000290 3b e9 fa e7 16 03 03 00 04 0e 00 00 00 |;............|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 86 10 00 00 82 00 80 1f e2 43 ee 88 |.............C..|
+00000010 22 0d a0 66 18 ce 8a 04 d1 00 fc 2b 6b 93 d5 b6 |"..f.......+k...|
+00000020 fd 13 48 fd ea 19 d8 5d 02 bf 8c d9 fb 64 e8 17 |..H....].....d..|
+00000030 a3 49 dc 1d 4d b7 8c eb 7d 8b 1d 13 20 78 4e 02 |.I..M...}... xN.|
+00000040 49 7e a5 bd dd 57 ac 45 47 e6 ea 2e 87 6f d2 ca |I~...W.EG....o..|
+00000050 e6 ef a4 9e 2d 3a 02 22 2e 67 6f ff 2d 78 6c 7d |....-:.".go.-xl}|
+00000060 33 a1 4c 5b ec d5 ae cb 4f db c0 7d 75 01 61 fa |3.L[....O..}u.a.|
+00000070 c2 8a dc 75 77 51 60 90 5d 35 45 ca 13 bb 1a c4 |...uwQ`.]5E.....|
+00000080 eb f3 74 ef 77 ec 23 ec 98 30 3c 14 03 03 00 01 |..t.w.#..0<.....|
+00000090 01 16 03 03 00 40 7a 07 bc 74 d3 6f ef 93 22 69 |.....@z..t.o.."i|
+000000a0 a8 05 df df db 5e 58 1e 4b 84 4f 20 7c f5 2c c3 |.....^X.K.O |.,.|
+000000b0 0d 51 0a a8 d0 a8 f0 07 02 d5 ca ec f2 4b 3f ef |.Q...........K?.|
+000000c0 c9 57 cb 9b 26 2e 62 e7 f2 84 6e ed b9 6e 1d 15 |.W..&.b...n..n..|
+000000d0 32 8c d6 b8 0d 8a |2.....|
+>>> 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 67 e1 22 17 24 |...........g.".$|
+00000020 95 b4 e5 62 59 15 56 4a af e4 82 76 ad b7 48 81 |...bY.VJ...v..H.|
+00000030 cf 55 d1 75 cd 36 86 0d 9d 15 24 4b 84 23 bc 98 |.U.u.6....$K.#..|
+00000040 8e c4 62 57 ab 96 0c 27 5d 1c 07 17 03 03 00 40 |..bW...']......@|
+00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000060 c9 b2 0e 04 40 43 26 92 91 45 e3 63 d7 49 09 3e |....@C&..E.c.I.>|
+00000070 03 45 e3 d6 af a2 d8 d9 61 36 e5 95 83 75 66 fa |.E......a6...uf.|
+00000080 90 c2 80 53 a2 d5 31 aa b1 2a da 45 a9 b3 aa 1f |...S..1..*.E....|
+00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
+000000a0 00 00 00 00 00 c4 52 cf b9 f6 0f e2 30 ba 90 18 |......R.....0...|
+000000b0 0c 76 c2 ee 4c 78 fb c2 cb 34 7f cb 35 15 5e b0 |.v..Lx...4..5.^.|
+000000c0 17 70 cb 76 8a |.p.v.|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-SNI b/src/crypto/tls/testdata/Server-TLSv12-SNI
new file mode 100644
index 0000000..0ea8375
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-SNI
@@ -0,0 +1,84 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 99 01 00 00 95 03 03 fb d6 71 b2 32 |.............q.2|
+00000010 74 6c e1 56 19 42 e6 46 a2 0e 37 1f ad 96 4b af |tl.V.B.F..7...K.|
+00000020 8b 4c aa 71 2a 53 d8 df 74 7d 39 00 00 04 00 2f |.L.q*S..t}9..../|
+00000030 00 ff 01 00 00 68 00 00 00 10 00 0e 00 00 0b 73 |.....h.........s|
+00000040 6e 69 74 65 73 74 2e 63 6f 6d 00 0b 00 04 03 00 |nitest.com......|
+00000050 01 02 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 |................|
+00000060 00 18 00 16 00 00 00 17 00 00 00 0d 00 30 00 2e |.............0..|
+00000070 04 03 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b |................|
+00000080 08 04 08 05 08 06 04 01 05 01 06 01 03 03 02 03 |................|
+00000090 03 01 02 01 03 02 02 02 04 02 05 02 06 02 |..............|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......|
+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 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................|
+00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0|
+00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.|
+00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......|
+00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G|
+00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R|
+00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000|
+000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000|
+000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....|
+000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0|
+000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......|
+000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.|
+000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].|
+00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...|
+00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....|
+00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4|
+00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..|
+00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. |
+00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...|
+00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....|
+00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....|
+00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..|
+00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.|
+000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....|
+000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......|
+000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0|
+000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM|
+000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...|
+000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example|
+00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..|
+00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[|
+00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..|
+00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..|
+00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.|
+00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....|
+00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.|
+00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...|
+00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=|
+00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e |.`.\!.;.........|
+000002a0 00 00 00 |...|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 86 10 00 00 82 00 80 a4 48 88 75 7b |............H.u{|
+00000010 a2 04 19 14 69 30 12 d6 14 00 0c 44 e4 68 06 c6 |....i0.....D.h..|
+00000020 11 56 53 0c e5 52 fb 84 e2 6e b7 c6 eb 0d 79 25 |.VS..R...n....y%|
+00000030 19 f0 bf e4 51 73 85 d5 82 5a 07 53 b2 65 97 6a |....Qs...Z.S.e.j|
+00000040 a1 1b 56 bb 23 35 15 83 0f 60 ee de 16 a2 ea 61 |..V.#5...`.....a|
+00000050 23 10 e1 5e cf 73 fe 5d 5a 53 16 42 0c 29 a5 ff |#..^.s.]ZS.B.)..|
+00000060 06 e5 c4 87 11 d6 24 91 25 e5 58 81 40 80 9e 71 |......$.%.X.@..q|
+00000070 49 40 47 50 37 28 7b ed 76 cc 5a fb 04 ba 9c f8 |I@GP7({.v.Z.....|
+00000080 be ce 87 07 75 d2 30 88 09 cf bc 14 03 03 00 01 |....u.0.........|
+00000090 01 16 03 03 00 40 60 1c 31 95 7d c2 a9 9b 29 c2 |.....@`.1.}...).|
+000000a0 ef 59 58 dd fb 26 34 81 60 dc 17 19 c1 23 8d 8f |.YX..&4.`....#..|
+000000b0 a8 d2 62 31 96 3d d2 61 b9 c8 7e bf 47 4c 04 fd |..b1.=.a..~.GL..|
+000000c0 7c 30 05 37 8e 03 df 13 a1 4d f1 81 05 d7 4c 49 ||0.7.....M....LI|
+000000d0 88 d6 c0 21 52 e3 |...!R.|
+>>> 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 73 15 54 76 ad |...........s.Tv.|
+00000020 c4 38 b0 40 45 32 a8 ca 05 19 bd ce 6e 39 77 6b |.8.@E2......n9wk|
+00000030 46 a7 f8 45 a8 cd cd 98 8c aa cf 46 83 f0 20 93 |F..E.......F.. .|
+00000040 0d 18 99 d4 2a f9 15 4a 2b f6 bf 17 03 03 00 40 |....*..J+......@|
+00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000060 79 8d 24 ef 72 b3 2c e2 10 a5 6d 3d 61 6c df c1 |y.$.r.,...m=al..|
+00000070 26 bf 7e b5 cd b2 8e 87 b9 54 bf ee 35 07 bc 55 |&.~......T..5..U|
+00000080 6c cd a2 d3 b4 bb 8c 63 fd ef b1 f0 2f 6d aa d9 |l......c..../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 7b f7 81 e6 5c f2 5c 9d 45 ec 1f |.....{...\.\.E..|
+000000b0 7b 0d f8 62 19 d4 83 a8 e5 90 71 03 6e 6a 72 4b |{..b......q.njrK|
+000000c0 7e 64 c4 c4 1a |~d...|
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..199253f
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-SNI-GetCertificate
@@ -0,0 +1,84 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 99 01 00 00 95 03 03 cf 09 e7 0d ce |................|
+00000010 ce d4 72 66 9d 30 e8 ee 39 b3 95 4c 3b 59 25 66 |..rf.0..9..L;Y%f|
+00000020 d2 f5 d3 82 68 7d e7 26 2e 38 97 00 00 04 00 2f |....h}.&.8...../|
+00000030 00 ff 01 00 00 68 00 00 00 10 00 0e 00 00 0b 73 |.....h.........s|
+00000040 6e 69 74 65 73 74 2e 63 6f 6d 00 0b 00 04 03 00 |nitest.com......|
+00000050 01 02 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 |................|
+00000060 00 18 00 16 00 00 00 17 00 00 00 0d 00 30 00 2e |.............0..|
+00000070 04 03 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b |................|
+00000080 08 04 08 05 08 06 04 01 05 01 06 01 03 03 02 03 |................|
+00000090 03 01 02 01 03 02 02 02 04 02 05 02 06 02 |..............|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......|
+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 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................|
+00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0|
+00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.|
+00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......|
+00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G|
+00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R|
+00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000|
+000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000|
+000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....|
+000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0|
+000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......|
+000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.|
+000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].|
+00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...|
+00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....|
+00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4|
+00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..|
+00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. |
+00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...|
+00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....|
+00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....|
+00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..|
+00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.|
+000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....|
+000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......|
+000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0|
+000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM|
+000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...|
+000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example|
+00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..|
+00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[|
+00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..|
+00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..|
+00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.|
+00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....|
+00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.|
+00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...|
+00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=|
+00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e |.`.\!.;.........|
+000002a0 00 00 00 |...|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 86 10 00 00 82 00 80 04 57 b2 56 f0 |............W.V.|
+00000010 a5 fb c3 4d 4e 7d ba 29 18 04 ea 6e 66 d3 97 68 |...MN}.)...nf..h|
+00000020 58 4e c1 47 fe 30 42 4d bf 5b 10 38 6a 01 83 98 |XN.G.0BM.[.8j...|
+00000030 2b e3 3a ac c8 67 e5 41 0c 5c 3f 88 d5 15 a2 ab |+.:..g.A.\?.....|
+00000040 6a 2b 70 24 d8 40 78 c1 d9 58 78 04 4d 90 03 eb |j+p$.@x..Xx.M...|
+00000050 3c b1 61 da 26 62 db b3 41 ab dc 94 22 44 66 b8 |<.a.&b..A..."Df.|
+00000060 49 2c fa 59 de c0 69 3c 20 f8 2f a5 e0 47 1d ec |I,.Y..i< ./..G..|
+00000070 3c 49 2d 39 f6 41 09 06 79 5f 26 c4 12 3d 9c 8d |<I-9.A..y_&..=..|
+00000080 16 7b 45 25 65 01 69 9c a8 f7 90 14 03 03 00 01 |.{E%e.i.........|
+00000090 01 16 03 03 00 40 96 71 33 e6 7e 26 2c 52 9b a5 |.....@.q3.~&,R..|
+000000a0 b3 d2 4e a3 6a 8f 9f 2a ec c6 23 51 6c 92 5d dd |..N.j..*..#Ql.].|
+000000b0 6e dd f2 5f 28 5e 8d e4 1f 80 35 16 84 59 0f 36 |n.._(^....5..Y.6|
+000000c0 ce a4 36 16 18 09 a8 30 8b 73 f6 22 0a 8f 22 28 |..6....0.s.".."(|
+000000d0 00 62 d2 8e 19 82 |.b....|
+>>> 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 5e ea d1 03 d7 |...........^....|
+00000020 de 82 9a b4 07 52 46 16 fd 28 86 fe 17 2e 77 52 |.....RF..(....wR|
+00000030 67 8f ec 64 93 1e 8e c9 fc fb 69 61 47 78 1a 1b |g..d......iaGx..|
+00000040 97 8d fc 56 76 f6 53 8b 62 53 4f 17 03 03 00 40 |...Vv.S.bSO....@|
+00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000060 f8 17 e8 ba c4 fb 0b 76 f5 a8 2d 3c 48 44 73 da |.......v..-<HDs.|
+00000070 dc 34 5d fe e4 23 85 28 38 df 1d fe c6 a6 32 35 |.4]..#.(8.....25|
+00000080 c6 bb 71 4a 6e ec e7 c4 4f e6 28 2b fc 06 5e ac |..qJn...O.(+..^.|
+00000090 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
+000000a0 00 00 00 00 00 b0 5a ef 20 24 de e4 16 ad 7e 54 |......Z. $....~T|
+000000b0 43 d1 22 a8 fb a6 a4 98 54 74 58 2d 5c af 34 24 |C.".....TtX-\.4$|
+000000c0 89 d1 ab 32 8b |...2.|
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..870e8fa
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-SNI-GetCertificateNotFound
@@ -0,0 +1,84 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 99 01 00 00 95 03 03 34 7d 89 eb 2a |...........4}..*|
+00000010 19 64 32 17 5d 37 0e dd 51 2c 7e 08 56 47 f3 2c |.d2.]7..Q,~.VG.,|
+00000020 ca d0 08 51 86 a6 a3 10 85 5a 41 00 00 04 00 2f |...Q.....ZA..../|
+00000030 00 ff 01 00 00 68 00 00 00 10 00 0e 00 00 0b 73 |.....h.........s|
+00000040 6e 69 74 65 73 74 2e 63 6f 6d 00 0b 00 04 03 00 |nitest.com......|
+00000050 01 02 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 |................|
+00000060 00 18 00 16 00 00 00 17 00 00 00 0d 00 30 00 2e |.............0..|
+00000070 04 03 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b |................|
+00000080 08 04 08 05 08 06 04 01 05 01 06 01 03 03 02 03 |................|
+00000090 03 01 02 01 03 02 02 02 04 02 05 02 06 02 |..............|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......|
+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 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................|
+00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0|
+00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.|
+00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......|
+00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G|
+00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R|
+00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000|
+000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000|
+000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....|
+000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0|
+000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......|
+000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.|
+000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].|
+00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...|
+00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....|
+00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4|
+00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..|
+00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. |
+00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...|
+00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....|
+00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....|
+00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..|
+00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.|
+000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....|
+000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......|
+000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0|
+000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM|
+000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...|
+000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example|
+00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..|
+00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[|
+00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..|
+00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..|
+00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.|
+00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....|
+00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.|
+00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...|
+00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=|
+00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 04 0e |.`.\!.;.........|
+000002a0 00 00 00 |...|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 86 10 00 00 82 00 80 38 86 92 3e 9a |...........8..>.|
+00000010 54 2d 44 46 76 d1 7c 07 04 83 2f 19 6d 89 c6 95 |T-DFv.|.../.m...|
+00000020 07 63 17 7d ac e5 f7 95 7f f7 f2 3a f6 eb 38 26 |.c.}.......:..8&|
+00000030 e5 c9 32 b1 27 88 46 85 f8 f6 eb 27 a8 9e de 5b |..2.'.F....'...[|
+00000040 92 f7 3f 03 be 73 f0 de 2e b4 44 a8 89 4a 5a 6f |..?..s....D..JZo|
+00000050 dc e7 16 9c dc f7 9f ca 40 9e 34 4b c2 45 58 7a |........@.4K.EXz|
+00000060 6d 5c 4c 58 6a 45 10 21 fb b5 2a 58 17 7d d9 c4 |m\LXjE.!..*X.}..|
+00000070 c9 7d d1 3b df 39 1b 59 6a 49 18 e1 fd 02 a2 1d |.}.;.9.YjI......|
+00000080 5a 2d 3d c5 ab e7 f6 60 0d aa 38 14 03 03 00 01 |Z-=....`..8.....|
+00000090 01 16 03 03 00 40 0e 2a fd e7 cd d0 72 ce 06 5c |.....@.*....r..\|
+000000a0 40 c1 81 ef eb 27 e9 77 a8 d4 cc 5c 1e 15 7c 62 |@....'.w...\..|b|
+000000b0 87 bd c5 8e b4 e6 6a 3f be 37 9d c0 fe f7 65 8b |......j?.7....e.|
+000000c0 b1 3a b8 b4 76 67 ca 58 1c f5 3f f1 10 7c 5b 57 |.:..vg.X..?..|[W|
+000000d0 90 e6 43 de d6 25 |..C..%|
+>>> 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 8b 11 9a 67 af |..............g.|
+00000020 5b 0e c9 01 dc 76 e8 48 2f 40 5c 76 13 ca 28 63 |[....v.H/@\v..(c|
+00000030 a9 6d 3c 6b c1 d4 79 4d 39 17 55 a5 b9 0e b6 fd |.m<k..yM9.U.....|
+00000040 9b 1a 8c 62 98 34 3c 85 b9 2b 40 17 03 03 00 40 |...b.4<..+@....@|
+00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000060 5e 82 20 cb bc 9a fd 36 13 3d aa 1b d6 72 df cb |^. ....6.=...r..|
+00000070 09 e1 2f 85 6c 99 12 36 73 f3 c7 44 47 d7 60 19 |../.l..6s..DG.`.|
+00000080 2e 59 23 7d fa 16 b9 64 40 ed 96 79 66 b7 97 4c |.Y#}...d@..yf..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 88 a2 85 5b 80 7d ee 4a 63 be da |........[.}.Jc..|
+000000b0 e4 8f cd 6f 1d f4 03 da ee 7c 29 2b d0 2d 3e 1c |...o.....|)+.->.|
+000000c0 b2 ea 47 71 1f |..Gq.|
diff --git a/src/crypto/tls/testdata/Server-TLSv12-X25519 b/src/crypto/tls/testdata/Server-TLSv12-X25519
new file mode 100644
index 0000000..c196336
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv12-X25519
@@ -0,0 +1,82 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 8f 01 00 00 8b 03 03 5d ff d6 27 db |...........]..'.|
+00000010 3b e5 2b 79 3a a6 cf 75 3d f7 c9 d9 0a d4 8c b2 |;.+y:..u=.......|
+00000020 af 3c 29 84 65 a2 d6 98 52 e2 eb 00 00 04 c0 2f |.<).e...R....../|
+00000030 00 ff 01 00 00 5e 00 00 00 0e 00 0c 00 00 09 31 |.....^.........1|
+00000040 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........|
+00000050 00 0a 00 04 00 02 00 1d 00 16 00 00 00 17 00 00 |................|
+00000060 00 0d 00 30 00 2e 04 03 05 03 06 03 08 07 08 08 |...0............|
+00000070 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 |................|
+00000080 06 01 03 03 02 03 03 01 02 01 03 02 02 02 04 02 |................|
+00000090 05 02 06 02 |....|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 37 02 00 00 33 03 03 00 00 00 00 00 |....7...3.......|
+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 0b ff 01 00 01 00 00 0b 00 02 01 00 16 03 03 02 |................|
+00000040 59 0b 00 02 55 00 02 52 00 02 4f 30 82 02 4b 30 |Y...U..R..O0..K0|
+00000050 82 01 b4 a0 03 02 01 02 02 09 00 e8 f0 9d 3f e2 |..............?.|
+00000060 5b ea a6 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b |[..0...*.H......|
+00000070 05 00 30 1f 31 0b 30 09 06 03 55 04 0a 13 02 47 |..0.1.0...U....G|
+00000080 6f 31 10 30 0e 06 03 55 04 03 13 07 47 6f 20 52 |o1.0...U....Go R|
+00000090 6f 6f 74 30 1e 17 0d 31 36 30 31 30 31 30 30 30 |oot0...160101000|
+000000a0 30 30 30 5a 17 0d 32 35 30 31 30 31 30 30 30 30 |000Z..2501010000|
+000000b0 30 30 5a 30 1a 31 0b 30 09 06 03 55 04 0a 13 02 |00Z0.1.0...U....|
+000000c0 47 6f 31 0b 30 09 06 03 55 04 03 13 02 47 6f 30 |Go1.0...U....Go0|
+000000d0 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 |..0...*.H.......|
+000000e0 00 03 81 8d 00 30 81 89 02 81 81 00 db 46 7d 93 |.....0.......F}.|
+000000f0 2e 12 27 06 48 bc 06 28 21 ab 7e c4 b6 a2 5d fe |..'.H..(!.~...].|
+00000100 1e 52 45 88 7a 36 47 a5 08 0d 92 42 5b c2 81 c0 |.RE.z6G....B[...|
+00000110 be 97 79 98 40 fb 4f 6d 14 fd 2b 13 8b c2 a5 2e |..y.@.Om..+.....|
+00000120 67 d8 d4 09 9e d6 22 38 b7 4a 0b 74 73 2b c2 34 |g....."8.J.ts+.4|
+00000130 f1 d1 93 e5 96 d9 74 7b f3 58 9f 6c 61 3c c0 b0 |......t{.X.la<..|
+00000140 41 d4 d9 2b 2b 24 23 77 5b 1c 3b bd 75 5d ce 20 |A..++$#w[.;.u]. |
+00000150 54 cf a1 63 87 1d 1e 24 c4 f3 1d 1a 50 8b aa b6 |T..c...$....P...|
+00000160 14 43 ed 97 a7 75 62 f4 14 c8 52 d7 02 03 01 00 |.C...ub...R.....|
+00000170 01 a3 81 93 30 81 90 30 0e 06 03 55 1d 0f 01 01 |....0..0...U....|
+00000180 ff 04 04 03 02 05 a0 30 1d 06 03 55 1d 25 04 16 |.......0...U.%..|
+00000190 30 14 06 08 2b 06 01 05 05 07 03 01 06 08 2b 06 |0...+.........+.|
+000001a0 01 05 05 07 03 02 30 0c 06 03 55 1d 13 01 01 ff |......0...U.....|
+000001b0 04 02 30 00 30 19 06 03 55 1d 0e 04 12 04 10 9f |..0.0...U.......|
+000001c0 91 16 1f 43 43 3e 49 a6 de 6d b6 80 d7 9f 60 30 |...CC>I..m....`0|
+000001d0 1b 06 03 55 1d 23 04 14 30 12 80 10 48 13 49 4d |...U.#..0...H.IM|
+000001e0 13 7e 16 31 bb a3 01 d5 ac ab 6e 7b 30 19 06 03 |.~.1......n{0...|
+000001f0 55 1d 11 04 12 30 10 82 0e 65 78 61 6d 70 6c 65 |U....0...example|
+00000200 2e 67 6f 6c 61 6e 67 30 0d 06 09 2a 86 48 86 f7 |.golang0...*.H..|
+00000210 0d 01 01 0b 05 00 03 81 81 00 9d 30 cc 40 2b 5b |...........0.@+[|
+00000220 50 a0 61 cb ba e5 53 58 e1 ed 83 28 a9 58 1a a9 |P.a...SX...(.X..|
+00000230 38 a4 95 a1 ac 31 5a 1a 84 66 3d 43 d3 2d d9 0b |8....1Z..f=C.-..|
+00000240 f2 97 df d3 20 64 38 92 24 3a 00 bc cf 9c 7d b7 |.... d8.$:....}.|
+00000250 40 20 01 5f aa d3 16 61 09 a2 76 fd 13 c3 cc e1 |@ ._...a..v.....|
+00000260 0c 5c ee b1 87 82 f1 6c 04 ed 73 bb b3 43 77 8d |.\.....l..s..Cw.|
+00000270 0c 1c f1 0f a1 d8 40 83 61 c9 4c 72 2b 9d ae db |......@.a.Lr+...|
+00000280 46 06 06 4d f4 c1 b3 3e c0 d1 bd 42 d4 db fe 3d |F..M...>...B...=|
+00000290 13 60 84 5c 21 d3 3b e9 fa e7 16 03 03 00 ac 0c |.`.\!.;.........|
+000002a0 00 00 a8 03 00 1d 20 2f e5 7d a3 47 cd 62 43 15 |...... /.}.G.bC.|
+000002b0 28 da ac 5f bb 29 07 30 ff f6 84 af c4 cf c2 ed |(.._.).0........|
+000002c0 90 99 5f 58 cb 3b 74 08 04 00 80 73 d6 a4 35 5f |.._X.;t....s..5_|
+000002d0 3f 46 ad de 81 13 a8 d9 21 17 25 37 61 cb 62 0d |?F......!.%7a.b.|
+000002e0 e2 bf 95 51 0e 9e e7 b1 ab bc be f6 ec 80 b1 f4 |...Q............|
+000002f0 3e 9c 69 3f c8 1e a4 02 82 fd 57 01 e7 0c 18 be |>.i?......W.....|
+00000300 c6 1b 01 68 cb ef dc d8 16 92 fb 1b 07 fd 98 f8 |...h............|
+00000310 00 77 a9 8e 71 2a e0 6c 68 d5 83 f9 36 c3 3b 99 |.w..q*.lh...6.;.|
+00000320 44 98 a0 96 00 1a 02 95 c5 7c ea ae 51 81 89 94 |D........|..Q...|
+00000330 57 b6 37 c5 88 56 9f 49 bf 36 26 48 08 36 a1 69 |W.7..V.I.6&H.6.i|
+00000340 48 a2 c4 b2 6f 0f 43 70 91 1e 8a 16 03 03 00 04 |H...o.Cp........|
+00000350 0e 00 00 00 |....|
+>>> Flow 3 (client to server)
+00000000 16 03 03 00 25 10 00 00 21 20 0a 1b 78 c4 bb eb |....%...! ..x...|
+00000010 a4 01 33 3b 69 95 c2 06 5d c9 3e b3 13 51 4b 93 |..3;i...].>..QK.|
+00000020 5e 3c 3e a7 42 12 22 e8 7e 49 14 03 03 00 01 01 |^<>.B.".~I......|
+00000030 16 03 03 00 28 fc c7 a1 45 50 e0 fe 27 fd ac a4 |....(...EP..'...|
+00000040 d8 a2 c6 54 df e1 d3 6f e7 d8 45 a6 57 16 2f 1f |...T...o..E.W./.|
+00000050 cf 89 26 c6 0a c3 4f 63 df ac bc c9 79 |..&...Oc....y|
+>>> 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 37 25 28 76 4e 31 dd 5e b0 5b 39 87 fc |...7%(vN1.^.[9..|
+00000020 0f 10 3c bc 6d 12 9a dd 59 89 0b 09 bc f2 2c d8 |..<.m...Y.....,.|
+00000030 05 a7 77 17 03 03 00 25 00 00 00 00 00 00 00 01 |..w....%........|
+00000040 fe 79 9d dd d9 e3 bc 48 47 65 30 64 c7 74 82 0a |.y.....HGe0d.t..|
+00000050 9f b7 45 a2 62 40 b5 dd 79 b9 ce 06 83 15 03 03 |..E.b@..y.......|
+00000060 00 1a 00 00 00 00 00 00 00 02 58 ed 37 40 33 e4 |..........X.7@3.|
+00000070 75 f0 a6 fa 14 f5 6b 93 9e 54 f2 a4 |u.....k..T..|
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..a071f60
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-AES128-SHA256
@@ -0,0 +1,100 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 dc 01 00 00 d8 03 03 5f b5 79 18 5f |..........._.y._|
+00000010 d2 f8 b0 fc da 39 90 af e1 ba 04 b5 70 86 c3 6b |.....9......p..k|
+00000020 ba b4 87 e3 81 9a 86 02 9b 26 44 20 21 e3 5b 03 |.........&D !.[.|
+00000030 0d 0a 6c 1f 71 ea b4 4c 56 aa b6 d1 e8 91 d6 7b |..l.q..LV......{|
+00000040 59 12 63 af db d2 69 80 cd 5f 62 22 00 04 13 01 |Y.c...i.._b"....|
+00000050 00 ff 01 00 00 8b 00 00 00 0e 00 0c 00 00 09 31 |...............1|
+00000060 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........|
+00000070 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................|
+00000080 00 16 00 00 00 17 00 00 00 0d 00 1e 00 1c 04 03 |................|
+00000090 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 |................|
+000000a0 08 05 08 06 04 01 05 01 06 01 00 2b 00 03 02 03 |...........+....|
+000000b0 04 00 2d 00 02 01 01 00 33 00 26 00 24 00 1d 00 |..-.....3.&.$...|
+000000c0 20 57 12 bc 06 e0 46 c7 75 43 b8 af f9 c1 f6 b8 | W....F.uC......|
+000000d0 e4 1e 13 6b 02 07 23 d2 e6 89 ec 18 ab c0 9f ae |...k..#.........|
+000000e0 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 21 e3 5b 03 |........... !.[.|
+00000030 0d 0a 6c 1f 71 ea b4 4c 56 aa b6 d1 e8 91 d6 7b |..l.q..LV......{|
+00000040 59 12 63 af db d2 69 80 cd 5f 62 22 13 01 00 00 |Y.c...i.._b"....|
+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 be 8f 95 d9 22 d7 |..............".|
+00000090 f7 ff 75 78 b6 9c bc 93 23 2f 76 62 c6 cd c6 92 |..ux....#/vb....|
+000000a0 fe 17 03 03 02 6d 31 54 c9 32 d0 38 53 8f f0 15 |.....m1T.2.8S...|
+000000b0 03 42 16 39 71 61 f9 17 f2 da c5 2e 4c 19 c3 30 |.B.9qa......L..0|
+000000c0 d5 c6 b8 ea 5d 3b 47 1b d9 20 31 64 ab 5c f3 00 |....];G.. 1d.\..|
+000000d0 43 5b e7 3b 36 69 12 c9 3b 3d e7 4f 91 72 e4 29 |C[.;6i..;=.O.r.)|
+000000e0 93 54 65 50 88 07 b9 e2 ed 5e 18 f7 00 0a 49 e5 |.TeP.....^....I.|
+000000f0 19 cc d8 e5 b2 c5 f6 bd 34 7a 7f e2 f1 7c 9d a0 |........4z...|..|
+00000100 d6 0c 50 4f 80 8a c5 a1 fe b8 2e 54 7c 0c ae 48 |..PO.......T|..H|
+00000110 c5 ff 46 d9 45 e6 c0 df 61 74 fc d5 e8 ec e1 84 |..F.E...at......|
+00000120 0b c8 df 73 77 e4 9f 13 e5 52 e5 0b d8 9f 65 b7 |...sw....R....e.|
+00000130 89 d5 04 74 f8 8d a6 2a c7 a1 76 ff 27 85 6a bb |...t...*..v.'.j.|
+00000140 ee 86 c9 38 5a 54 bc ac bc ad 79 85 7c 26 65 c3 |...8ZT....y.|&e.|
+00000150 36 97 56 76 d2 4c 55 32 71 82 ec d1 81 22 46 9e |6.Vv.LU2q...."F.|
+00000160 75 d8 55 a8 1e 61 10 c8 dc e8 c7 ad fe 96 0e 54 |u.U..a.........T|
+00000170 1c 79 0c 41 b9 98 b0 44 f8 45 6e c7 b3 41 68 2d |.y.A...D.En..Ah-|
+00000180 ea 73 be 55 99 fe 88 02 e3 5d 0f f3 d1 70 9a 5e |.s.U.....]...p.^|
+00000190 be e7 80 96 6c 94 7f 9f ec 1c b6 24 28 ef 90 95 |....l......$(...|
+000001a0 d5 5b d4 7b 1b b1 a4 9c 66 09 11 23 ad f5 87 ee |.[.{....f..#....|
+000001b0 0b 1f e5 d2 0e 57 16 e9 14 ae 0f 98 9b a1 bc 9e |.....W..........|
+000001c0 68 dc d0 fb 76 aa c8 f2 bc e5 d3 ff e2 85 df 01 |h...v...........|
+000001d0 2f ad 72 78 85 0f f7 0a 64 a4 cd 61 2a e6 2b a3 |/.rx....d..a*.+.|
+000001e0 d5 4a c9 08 00 af 5c 6c 9d 35 e4 1e 7c 32 1a d0 |.J....\l.5..|2..|
+000001f0 f3 6d 73 16 9c c8 72 28 4b 67 cf d8 ff 2b 1e 33 |.ms...r(Kg...+.3|
+00000200 18 c4 ed c9 31 5d 6a 0f c5 05 bf 08 eb 0b 44 05 |....1]j.......D.|
+00000210 83 49 40 d2 1f 7f 5c 08 ef 98 1f 09 f1 09 33 02 |.I@...\.......3.|
+00000220 56 04 66 53 69 93 ef 07 0d 8a e7 84 b5 03 b9 78 |V.fSi..........x|
+00000230 bb 52 84 3f bb 4e d3 f9 c4 8a 2a d1 59 02 59 36 |.R.?.N....*.Y.Y6|
+00000240 88 52 6a 9d 1f 7e c1 5b a6 8a a4 cc 42 f4 44 59 |.Rj..~.[....B.DY|
+00000250 ca d2 fa 0e 09 5f 25 e5 cc 27 55 8b 16 b5 f1 62 |....._%..'U....b|
+00000260 aa f7 a9 bc 7a 36 fa 16 34 b7 ce 2d b8 bd 67 f0 |....z6..4..-..g.|
+00000270 75 15 17 c4 49 81 55 b1 5a e0 d2 b8 45 79 d0 16 |u...I.U.Z...Ey..|
+00000280 71 21 01 57 ad 10 48 1f 0d bf 43 da b7 c9 a8 93 |q!.W..H...C.....|
+00000290 88 af be 2d 65 a0 81 26 23 de fe e2 a3 9c f6 40 |...-e..&#......@|
+000002a0 96 f9 a1 21 0b fe 31 7f 24 ec 75 ae cf b0 8c a7 |...!..1.$.u.....|
+000002b0 fe f8 2f ee 60 65 72 5c 86 a6 45 22 11 55 62 29 |../.`er\..E".Ub)|
+000002c0 02 8b b5 ff 4b f8 73 71 3d 8c c3 37 68 2d 2c 24 |....K.sq=..7h-,$|
+000002d0 b7 dc be 5a 37 d8 25 3b b6 16 e6 2a e9 80 48 0b |...Z7.%;...*..H.|
+000002e0 77 be 05 35 b2 86 97 51 49 31 ac de 85 eb a9 a8 |w..5...QI1......|
+000002f0 74 1d 00 07 4c 1b 8c a5 ec 1b b5 7a 57 84 da 40 |t...L......zW..@|
+00000300 10 6c c9 ed b3 43 06 81 11 e2 84 3c 4c ae 22 6b |.l...C.....<L."k|
+00000310 e6 96 dc 17 03 03 00 99 2b 4a 51 8f 5e c1 82 70 |........+JQ.^..p|
+00000320 e7 e2 ca 34 cb d1 24 c9 da 69 06 7c 75 d0 0f 16 |...4..$..i.|u...|
+00000330 cc 9c e1 26 60 d0 cc 18 16 18 15 f0 26 f8 d4 d7 |...&`.......&...|
+00000340 f8 81 77 0c 68 cd fe 7a 28 d6 32 60 29 c3 e2 87 |..w.h..z(.2`)...|
+00000350 9b 1c ad 3b 7d 42 31 23 74 61 f5 b7 28 5f 5a 8a |...;}B1#ta..(_Z.|
+00000360 16 98 f8 74 01 63 7d 0a 2c 51 d7 5e 04 8b 2e 58 |...t.c}.,Q.^...X|
+00000370 c3 6f d7 4a 1e fa 55 84 8d a9 24 ef de 4c e3 2e |.o.J..U...$..L..|
+00000380 44 2b 1f e8 b4 a2 6f cc e6 a6 d2 1f fa 60 ab 20 |D+....o......`. |
+00000390 e0 06 8e 00 1a 24 57 50 93 e5 71 d0 cc 63 9b 60 |.....$WP..q..c.`|
+000003a0 f8 e9 c2 de 4b 65 b6 9a 3b dd 60 d6 fb 37 c7 3c |....Ke..;.`..7.<|
+000003b0 e2 17 03 03 00 35 82 7c 22 13 69 48 00 19 51 5c |.....5.|".iH..Q\|
+000003c0 9d 19 3b 1a 25 a9 b8 db 9b c3 25 40 c9 ed c7 dd |..;.%.....%@....|
+000003d0 e6 31 e7 55 ed 48 f0 af 95 1b 0e ca 9a f4 7f 60 |.1.U.H.........`|
+000003e0 03 11 e8 51 57 5e df 4e c2 ec 7a 17 03 03 00 93 |...QW^.N..z.....|
+000003f0 76 84 60 d6 f5 6f 27 c2 47 88 fa 80 78 a6 22 0a |v.`..o'.G...x.".|
+00000400 16 a6 26 12 1b 14 6c 6f 40 10 ce 7c 7c 16 f9 64 |..&...lo@..||..d|
+00000410 e6 98 13 51 36 b0 41 d9 6d 9c fb ba 3e 59 9d 33 |...Q6.A.m...>Y.3|
+00000420 76 f0 23 23 27 94 df 2f 21 6a c0 a9 5a 3d af 41 |v.##'../!j..Z=.A|
+00000430 31 4d 9b d5 75 57 f1 a9 c5 57 2a 7a c7 1d b1 a7 |1M..uW...W*z....|
+00000440 15 a5 80 ae 63 f8 85 92 46 13 d2 31 26 62 7d 83 |....c...F..1&b}.|
+00000450 95 f9 97 9d e8 86 7d 09 f3 cc 30 b1 db 54 2a 8d |......}...0..T*.|
+00000460 0f 04 da d9 cf 59 52 2a e3 7d 64 20 f3 26 4a 2e |.....YR*.}d .&J.|
+00000470 74 07 c5 2f 98 a2 f7 e1 53 01 e0 c2 3b c7 42 1b |t../....S...;.B.|
+00000480 a0 48 12 |.H.|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 57 4a c4 5a c1 |..........5WJ.Z.|
+00000010 3a b9 ae f0 1d e8 8f 31 38 0e 64 9e 61 13 e6 b2 |:......18.d.a...|
+00000020 1b 02 aa b6 46 5a 50 97 07 93 86 13 dc 3d 76 6a |....FZP......=vj|
+00000030 67 01 1b 18 9b 7e 21 b2 c1 d4 a5 25 22 4d 14 dc |g....~!....%"M..|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e 61 63 5a 22 d2 e6 8e e8 8e 69 7d |.....acZ".....i}|
+00000010 24 69 a5 b8 e3 59 98 ac 64 0b 34 6b 16 60 92 db |$i...Y..d.4k.`..|
+00000020 6b 62 45 17 03 03 00 13 b7 12 c6 59 fe 23 f4 6c |kbE........Y.#.l|
+00000030 a6 d3 8d 59 1b 40 60 72 d6 97 b4 |...Y.@`r...|
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..60aa82d
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-AES256-SHA384
@@ -0,0 +1,103 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 dc 01 00 00 d8 03 03 70 b7 07 12 16 |...........p....|
+00000010 50 d7 b9 c9 5f 02 47 2d ff 93 a7 2f e8 51 dc a0 |P..._.G-.../.Q..|
+00000020 8f 0d c8 80 38 c7 af 7e da bb ed 20 67 73 58 d7 |....8..~... gsX.|
+00000030 11 8b c6 0d 72 86 e0 08 3e 2d d9 b9 16 9f 85 6e |....r...>-.....n|
+00000040 3c 87 fd 87 c3 95 f6 4c 76 21 50 af 00 04 13 02 |<......Lv!P.....|
+00000050 00 ff 01 00 00 8b 00 00 00 0e 00 0c 00 00 09 31 |...............1|
+00000060 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........|
+00000070 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................|
+00000080 00 16 00 00 00 17 00 00 00 0d 00 1e 00 1c 04 03 |................|
+00000090 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 |................|
+000000a0 08 05 08 06 04 01 05 01 06 01 00 2b 00 03 02 03 |...........+....|
+000000b0 04 00 2d 00 02 01 01 00 33 00 26 00 24 00 1d 00 |..-.....3.&.$...|
+000000c0 20 f4 08 51 f6 69 b7 d6 a9 3e 18 a7 ee c0 30 f3 | ..Q.i...>....0.|
+000000d0 13 63 52 40 30 7c 79 6c 24 03 c9 89 25 bd a4 5f |.cR@0|yl$...%.._|
+000000e0 64 |d|
+>>> 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 73 58 d7 |........... gsX.|
+00000030 11 8b c6 0d 72 86 e0 08 3e 2d d9 b9 16 9f 85 6e |....r...>-.....n|
+00000040 3c 87 fd 87 c3 95 f6 4c 76 21 50 af 13 02 00 00 |<......Lv!P.....|
+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 b9 e4 43 5e f6 |.............C^.|
+00000090 9a 5a 62 14 02 39 fb 13 76 e8 10 db 26 1c 07 ec |.Zb..9..v...&...|
+000000a0 06 17 03 03 02 6d 39 e9 a0 33 ee 39 36 54 62 f1 |.....m9..3.96Tb.|
+000000b0 e9 1d 32 45 0f 5a ca 72 f7 7e 43 d8 89 97 00 3d |..2E.Z.r.~C....=|
+000000c0 59 70 08 b4 d1 e1 84 24 7a b8 45 3c b8 32 93 b5 |Yp.....$z.E<.2..|
+000000d0 51 a5 58 60 3f 60 52 aa c1 ff 85 fb fd 50 87 38 |Q.X`?`R......P.8|
+000000e0 47 7a 88 c6 d1 e6 3c b3 16 14 5b cb 23 50 26 7a |Gz....<...[.#P&z|
+000000f0 1d 28 d1 d2 29 5d b0 40 97 2f 3b 58 7c 8a 76 1f |.(..)].@./;X|.v.|
+00000100 1c c1 d2 2b 63 9d 53 bc fb c2 42 cb 40 0d d0 7c |...+c.S...B.@..||
+00000110 73 6c dc 63 90 89 e3 66 67 2b a2 70 af e0 af fe |sl.c...fg+.p....|
+00000120 0c c0 db 41 76 d0 16 37 2a 09 7a 79 31 03 c6 4a |...Av..7*.zy1..J|
+00000130 f4 06 22 ac 96 b4 25 1f 54 11 24 c8 67 22 8f 2a |.."...%.T.$.g".*|
+00000140 56 0c 24 fa 20 ed a8 37 66 f7 38 44 43 e2 e6 e3 |V.$. ..7f.8DC...|
+00000150 96 b5 d5 dd a5 2c 23 e4 57 57 7d 7a 59 e2 4f 66 |.....,#.WW}zY.Of|
+00000160 c4 29 d6 d1 32 a3 9c 4c dd 63 b2 a6 dc ff 6f 61 |.)..2..L.c....oa|
+00000170 c2 db 88 80 23 c1 27 d4 be dd 4f b4 c9 b8 56 4c |....#.'...O...VL|
+00000180 65 b6 f8 32 b2 60 7b af 5f 54 71 61 20 db 25 85 |e..2.`{._Tqa .%.|
+00000190 34 b6 58 9b 71 01 dd 53 cd 13 65 2e 23 69 96 0e |4.X.q..S..e.#i..|
+000001a0 89 94 75 09 64 60 76 d2 65 85 38 3d f1 0e cb 47 |..u.d`v.e.8=...G|
+000001b0 c1 2c 52 f8 ce 7a a6 9f dd 7c 39 7e a7 f9 a6 1b |.,R..z...|9~....|
+000001c0 c1 23 81 a6 7a b1 6c d4 3c 1c f3 71 ce 72 24 01 |.#..z.l.<..q.r$.|
+000001d0 4a 8d e9 24 47 51 73 67 dc 7a 9f 0b 63 7d 29 e1 |J..$GQsg.z..c}).|
+000001e0 3e 5e ac 72 d7 c8 d9 c2 13 de 92 dd 04 cb 09 21 |>^.r...........!|
+000001f0 ad 41 69 27 77 48 eb 87 cb 3b 23 ba 06 a3 68 96 |.Ai'wH...;#...h.|
+00000200 ad 24 35 f6 a6 03 87 a7 4d 9f d4 bf e5 8b 9f 56 |.$5.....M......V|
+00000210 54 dd 0e 08 da 29 ff eb 9b e1 0a a5 25 b1 85 be |T....)......%...|
+00000220 f8 ae 63 f4 49 64 cc 0a 41 0e 26 8a 8e bc 6f c9 |..c.Id..A.&...o.|
+00000230 f5 41 55 80 0d bd 70 ad 85 b0 d4 8d 33 ac b6 40 |.AU...p.....3..@|
+00000240 3e 76 fc fb 8f d2 7d 06 14 d4 45 24 6e 36 46 1c |>v....}...E$n6F.|
+00000250 06 d3 f7 f3 4c 3a a5 83 4f 75 72 77 b4 5e 37 49 |....L:..Ourw.^7I|
+00000260 41 f1 9f e6 d1 46 87 56 c8 64 28 fd 38 f0 0f 9c |A....F.V.d(.8...|
+00000270 d0 39 ff 4b 46 56 73 0d 12 7d bf 63 b4 b8 0d 33 |.9.KFVs..}.c...3|
+00000280 6b 4a 2b f8 39 67 f1 ec 2d a6 0b 5c 91 2d d8 3e |kJ+.9g..-..\.-.>|
+00000290 91 81 1a 37 29 c7 14 d2 be db 31 61 dc 5d b1 e4 |...7).....1a.]..|
+000002a0 64 af 14 9c 93 85 e7 5b 0e 42 63 c7 5e b5 cc 51 |d......[.Bc.^..Q|
+000002b0 ca 83 ca fa 52 bd 44 a1 1c 76 20 bc 3d 9f 82 79 |....R.D..v .=..y|
+000002c0 20 5c 01 14 e3 07 02 4c f6 87 f7 46 b8 de 47 23 | \.....L...F..G#|
+000002d0 5d 5c b3 8f cd 96 49 51 32 3f d2 5d 92 32 19 b5 |]\....IQ2?.].2..|
+000002e0 10 33 46 37 f0 b5 82 23 a5 91 1f 60 fb 21 2c 08 |.3F7...#...`.!,.|
+000002f0 c3 6e 17 72 0b 5d c9 7b cc 77 97 6f 20 d9 a6 fa |.n.r.].{.w.o ...|
+00000300 cc 4a bb c6 3b 0e b1 66 ae 57 f5 1b 16 46 36 b7 |.J..;..f.W...F6.|
+00000310 a5 94 ae 17 03 03 00 99 d7 86 a0 5f c0 d2 33 3e |..........._..3>|
+00000320 ce ce ea db cb a1 a5 11 b7 cc a1 48 b6 86 f5 11 |...........H....|
+00000330 d6 32 8c f9 e8 bb e3 3e ea 6f 1a df 64 cd c8 7d |.2.....>.o..d..}|
+00000340 e9 cb e4 19 fe cd 75 74 03 4a fe 91 1d 87 28 65 |......ut.J....(e|
+00000350 25 79 3a 19 13 ba 67 16 aa 7e 8e c0 e6 53 4f bb |%y:...g..~...SO.|
+00000360 98 ed cc 59 db 5e 73 23 d4 a9 a7 2a 6d 01 73 4a |...Y.^s#...*m.sJ|
+00000370 e6 65 2e c0 34 49 c1 d8 70 2e 70 1b 10 97 74 23 |.e..4I..p.p...t#|
+00000380 fe 6b 5d cd fa 71 c8 43 c3 5b 42 5c 7b e0 9e 3f |.k]..q.C.[B\{..?|
+00000390 a8 3d a9 d1 97 17 87 80 af 7c 5d 8b 70 ba 87 06 |.=.......|].p...|
+000003a0 67 dd 29 df f3 ca 9a f4 c8 93 e8 f8 ac c0 df 8e |g.).............|
+000003b0 c5 17 03 03 00 45 40 a4 26 66 29 18 b8 d6 a7 87 |.....E@.&f).....|
+000003c0 91 5f 6d 79 13 f8 7a 47 cf ac 93 7c 11 cb 4a b2 |._my..zG...|..J.|
+000003d0 24 a6 40 fb d4 ed 71 ec 19 53 ba ae e0 bb e6 cf |$.@...q..S......|
+000003e0 d6 8a a6 3c 6a 4e a3 6f 6c d7 2d e1 8a a4 6c da |...<jN.ol.-...l.|
+000003f0 a1 ab fd c0 de 59 e9 18 fc 47 f2 17 03 03 00 a3 |.....Y...G......|
+00000400 5b 85 84 a4 0d ff be 3e ea 00 71 3d ea be c7 e2 |[......>..q=....|
+00000410 dc 2f 4a 62 c2 9f e2 e5 16 51 ff 35 a7 70 df 12 |./Jb.....Q.5.p..|
+00000420 23 d6 f7 6c 96 91 7f 0f 6d d4 45 5f c6 8c c5 93 |#..l....m.E_....|
+00000430 b1 b7 46 ef f0 f4 a3 68 35 ff 09 38 8d 6d c6 84 |..F....h5..8.m..|
+00000440 d3 1c 4d 48 4e fc 4a c0 46 06 b1 a5 1c 74 a0 44 |..MHN.J.F....t.D|
+00000450 69 68 20 33 df 70 60 69 57 c7 85 bd 3e ed 55 d0 |ih 3.p`iW...>.U.|
+00000460 56 84 8f 19 03 5a 54 9a d5 3e 5d 37 98 40 4c f0 |V....ZT..>]7.@L.|
+00000470 5e f1 26 e5 97 01 fc 0f 2a 09 e9 7a 51 69 c0 8e |^.&.....*..zQi..|
+00000480 d4 25 80 f4 ca 91 f3 a7 5c 0c 96 ba ec a8 b5 ee |.%......\.......|
+00000490 ab ec 05 cb 99 30 78 48 1b 78 bf 3d b9 f4 e8 33 |.....0xH.x.=...3|
+000004a0 4d 45 d1 |ME.|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 45 54 0e c1 aa 95 |..........ET....|
+00000010 fd c5 d2 8b a0 ae 40 a1 9a b8 87 39 17 53 f7 10 |......@....9.S..|
+00000020 62 6f 55 18 42 cf 75 cb 05 de 32 28 c4 a0 f1 17 |boU.B.u...2(....|
+00000030 f1 55 ae 2c 97 9e dd d2 d0 a7 6b c6 51 51 c6 0c |.U.,......k.QQ..|
+00000040 81 3f 04 db 94 e6 68 f0 a1 80 10 39 06 99 25 e2 |.?....h....9..%.|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e e4 4f d5 b0 e7 a0 e2 13 69 75 7c |......O......iu||
+00000010 b1 84 93 be 99 ea 27 20 dd 08 89 6c e2 5a c6 bc |......' ...l.Z..|
+00000020 b8 41 3d 17 03 03 00 13 cf 64 ad ad d9 84 87 36 |.A=......d.....6|
+00000030 b9 ea b8 76 97 93 c1 03 44 c5 de |...v....D..|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-ALPN b/src/crypto/tls/testdata/Server-TLSv13-ALPN
new file mode 100644
index 0000000..df8dd45
--- /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 8e d2 a1 8f ea |................|
+00000010 e3 7d 5f 7c 70 74 c3 7e 5f 06 bb 21 35 28 38 7a |.}_|pt.~_..!5(8z|
+00000020 7f 00 11 86 6e ac 19 38 7f d4 88 20 33 3a b2 14 |....n..8... 3:..|
+00000030 c2 4e 6a 39 71 24 81 21 27 21 2d b7 3d bc 5e 97 |.Nj9q$.!'!-.=.^.|
+00000040 f8 ed 55 83 be 9a d3 27 b5 e0 0e bd 00 04 13 03 |..U....'........|
+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 89 4d b8 22 62 39 22 e6 5a |&.$... .M."b9".Z|
+000000d0 b1 86 ea c9 d9 d1 77 c9 12 c3 62 e1 8e 17 cb ab |......w...b.....|
+000000e0 91 83 d8 af 9b be 0a |.......|
+>>> 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 33 3a b2 14 |........... 3:..|
+00000030 c2 4e 6a 39 71 24 81 21 27 21 2d b7 3d bc 5e 97 |.Nj9q$.!'!-.=.^.|
+00000040 f8 ed 55 83 be 9a d3 27 b5 e0 0e bd 13 03 00 00 |..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 24 60 9e a3 43 47 75 |.........$`..CGu|
+00000090 d2 38 11 fd 9d da a5 f6 65 de 3c 2a 3d a9 46 7e |.8......e.<*=.F~|
+000000a0 50 c8 52 a1 7d e6 95 a7 4b 48 b7 35 e7 a7 17 03 |P.R.}...KH.5....|
+000000b0 03 02 6d b8 30 43 88 03 d4 6c cf c6 45 80 b2 6c |..m.0C...l..E..l|
+000000c0 52 d7 1e 08 de 0b 6e 7a 27 c8 2c 59 d4 03 41 24 |R.....nz'.,Y..A$|
+000000d0 e3 4a e1 d3 85 68 de 23 f6 c4 3a bb 45 ae b1 ac |.J...h.#..:.E...|
+000000e0 8b b3 22 7d e7 a6 7c e3 07 68 b1 9c 97 6a d3 e4 |.."}..|..h...j..|
+000000f0 5d 0a 73 a3 16 ad e4 7f b9 d7 0a b7 7c 48 bb f2 |].s.........|H..|
+00000100 ed 49 61 f7 cb 5e ea d2 d9 a3 73 ea a7 4f a3 10 |.Ia..^....s..O..|
+00000110 f7 3e 8f ce b9 56 a0 88 54 52 59 1f f3 55 2b 15 |.>...V..TRY..U+.|
+00000120 df fd fa 85 9e 20 ff 72 f3 26 6a 2c 1f 11 a8 3d |..... .r.&j,...=|
+00000130 8e 66 75 aa 90 fc 9f 9f a7 67 8f ac 98 54 19 04 |.fu......g...T..|
+00000140 c9 1f 48 f7 ed 8f 13 0a f9 6c 9b f8 e9 0a c5 a9 |..H......l......|
+00000150 f2 ef 5b 65 a1 ad 40 e4 e7 ff c1 ff e9 d6 ab 5c |..[e..@........\|
+00000160 f8 f1 7b 4d 39 33 1d 68 d3 38 20 10 c4 3b 7a 9f |..{M93.h.8 ..;z.|
+00000170 fe 55 1d 83 5c 8f 67 d0 bb 5f 32 80 b2 91 38 0a |.U..\.g.._2...8.|
+00000180 71 bb b4 3a 10 1c 98 f9 d4 19 7c 7d d5 f7 4b 0a |q..:......|}..K.|
+00000190 02 2f bd 0b f9 ff 28 b2 2d ba dd 7f 0d 51 a2 4c |./....(.-....Q.L|
+000001a0 51 92 1e e9 47 51 ae 1a d0 66 9c ef 0a 02 dc 69 |Q...GQ...f.....i|
+000001b0 95 79 2b b0 8f 7b a2 3d 57 cf 5c 7e b4 0a 91 34 |.y+..{.=W.\~...4|
+000001c0 e6 d0 0d 93 1b 6c 61 9e 58 12 47 5f 3a ec 67 19 |.....la.X.G_:.g.|
+000001d0 d8 fb 44 43 4d cd 4e ad 1d bc f2 05 66 42 3f 3f |..DCM.N.....fB??|
+000001e0 85 5d 93 56 8e ca 62 47 38 ee d2 0e 81 8b 71 7d |.].V..bG8.....q}|
+000001f0 d8 cf 6e 4b 61 80 fe 28 34 f4 f1 58 06 36 2a 40 |..nKa..(4..X.6*@|
+00000200 93 98 3d d0 9c 69 6f 6a 3a 40 b9 8c 2e 71 5d 52 |..=..ioj:@...q]R|
+00000210 66 5d 55 45 e7 38 b7 ce 74 c2 1c ae 2e 4a 03 86 |f]UE.8..t....J..|
+00000220 d4 15 c3 40 d9 58 b7 ba ed 84 fd 20 35 a4 1c c6 |...@.X..... 5...|
+00000230 8a 50 7a 0c 87 53 d7 2d 4b 5b 7d 23 79 8f 66 f8 |.Pz..S.-K[}#y.f.|
+00000240 72 05 72 7b 7d 7a 64 97 8d da c9 dd 23 6a 44 b6 |r.r{}zd.....#jD.|
+00000250 e1 99 e4 45 76 a5 53 d8 1b 54 a0 b9 9e ec 0e d3 |...Ev.S..T......|
+00000260 91 1b 5e c0 a7 c8 3a 34 22 f9 58 7d da 2b f4 fd |..^...:4".X}.+..|
+00000270 2b 9a 9e 26 20 6f d3 9d e9 48 a1 62 70 fe 06 04 |+..& o...H.bp...|
+00000280 c2 63 f7 c4 a2 b9 74 28 a8 b3 f9 f0 a1 2a 46 0c |.c....t(.....*F.|
+00000290 f5 6b cc 7e b4 c0 47 eb 00 96 6a 3d 32 58 e0 0a |.k.~..G...j=2X..|
+000002a0 59 01 3c 42 45 a7 76 6d 78 05 1f 2c db a4 08 5b |Y.<BE.vmx..,...[|
+000002b0 e8 8e b1 10 cb a9 d9 e5 c3 a4 5a f7 63 30 c7 ac |..........Z.c0..|
+000002c0 8d 62 14 9d 30 ee 9f 9f 1b c4 ca 7f e8 d4 64 2a |.b..0.........d*|
+000002d0 46 0d 43 e1 bd 4e ed 83 f1 6b 33 78 ed 8e 98 58 |F.C..N...k3x...X|
+000002e0 13 c5 7a 8a b3 20 c4 db 17 1a 83 7d 04 ec ae 02 |..z.. .....}....|
+000002f0 cd ef 9b 27 5a f0 94 0d 71 24 bf 6f 31 c4 05 a3 |...'Z...q$.o1...|
+00000300 ca b5 bf 5d cb 23 e7 76 75 b0 2e 8b d7 65 60 12 |...].#.vu....e`.|
+00000310 97 8b 02 6c 4a ba 44 2d a3 e8 47 ff 0e cd 7e a1 |...lJ.D-..G...~.|
+00000320 17 03 03 00 99 a9 d7 60 8b 76 f6 fa 62 91 32 fe |.......`.v..b.2.|
+00000330 70 3f a1 87 36 b3 d0 01 22 61 76 4f 62 52 26 08 |p?..6..."avObR&.|
+00000340 06 db 41 b9 f6 57 ed 7f 7d 69 5b 19 37 f1 8c 99 |..A..W..}i[.7...|
+00000350 c1 8f d8 45 ab 6f 30 5f 11 34 12 9e 18 7a e9 8d |...E.o0_.4...z..|
+00000360 33 23 c1 61 19 f7 3b 90 60 04 86 53 7d a0 be e9 |3#.a..;.`..S}...|
+00000370 c8 48 19 ef 99 16 54 e1 82 7f e9 7c b4 50 bd d0 |.H....T....|.P..|
+00000380 75 31 69 77 f5 d5 64 41 82 21 5c aa a9 a6 b2 cf |u1iw..dA.!\.....|
+00000390 d6 73 d3 79 3f b5 ba cb d4 4a 70 ae b8 9a d8 0f |.s.y?....Jp.....|
+000003a0 24 47 3a 30 31 6e 4c 79 a4 28 63 6e 2b 90 1c 6d |$G:01nLy.(cn+..m|
+000003b0 00 6e e3 90 60 fb d2 96 66 f9 a2 c0 af c9 17 03 |.n..`...f.......|
+000003c0 03 00 35 f6 41 b8 95 b6 98 56 4b 39 4f 42 8a 88 |..5.A....VK9OB..|
+000003d0 35 f1 15 7f 7a e0 0e 04 a8 6f 02 f0 64 e8 83 f2 |5...z....o..d...|
+000003e0 2f 03 2e 1f 24 0f 7a 4e 36 2d f7 54 9e ad 22 15 |/...$.zN6-.T..".|
+000003f0 f5 57 8f 19 f0 f0 46 11 17 03 03 00 93 26 4a 78 |.W....F......&Jx|
+00000400 60 d7 d6 5c 18 17 12 f5 a7 c5 42 de 63 6a cb 10 |`..\......B.cj..|
+00000410 c3 a1 66 57 85 0e 78 50 99 77 aa 5e 8f fb 0d 59 |..fW..xP.w.^...Y|
+00000420 f0 09 b1 b1 10 be a5 64 e1 85 48 79 8d b6 07 52 |.......d..Hy...R|
+00000430 05 bb aa 0d 46 42 dd 1d 1b 2e a7 cb 28 cd 97 24 |....FB......(..$|
+00000440 8e d4 7a 2d 1c 4a 25 12 eb 25 0b 14 40 94 0e 5d |..z-.J%..%..@..]|
+00000450 d0 04 9c 87 88 44 d5 70 c6 3d 0b 3f 10 19 cc 18 |.....D.p.=.?....|
+00000460 c5 89 b8 c3 5d 5f 3e 96 cc 9b 63 e9 f3 b1 66 2f |....]_>...c...f/|
+00000470 24 2a 06 1b f3 91 a7 7c dd d9 b5 1f b3 9e 7f ce |$*.....|........|
+00000480 db 96 cd 2e 36 69 f0 94 0c 5f e8 0b 15 6a 38 40 |....6i..._...j8@|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 32 39 09 c6 64 |..........529..d|
+00000010 aa 86 b7 a7 37 6c fa ef 66 01 d4 de e6 35 8d 31 |....7l..f....5.1|
+00000020 68 71 f3 27 56 fd 7f 7b cf c8 3c d1 44 ff e0 c7 |hq.'V..{..<.D...|
+00000030 78 b7 6c c8 ac 01 0e ee e1 78 b9 dd 1a e1 a9 b6 |x.l......x......|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e da e7 79 04 f5 65 2e f6 c3 c3 b9 |.......y..e.....|
+00000010 34 37 14 8f c2 32 cb 81 58 bc cf d0 3b 08 f0 61 |47...2..X...;..a|
+00000020 b3 ae b4 17 03 03 00 13 e3 32 09 02 e0 29 5e 4a |.........2...)^J|
+00000030 9b 36 a9 b0 65 e9 2c 1d fb ad 50 |.6..e.,...P|
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..6203e68
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-ALPN-Fallback
@@ -0,0 +1,100 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 eb 01 00 00 e7 03 03 1c d3 8e 3b d9 |..............;.|
+00000010 fe 7d e7 f9 9f fa c6 51 c3 8c 1b dd dc 87 95 f4 |.}.....Q........|
+00000020 39 23 67 e4 d6 bd 94 93 fc 88 4e 20 c3 c0 e2 c1 |9#g.......N ....|
+00000030 3d 12 ec 4c 0a 3f 40 51 13 24 61 11 c0 5d 09 f9 |=..L.?@Q.$a..]..|
+00000040 08 d6 3e cd e7 b3 51 c3 06 8f b4 42 00 04 13 03 |..>...Q....B....|
+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 f4 05 eb 4a 7a 73 20 18 74 aa 14 2a 0c 35 63 29 |...Jzs .t..*.5c)|
+000000e0 cb f2 ad d1 a2 3d bd 9d 02 b4 62 00 bc eb 10 58 |.....=....b....X|
+>>> 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 c3 c0 e2 c1 |........... ....|
+00000030 3d 12 ec 4c 0a 3f 40 51 13 24 61 11 c0 5d 09 f9 |=..L.?@Q.$a..]..|
+00000040 08 d6 3e cd e7 b3 51 c3 06 8f b4 42 13 03 00 00 |..>...Q....B....|
+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 fb 75 d8 5c 50 35 |...........u.\P5|
+00000090 55 82 ba 65 1e 63 73 b8 c1 e9 d7 f5 28 68 3c c1 |U..e.cs.....(h<.|
+000000a0 5d 17 03 03 02 6d 56 c9 a9 09 73 6a bc fd 1a 3c |]....mV...sj...<|
+000000b0 6a f8 3e 32 99 83 e8 f6 01 9e 5e 30 e8 53 7f 72 |j.>2......^0.S.r|
+000000c0 fd 86 72 a8 9e 47 25 67 c1 f1 9a 03 c0 9d 6f 9d |..r..G%g......o.|
+000000d0 bd ed 29 30 8f 3c 01 ce 49 bb 5f dd 58 9a ae 80 |..)0.<..I._.X...|
+000000e0 5c 2d 81 fc ea 7b 03 03 3d 5d bb 92 23 73 67 89 |\-...{..=]..#sg.|
+000000f0 2e f0 ec 08 20 8a 36 eb 43 a6 a1 68 d0 39 95 37 |.... .6.C..h.9.7|
+00000100 6b 15 a9 0e 46 20 92 51 9c 04 bf 3b 07 97 84 cb |k...F .Q...;....|
+00000110 1f 30 38 37 2e ff e7 0f f5 14 93 5a 84 f1 f7 10 |.087.......Z....|
+00000120 c2 a5 0d bb 97 96 ef 4a e0 13 c0 63 72 2b 60 f3 |.......J...cr+`.|
+00000130 59 b5 57 aa 5f d1 da a9 0e dd 9c dd c2 cb 61 fe |Y.W._.........a.|
+00000140 e2 69 8e db 5d 70 6c 3a 33 e0 9e db 9a 31 26 6a |.i..]pl:3....1&j|
+00000150 2b 9e 19 8e bb 5d 06 48 ea c0 a1 c6 11 24 fb c4 |+....].H.....$..|
+00000160 ce ae 48 54 64 81 d1 84 38 a6 e0 7a 7b 74 2b bc |..HTd...8..z{t+.|
+00000170 ce 07 8b b6 04 1f 5b 4c 36 29 68 0c 8c c7 32 15 |......[L6)h...2.|
+00000180 93 e0 10 52 c2 27 23 96 c5 0c 9c e9 e2 a9 08 7d |...R.'#........}|
+00000190 25 68 65 f5 4e 44 eb a9 85 78 13 e1 0d 86 5e dc |%he.ND...x....^.|
+000001a0 fd e5 c6 dd 65 46 8e 2f 32 82 83 0b dd 67 f8 42 |....eF./2....g.B|
+000001b0 65 87 3b 08 fe b1 f5 12 e9 74 21 04 12 6d 75 35 |e.;......t!..mu5|
+000001c0 b2 eb 93 95 72 10 fa 56 96 77 c3 0c 17 8c 9e f6 |....r..V.w......|
+000001d0 77 19 28 37 96 3e 73 98 f4 d2 91 4f 40 db 76 56 |w.(7.>s....O@.vV|
+000001e0 ce b5 a8 7a b8 86 d0 9a ba b5 8b 40 c2 63 e1 cf |...z.......@.c..|
+000001f0 49 29 2c 5d 1a 9b 8b 56 cb 93 ca 2c c0 d0 15 b7 |I),]...V...,....|
+00000200 8a f1 6a d5 0a a8 81 57 b1 6e 10 cd a5 ff b1 4d |..j....W.n.....M|
+00000210 47 c6 9b 35 f1 5f 83 91 22 f6 88 68 65 b3 b9 c9 |G..5._.."..he...|
+00000220 02 dc 4b f7 13 39 06 e6 3a ec 94 ef 51 15 05 72 |..K..9..:...Q..r|
+00000230 1d f4 9d 3b da ca 8d 2c 64 be 9b 45 99 2c 63 cc |...;...,d..E.,c.|
+00000240 22 b3 8b 93 ad f6 2c f0 d2 d9 11 3f 5b c0 40 fa |".....,....?[.@.|
+00000250 90 6e a0 76 b2 43 b9 4c 72 c4 24 28 a2 bf 56 d6 |.n.v.C.Lr.$(..V.|
+00000260 d2 a7 2a d1 8c 5e 1d eb f8 be d0 43 da 7a c7 88 |..*..^.....C.z..|
+00000270 61 67 a2 69 85 23 43 3e d4 88 f2 33 c3 5b 38 0a |ag.i.#C>...3.[8.|
+00000280 1e de 28 3b 3b 19 de 95 2f 84 c0 37 88 80 59 2f |..(;;.../..7..Y/|
+00000290 a6 ee 93 1a 69 08 c3 df 7c cf da c3 9b 96 70 d9 |....i...|.....p.|
+000002a0 60 c5 e9 0f 42 f6 1a f2 58 5e f2 32 61 6a b2 a3 |`...B...X^.2aj..|
+000002b0 1f 97 fa 08 6c 3f 4b 83 1f 04 66 80 8a 26 3a 7f |....l?K...f..&:.|
+000002c0 24 30 ec 10 ae 7d 19 ff 39 91 ca 97 4e ed 0a d7 |$0...}..9...N...|
+000002d0 64 3b 6b 50 29 33 0d b2 10 bc 83 63 3c fb 9a 82 |d;kP)3.....c<...|
+000002e0 3b 7f bc 04 40 f1 33 64 4a 80 cd 01 f9 f4 c6 89 |;...@.3dJ.......|
+000002f0 65 27 25 f9 cf 4f 7e c8 6e d9 0e ec 47 4a 51 29 |e'%..O~.n...GJQ)|
+00000300 2f be 34 50 bd 9b d2 d8 b7 ea bb 0b a1 e0 20 1b |/.4P.......... .|
+00000310 02 9c f2 17 03 03 00 99 61 dc 0b 3a 30 de 39 f6 |........a..:0.9.|
+00000320 f3 db f8 6c 3b fa 4e 1e 7e 62 a5 ae 73 ba e1 41 |...l;.N.~b..s..A|
+00000330 58 77 2a c1 7a 0c 50 bb 0c 57 b4 c4 25 bf 2f 9f |Xw*.z.P..W..%./.|
+00000340 38 91 e2 65 22 9d ca ac 18 58 7e 81 2d fd 74 24 |8..e"....X~.-.t$|
+00000350 28 69 76 11 df 9d 23 b8 be ae 8b e0 93 8e 5d df |(iv...#.......].|
+00000360 0a 64 d0 b7 02 68 aa 86 01 0d 55 11 3b 76 70 c6 |.d...h....U.;vp.|
+00000370 83 0c 5e 0a e3 37 a5 8b ad 25 50 b9 e8 5c 6b 04 |..^..7...%P..\k.|
+00000380 b4 51 ec 9c d3 fa c6 b7 9c f0 46 aa 73 da 3c 0d |.Q........F.s.<.|
+00000390 d3 bd 32 81 d4 d2 f1 1a b0 92 f3 73 3e 54 2b 05 |..2........s>T+.|
+000003a0 92 24 34 75 df d6 18 a0 6a 82 95 4c 9b fc 7e b6 |.$4u....j..L..~.|
+000003b0 8e 17 03 03 00 35 8f 34 0e 3b 91 d8 e7 74 24 71 |.....5.4.;...t$q|
+000003c0 0e 7b f3 12 bb 76 2f 31 12 17 b8 9e 24 ce f9 2f |.{...v/1....$../|
+000003d0 3f 5d f2 13 4b 2e 9b 1e c4 78 03 a6 c8 07 11 a3 |?]..K....x......|
+000003e0 98 79 61 6e 4f 44 6e 18 ee c4 9b 17 03 03 00 93 |.yanODn.........|
+000003f0 64 dd 52 a9 d9 51 63 6a a0 a3 c2 75 6b 5d 1d 54 |d.R..Qcj...uk].T|
+00000400 ce d4 53 7e 14 8e d9 26 93 28 78 65 16 1b 95 77 |..S~...&.(xe...w|
+00000410 68 0a 46 f1 82 36 bb 8a fa 0d df 54 8c 3d 83 e0 |h.F..6.....T.=..|
+00000420 d7 de 2d 96 e9 c4 d7 22 d3 97 8e ae 90 f8 fc e6 |..-...."........|
+00000430 a6 4b 78 98 4c c5 28 87 91 46 fa f4 1c 8d 0e ec |.Kx.L.(..F......|
+00000440 0d 71 40 9a 04 49 b4 e8 5b 62 6f cd 16 c1 d5 fb |.q@..I..[bo.....|
+00000450 73 2a 96 8f e5 a2 f4 11 1e df 2d 40 45 6b d5 a9 |s*........-@Ek..|
+00000460 e4 e3 f7 93 fc fa d7 20 af d5 f7 b4 0e 09 ad d5 |....... ........|
+00000470 26 87 b8 6c e2 20 95 fb c0 70 3e 38 be b7 b1 9f |&..l. ...p>8....|
+00000480 70 da c1 |p..|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 29 d2 b9 bb 9b |..........5)....|
+00000010 de 6c 5d 22 23 c1 fe 99 4c c5 33 bf fd 70 36 6b |.l]"#...L.3..p6k|
+00000020 f1 a5 92 e8 bf 7c 3d 6e ef 6a 44 73 bc cb 27 1c |.....|=n.jDs..'.|
+00000030 09 5d bf 99 4c 19 24 c3 3b 30 91 b5 e3 b6 63 45 |.]..L.$.;0....cE|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e 52 55 85 7c b8 87 dd c7 b2 d9 5b |.....RU.|......[|
+00000010 18 1d bb ac bf b6 ab 76 82 be 64 0e b2 7b 2c 0f |.......v..d..{,.|
+00000020 aa 17 92 17 03 03 00 13 79 0a 60 b1 46 20 33 74 |........y.`.F 3t|
+00000030 ed 12 a0 23 de 68 88 fc 6f dd 8e |...#.h..o..|
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..b51ff25
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-ALPN-NoMatch
@@ -0,0 +1,27 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 e2 01 00 00 de 03 03 9f 73 81 5f 56 |............s._V|
+00000010 a9 02 5f 8c 33 db dc 2a 92 d0 5e 7c e9 e6 01 d7 |.._.3..*..^|....|
+00000020 67 b6 bb 74 da bb d0 c1 11 08 20 20 9f bd d6 f8 |g..t...... ....|
+00000030 d7 8c e5 32 15 1d 4a 4c 36 ce 72 90 cb 68 ca dc |...2..JL6.r..h..|
+00000040 ea b3 57 93 9a 12 e6 0e 9a bd 91 1a 00 04 13 03 |..W.............|
+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 79 79 04 d3 03 58 93 22 5d |&.$... yy...X."]|
+000000d0 06 69 1a 03 11 4e 65 e5 30 85 29 02 22 c8 11 6d |.i...Ne.0.)."..m|
+000000e0 21 86 d4 4d 58 93 74 |!..MX.t|
+>>> 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 9f bd d6 f8 |........... ....|
+00000030 d7 8c e5 32 15 1d 4a 4c 36 ce 72 90 cb 68 ca dc |...2..JL6.r..h..|
+00000040 ea b3 57 93 9a 12 e6 0e 9a bd 91 1a 13 03 00 00 |..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 13 7c ab 7f dd 94 cf |..........|.....|
+00000090 d7 98 34 16 75 02 63 37 fa 4f 19 4e 18 |..4.u.c7.O.N.|
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..e0830d3
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-ALPN-NotConfigured
@@ -0,0 +1,100 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 e2 01 00 00 de 03 03 9f 49 a7 46 f8 |............I.F.|
+00000010 72 04 47 a1 8e 4f 89 c3 cd 89 92 2f 7a 8a 07 37 |r.G..O...../z..7|
+00000020 8c 25 10 42 26 07 8b a2 71 3e 92 20 4c 83 1b 70 |.%.B&...q>. L..p|
+00000030 45 c3 79 68 c3 83 a7 05 c2 22 06 c6 91 da 8b 96 |E.yh....."......|
+00000040 4c 9d 89 c2 ec b8 49 87 17 3f 6c ae 00 04 13 03 |L.....I..?l.....|
+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 f4 91 87 6a ac cd 25 5e f1 |&.$... ...j..%^.|
+000000d0 0d 25 fb af a4 d4 fb 16 32 63 af 04 2d 21 d7 2f |.%......2c..-!./|
+000000e0 61 f2 c2 d4 c4 6c 2b |a....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 4c 83 1b 70 |........... L..p|
+00000030 45 c3 79 68 c3 83 a7 05 c2 22 06 c6 91 da 8b 96 |E.yh....."......|
+00000040 4c 9d 89 c2 ec b8 49 87 17 3f 6c ae 13 03 00 00 |L.....I..?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 60 79 16 61 4f 6c |..........`y.aOl|
+00000090 9e 2e ce fd cc f5 29 67 38 e7 53 67 92 b1 5f 9d |......)g8.Sg.._.|
+000000a0 db 17 03 03 02 6d 54 d9 d6 a1 8e c2 1b 70 3f 3d |.....mT......p?=|
+000000b0 a2 2e 0f a5 37 96 e1 68 66 69 cc f8 e9 06 4d bc |....7..hfi....M.|
+000000c0 c2 9a 6e 0f ea d4 73 59 6a 59 28 79 7f 44 0c 32 |..n...sYjY(y.D.2|
+000000d0 29 22 51 d1 fb 00 c7 33 44 8b 19 71 98 8a 03 44 |)"Q....3D..q...D|
+000000e0 e0 95 ad 8f 91 66 e6 15 b8 99 b3 f8 2f 02 e9 a0 |.....f....../...|
+000000f0 4a 25 ec 3f 36 56 0c eb 0a a3 e0 d3 79 a1 b3 9e |J%.?6V......y...|
+00000100 dc 42 08 76 a4 c3 55 91 06 11 e7 0c 94 dd 71 fc |.B.v..U.......q.|
+00000110 bf 8a 87 d2 97 07 a3 b9 36 7e 58 ff ef b3 a3 f4 |........6~X.....|
+00000120 6e f1 23 d6 50 e3 23 d3 dc e7 20 ce 9d 84 17 cf |n.#.P.#... .....|
+00000130 2d 5f b1 f9 8d 36 41 7d ba 3b 93 63 2f bc be f0 |-_...6A}.;.c/...|
+00000140 a1 3a bb 5f b3 99 03 13 fb d2 2c 1a 8c cc 32 02 |.:._......,...2.|
+00000150 ef 93 b4 58 a8 f8 b1 42 52 24 c2 73 01 cb 5a fb |...X...BR$.s..Z.|
+00000160 9f fc 38 08 d7 f9 0d d7 20 fa dc 8b 1a 8c 73 0f |..8..... .....s.|
+00000170 f8 79 b2 84 e1 49 2d 8e 6d 46 16 38 0e 02 2a 2c |.y...I-.mF.8..*,|
+00000180 f4 44 89 da f1 7a 01 55 9e 93 a8 d6 d5 f5 72 28 |.D...z.U......r(|
+00000190 47 2b 4f 17 7e a5 01 fd ad 85 e0 6d f9 82 e8 cd |G+O.~......m....|
+000001a0 09 18 84 8c 9d 4f 4e a1 43 ff d6 3d 55 05 fc 56 |.....ON.C..=U..V|
+000001b0 e6 d6 b6 61 4a c7 c7 9c 62 64 26 1d 33 1e 4f d5 |...aJ...bd&.3.O.|
+000001c0 5e ee 1f a9 ad 24 e4 7f 05 cc 02 7a f7 e0 c2 ce |^....$.....z....|
+000001d0 b8 11 c9 a1 fd c5 d8 0e ef f8 c9 6a 2d 49 30 63 |...........j-I0c|
+000001e0 e3 9b 43 bf 87 e1 5f 55 39 fa 80 ec 84 55 59 5d |..C..._U9....UY]|
+000001f0 52 76 4c f4 70 eb 43 6a b2 07 d5 29 4c 58 39 04 |RvL.p.Cj...)LX9.|
+00000200 46 42 70 8d 28 61 7c d5 7a 3a 2e a0 9f 74 49 2d |FBp.(a|.z:...tI-|
+00000210 33 8d 39 18 70 8d 3c 50 4f 62 07 77 2d 15 1f 4b |3.9.p.<POb.w-..K|
+00000220 22 01 c6 cb ac 2f 2d 9a cf a6 9b 0e 24 99 41 64 |"..../-.....$.Ad|
+00000230 3e f2 9f 5f 17 7b d7 b8 3c b6 6d 24 5b 91 8c 13 |>.._.{..<.m$[...|
+00000240 1a 40 4e 80 7f 44 12 57 c9 03 57 c6 9b 54 0d 39 |.@N..D.W..W..T.9|
+00000250 91 88 72 3e c8 f9 18 eb 34 7c 0a eb 2d c8 56 1c |..r>....4|..-.V.|
+00000260 84 8a 62 a2 3a 0a 52 b8 5a b6 5d 54 78 ae 05 b2 |..b.:.R.Z.]Tx...|
+00000270 f4 6c 2d 5e 92 94 6b f3 1e 93 13 1a 65 74 60 e3 |.l-^..k.....et`.|
+00000280 dd 15 36 62 2b 71 b1 bb 59 19 08 af 8e 9b d0 47 |..6b+q..Y......G|
+00000290 05 7b a3 89 ac 68 cf a0 32 ba 4a 2b 9e 5f a5 dc |.{...h..2.J+._..|
+000002a0 b3 00 79 a8 1c f6 11 b8 6d 9c 51 b7 f1 f6 b2 13 |..y.....m.Q.....|
+000002b0 56 57 4e ac 97 ff 5a b8 52 33 0c c1 3d 52 81 6e |VWN...Z.R3..=R.n|
+000002c0 85 ba b2 04 4b eb 41 aa 03 ff ae 63 93 72 3a 5f |....K.A....c.r:_|
+000002d0 65 81 f9 6a 2a e4 70 f8 b3 59 31 51 62 ad 25 24 |e..j*.p..Y1Qb.%$|
+000002e0 82 0c b5 ad 7c 87 21 97 07 c0 c1 6d f0 22 97 0d |....|.!....m."..|
+000002f0 28 cf a7 4d 74 d2 9c ac d7 15 83 26 f7 2f 76 d4 |(..Mt......&./v.|
+00000300 ad cf e7 ef 1c f4 3e 1f b4 f4 4f 76 6a 98 15 01 |......>...Ovj...|
+00000310 cd 17 8b 17 03 03 00 99 0b 15 9d 16 c6 2a 52 53 |.............*RS|
+00000320 33 d7 01 db 8a 49 1d d6 83 b7 28 a4 07 f0 73 5e |3....I....(...s^|
+00000330 60 03 2c 6f 3f e0 88 a1 76 22 d6 23 0a df ca 86 |`.,o?...v".#....|
+00000340 b0 44 b9 1d 9a d7 53 f2 2b 57 a1 65 01 d4 e7 b4 |.D....S.+W.e....|
+00000350 9e 22 00 d2 20 da cd 55 7d 61 86 86 19 81 f9 ed |.".. ..U}a......|
+00000360 f8 af c4 69 54 1d 35 0a 6f 9e 69 40 13 08 82 dd |...iT.5.o.i@....|
+00000370 59 11 31 f2 81 a7 4b f1 bd d9 f2 5c 29 22 16 49 |Y.1...K....\)".I|
+00000380 86 62 8c a8 b8 89 58 96 cc d1 e4 e8 5e ef 6c b7 |.b....X.....^.l.|
+00000390 00 71 3d ab 92 b8 78 56 a7 25 5e a0 c4 d8 8c 02 |.q=...xV.%^.....|
+000003a0 c4 c8 eb d3 be 68 21 05 5c 5f 9c b0 ec 20 99 ff |.....h!.\_... ..|
+000003b0 00 17 03 03 00 35 c9 c1 5e 25 1c b9 64 8e c2 fd |.....5..^%..d...|
+000003c0 50 87 48 e6 02 36 75 31 67 f6 82 3c 94 79 7d 0b |P.H..6u1g..<.y}.|
+000003d0 cb 83 b1 f4 e1 00 5f a6 b6 2c 2d 63 40 ab 98 f9 |......_..,-c@...|
+000003e0 e3 8e 4a 7e d4 77 3d 55 90 10 75 17 03 03 00 93 |..J~.w=U..u.....|
+000003f0 47 c4 6e 19 29 c2 5e d5 93 b7 c2 cc 46 a9 49 9d |G.n.).^.....F.I.|
+00000400 8a 3b 9a 35 bb 45 22 13 b6 eb c9 ec ba 44 3c 24 |.;.5.E"......D<$|
+00000410 f2 ed bd 76 11 cc af 00 b3 89 63 5d 79 32 cc d7 |...v......c]y2..|
+00000420 5c 34 f3 5e 64 36 92 5d ac ac 33 74 f4 3d c4 b8 |\4.^d6.]..3t.=..|
+00000430 4d ac d0 49 4e 59 1c 16 74 8c 43 94 4b 13 b9 22 |M..INY..t.C.K.."|
+00000440 de d7 ee 30 09 63 f3 32 5f a2 9d a1 20 ea ee 91 |...0.c.2_... ...|
+00000450 ca d8 01 33 df 43 19 69 63 ee 6a 2c 80 99 ad f0 |...3.C.ic.j,....|
+00000460 5e 20 b6 b6 81 28 b6 9d 4a 9a 91 30 30 04 c1 70 |^ ...(..J..00..p|
+00000470 68 54 1e e0 72 00 4c fd 23 a8 41 a2 6a ab a3 01 |hT..r.L.#.A.j...|
+00000480 7a 40 1a |z@.|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 20 1f 0d 20 a8 |..........5 .. .|
+00000010 34 c4 dc fa f9 d6 2b fe 01 eb f1 54 f0 14 c2 2d |4.....+....T...-|
+00000020 bb 59 db 04 96 f2 18 8b bd 7e b0 38 b7 15 b5 d8 |.Y.......~.8....|
+00000030 6b f2 80 25 40 f6 97 67 fb 9e 5a 5c ad 33 c6 5f |k..%@..g..Z\.3._|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e 3a 8a fc 60 3a 99 ee b6 01 b7 fe |.....:..`:......|
+00000010 54 a9 2d 34 28 ae af 3b 6a bd e0 32 6b df 87 fe |T.-4(..;j..2k...|
+00000020 d0 97 8d 17 03 03 00 13 c6 89 d5 ae 4c fa d5 71 |............L..q|
+00000030 66 6e 07 b5 9b 00 e8 50 7e b9 5f |fn.....P~._|
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..760c597
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-CHACHA20-SHA256
@@ -0,0 +1,100 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 dc 01 00 00 d8 03 03 7f d6 02 2f 2d |............../-|
+00000010 ed b1 3c f2 c2 48 5e d5 f4 57 c9 8c ba 81 36 52 |..<..H^..W....6R|
+00000020 85 3e 79 de 79 cc 36 6a f9 88 89 20 db e1 89 a5 |.>y.y.6j... ....|
+00000030 26 4c 2a 2d 0f 33 e2 3f 57 05 cc 74 cd 4c 96 be |&L*-.3.?W..t.L..|
+00000040 91 94 ef 54 1c 1f 01 ef d4 36 75 2f 00 04 13 03 |...T.....6u/....|
+00000050 00 ff 01 00 00 8b 00 00 00 0e 00 0c 00 00 09 31 |...............1|
+00000060 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........|
+00000070 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................|
+00000080 00 16 00 00 00 17 00 00 00 0d 00 1e 00 1c 04 03 |................|
+00000090 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 |................|
+000000a0 08 05 08 06 04 01 05 01 06 01 00 2b 00 03 02 03 |...........+....|
+000000b0 04 00 2d 00 02 01 01 00 33 00 26 00 24 00 1d 00 |..-.....3.&.$...|
+000000c0 20 30 20 a8 d0 3d ea df 38 aa 65 6f dd c8 25 13 | 0 ..=..8.eo..%.|
+000000d0 03 c4 a2 24 d4 a8 0d 1a a6 65 32 75 83 ef 71 70 |...$.....e2u..qp|
+000000e0 30 |0|
+>>> 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 db e1 89 a5 |........... ....|
+00000030 26 4c 2a 2d 0f 33 e2 3f 57 05 cc 74 cd 4c 96 be |&L*-.3.?W..t.L..|
+00000040 91 94 ef 54 1c 1f 01 ef d4 36 75 2f 13 03 00 00 |...T.....6u/....|
+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 f4 9a 6e ea 99 81 |............n...|
+00000090 59 33 26 a6 6a 40 1d a9 59 67 31 35 09 b0 ed 15 |Y3&.j@..Yg15....|
+000000a0 83 17 03 03 02 6d 56 59 69 c8 6d 45 c6 2f 58 3d |.....mVYi.mE./X=|
+000000b0 db 87 dd 56 0f 2d d9 21 1b 97 94 77 f2 72 28 0d |...V.-.!...w.r(.|
+000000c0 48 04 79 83 7e 2e a1 c9 30 56 d7 9c c8 0a 37 65 |H.y.~...0V....7e|
+000000d0 b6 6b 31 ae 9a 5f ff 13 15 94 99 7c 92 e1 32 80 |.k1.._.....|..2.|
+000000e0 28 3c ab b1 cc fe ba 92 3c 03 bb fd b8 55 f5 f2 |(<......<....U..|
+000000f0 ba be 28 90 c5 7e 07 48 d5 45 b6 84 80 02 2d cd |..(..~.H.E....-.|
+00000100 14 27 81 b6 4e b4 7f 5f 78 a3 26 c2 0c af 12 d6 |.'..N.._x.&.....|
+00000110 e9 14 22 c8 ee 2e 5e fc c3 ca 8f 01 9b 37 6a b0 |.."...^......7j.|
+00000120 f8 53 b2 8e 31 d7 1f 34 f6 35 ed 81 e0 f7 6f e1 |.S..1..4.5....o.|
+00000130 90 cf 1a 4f 44 50 d5 cd 96 c3 4a 22 7a 54 28 bd |...ODP....J"zT(.|
+00000140 88 56 5c 77 67 eb a6 78 5c 8b 82 39 03 13 55 c3 |.V\wg..x\..9..U.|
+00000150 20 68 45 26 7a 96 fe 1c f9 33 14 1e 1d 8a 5f 51 | hE&z....3...._Q|
+00000160 c3 2f 17 91 ba 37 63 49 e1 65 89 bf e8 a1 27 5f |./...7cI.e....'_|
+00000170 fd 59 46 80 f7 9b 45 89 50 ab cd 9b aa b4 45 04 |.YF...E.P.....E.|
+00000180 b5 1b 85 88 1c 59 ba b2 d6 50 0b fd 5c d9 59 83 |.....Y...P..\.Y.|
+00000190 7a 6c 9b ad 27 33 a0 49 74 eb a6 cd a8 e8 4b d7 |zl..'3.It.....K.|
+000001a0 71 ef 63 64 ff 24 a7 09 2e b7 f6 6f 9d 9f 75 84 |q.cd.$.....o..u.|
+000001b0 97 0a 76 bf 72 ed ff e8 1a 49 ca 0b 0d f5 2c fb |..v.r....I....,.|
+000001c0 69 c2 5c fe db 58 0a a1 9c d4 47 6a 8f a6 bd ec |i.\..X....Gj....|
+000001d0 32 fb 40 6a 71 9d 19 37 e6 fd d4 3d fa 5b f3 53 |2.@jq..7...=.[.S|
+000001e0 43 df d5 fa 53 29 40 70 77 a6 9e f7 03 7d 08 8b |C...S)@pw....}..|
+000001f0 5a 71 73 e5 af 45 58 56 9f 56 ad 73 aa d2 b3 7c |Zqs..EXV.V.s...||
+00000200 92 99 c8 04 16 bf ca f2 81 2e 29 c3 79 21 f1 11 |..........).y!..|
+00000210 92 f4 1d 34 24 73 e3 82 28 5a 31 70 45 da 8d 94 |...4$s..(Z1pE...|
+00000220 38 75 31 bc f9 e5 2b 11 7e fd bc 19 fe 65 ad 53 |8u1...+.~....e.S|
+00000230 e5 e6 17 b8 69 ea 54 fd 92 a9 41 7a 8c 7f da 4f |....i.T...Az...O|
+00000240 ba f1 9f a2 e2 5b e7 7a 23 17 9e 29 95 7e 72 79 |.....[.z#..).~ry|
+00000250 22 67 c5 68 0a 4d fb e9 64 61 3a 53 18 e7 dd 7d |"g.h.M..da:S...}|
+00000260 5b 16 b9 fa 69 95 82 eb ee 1a 30 97 93 97 fc ee |[...i.....0.....|
+00000270 9e 2b 22 64 08 7d 25 05 77 5e d7 bd 0e c3 9f a4 |.+"d.}%.w^......|
+00000280 f4 bf 77 3d 56 84 c8 a1 10 1c e0 5b da 39 3d 2d |..w=V......[.9=-|
+00000290 92 80 9a 07 b2 29 c5 ab e0 e1 1c ad ba 3e fa 4e |.....).......>.N|
+000002a0 65 4f 31 63 de 33 6a 5c af e0 88 70 fc 6e 6a a2 |eO1c.3j\...p.nj.|
+000002b0 ca da 2f 14 1d 4f 8c 7d 8d da 36 9b ea 7f 7e 79 |../..O.}..6...~y|
+000002c0 9c dc 4a 3b 69 d9 50 31 bb f2 f8 8a 7f 6e 73 bc |..J;i.P1.....ns.|
+000002d0 41 7c 3a 86 10 91 9b 3a 8e 3e c8 bc 6a c4 4d f2 |A|:....:.>..j.M.|
+000002e0 45 87 49 49 d2 2f aa 4d d0 6f e9 1e a4 d6 06 63 |E.II./.M.o.....c|
+000002f0 ac 90 ce 9a cb f7 97 55 2b e8 8c 8d 55 f6 32 26 |.......U+...U.2&|
+00000300 55 d4 60 0e c0 0b da 0e ac c9 4c c3 95 03 54 d7 |U.`.......L...T.|
+00000310 99 ec e1 17 03 03 00 99 c4 65 5e 67 e3 a1 98 d6 |.........e^g....|
+00000320 f8 34 15 ed a9 55 80 c7 c0 e7 ca 67 f1 cb 58 e2 |.4...U.....g..X.|
+00000330 6e 4d d4 9e 18 c3 37 c2 ff 72 bc cb 8e 6a 97 e2 |nM....7..r...j..|
+00000340 b5 83 75 34 2a 75 9f 7f 8e 1e 47 e6 cd 53 85 c5 |..u4*u....G..S..|
+00000350 69 b6 c0 46 9f 46 a8 09 6a 21 d5 af 36 d2 d0 ba |i..F.F..j!..6...|
+00000360 65 0f da a5 af eb 3a 0c 8b 85 00 2a dd 11 71 28 |e.....:....*..q(|
+00000370 5b 71 a9 df 69 20 8a d9 27 1e 4f 02 89 03 6f 27 |[q..i ..'.O...o'|
+00000380 20 e1 37 17 69 c2 62 3e 46 39 43 2d 64 43 f3 cc | .7.i.b>F9C-dC..|
+00000390 14 5f a0 73 06 bf 42 cb da 79 21 28 b1 a1 c4 de |._.s..B..y!(....|
+000003a0 39 98 83 ad 3a d6 05 fd 58 b0 2c 97 bf 48 74 0e |9...:...X.,..Ht.|
+000003b0 25 17 03 03 00 35 69 10 76 25 e3 9e 63 10 76 73 |%....5i.v%..c.vs|
+000003c0 f5 fc 90 2c 95 e5 dc 29 79 a0 ed 0a 3a 72 58 38 |...,...)y...:rX8|
+000003d0 bf b9 17 af 77 9f 05 92 af d4 a7 c7 d6 56 77 01 |....w........Vw.|
+000003e0 da 94 31 d2 be be 95 e1 b1 95 75 17 03 03 00 93 |..1.......u.....|
+000003f0 f9 fa a9 41 89 d3 e8 3b cb 11 63 76 56 fe 28 86 |...A...;..cvV.(.|
+00000400 87 b0 0f d0 4d a8 fb 22 e9 89 f6 40 8a db 51 be |....M.."...@..Q.|
+00000410 2c 9f 9c 39 f4 43 bc 1f b0 32 9b 9c 8e a6 6e e1 |,..9.C...2....n.|
+00000420 f3 f7 f0 91 ed 56 6f 2d be 37 6b 3b ed f7 5b a6 |.....Vo-.7k;..[.|
+00000430 d3 14 0a f9 58 b8 7b 37 fc 15 97 57 79 16 8c 0c |....X.{7...Wy...|
+00000440 d2 93 7a 58 b8 48 51 f7 58 82 7d a0 4b e1 41 f6 |..zX.HQ.X.}.K.A.|
+00000450 e1 44 12 1e ea 80 f3 b6 d0 72 ec 5c 84 01 6a b3 |.D.......r.\..j.|
+00000460 f7 83 b5 47 22 0b e7 03 60 09 a7 23 23 20 5e 6b |...G"...`..## ^k|
+00000470 f6 25 34 64 11 ad 46 90 db cb 13 f5 10 0a 75 e8 |.%4d..F.......u.|
+00000480 3e c8 03 |>..|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 27 f0 39 68 fc |..........5'.9h.|
+00000010 9f 6c a4 fd a7 cf 1f 25 67 54 3c e6 9e 7c 99 5a |.l.....%gT<..|.Z|
+00000020 e9 b7 3c 0c f2 dc b6 22 36 0d 43 a3 ee 76 4b a9 |..<...."6.C..vK.|
+00000030 6a cb b8 f6 8a c8 58 91 79 19 95 7c 83 a0 87 57 |j.....X.y..|...W|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e d5 8a ef 04 f9 6c 27 62 0a f1 a4 |..........l'b...|
+00000010 4b 7f e4 e4 ff 53 f3 61 20 b9 56 96 30 f9 06 c9 |K....S.a .V.0...|
+00000020 cc 9c ed 17 03 03 00 13 4a 83 cd 86 98 97 20 45 |........J..... E|
+00000030 ab 2f c5 72 15 f6 ed a8 8c 8c 0e |./.r.......|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndECDSAGiven b/src/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndECDSAGiven
new file mode 100644
index 0000000..0b6eaf4
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndECDSAGiven
@@ -0,0 +1,179 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 ca 01 00 00 c6 03 03 54 78 64 8e b6 |...........Txd..|
+00000010 69 c6 1c 8a 69 eb 09 ef 32 59 f9 9f 63 ac 6e 66 |i...i...2Y..c.nf|
+00000020 97 b4 bb b7 71 27 60 52 af c4 64 20 26 de 8d 3e |....q'`R..d &..>|
+00000030 90 5b c8 96 b5 10 a3 e4 67 f3 39 fb f5 b7 df 50 |.[......g.9....P|
+00000040 2b 8f 2d cb a5 c4 0a c9 28 1b c3 21 00 04 13 01 |+.-.....(..!....|
+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 65 |-.....3.&.$... e|
+000000b0 42 a2 bd 1e e0 0a 52 2d 7a 1e f0 37 86 db 9e c6 |B.....R-z..7....|
+000000c0 d6 cd ff 7b 71 f3 4c a3 23 44 2d 94 60 93 0b |...{q.L.#D-.`..|
+>>> 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 26 de 8d 3e |........... &..>|
+00000030 90 5b c8 96 b5 10 a3 e4 67 f3 39 fb f5 b7 df 50 |.[......g.9....P|
+00000040 2b 8f 2d cb a5 c4 0a c9 28 1b c3 21 13 01 00 00 |+.-.....(..!....|
+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 f1 7c 16 5a 86 b4 |...........|.Z..|
+00000090 13 82 93 fa ba 07 35 24 03 f5 24 25 cc 2d c8 e5 |......5$..$%.-..|
+000000a0 6c 17 03 03 00 3e cb 02 08 06 a3 75 03 c6 5d d9 |l....>.....u..].|
+000000b0 9c 66 ad db 29 6d 93 a6 53 c6 38 7f 9c 56 1e b1 |.f..)m..S.8..V..|
+000000c0 f5 a8 77 19 43 c3 93 5e 67 dc 80 db 1b c8 30 b2 |..w.C..^g.....0.|
+000000d0 04 85 6e 5c 8f 3a 4a f2 d2 aa 17 c7 d3 ea 29 f2 |..n\.:J.......).|
+000000e0 09 08 49 90 17 03 03 02 6d dd 26 0f f5 1b 6b 11 |..I.....m.&...k.|
+000000f0 1c c7 e9 87 bf de 58 08 e4 bc a6 49 98 fd bf 87 |......X....I....|
+00000100 31 35 59 c1 88 5a 8c 0d e7 42 47 b6 cb ec 3c 6f |15Y..Z...BG...<o|
+00000110 ba 01 4a bb 0c 7d d3 ae 0c 62 97 20 b5 f4 84 a0 |..J..}...b. ....|
+00000120 4c 30 87 8e 3c 11 24 b6 6f cc 8b de d4 ee 47 c0 |L0..<.$.o.....G.|
+00000130 47 92 00 0f 56 91 04 b3 42 93 1f 5c df 6e f6 f1 |G...V...B..\.n..|
+00000140 51 68 95 ad cd 4d 6e 7e 98 b9 57 da fb 01 45 45 |Qh...Mn~..W...EE|
+00000150 a7 d6 62 3d cb 48 f2 7c 18 03 52 50 51 c4 84 3e |..b=.H.|..RPQ..>|
+00000160 16 e6 ff be 29 a3 60 13 f8 8c 82 6c 84 dd c1 c8 |....).`....l....|
+00000170 8b a2 bf e5 70 03 c3 a4 92 3d 99 a8 fc 92 15 e4 |....p....=......|
+00000180 1d 13 7d b5 1f d3 a6 76 1c 8c 9f 9f e7 87 b4 fb |..}....v........|
+00000190 25 b8 cf 83 0a 3b bd c7 e8 30 d4 15 6f ae d5 b9 |%....;...0..o...|
+000001a0 da 3b c6 3f 0c 06 7a 78 e6 ac ca 64 cb 34 cc 7b |.;.?..zx...d.4.{|
+000001b0 46 78 ec e2 22 9e 31 39 63 a7 7b 1d d6 c2 4b 91 |Fx..".19c.{...K.|
+000001c0 45 fa 95 54 ef 9b b3 2e 55 83 77 c8 cf 15 b5 34 |E..T....U.w....4|
+000001d0 11 4c 92 36 22 54 3d 2f b0 cb 28 7f 2b 1e b1 3f |.L.6"T=/..(.+..?|
+000001e0 38 4a 4a d6 e8 a1 e6 e0 4f 20 ab 04 6f 6b 00 5e |8JJ.....O ..ok.^|
+000001f0 d4 16 42 ab a5 04 67 9b 89 45 78 8b ea 0e 7d c8 |..B...g..Ex...}.|
+00000200 24 d5 fb 83 c7 13 25 b7 1b 6f 3f 2a 2e cf bb 71 |$.....%..o?*...q|
+00000210 11 48 5d e6 98 5e ca dd f7 6d dc 93 b1 51 1e 99 |.H]..^...m...Q..|
+00000220 b9 e0 4c 39 c8 82 d8 9f 8d 70 25 78 5b b1 85 1d |..L9.....p%x[...|
+00000230 cb 75 31 61 c3 ad d5 c1 d5 1f 26 06 60 5f cd eb |.u1a......&.`_..|
+00000240 ee 4c 99 43 02 b9 e5 f5 99 98 94 cf 14 1c ad 54 |.L.C...........T|
+00000250 20 a9 d3 73 f2 3f bc a1 25 39 8b ff c4 e0 ee 8b | ..s.?..%9......|
+00000260 ba ec fc b0 c2 42 4c 5a 30 9c 26 1b f0 f2 da 94 |.....BLZ0.&.....|
+00000270 26 69 55 0e fb 84 a0 58 95 43 08 6c 87 82 93 02 |&iU....X.C.l....|
+00000280 cf 27 99 94 a3 ae 9f 08 d0 6e f2 a8 e8 29 fc a8 |.'.......n...)..|
+00000290 67 d3 20 37 83 5d 8a 12 0a 57 10 bf 30 5a e1 05 |g. 7.]...W..0Z..|
+000002a0 30 e0 b7 7b 47 7e a6 07 cc 9a dd 6d e8 11 89 c7 |0..{G~.....m....|
+000002b0 7d 98 c3 6d 83 9f 1b f4 ff ca 31 c8 39 7b c2 fb |}..m......1.9{..|
+000002c0 69 dc ee eb ab e2 39 72 35 6b 22 e4 84 2f 1d 58 |i.....9r5k"../.X|
+000002d0 07 b0 9e 3e 69 ca ff 17 44 d6 e4 a8 56 6a 24 35 |...>i...D...Vj$5|
+000002e0 08 39 42 41 da 76 4b 4f 00 ce 41 58 4e 70 d5 b6 |.9BA.vKO..AXNp..|
+000002f0 50 b4 88 91 47 4a 89 04 ef e8 14 2e cf e3 9d 36 |P...GJ.........6|
+00000300 c0 b5 2b 8e 42 2f 4b 95 39 55 6f 5a 23 5b 5e 05 |..+.B/K.9UoZ#[^.|
+00000310 f0 34 70 c0 f7 92 54 e2 5c 52 20 b0 c1 2a 9a cb |.4p...T.\R ..*..|
+00000320 3a 32 0e 93 77 96 f2 6a d8 f7 bc 7c d8 40 4e 5e |:2..w..j...|.@N^|
+00000330 37 1c 8b aa 75 89 94 51 da 19 72 80 86 c8 3d bd |7...u..Q..r...=.|
+00000340 fd 7d 06 13 bb 54 a1 0b 46 58 07 e5 35 b3 f3 ff |.}...T..FX..5...|
+00000350 8a 98 9d e6 e8 05 17 03 03 00 99 5a 63 3c ff cc |...........Zc<..|
+00000360 a0 ec 5f 52 4d 28 96 80 22 f7 8c a7 ad b7 1f 4a |.._RM(.."......J|
+00000370 8c 46 79 06 31 96 46 f9 f0 57 8c c4 5b f9 71 61 |.Fy.1.F..W..[.qa|
+00000380 34 0d 3e 78 67 05 1c 93 a7 a2 cd ea ce e5 a2 6e |4.>xg..........n|
+00000390 37 4f 16 a4 e4 4c 60 d5 5a 37 f1 2a bf ce 2f 80 |7O...L`.Z7.*../.|
+000003a0 ea 65 e6 25 03 fc 2b 17 3f a4 71 3f 04 46 2b f7 |.e.%..+.?.q?.F+.|
+000003b0 12 b0 a6 f3 fc 8d cf 5e 95 85 84 88 e4 db 46 a4 |.......^......F.|
+000003c0 f2 3a a5 27 44 3d a2 03 b3 65 af 1f e3 44 aa 02 |.:.'D=...e...D..|
+000003d0 0f 39 eb 3d 0e 2a ae 0c 1b ed 84 df 8d e3 a2 1d |.9.=.*..........|
+000003e0 6d 55 bf d6 13 f6 00 da 93 a7 fc b1 50 79 2c a9 |mU..........Py,.|
+000003f0 93 cb 7d 70 17 03 03 00 35 9e b7 c2 c6 29 a9 43 |..}p....5....).C|
+00000400 3f df 06 80 31 ac d9 f7 3b cd 14 16 a0 85 ca e6 |?...1...;.......|
+00000410 34 70 e3 fc af 1c 94 9b 87 b3 17 6c a4 83 64 2c |4p.........l..d,|
+00000420 6e 26 4c e9 ab 79 a9 c8 1d d4 1c 96 2c f2 |n&L..y......,.|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 02 1e 08 6d ee 1c 88 |............m...|
+00000010 63 86 93 3e 73 8e 87 6f 51 8b d3 d2 91 c5 cb 55 |c..>s..oQ......U|
+00000020 2d 7c 9f 32 d8 0a ab e5 53 95 4b 0c 22 12 23 56 |-|.2....S.K.".#V|
+00000030 07 ce 1b e1 46 f7 46 84 cb 47 83 62 4a 16 39 44 |....F.F..G.bJ.9D|
+00000040 bf 58 25 6e f1 22 d0 ea 06 d8 da 44 91 bb 27 41 |.X%n.".....D..'A|
+00000050 1f 6e 46 89 88 93 a7 0a 60 8f 1a e5 31 19 5c 27 |.nF.....`...1.\'|
+00000060 a3 f6 8c 1b ee 5b 2b 21 c4 64 c7 d9 92 7b e9 ca |.....[+!.d...{..|
+00000070 e0 16 29 d0 64 32 95 a8 8f a8 24 cc 56 c6 3e 7d |..).d2....$.V.>}|
+00000080 1b f6 06 a6 fa d6 dc 79 38 60 4f 6f b7 e1 10 ab |.......y8`Oo....|
+00000090 21 14 8e e1 90 95 6d b6 f3 ca 86 1a dd 32 c5 33 |!.....m......2.3|
+000000a0 e1 fc 8c da 77 02 54 88 73 f3 72 71 c6 58 ad 1a |....w.T.s.rq.X..|
+000000b0 10 b8 15 c3 69 f1 cc 71 b6 ea 7e b7 81 4b de 7b |....i..q..~..K.{|
+000000c0 77 87 24 e0 c0 39 5c 5b 17 ad 7c 59 53 43 cf 7e |w.$..9\[..|YSC.~|
+000000d0 cb 70 4d 51 f1 7e 8c 2b 19 61 13 75 bf 25 df 80 |.pMQ.~.+.a.u.%..|
+000000e0 f2 fa cd 70 8d db eb bc 38 ae 6a 0c ad ef d2 e2 |...p....8.j.....|
+000000f0 f0 f1 02 97 ce 37 8b 8f 9e bd 4f 92 40 e7 8f 9f |.....7....O.@...|
+00000100 26 b7 cd ef cf 57 28 2f 12 cc 69 e1 be f2 59 c6 |&....W(/..i...Y.|
+00000110 be dc 51 9a 67 be 4a f1 97 f9 7a d9 01 05 1f d0 |..Q.g.J...z.....|
+00000120 2b 96 5b b5 4d 1d c1 2e 99 7e eb e3 20 92 b0 f8 |+.[.M....~.. ...|
+00000130 ac 9f c1 e3 10 cd b1 e9 05 46 15 3c c2 fb ce 27 |.........F.<...'|
+00000140 5e f1 47 e7 d8 ca 89 0e 77 37 86 6c c9 d4 e3 ae |^.G.....w7.l....|
+00000150 1e 6e 63 4f 5c 2d aa a0 88 7c 35 47 87 e8 40 22 |.ncO\-...|5G..@"|
+00000160 f8 45 2f 57 b4 e8 e1 95 45 58 02 53 3c 19 b5 92 |.E/W....EX.S<...|
+00000170 73 55 fd 49 31 ec db dc 4c 6f 6f a7 9a 90 89 83 |sU.I1...Loo.....|
+00000180 08 97 53 5a c6 6c 23 75 cd 68 37 54 2c 00 d3 56 |..SZ.l#u.h7T,..V|
+00000190 5e 24 87 7b 92 a9 61 73 1e 84 31 0e ff d7 f2 fb |^$.{..as..1.....|
+000001a0 62 5e f9 27 35 18 bb ca b2 c2 d7 5c bf 7f 6d 36 |b^.'5......\..m6|
+000001b0 fa e6 02 4a d0 fa bd b8 c0 d0 2f 0c 27 6b 49 92 |...J....../.'kI.|
+000001c0 20 54 01 ea 3c d2 07 f1 2e d6 e3 a3 a3 bd 1d 33 | T..<..........3|
+000001d0 90 ee 26 ad a6 5c ee c7 de 4d e8 fc d2 b5 5a b5 |..&..\...M....Z.|
+000001e0 7c 6f c5 61 23 11 20 eb 0f 7c b7 0a cc 8c 65 b7 ||o.a#. ..|....e.|
+000001f0 e2 87 16 10 b0 fd 40 75 78 d1 3c 70 54 66 b8 cb |......@ux.<pTf..|
+00000200 a5 84 c6 ee af 57 3c 73 64 2d ba 5d b9 a3 93 84 |.....W<sd-.]....|
+00000210 d1 2e d4 87 15 4f 9b 1c e5 da 02 b0 c5 2e 9f 31 |.....O.........1|
+00000220 d4 3f 6e e8 b7 02 d3 f3 71 17 03 03 00 a4 14 81 |.?n.....q.......|
+00000230 dd 8d 55 4d 0a 18 cb 08 0a b0 1e e3 7d d6 54 8e |..UM........}.T.|
+00000240 e3 e6 5d 2a c8 59 6c 5e 19 a7 db 0f 96 b2 55 db |..]*.Yl^......U.|
+00000250 71 f8 6f bb a4 b8 d3 c7 a2 ee 01 c0 1a 15 00 20 |q.o............ |
+00000260 1a 88 07 b5 69 83 4d 8b 45 65 da 6d e5 df c2 82 |....i.M.Ee.m....|
+00000270 a3 b5 92 75 7b 76 86 f8 f8 13 63 c9 37 2f 06 ce |...u{v....c.7/..|
+00000280 7c 64 da 08 1f 4e a3 4f a4 5a 4a 36 a3 b8 99 6f ||d...N.O.ZJ6...o|
+00000290 fa b2 8a f6 41 91 ea 5e 6c bd c9 40 65 a1 10 08 |....A..^l..@e...|
+000002a0 c2 a5 2e 13 d9 ce 59 d8 fb d1 48 77 94 5a 2d d0 |......Y...Hw.Z-.|
+000002b0 23 ba 02 4a 55 b5 be da ca c1 61 f5 15 d0 7a ba |#..JU.....a...z.|
+000002c0 a4 cf e7 1f 1d 99 32 cf 41 19 87 eb 79 97 0e fa |......2.A...y...|
+000002d0 6e ae 17 03 03 00 35 7c 26 f7 77 3f 3c 10 90 47 |n.....5|&.w?<..G|
+000002e0 54 bd e7 c6 b7 9e 14 a9 ca 3a 12 c8 42 9a e1 38 |T........:..B..8|
+000002f0 e4 60 ed a9 4a d8 d3 6d 15 ab b2 f2 16 81 09 b1 |.`..J..m........|
+00000300 fd b5 56 67 8d e0 b1 e9 4b b9 ad 7a |..Vg....K..z|
+>>> Flow 4 (server to client)
+00000000 17 03 03 02 98 07 3b b6 4e c1 7e 84 44 a0 5d 3c |......;.N.~.D.]<|
+00000010 b8 45 37 1e bf 0f 43 cf d6 11 c7 0d d9 a4 25 7b |.E7...C.......%{|
+00000020 27 fa 6e e1 9c 24 5f e5 f9 12 e8 a1 33 2e cc 24 |'.n..$_.....3..$|
+00000030 43 3b ac e3 bd f2 7b 1d 66 70 eb 31 21 7f 3e 5e |C;....{.fp.1!.>^|
+00000040 09 7a 29 8f 43 43 cb c4 6d 70 a7 51 1c 0f dc 21 |.z).CC..mp.Q...!|
+00000050 e9 4c f5 16 8f 35 e8 5b ae 7f e0 47 e7 d4 53 66 |.L...5.[...G..Sf|
+00000060 b2 cc ef 44 b7 3e 34 2b 32 a9 e6 89 b9 c6 f6 56 |...D.>4+2......V|
+00000070 97 b3 78 37 3c 89 2f 35 8e a5 c7 ae c4 92 91 69 |..x7<./5.......i|
+00000080 50 ae ee c9 7b 7a 3a 10 ce 1c 68 fd 09 57 3d 92 |P...{z:...h..W=.|
+00000090 52 42 0e 4e 91 12 b4 fd e4 59 d4 1e 5a c7 25 b3 |RB.N.....Y..Z.%.|
+000000a0 dd a1 dd 7d 7d 92 08 52 ec 85 15 c7 b6 60 70 fb |...}}..R.....`p.|
+000000b0 76 6b 42 da 84 8e e5 a9 cb a4 b1 76 89 51 93 55 |vkB........v.Q.U|
+000000c0 f3 92 aa cc 04 3b 78 97 ed 10 88 d8 77 d1 32 35 |.....;x.....w.25|
+000000d0 93 82 a4 1d ca 47 df c8 72 93 10 90 e0 75 2d 3f |.....G..r....u-?|
+000000e0 b0 6a 3d 9e b6 20 1d 0a 2a 03 66 be 18 18 d3 25 |.j=.. ..*.f....%|
+000000f0 47 a2 ab 67 08 44 24 cb 94 29 8a f7 8b 8e ca a0 |G..g.D$..)......|
+00000100 20 71 d0 af 87 5b e1 d9 5d e0 0c 70 13 3d 82 42 | q...[..]..p.=.B|
+00000110 b3 b8 fb 5e 1d f1 58 88 ea 11 67 28 49 11 d4 27 |...^..X...g(I..'|
+00000120 05 87 e4 b1 21 15 d1 3a 6a df ee 6d 40 7c 3f 8c |....!..:j..m@|?.|
+00000130 7e cd 7b 0c 0e ef fd 17 29 29 f8 03 98 8e 76 ac |~.{.....))....v.|
+00000140 23 e2 81 30 8b c7 7b 9b 5a 78 f7 6a 53 32 5c bd |#..0..{.Zx.jS2\.|
+00000150 d7 42 cb 77 f5 1d ea 03 74 9f ec 1d 1b 68 72 aa |.B.w....t....hr.|
+00000160 9f e0 7d 58 2f 26 47 6b 2d e4 1f 78 f4 ab d3 ae |..}X/&Gk-..x....|
+00000170 51 6c 2a 35 0a 6f 9a c8 2b 75 ff 69 3e 4b 61 bc |Ql*5.o..+u.i>Ka.|
+00000180 03 29 60 04 8b 53 9f ae e4 00 7f 88 7a d4 70 b8 |.)`..S......z.p.|
+00000190 65 83 87 96 5d ef f1 b2 e8 7e 0e af 0b 2c 07 dd |e...]....~...,..|
+000001a0 a9 0e f8 c3 9b 59 aa cf 74 02 5e 46 8c cb 3d ee |.....Y..t.^F..=.|
+000001b0 72 67 7c 46 37 29 78 d8 80 6e 42 16 b7 a8 59 35 |rg|F7)x..nB...Y5|
+000001c0 cb 36 ce 73 50 80 d2 35 7a 69 b9 f3 14 73 04 e7 |.6.sP..5zi...s..|
+000001d0 ec dd 92 80 b0 f6 b7 51 28 15 56 c4 bb 83 00 86 |.......Q(.V.....|
+000001e0 9e 21 e7 bd 91 33 15 d4 aa da 8a 07 eb 2e d9 48 |.!...3.........H|
+000001f0 c3 71 1a da be 6f 00 45 bd 08 a3 70 17 d5 c0 1a |.q...o.E...p....|
+00000200 74 87 5a 95 60 aa 1d ce 0e e1 46 57 85 8c e0 ae |t.Z.`.....FW....|
+00000210 98 1a f9 83 7f ec 04 bd 90 dc 51 4f 7e d2 52 28 |..........QO~.R(|
+00000220 ca 33 f6 60 4a 0c e4 7d b3 93 4f 70 7a ce d3 3e |.3.`J..}..Opz..>|
+00000230 0a dd 50 b0 17 0a 2e db 2c ad 3d 86 d3 e6 60 07 |..P.....,.=...`.|
+00000240 43 61 9c a0 ff 45 37 9a 60 3d c5 f7 4d 27 fc b4 |Ca...E7.`=..M'..|
+00000250 9a 05 1c 0a ae 08 9d d9 5c 15 09 c9 8e 24 bb e2 |........\....$..|
+00000260 ec a1 a7 27 f0 42 97 a9 af ed 25 fd 5f f1 2a 4d |...'.B....%._.*M|
+00000270 ac ab 9c a5 7d 28 6b c8 36 ec 0c 12 5b eb fa 64 |....}(k.6...[..d|
+00000280 83 74 13 6e 44 5a 23 38 f0 a6 22 3e f9 88 f1 0d |.t.nDZ#8..">....|
+00000290 2a 55 b8 bf aa 87 de a4 7f 8b ba 52 23 17 03 03 |*U.........R#...|
+000002a0 00 1e fb 80 15 2b ff db 63 29 a7 77 ef 1e 82 28 |.....+..c).w...(|
+000002b0 8d d5 f0 5b 5d 42 8e 34 f9 64 5c 47 eb c3 10 4c |...[]B.4.d\G...L|
+000002c0 17 03 03 00 13 a1 8b 9e d8 57 0e 04 96 7c b4 83 |.........W...|..|
+000002d0 70 a2 20 03 ee 28 23 c7 |p. ..(#.|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndEd25519Given b/src/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndEd25519Given
new file mode 100644
index 0000000..d80b76f
--- /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 3d 6d 5a b0 92 |...........=mZ..|
+00000010 7b 62 6d 14 22 f5 08 70 77 4a 80 fa 69 1a 1c 92 |{bm."..pwJ..i...|
+00000020 4c d3 e5 ca 3a d0 ee 33 40 c8 64 20 e5 a7 f1 57 |L...:..3@.d ...W|
+00000030 39 32 e3 9f 7c 33 58 16 61 58 29 44 aa e4 50 b1 |92..|3X.aX)D..P.|
+00000040 37 c5 59 27 f2 d5 b8 6e 01 24 c2 6b 00 04 13 01 |7.Y'...n.$.k....|
+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 cb |-.....3.&.$... .|
+000000b0 da f4 03 da e7 6f e5 2b 25 c0 cb cf 52 0a fb af |.....o.+%...R...|
+000000c0 8a 87 4c 2b 88 e4 1a b3 a0 34 30 fb 9d 4e 0e |..L+.....40..N.|
+>>> 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 e5 a7 f1 57 |........... ...W|
+00000030 39 32 e3 9f 7c 33 58 16 61 58 29 44 aa e4 50 b1 |92..|3X.aX)D..P.|
+00000040 37 c5 59 27 f2 d5 b8 6e 01 24 c2 6b 13 01 00 00 |7.Y'...n.$.k....|
+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 2d 8b 08 3c eb 5e |..........-..<.^|
+00000090 e6 d7 8e 9a 11 d0 e1 a3 3f 88 cc 83 49 e3 af 50 |........?...I..P|
+000000a0 66 17 03 03 00 3e 24 ba 0e 2f d7 51 a9 52 5d 51 |f....>$../.Q.R]Q|
+000000b0 a4 7d b6 dc 5c 43 2e d8 58 5e 72 f1 86 98 15 b8 |.}..\C..X^r.....|
+000000c0 db 0a 48 0a 06 c4 ad 36 41 84 f1 89 36 e9 24 da |..H....6A...6.$.|
+000000d0 05 5a dc 82 02 a1 3d 39 ae 4c 7e d9 7b 43 1f 2c |.Z....=9.L~.{C.,|
+000000e0 06 71 a0 2f 17 03 03 02 6d 48 44 6b d1 65 fb e1 |.q./....mHDk.e..|
+000000f0 fb 96 00 e5 ad c6 60 e2 b5 f6 bf 7c b7 f4 6f 0e |......`....|..o.|
+00000100 db a2 4b f7 cd d7 73 29 f8 af 23 5d d4 55 df 37 |..K...s)..#].U.7|
+00000110 b7 62 38 d0 95 5c f1 48 32 5f cb fa 67 18 20 7f |.b8..\.H2_..g. .|
+00000120 b7 0f ac fc 64 b7 b0 7b 4b 1f 65 1d 2a 94 8d 76 |....d..{K.e.*..v|
+00000130 b4 30 3b ee 44 a5 f6 74 5b 7e bd a7 bb b2 d8 d6 |.0;.D..t[~......|
+00000140 ac c6 1f b4 88 34 85 7e 89 2c 2e 0d bf 6c 16 0c |.....4.~.,...l..|
+00000150 ce 35 57 13 29 55 60 20 86 21 20 c0 46 bc 9e dd |.5W.)U` .! .F...|
+00000160 8a a0 41 60 b5 a9 16 cc 66 cb 4a ba 58 e0 70 d1 |..A`....f.J.X.p.|
+00000170 a5 b4 eb ac 54 7e 95 11 00 f0 70 63 af 56 57 99 |....T~....pc.VW.|
+00000180 68 57 b4 5b aa db f1 08 2e c0 fb df 93 b8 4a f8 |hW.[..........J.|
+00000190 2e 04 b3 2c 2b f9 47 09 a1 5f a3 3e 97 eb d4 d5 |...,+.G.._.>....|
+000001a0 df ec d1 9e 05 5e 10 b0 2b 7e 0e b4 c8 e1 e3 50 |.....^..+~.....P|
+000001b0 29 19 8b 3c f7 d0 95 30 ae 4c e4 60 c8 13 09 15 |)..<...0.L.`....|
+000001c0 b7 80 f3 ad a0 06 6b a7 b7 4a c4 6d 65 09 21 d3 |......k..J.me.!.|
+000001d0 3b 56 dc ce f5 d3 fa 93 e9 03 8e 0c c9 47 21 89 |;V...........G!.|
+000001e0 7f 39 23 f8 aa 68 f6 b4 82 50 1f b8 46 5d 26 dc |.9#..h...P..F]&.|
+000001f0 b1 1f e5 e5 6b ad ad 0d d8 55 b7 8b 7a f8 5d fc |....k....U..z.].|
+00000200 bd 74 a4 15 72 33 1b a7 3b 8c 09 55 d9 fd 21 bf |.t..r3..;..U..!.|
+00000210 cd dd 67 d2 0c d0 bd 9b de 52 e3 5f 4d 54 c0 6c |..g......R._MT.l|
+00000220 bd 93 ae 66 55 4b e9 75 6b db cd 6b 80 33 f4 b7 |...fUK.uk..k.3..|
+00000230 61 9e e4 5d 75 b5 44 26 79 b5 da bf af 54 8c 40 |a..]u.D&y....T.@|
+00000240 23 99 32 60 2a 76 b3 0a 46 37 c9 85 1c fe e9 a1 |#.2`*v..F7......|
+00000250 a3 e8 61 67 04 eb 3e e8 2b d3 12 75 87 04 67 40 |..ag..>.+..u..g@|
+00000260 19 63 c5 ef 75 d0 39 63 a0 c3 ae 3c b1 88 34 db |.c..u.9c...<..4.|
+00000270 c7 29 0c 33 c8 40 c0 b0 e6 76 44 cc 99 4f 2b a6 |.).3.@...vD..O+.|
+00000280 b3 e1 28 69 6c 41 74 55 53 a9 87 06 9a cb 14 5d |..(ilAtUS......]|
+00000290 ec 74 77 e2 a0 ce 54 02 ba f8 04 2c 84 9a de 2b |.tw...T....,...+|
+000002a0 dc 02 32 01 ad 96 5c a0 87 3c 55 dd ee 4d cb fd |..2...\..<U..M..|
+000002b0 ee a1 d4 9e 3f fd 66 10 fc eb cf 2e d3 f1 aa 9d |....?.f.........|
+000002c0 a2 fe 37 d5 b7 c7 6a b2 59 48 7a 57 9f 45 ff 22 |..7...j.YHzW.E."|
+000002d0 4c e2 dd 50 72 00 e0 9e af 35 7e 19 32 f2 f8 f0 |L..Pr....5~.2...|
+000002e0 5c af ff 4f e8 37 44 8a 12 f5 14 e6 c2 79 7e 90 |\..O.7D......y~.|
+000002f0 72 65 b7 cf f4 51 fc c9 fb 08 80 ef d5 4c ba 4e |re...Q.......L.N|
+00000300 a0 e2 0a 72 1a 4c 02 35 14 59 41 02 28 73 12 94 |...r.L.5.YA.(s..|
+00000310 ef 39 c5 b8 0e 43 ae 4e 0e 96 de d3 6e 25 8f ae |.9...C.N....n%..|
+00000320 ff 52 c2 ca 22 bb 77 b3 48 0c 9b e8 c1 0c 03 94 |.R..".w.H.......|
+00000330 a9 1e a5 6b 00 46 39 f7 52 4f 39 14 07 40 99 5a |...k.F9.RO9..@.Z|
+00000340 b0 c0 ba d3 0f a6 1e 30 ab 06 b4 5a b6 21 c6 93 |.......0...Z.!..|
+00000350 88 f8 a4 18 4d 37 17 03 03 00 99 87 d1 c8 64 88 |....M7........d.|
+00000360 d3 01 40 b6 89 cd 3d 26 a9 ea 36 bb 13 29 fa a0 |..@...=&..6..)..|
+00000370 f2 ba 28 65 a9 55 05 ff 47 53 37 0d 09 c6 30 b2 |..(e.U..GS7...0.|
+00000380 be 9f 31 e3 97 bc 5f 06 25 c2 d1 8a b6 3b c1 4e |..1..._.%....;.N|
+00000390 54 1a ea 57 2a 10 33 df ec 57 27 2e 71 a9 ea 16 |T..W*.3..W'.q...|
+000003a0 09 98 dd 40 f1 4d f3 34 d8 c5 f9 7a d3 db 57 f1 |...@.M.4...z..W.|
+000003b0 cc e8 1a 0f 88 51 ba 52 23 5f e9 91 f5 e3 1c ef |.....Q.R#_......|
+000003c0 59 b1 e1 e5 da 64 0e 56 00 65 77 82 32 b9 eb bd |Y....d.V.ew.2...|
+000003d0 d2 07 87 cd 83 94 39 63 64 90 d7 e7 8e 25 b9 66 |......9cd....%.f|
+000003e0 34 d3 a1 80 06 33 4d c9 69 ff ab 28 12 b9 19 a4 |4....3M.i..(....|
+000003f0 a6 05 94 db 17 03 03 00 35 68 36 21 a4 85 d8 96 |........5h6!....|
+00000400 52 51 a3 99 61 41 1e c4 84 97 9f 85 ed da d7 72 |RQ..aA.........r|
+00000410 79 ce 52 3a b9 31 31 19 f3 e5 d7 03 72 0c ab a9 |y.R:.11.....r...|
+00000420 7c 0f 17 38 9c 82 26 a5 95 1f 02 85 5b f6 ||..8..&.....[.|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 01 50 d8 03 a6 37 13 |..........P...7.|
+00000010 5f fb 65 9f 33 33 79 ae 89 c3 de ea 4b 55 e2 b3 |_.e.33y.....KU..|
+00000020 13 07 0d 95 c6 f7 79 74 ad 8a 42 dd 78 55 a5 01 |......yt..B.xU..|
+00000030 69 f2 11 cf 72 de 85 04 56 78 9c ba 21 77 b8 76 |i...r...Vx..!w.v|
+00000040 e3 58 23 3d 2b 8a ee a4 5c 52 60 4b 50 0d c4 83 |.X#=+...\R`KP...|
+00000050 a1 8d 06 82 68 99 34 65 7a 7b 55 8e 46 04 47 55 |....h.4ez{U.F.GU|
+00000060 4d 42 02 41 b6 e4 dd a4 33 6a 04 97 e6 4a 80 3a |MB.A....3j...J.:|
+00000070 e1 7e 0a a5 4f 0c f9 de 7a 91 96 4f 6a 6a 8a 4b |.~..O...z..Ojj.K|
+00000080 fd 24 b9 bf e7 d5 5a 27 17 18 45 77 1d e2 c9 ea |.$....Z'..Ew....|
+00000090 23 57 c4 e1 30 9e de d2 bd 0c 28 59 dc a1 12 d9 |#W..0.....(Y....|
+000000a0 ee 2e 43 4b 83 fc d7 6c a4 e7 47 c4 14 c1 1f ee |..CK...l..G.....|
+000000b0 79 60 26 86 73 5c ec c9 c0 ec f9 c9 38 98 2d ba |y`&.s\......8.-.|
+000000c0 10 83 1b fe 8f cf 59 77 f0 60 fe c0 d0 7e 0f 2d |......Yw.`...~.-|
+000000d0 69 04 dd 79 49 c5 b1 d9 9b 48 ad de 55 cf d3 47 |i..yI....H..U..G|
+000000e0 9b eb 64 ae ed cb b0 48 78 a9 27 24 b8 8d 53 36 |..d....Hx.'$..S6|
+000000f0 b7 0f 82 1c ee 11 4b 5a 98 1d 21 73 b4 f4 06 ce |......KZ..!s....|
+00000100 50 bc 36 27 e1 87 70 04 68 1b 30 3a 86 68 b3 71 |P.6'..p.h.0:.h.q|
+00000110 8c 57 69 60 d6 a8 bd fa 13 46 2b 52 00 dc 45 53 |.Wi`.....F+R..ES|
+00000120 06 79 5b 96 78 69 d0 a8 cd 2d 39 8c 11 12 9f 65 |.y[.xi...-9....e|
+00000130 72 01 5e b4 c5 df bc 9d a2 7f 00 a7 cc 95 3b 0b |r.^...........;.|
+00000140 09 05 19 9f a5 b7 dd 48 3f ab f1 aa 36 da 70 96 |.......H?...6.p.|
+00000150 0f f9 f3 bc 80 84 09 a3 76 92 56 17 03 03 00 59 |........v.V....Y|
+00000160 4a ba a9 1c c7 f6 ef 77 8e cc 9a 8c 51 9f 43 1e |J......w....Q.C.|
+00000170 ec 8f f3 33 93 eb 81 db 06 03 97 fd 3f b2 e0 e5 |...3........?...|
+00000180 e7 73 b2 2c 2c f0 c0 a4 51 18 10 79 4e 30 96 3a |.s.,,...Q..yN0.:|
+00000190 d8 26 b1 a0 f4 1b e6 12 fe 74 58 68 97 45 1e 85 |.&.......tXh.E..|
+000001a0 3a db 04 a6 12 5d ba 19 e4 f6 b1 17 f3 04 75 f2 |:....]........u.|
+000001b0 ea 04 db 6c d4 d8 d5 cc fb 17 03 03 00 35 1d c5 |...l.........5..|
+000001c0 cd 92 9c 80 3a ec 3c 06 3e 12 ed 7a 82 23 ab 18 |....:.<.>..z.#..|
+000001d0 67 4a 92 7d 30 e4 57 7b 25 34 a1 54 46 41 b7 60 |gJ.}0.W{%4.TFA.`|
+000001e0 69 cf a2 61 7a 59 6f b3 78 6f 41 0f 7d 9b 4f 00 |i..azYo.xoA.}.O.|
+000001f0 91 c7 93 |...|
+>>> Flow 4 (server to client)
+00000000 17 03 03 01 ca 52 99 bb 74 e8 8e ab 48 c6 03 1d |.....R..t...H...|
+00000010 f9 9a a8 be e4 b1 dc b9 8d e5 a8 11 2b d6 54 63 |............+.Tc|
+00000020 6f 0d dc 6e d7 55 c8 af 3c 88 c4 3e ab 30 ab b9 |o..n.U..<..>.0..|
+00000030 69 94 75 60 0f 75 77 e1 b1 29 09 9f db c1 74 43 |i.u`.uw..)....tC|
+00000040 92 2a 55 b9 ae 71 12 79 b9 4d ba 82 84 96 b1 01 |.*U..q.y.M......|
+00000050 14 b5 9c 5d 0c fe eb cc a6 44 e5 0b 93 1c 8d 45 |...].....D.....E|
+00000060 d8 aa 7c 1b d1 47 5a 36 46 f8 f5 82 c7 fe 2b f3 |..|..GZ6F.....+.|
+00000070 46 17 9f 0c 03 df cd dd 0a 38 77 28 45 45 f2 3c |F........8w(EE.<|
+00000080 06 1d 88 1b 55 d8 8f 70 9b a8 bb 37 a8 41 81 a6 |....U..p...7.A..|
+00000090 a7 f4 28 c1 f1 d2 8b ba 98 0e 35 92 88 ac cb b6 |..(.......5.....|
+000000a0 25 dd 5e 62 d5 e7 e9 da 4f 0e 55 b4 36 4d 09 20 |%.^b....O.U.6M. |
+000000b0 73 ef b3 6c 4c 6d c6 6a e9 f3 f8 28 74 0d 50 b0 |s..lLm.j...(t.P.|
+000000c0 ad 75 f7 c5 fb eb bc 06 6b 07 23 80 70 87 8e a8 |.u......k.#.p...|
+000000d0 3e 66 87 07 53 8e 19 bb 3f 94 f1 9e 4b 05 f6 55 |>f..S...?...K..U|
+000000e0 34 3b d0 14 36 32 66 6a 62 8a ec 22 a1 82 0a 95 |4;..62fjb.."....|
+000000f0 95 b6 85 0c 2c c4 b4 3e 00 59 2a 1e c6 03 4b 2a |....,..>.Y*...K*|
+00000100 e4 06 d5 29 e5 a1 e1 57 b0 a1 45 1b b7 0c 12 3f |...)...W..E....?|
+00000110 0d 31 1a b2 ef 3d 90 73 3a 39 28 00 8a 0d e0 20 |.1...=.s:9(.... |
+00000120 83 a7 32 b8 02 d0 9f 90 f3 b3 ca df 36 ae d4 f8 |..2.........6...|
+00000130 c4 4b 82 06 13 04 66 e7 01 63 4e e8 80 b8 52 c0 |.K....f..cN...R.|
+00000140 8c a4 5b 3f b9 85 48 ac 01 f0 b6 ee db 73 d0 62 |..[?..H......s.b|
+00000150 e2 05 e7 71 7e 87 4b 7b cf d0 a1 77 eb 38 64 85 |...q~.K{...w.8d.|
+00000160 5c 3d af fc e3 17 46 e7 c5 71 c9 63 bf 03 ae 35 |\=....F..q.c...5|
+00000170 7b 60 61 5d 5a 7b 57 88 79 82 55 68 45 a1 59 bc |{`a]Z{W.y.UhE.Y.|
+00000180 e5 3b 5a 31 32 5c 24 13 e3 fc b7 53 41 76 1d 24 |.;Z12\$....SAv.$|
+00000190 7f 08 89 c6 f0 b9 57 3a 4d 91 66 66 e4 57 33 51 |......W:M.ff.W3Q|
+000001a0 1d b9 1e c5 68 9a 6a 74 1e c3 16 de 15 92 e3 d0 |....h.jt........|
+000001b0 0a 64 a4 64 e8 c4 a5 9c 55 30 a9 c3 b0 53 72 54 |.d.d....U0...SrT|
+000001c0 75 d7 a0 7a 54 85 6e 9a 4d ff 9f 13 3c b9 42 17 |u..zT.n.M...<.B.|
+000001d0 03 03 00 1e 6f 06 3f 1c da f6 55 50 05 de 38 9d |....o.?...UP..8.|
+000001e0 07 00 bb 28 32 a5 3f 04 22 4c 6e f2 ea 3a e0 cc |...(2.?."Ln..:..|
+000001f0 5d 5b 17 03 03 00 13 3b b8 7c df 14 b4 ba fa 6e |][.....;.|.....n|
+00000200 2e 61 d6 6b bf b5 ad c2 35 73 |.a.k....5s|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndGiven b/src/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedAndGiven
new file mode 100644
index 0000000..800f999
--- /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 c8 2f b4 54 5b |............/.T[|
+00000010 11 8a 88 a9 a2 9b bf 66 f2 b4 e5 fb 32 af d6 dd |.......f....2...|
+00000020 6c 6c 99 4f d6 48 cd eb 63 6e 1d 20 bb 0a 48 2e |ll.O.H..cn. ..H.|
+00000030 45 4e 86 2d ae d6 fb 3e 0c 3e 9f a3 17 4a e3 39 |EN.-...>.>...J.9|
+00000040 58 a7 92 92 cb 30 03 0d be b5 79 a5 00 04 13 01 |X....0....y.....|
+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 f0 |-.....3.&.$... .|
+000000b0 8e 19 a6 04 b7 f1 b0 cd a1 28 bb 10 60 30 92 dc |.........(..`0..|
+000000c0 bc 7a 1c fc a7 f4 dc 01 2e 88 f3 0e 80 82 71 |.z............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 bb 0a 48 2e |........... ..H.|
+00000030 45 4e 86 2d ae d6 fb 3e 0c 3e 9f a3 17 4a e3 39 |EN.-...>.>...J.9|
+00000040 58 a7 92 92 cb 30 03 0d be b5 79 a5 13 01 00 00 |X....0....y.....|
+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 1a 9d c2 a8 12 c1 |................|
+00000090 c3 97 41 bd 1f 6e 48 98 36 4b 13 cd b9 9f 70 34 |..A..nH.6K....p4|
+000000a0 60 17 03 03 00 3e f8 19 ab 88 f7 15 07 97 72 ec |`....>........r.|
+000000b0 41 6c 0a 64 b3 26 4a 56 21 20 d7 9c a2 84 06 ab |Al.d.&JV! ......|
+000000c0 cb e6 99 1b 45 ce ca e7 c6 57 04 c9 3a 76 84 97 |....E....W..:v..|
+000000d0 fe a3 be 60 b2 2c 53 31 ab cd 49 d5 fc 59 80 69 |...`.,S1..I..Y.i|
+000000e0 38 d3 66 32 17 03 03 02 6d 8f 8b 7a 7d 78 d3 4b |8.f2....m..z}x.K|
+000000f0 98 1e 0b 05 38 60 58 d0 0a 7a f8 a7 70 53 67 ce |....8`X..z..pSg.|
+00000100 ea ed 86 3e 79 9d 37 66 b2 61 be 34 bf 15 5a d8 |...>y.7f.a.4..Z.|
+00000110 4e fb 52 62 8d e2 ae e9 58 b9 bc f9 e9 75 81 16 |N.Rb....X....u..|
+00000120 af fa 92 c3 aa ac d2 2c 7b c2 21 2f b0 0d e9 53 |.......,{.!/...S|
+00000130 d3 e3 ec d5 e7 95 23 83 d9 b1 ff 25 55 47 6a 1c |......#....%UGj.|
+00000140 97 37 84 9a ce 67 15 63 0f ff 24 63 af 43 8a 7d |.7...g.c..$c.C.}|
+00000150 46 63 bb 33 67 7a de 86 b4 6a 70 2d 6a 7f 82 c2 |Fc.3gz...jp-j...|
+00000160 24 3c e1 0f a9 7f 93 76 d2 c9 e2 56 d3 cb b9 17 |$<.....v...V....|
+00000170 97 2f 8a 25 40 dc 35 e4 00 3a 3f 2b 1e 09 1b f2 |./.%@.5..:?+....|
+00000180 12 2a 76 c0 2e cd 17 06 32 a9 f8 08 70 3f 06 fa |.*v.....2...p?..|
+00000190 c7 1b c4 50 4f b8 1e 0f 6f 6a 3a ba f6 28 1b d0 |...PO...oj:..(..|
+000001a0 a7 34 a5 8c 02 fe 35 4f b4 97 45 96 48 bc b9 0d |.4....5O..E.H...|
+000001b0 c9 2f df bd c1 8b 19 44 33 12 90 2c d2 99 09 36 |./.....D3..,...6|
+000001c0 97 3f 29 56 30 77 15 df 15 c9 b1 26 9c f4 6a 59 |.?)V0w.....&..jY|
+000001d0 00 3e d8 28 74 19 6c 38 6c 68 63 16 ab cb f0 3d |.>.(t.l8lhc....=|
+000001e0 ce 30 f6 9c 06 00 06 cc 5a 8e 78 73 af 53 a4 e6 |.0......Z.xs.S..|
+000001f0 49 10 5b 9d 4d f3 7d 48 f0 5d 87 27 d8 7e 58 a6 |I.[.M.}H.].'.~X.|
+00000200 86 51 a0 d6 e8 82 20 6b d3 f9 99 4d 11 b7 49 ad |.Q.... k...M..I.|
+00000210 f9 1a 1b f5 cd 81 81 bd 51 76 a4 5a 5f 35 7a 52 |........Qv.Z_5zR|
+00000220 12 1b 73 f6 f3 1d cf 93 7a 8e a0 1d 4c f3 b2 f5 |..s.....z...L...|
+00000230 16 00 57 21 2f c6 85 af 8c 8b f9 bd 2a f1 ee 15 |..W!/.......*...|
+00000240 ec ee 80 b9 8b 0a 50 36 cb 53 fd ca 53 b4 0e 96 |......P6.S..S...|
+00000250 7b db e6 93 f7 9e 8d e4 6a d5 ff e3 74 31 76 3a |{.......j...t1v:|
+00000260 a8 de ce 06 97 3d 4e 91 c5 cd 85 06 c9 a6 02 91 |.....=N.........|
+00000270 f9 36 33 8d 28 23 54 f5 c3 f0 b2 1a a1 6b b7 c6 |.63.(#T......k..|
+00000280 d1 c3 31 ad d6 6f 0c 44 e4 34 d8 26 b6 ff 06 6f |..1..o.D.4.&...o|
+00000290 f3 56 19 46 8d f3 75 c2 d9 69 4a 5b ff 3a b8 1d |.V.F..u..iJ[.:..|
+000002a0 86 a9 6f 45 dc 3a e4 aa 9b 7d 3a 5a 50 ad c6 f6 |..oE.:...}:ZP...|
+000002b0 8c e3 0e ca b6 7a 99 e7 4b 58 26 c2 18 95 14 a4 |.....z..KX&.....|
+000002c0 f9 ae 79 4f f6 c0 f8 0e d4 52 fb 3c 5d a2 30 9c |..yO.....R.<].0.|
+000002d0 ea d9 8d f4 27 4c 6f 7a 02 45 8f ca 8c b1 bc d2 |....'Loz.E......|
+000002e0 c5 dc 8b 09 d7 c4 0f ea f6 51 be f7 cd 01 1e 78 |.........Q.....x|
+000002f0 a1 37 4a 88 ae 5f c5 79 9c e2 4d c9 74 e7 2e 18 |.7J.._.y..M.t...|
+00000300 86 e8 62 3f 6c 39 73 eb c2 e2 54 0c 13 ca f6 57 |..b?l9s...T....W|
+00000310 20 92 6a 1d 03 28 d0 53 6f 6e cb 57 da 33 20 1a | .j..(.Son.W.3 .|
+00000320 c8 3d 09 73 5f 28 14 6f 4c 16 8c 41 cd 44 ad df |.=.s_(.oL..A.D..|
+00000330 77 08 0f f1 3c 4c 2b 37 03 60 9d 07 85 e7 66 f7 |w...<L+7.`....f.|
+00000340 e7 7f 7b 45 0a db 3f 62 88 ca 84 ff e9 08 32 92 |..{E..?b......2.|
+00000350 07 77 cc c0 b7 31 17 03 03 00 99 d0 7e f0 62 28 |.w...1......~.b(|
+00000360 21 cb 07 5c 54 0b 79 94 26 e3 63 25 57 df e4 79 |!..\T.y.&.c%W..y|
+00000370 32 d1 1d 08 dc 66 76 30 68 62 c1 a7 9c 72 f6 07 |2....fv0hb...r..|
+00000380 e6 0e 30 de ef 4a 6e d8 0d 0e df 40 e7 6e 8b 48 |..0..Jn....@.n.H|
+00000390 07 62 27 7f 97 c8 8d 3f 8d ce b3 e4 9e ed c5 e0 |.b'....?........|
+000003a0 9e ec f2 7b 7e 4d e0 1b 14 69 ef c6 5d 04 5c a6 |...{~M...i..].\.|
+000003b0 1a 41 62 25 79 88 39 0e b5 1a 6c 75 d0 fe 92 6a |.Ab%y.9...lu...j|
+000003c0 7e 4f e2 36 f0 09 b8 a7 1a 4a 3a 94 f6 27 25 7f |~O.6.....J:..'%.|
+000003d0 c9 ad 2e 50 41 64 a4 73 34 d2 4e 02 05 af 68 84 |...PAd.s4.N...h.|
+000003e0 40 81 d9 f7 a9 0b 77 ee 6c 83 0c d5 d5 70 49 e5 |@.....w.l....pI.|
+000003f0 a5 0a 3e 12 17 03 03 00 35 35 88 42 4c 14 18 a9 |..>.....55.BL...|
+00000400 3e 26 15 0a f1 c3 a6 ab 94 a3 72 bd c7 04 22 bc |>&........r...".|
+00000410 67 32 15 16 23 f5 50 97 bc 7f ab f8 ef f0 02 7d |g2..#.P........}|
+00000420 2d 76 01 18 72 18 77 c1 f5 9b e9 e9 97 8d |-v..r.w.......|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 02 11 4b 29 10 c9 7b |...........K)..{|
+00000010 98 9a fa ce 7a 17 a4 7d 15 5f 97 4f 40 67 37 f0 |....z..}._.O@g7.|
+00000020 0b 2d ca 62 77 23 ab 78 d7 9f b6 1d 5c 64 fb 68 |.-.bw#.x....\d.h|
+00000030 70 5f 21 df e1 55 3b e3 bb 8e 61 31 11 ba 2b eb |p_!..U;...a1..+.|
+00000040 de 78 39 5c 31 62 a3 fb 9a 57 a4 50 34 43 76 55 |.x9\1b...W.P4CvU|
+00000050 ae f9 36 b1 35 ee 2b 8d ab c2 70 52 b0 8c d6 1b |..6.5.+...pR....|
+00000060 fe 0f fc 5e 79 c3 cf ab d3 9a 81 af 63 2c b3 f7 |...^y.......c,..|
+00000070 a6 b7 13 c4 70 22 fa 56 6d 77 cb d1 bf a5 9e c8 |....p".Vmw......|
+00000080 74 83 80 f9 9a 19 f3 a3 94 15 72 7c 55 0e 21 47 |t.........r|U.!G|
+00000090 2b a2 d3 b8 74 e1 07 37 7f 12 f6 ad ba 71 e5 ca |+...t..7.....q..|
+000000a0 17 42 2b 78 9e 90 7d 28 b1 f4 dd 7d b8 69 dd c6 |.B+x..}(...}.i..|
+000000b0 eb 3d 93 45 06 ac 5d fe 02 18 b8 f3 8c e4 4e 97 |.=.E..].......N.|
+000000c0 05 8b 36 94 cb 0f 66 64 ed a8 50 22 ba c8 a7 23 |..6...fd..P"...#|
+000000d0 7d f9 d5 4f d5 27 83 f3 b6 09 3f 4f 69 92 6d be |}..O.'....?Oi.m.|
+000000e0 4a 30 02 d2 d5 e6 14 d4 21 e2 c8 5b cb 08 1e 9a |J0......!..[....|
+000000f0 28 f7 f4 13 8c 58 9b 69 2c 55 3d 78 f2 ce 93 89 |(....X.i,U=x....|
+00000100 2f 62 56 ea a3 21 96 f6 e7 ee a4 3d d8 7d 86 4d |/bV..!.....=.}.M|
+00000110 79 c9 3b c8 cf ea a0 6b 5f 29 8c ed c2 d6 73 27 |y.;....k_)....s'|
+00000120 a0 35 bb 2b 8b 6c 4e 59 74 e5 84 c4 d2 1a f1 0d |.5.+.lNYt.......|
+00000130 5c 36 33 f7 42 d6 08 c3 f8 5b ea 27 a1 cc b9 72 |\63.B....[.'...r|
+00000140 d5 b9 4e 17 36 b3 05 29 50 da 52 bc 23 f7 82 82 |..N.6..)P.R.#...|
+00000150 c0 67 2b 80 a2 7f e2 ec b9 12 bb dc b6 04 b6 4f |.g+............O|
+00000160 87 15 16 13 de c4 1c 04 71 33 ba d7 a7 da f1 f5 |........q3......|
+00000170 77 c6 4e 8e b2 65 a1 6c a8 c2 5b a1 f5 da 49 6c |w.N..e.l..[...Il|
+00000180 85 ee 21 8d 10 6b 82 bf 0c 0f 7e 33 8b 5e 44 5b |..!..k....~3.^D[|
+00000190 70 db bc 76 40 a0 5c 02 f6 8a 9b de aa a4 b2 94 |p..v@.\.........|
+000001a0 d0 e0 b7 60 af df ad 3d e3 17 a9 60 e0 d9 a8 3e |...`...=...`...>|
+000001b0 c6 06 9b ad 97 0b dc 21 16 9d 42 29 74 a1 f5 03 |.......!..B)t...|
+000001c0 d4 15 0d ee fd fa 6b 85 12 2f 8c 26 fd 96 ce 85 |......k../.&....|
+000001d0 a5 b7 ba bb ac 8a 6d 54 f5 fd e6 6c 32 24 a9 e7 |......mT...l2$..|
+000001e0 1a 11 bf 4d cb f9 18 9a b8 1e a6 e4 1f 61 b1 ce |...M.........a..|
+000001f0 1c ca 5d 81 e7 84 e0 a9 4e c7 f9 5d 71 72 76 4b |..].....N..]qrvK|
+00000200 65 ca 3a a4 4d d8 ec 82 aa 33 80 bb 15 48 2d 7c |e.:.M....3...H-||
+00000210 4e 5e d2 ec 13 1a e7 03 d5 29 95 80 17 03 03 00 |N^.......)......|
+00000220 99 60 a2 43 34 23 c0 a4 4c 0a 18 c5 27 96 2f 7c |.`.C4#..L...'./||
+00000230 af 2b 2c 36 f2 9b cf 93 e7 3e 79 3b 20 d4 3b 60 |.+,6.....>y; .;`|
+00000240 a2 ef af 36 d5 45 d4 20 89 be 80 1d 1e ca f7 19 |...6.E. ........|
+00000250 35 8f 26 3f be c0 a2 f6 c6 85 a3 88 76 cd 06 f9 |5.&?........v...|
+00000260 4f ff 54 79 6c ac 33 71 31 90 70 36 eb 9c c1 b4 |O.Tyl.3q1.p6....|
+00000270 4a c8 3a 52 85 2b be 4a 19 8a 24 fd 6f 08 47 19 |J.:R.+.J..$.o.G.|
+00000280 84 88 a0 48 f6 17 80 f8 fe 9e 21 68 e1 75 17 14 |...H......!h.u..|
+00000290 d4 e2 3a e2 de 9d 19 56 ad cc 33 13 f3 52 b2 1b |..:....V..3..R..|
+000002a0 f4 65 04 05 79 9f 3e 14 fb 1f 9c d1 c4 53 c0 93 |.e..y.>......S..|
+000002b0 49 ad 3c 2e de c1 b4 fe be b3 17 03 03 00 35 32 |I.<...........52|
+000002c0 81 98 1a 6c 38 ca 67 64 c5 30 0b 81 7d fd a1 b9 |...l8.gd.0..}...|
+000002d0 2e af 41 1d e9 b7 31 17 d8 08 ce d5 f6 12 4d da |..A...1.......M.|
+000002e0 fc db fb e1 fa 5b cd 70 12 e7 bb 26 dd 53 9c 43 |.....[.p...&.S.C|
+000002f0 02 06 1f 70 |...p|
+>>> Flow 4 (server to client)
+00000000 17 03 03 02 8b 8e b1 29 40 b6 53 bc 89 c7 87 69 |.......)@.S....i|
+00000010 4c 6d 5b 61 d9 ba 5b 96 22 ac 57 71 58 f8 0e ea |Lm[a..[.".WqX...|
+00000020 81 ea bf f9 34 6d a0 ce 1f d2 97 52 62 2b 9e f7 |....4m.....Rb+..|
+00000030 03 28 96 56 c0 a1 0e 69 7c 98 13 e5 91 8c 48 5f |.(.V...i|.....H_|
+00000040 4e 78 87 14 38 f8 fa 3c 17 97 f9 de 38 3b cf 0f |Nx..8..<....8;..|
+00000050 d9 dd 41 0a bb 65 ca a7 0b fd a5 11 c2 c3 6a b8 |..A..e........j.|
+00000060 5a e1 68 a1 8d f8 35 9d c6 e1 3e e1 03 a9 06 ee |Z.h...5...>.....|
+00000070 1f 92 ca b5 f4 df 3e e5 69 63 9e a2 ea 5e b8 d9 |......>.ic...^..|
+00000080 26 31 9e 25 de a8 ea 44 1a c0 86 0b 38 75 04 dc |&1.%...D....8u..|
+00000090 2d 37 ad 40 e3 2f d1 b0 9e 9e 64 57 8b 31 20 d6 |-7.@./....dW.1 .|
+000000a0 16 64 fd 1b c1 01 58 af 4b 88 49 23 7a f6 a2 15 |.d....X.K.I#z...|
+000000b0 ca 02 4b d6 6d 7c f8 7a c9 c0 0d 32 6e 1d 83 ca |..K.m|.z...2n...|
+000000c0 47 e5 6f 86 a0 f7 8b 50 1d 91 ec fa 2b 4a 72 f7 |G.o....P....+Jr.|
+000000d0 a0 09 f1 65 fb 81 32 d2 a0 be 18 07 9f 5d 89 98 |...e..2......]..|
+000000e0 08 09 a6 1d 9a 5a 10 67 81 58 82 00 9d 01 48 a8 |.....Z.g.X....H.|
+000000f0 5b df 54 b3 cd 84 87 e0 41 e6 1e 47 46 33 56 0c |[.T.....A..GF3V.|
+00000100 67 82 b9 bc 28 68 f3 5b 51 a8 c0 0e 43 14 62 bb |g...(h.[Q...C.b.|
+00000110 8a bd 3f 4d d6 33 c4 76 4f c1 06 f8 9b bf 64 41 |..?M.3.vO.....dA|
+00000120 6c e5 40 8d 93 4a 6b 6f fe 72 6b db ac 35 b4 fc |l.@..Jko.rk..5..|
+00000130 84 13 fa 8a 7d 35 e3 73 12 eb 1a 5f a9 e2 28 53 |....}5.s..._..(S|
+00000140 0c 6d 41 ec 4b 76 f5 d9 48 2a c2 85 2a 1f 7d 61 |.mA.Kv..H*..*.}a|
+00000150 f6 1f 27 ef 47 c9 c7 b3 19 5c 07 d5 18 ec fd 3e |..'.G....\.....>|
+00000160 78 41 cb a4 3a 47 22 cf 7e 7e 17 be 27 c4 90 ce |xA..:G".~~..'...|
+00000170 2a cb cd ed 0f a3 bf 1e 4c 62 7a 80 ff 21 38 c5 |*.......Lbz..!8.|
+00000180 c2 37 9f 62 4b d8 c0 9e df ae 3c 69 cd 25 f5 65 |.7.bK.....<i.%.e|
+00000190 ec f6 c2 0e 0f f0 b2 12 85 c4 2a 4b 8f 18 1a 0a |..........*K....|
+000001a0 fa 4d 12 5f ee d4 11 64 21 f9 c7 c4 a6 ba e5 3b |.M._...d!......;|
+000001b0 e9 54 ec ee e6 d3 09 31 9f 6e 99 ec 71 7e 42 5d |.T.....1.n..q~B]|
+000001c0 78 88 ba eb 9f dd 99 59 fe 4e 29 1a 2e 35 12 4b |x......Y.N)..5.K|
+000001d0 98 d4 14 79 80 b7 86 d3 da b5 c8 a6 34 cb 06 57 |...y........4..W|
+000001e0 a6 70 5c 6d 15 0b a7 ec c9 ab fb 24 ad b7 c0 2b |.p\m.......$...+|
+000001f0 ec fb 9b d4 57 b1 44 86 cf 75 c4 de c6 32 f9 01 |....W.D..u...2..|
+00000200 ab 84 85 17 2a 0a 7e 48 e9 94 28 0c ba a8 98 a8 |....*.~H..(.....|
+00000210 b2 36 89 62 ed 0d d8 e8 af 91 1b fd f8 97 25 c9 |.6.b..........%.|
+00000220 56 27 ff 1b d8 56 23 ec 96 8f ed 7b db 80 1e d4 |V'...V#....{....|
+00000230 b8 79 d4 23 d2 3c 89 38 32 14 b9 4e b4 55 99 1f |.y.#.<.82..N.U..|
+00000240 4f 56 3f 65 c7 b8 bd 28 47 f8 74 50 bb 16 5f de |OV?e...(G.tP.._.|
+00000250 e1 4d bf d9 bf 0e c0 57 3b a4 7d 7a 95 42 49 95 |.M.....W;.}z.BI.|
+00000260 b2 e2 99 68 72 38 9b 87 b6 c0 4c d5 b9 da 08 81 |...hr8....L.....|
+00000270 27 f8 5f 68 30 fd 01 7f c4 d5 74 9f e6 3f 28 93 |'._h0.....t..?(.|
+00000280 83 18 38 bd c5 cf be c7 a1 bd 65 a1 74 fb cc e9 |..8.......e.t...|
+00000290 17 03 03 00 1e c3 24 ce a6 69 b8 6c fe 2a 71 a9 |......$..i.l.*q.|
+000002a0 74 4a 04 8b 40 f4 06 06 99 e0 52 fd 13 78 b2 08 |tJ..@.....R..x..|
+000002b0 b7 c1 8a 17 03 03 00 13 ea fb 49 f8 a7 37 b2 f0 |..........I..7..|
+000002c0 ef 9d 6b 7e 68 04 5a 27 fa 36 a5 |..k~h.Z'.6.|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedNotGiven b/src/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedNotGiven
new file mode 100644
index 0000000..fb2fb34
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-ClientAuthRequestedNotGiven
@@ -0,0 +1,104 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 ca 01 00 00 c6 03 03 15 b6 db 09 24 |...............$|
+00000010 50 ea d6 f7 ae d7 32 2f 72 25 23 db 11 ad 6f c1 |P.....2/r%#...o.|
+00000020 5d 62 af e7 93 63 1a 8b f3 82 80 20 5f 15 2e 86 |]b...c..... _...|
+00000030 86 2c 2e 2f 82 11 3c d2 9f 00 32 d4 3d 05 04 fa |.,./..<...2.=...|
+00000040 36 41 8d dc 30 ce a6 2b 6e d4 3c 9c 00 04 13 01 |6A..0..+n.<.....|
+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 98 |-.....3.&.$... .|
+000000b0 b7 40 03 d8 a3 4c 9e 16 82 77 16 9b c1 17 3a 2a |.@...L...w....:*|
+000000c0 fc 25 73 5d 2d 5c dc 15 78 36 12 7a 28 f2 0e |.%s]-\..x6.z(..|
+>>> 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 5f 15 2e 86 |........... _...|
+00000030 86 2c 2e 2f 82 11 3c d2 9f 00 32 d4 3d 05 04 fa |.,./..<...2.=...|
+00000040 36 41 8d dc 30 ce a6 2b 6e d4 3c 9c 13 01 00 00 |6A..0..+n.<.....|
+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 14 12 e8 30 75 5a |.............0uZ|
+00000090 a4 27 7d 83 2e 51 0e 48 14 7b 53 0c 65 24 71 c5 |.'}..Q.H.{S.e$q.|
+000000a0 44 17 03 03 00 3e 34 38 ac c0 b5 05 e1 03 e1 a3 |D....>48........|
+000000b0 d3 42 ec e3 94 96 e7 a3 05 d8 44 ca 1d 89 b6 6f |.B........D....o|
+000000c0 52 ce 3c 7d 61 f1 b4 a2 83 31 ab cf e7 ca 53 57 |R.<}a....1....SW|
+000000d0 b8 eb f4 7a 8a 7c ce 31 fe a4 b6 c7 a5 ed f2 2d |...z.|.1.......-|
+000000e0 da 36 d6 49 17 03 03 02 6d 2c b4 e1 f3 87 4e c7 |.6.I....m,....N.|
+000000f0 ab db ea fa 0d 31 20 f2 1e 63 1d 10 bd 61 98 a2 |.....1 ..c...a..|
+00000100 50 8d 12 0d c8 5c f8 e4 97 9c 5f f3 47 f4 60 a5 |P....\...._.G.`.|
+00000110 59 16 a2 27 06 94 80 93 af 1e 9d c0 9a 23 20 bf |Y..'.........# .|
+00000120 a4 5a 26 2c 37 86 d8 8a b7 e2 bd e2 4f ab 53 65 |.Z&,7.......O.Se|
+00000130 bd 34 2c 1a 88 72 bf 8f 20 0c e2 51 0f ea 3f 47 |.4,..r.. ..Q..?G|
+00000140 dc 0e cd 21 3c d0 cc 7d 38 b8 b9 1b 20 67 83 a9 |...!<..}8... g..|
+00000150 af 4c f7 7b c0 d9 00 5c 66 e3 d7 2e 3b 6a b5 9c |.L.{...\f...;j..|
+00000160 6e f6 ed 96 25 3c ce ea db fa 85 ba e2 d8 4c 95 |n...%<........L.|
+00000170 92 06 0a 38 19 7f 52 30 2b ef fc 23 c6 b3 e5 d1 |...8..R0+..#....|
+00000180 83 2e 56 65 d6 ef 06 3a 71 d6 39 e9 16 62 65 78 |..Ve...:q.9..bex|
+00000190 59 c1 9f 7f 99 be c2 b9 0b 56 0a db 26 ec 16 15 |Y........V..&...|
+000001a0 be 27 cb bb cf 4a 9c a1 fd 5c 7d 5d c6 df a2 ed |.'...J...\}]....|
+000001b0 f1 70 74 03 40 7c 8f af ea 3c 6a c7 c6 30 98 4c |.pt.@|...<j..0.L|
+000001c0 5a c1 e5 33 fb 56 8f 02 df 22 01 7b 11 f7 8a 5f |Z..3.V...".{..._|
+000001d0 70 75 39 96 f9 1f 1b c9 d4 64 d8 8c a2 04 33 fd |pu9......d....3.|
+000001e0 5e 07 37 30 12 2a 91 21 6f 83 23 95 2b 5a 72 13 |^.70.*.!o.#.+Zr.|
+000001f0 5a 0d 4a 05 57 c9 dd fc 77 ff 74 b1 5d 14 25 70 |Z.J.W...w.t.].%p|
+00000200 ee 8e 93 1b bc d3 3c d9 ba 3f 8a f0 79 45 a2 c6 |......<..?..yE..|
+00000210 23 f2 7d dc 21 4f cd 01 a5 4a 2c 46 96 21 5c 15 |#.}.!O...J,F.!\.|
+00000220 30 eb 1d 44 0f e7 fc 45 6b d5 e6 33 f5 88 71 53 |0..D...Ek..3..qS|
+00000230 96 2a c1 c7 61 cb 1d 6a 95 8d ee 64 8a 58 1c a6 |.*..a..j...d.X..|
+00000240 6a c9 75 86 6a f0 d2 4c f0 1c 6d 36 18 fd 6b d8 |j.u.j..L..m6..k.|
+00000250 da 3d d0 0f 7b d3 33 f8 30 c9 f2 1a c2 1d 55 3d |.=..{.3.0.....U=|
+00000260 2d 71 15 6d 26 f7 ad 05 23 de b0 50 83 f5 c0 39 |-q.m&...#..P...9|
+00000270 09 62 73 d6 c2 b9 53 c9 85 ff b9 ff 60 23 5c 06 |.bs...S.....`#\.|
+00000280 f9 87 e3 25 28 cf 75 9d 58 26 76 9e 55 91 71 aa |...%(.u.X&v.U.q.|
+00000290 92 ea 3c 97 d4 43 4b d8 b8 5f 8a fc 4b a4 ad a0 |..<..CK.._..K...|
+000002a0 aa 5b 91 b6 8d 5d 84 19 40 13 93 5a 33 a9 fd 65 |.[...]..@..Z3..e|
+000002b0 86 ca b3 fe be e7 ef 75 a5 b2 35 8d 6f cb ed 27 |.......u..5.o..'|
+000002c0 17 2e 72 f8 46 60 f1 90 79 46 30 6b 42 31 09 4b |..r.F`..yF0kB1.K|
+000002d0 fa a4 9b 69 4c 86 0c 9f e4 6b 13 08 c4 9c 81 a3 |...iL....k......|
+000002e0 f3 74 99 1f d7 c1 d6 7c 12 25 25 92 3a 05 33 eb |.t.....|.%%.:.3.|
+000002f0 3b be 38 f3 07 1d 3b 9d a9 1b cc bc 37 2d 41 1d |;.8...;.....7-A.|
+00000300 61 c6 ac b7 30 30 78 df b4 be f6 1d d6 e5 c8 af |a...00x.........|
+00000310 42 9b a7 b3 9c 4c 70 2c 23 e8 d5 8b 14 e0 21 d1 |B....Lp,#.....!.|
+00000320 66 af 2a 3a b4 f0 fa 44 88 2e 05 7a 2a 36 b2 21 |f.*:...D...z*6.!|
+00000330 27 5f a7 ff 3a cf dc 63 9e bd 81 d1 30 06 4b da |'_..:..c....0.K.|
+00000340 ed f5 3f 1e 69 83 9b e2 7c 58 26 fa de d9 49 8c |..?.i...|X&...I.|
+00000350 96 35 d0 37 63 08 17 03 03 00 99 4b 17 f2 3b bc |.5.7c......K..;.|
+00000360 f3 b5 e2 0a da dd 4f 17 49 78 51 9b 58 b1 5c 79 |......O.IxQ.X.\y|
+00000370 d7 bd ac ee b9 25 24 9e 3d 28 37 ea 81 3c 98 ac |.....%$.=(7..<..|
+00000380 c6 bd a8 e2 8a b4 f7 15 a3 07 b0 2c 09 de 62 4d |...........,..bM|
+00000390 be 09 6e 3c 4f 7d c2 0e 35 d7 22 39 0e 8b 0a 99 |..n<O}..5."9....|
+000003a0 c8 60 21 cf bd 41 57 da 69 47 fe 6e 15 22 90 a7 |.`!..AW.iG.n."..|
+000003b0 34 51 64 d2 3a b6 8e 6e 28 a6 e3 42 1e 45 d9 9a |4Qd.:..n(..B.E..|
+000003c0 95 71 82 a8 18 2b 13 93 ed 8f dd 74 8e 20 6e c7 |.q...+.....t. n.|
+000003d0 09 35 94 92 6b 98 9c c8 2c 03 30 16 67 f1 ee 4d |.5..k...,.0.g..M|
+000003e0 26 7c be ae 38 83 e3 b9 e4 60 cc e3 6b 3f 8e ad |&|..8....`..k?..|
+000003f0 63 90 c5 25 17 03 03 00 35 d9 2b cb 6f 6c 5b ac |c..%....5.+.ol[.|
+00000400 01 e1 c6 f8 5e 70 62 56 03 a9 a4 19 c4 55 d2 d5 |....^pbV.....U..|
+00000410 96 1f 48 85 13 24 57 f1 34 4c 4e 79 03 ec 84 c2 |..H..$W.4LNy....|
+00000420 ce c6 83 3c 71 1d 93 6d d7 e3 7a e0 4a 11 |...<q..m..z.J.|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 19 83 88 d2 c3 d4 |................|
+00000010 a8 98 6c 8f fa 1b 52 a5 83 58 e3 62 89 3e 22 a3 |..l...R..X.b.>".|
+00000020 37 b8 ee 13 17 03 03 00 35 b5 5f aa fd ca 85 74 |7.......5._....t|
+00000030 ee c6 06 d9 2e d8 4f 7d 87 a2 b7 20 80 a5 3b 97 |......O}... ..;.|
+00000040 41 bc 80 20 af b5 c4 66 26 2e 39 fd 81 e0 1a a0 |A.. ...f&.9.....|
+00000050 6f c3 08 d0 23 c2 27 49 91 58 77 15 2d 49 |o...#.'I.Xw.-I|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 93 10 f4 e9 f1 51 30 25 9e f0 c4 d2 |.........Q0%....|
+00000010 b8 f4 4b ad dd 89 ad ab 1a 39 88 44 98 a2 53 4e |..K......9.D..SN|
+00000020 1c e9 bb 4a b7 c1 d8 cc bc 76 e6 a8 e6 41 b9 42 |...J.....v...A.B|
+00000030 c8 7a 0a f4 35 73 cc 9f 9d 30 ff 4e e3 44 89 a5 |.z..5s...0.N.D..|
+00000040 d0 2b 88 36 0a 87 72 b4 bf 48 6a 4e 2e 03 1a 96 |.+.6..r..HjN....|
+00000050 1e 01 07 90 61 b0 f1 c5 58 e0 48 30 db d6 e9 5c |....a...X.H0...\|
+00000060 88 05 0d 47 fc d1 33 6e 7e c4 fb 81 e3 80 ce 67 |...G..3n~......g|
+00000070 93 59 5e 68 39 6c b2 c3 c3 56 09 61 e5 a1 d6 d9 |.Y^h9l...V.a....|
+00000080 95 3a 70 6a 5c 4a 51 24 d9 e7 ed 88 7f 6c 32 0a |.:pj\JQ$.....l2.|
+00000090 2d 5d 79 40 75 c9 b9 d4 17 03 03 00 1e 24 cc 07 |-]y@u........$..|
+000000a0 53 2b 27 c1 36 47 88 b8 3c 91 9e 8b 13 da 9d 3c |S+'.6G..<......<|
+000000b0 f9 65 9d 78 ed 92 36 11 41 fe 42 17 03 03 00 13 |.e.x..6.A.B.....|
+000000c0 2b 52 80 d0 d5 39 77 77 38 ad e0 ad 78 f8 0a 59 |+R...9ww8...x..Y|
+000000d0 96 18 7e |..~|
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..d2b0250
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-ECDHE-ECDSA-AES
@@ -0,0 +1,96 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 dc 01 00 00 d8 03 03 90 bc cf 62 d0 |..............b.|
+00000010 bc 89 6b 84 ad 18 87 f5 9c 96 0e 02 3f ae a5 4b |..k.........?..K|
+00000020 80 70 f8 54 47 b1 78 03 48 4d 06 20 ae 9e 3c 17 |.p.TG.x.HM. ..<.|
+00000030 1a c6 fa 52 84 da ea a9 9c 08 e7 10 65 3a 65 4e |...R........e:eN|
+00000040 d1 65 61 40 bf 7c ee db d4 f2 73 ff 00 04 13 01 |.ea@.|....s.....|
+00000050 00 ff 01 00 00 8b 00 00 00 0e 00 0c 00 00 09 31 |...............1|
+00000060 32 37 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 |27.0.0.1........|
+00000070 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 00 18 |................|
+00000080 00 16 00 00 00 17 00 00 00 0d 00 1e 00 1c 04 03 |................|
+00000090 05 03 06 03 08 07 08 08 08 09 08 0a 08 0b 08 04 |................|
+000000a0 08 05 08 06 04 01 05 01 06 01 00 2b 00 03 02 03 |...........+....|
+000000b0 04 00 2d 00 02 01 01 00 33 00 26 00 24 00 1d 00 |..-.....3.&.$...|
+000000c0 20 ad 11 a7 07 20 9c cb 33 96 f4 0d 78 a1 89 55 | .... ..3...x..U|
+000000d0 6c af 70 f4 ac d6 cb d9 0d 1b 13 fa 50 de 68 17 |l.p.........P.h.|
+000000e0 1d |.|
+>>> 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 ae 9e 3c 17 |........... ..<.|
+00000030 1a c6 fa 52 84 da ea a9 9c 08 e7 10 65 3a 65 4e |...R........e:eN|
+00000040 d1 65 61 40 bf 7c ee db d4 f2 73 ff 13 01 00 00 |.ea@.|....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 f1 16 14 8f 0a b5 |................|
+00000090 92 fa 55 d7 fb 6c 33 04 ae c6 ed 3b 90 27 e9 ae |..U..l3....;.'..|
+000000a0 e8 17 03 03 02 22 ca b1 97 19 9d da 2e 1d 12 f4 |....."..........|
+000000b0 05 af 35 28 1e 85 9d 28 81 f0 5a 83 46 9c df f7 |..5(...(..Z.F...|
+000000c0 58 2e 30 fa b9 07 00 cf fe 69 37 5e f2 75 a0 ef |X.0......i7^.u..|
+000000d0 f3 ab 60 0b c5 09 72 bd b4 42 2f 45 24 3e 82 d0 |..`...r..B/E$>..|
+000000e0 f1 a1 dd 3a de 6a b9 9d 85 2b 83 75 47 c9 d2 c3 |...:.j...+.uG...|
+000000f0 25 91 85 c2 a1 97 6a 62 dd aa 19 11 94 e2 6b f9 |%.....jb......k.|
+00000100 7d 5a bc 5e d4 64 bc 74 44 85 d1 7a eb 3a ef d5 |}Z.^.d.tD..z.:..|
+00000110 96 f4 22 64 61 2b 79 77 ac 8b 61 69 cc eb ad fd |.."da+yw..ai....|
+00000120 38 5e 61 74 d9 4f 70 82 06 3b 3e f8 a8 53 7c e8 |8^at.Op..;>..S|.|
+00000130 9d 98 43 a1 af 86 ba d9 64 64 f0 e0 b0 8f 39 6b |..C.....dd....9k|
+00000140 16 d6 92 09 8d 5b d0 34 f4 14 60 69 a0 28 73 3a |.....[.4..`i.(s:|
+00000150 24 7f 81 4e 8b d1 50 49 1a c0 60 92 fd 02 47 6d |$..N..PI..`...Gm|
+00000160 d8 97 62 b2 b4 57 8b d7 d1 b6 bf 19 40 cb 13 09 |..b..W......@...|
+00000170 ef d6 55 66 39 88 29 e0 14 2d 06 98 d6 b6 bf a6 |..Uf9.)..-......|
+00000180 04 10 47 d5 64 fe 38 69 db 33 a4 fc 12 de 83 5b |..G.d.8i.3.....[|
+00000190 c9 8e 76 56 bc f7 dd ac 96 c6 a0 ed e5 43 0b 13 |..vV.........C..|
+000001a0 1e 78 94 18 fd 57 50 79 08 91 18 aa 84 63 4e 46 |.x...WPy.....cNF|
+000001b0 53 db e0 f3 9a 0b d6 13 20 36 aa 56 dd 7a 62 d9 |S....... 6.V.zb.|
+000001c0 3f f6 bd 87 74 3c 86 d1 94 a1 04 79 a8 54 e4 8e |?...t<.....y.T..|
+000001d0 11 d6 52 42 5c 4b 77 18 b9 d7 db f7 48 9a 69 e1 |..RB\Kw.....H.i.|
+000001e0 2d b9 38 38 e4 e8 94 5e b1 7e 2c 81 96 6a a0 ed |-.88...^.~,..j..|
+000001f0 bb 35 6a 8c 93 f2 6d 38 70 df 79 54 d9 45 c8 b8 |.5j...m8p.yT.E..|
+00000200 b2 9c 0f 9f 70 34 8f ac b3 08 f5 3e b1 d2 5a d7 |....p4.....>..Z.|
+00000210 7b ee f3 dc 9a d1 12 c3 77 24 76 9b bf 09 50 a7 |{.......w$v...P.|
+00000220 3c ab 7f 1f 99 b5 02 8c ac 5e 85 cc 53 fd ca e0 |<........^..S...|
+00000230 c7 e2 41 08 fd cb b0 79 0c 8b 02 4f 80 92 c2 cd |..A....y...O....|
+00000240 6c a1 aa 75 d2 4c d1 25 40 7c 14 41 a7 15 20 a3 |l..u.L.%@|.A.. .|
+00000250 a6 81 64 7c c0 c7 2d dd 82 84 ad 2a f4 06 f9 61 |..d|..-....*...a|
+00000260 23 1c dd c6 ef 72 da 6b eb be 41 f0 b4 5f 9a 02 |#....r.k..A.._..|
+00000270 ee a8 f3 bb 05 48 ec 50 a3 ff f3 94 bb d8 a9 6d |.....H.P.......m|
+00000280 92 49 7c bf a1 eb 55 26 08 26 d3 80 d6 cb 05 ea |.I|...U&.&......|
+00000290 d1 db bf 97 3d 10 ff 4e f6 05 33 23 68 95 31 42 |....=..N..3#h.1B|
+000002a0 5a d5 30 61 79 c4 88 7f e1 be 28 ad 72 bb 78 36 |Z.0ay.....(.r.x6|
+000002b0 ba bb 38 75 fb 97 33 b6 28 8c a2 f4 46 fe 37 d8 |..8u..3.(...F.7.|
+000002c0 b0 67 63 97 c1 51 0c 61 17 03 03 00 a4 20 15 70 |.gc..Q.a..... .p|
+000002d0 7a 69 b1 33 c2 e1 f5 9c 2b b2 06 1e 01 a6 7f 03 |zi.3....+.......|
+000002e0 cd 00 13 02 3b 0c 2b 3f 85 d8 ed 6d 81 7e e9 b2 |....;.+?...m.~..|
+000002f0 b6 be 7b 77 51 30 dd b5 fc 93 08 91 9e 46 e2 85 |..{wQ0.......F..|
+00000300 74 3c 9a 04 26 86 b8 6c 98 99 57 7e 36 54 0d 90 |t<..&..l..W~6T..|
+00000310 4c 55 65 77 69 59 b2 e5 5b a3 19 4a b0 72 3d 91 |LUewiY..[..J.r=.|
+00000320 2e 5d 9b 8c 52 a1 e6 f5 22 c6 3c 0d 9b d8 9c b9 |.]..R...".<.....|
+00000330 cb 90 51 bc 16 69 06 30 22 16 62 08 3b 3f 05 99 |..Q..i.0".b.;?..|
+00000340 60 2a cc cf 29 f5 e1 b0 84 81 c8 63 00 d4 d4 13 |`*..)......c....|
+00000350 b5 5d 4c 63 8a 60 3e 44 24 03 30 85 91 4c 3d f2 |.]Lc.`>D$.0..L=.|
+00000360 2c c2 78 f2 c3 4c bb 90 60 0b 66 18 02 e7 5c 85 |,.x..L..`.f...\.|
+00000370 19 17 03 03 00 35 49 76 5f ff 32 3a 09 7a 4b f2 |.....5Iv_.2:.zK.|
+00000380 fe f3 38 b6 76 f4 12 f2 aa a3 ed b6 02 ab 0b b9 |..8.v...........|
+00000390 3b 9d 00 51 f1 5c 96 23 6b 49 f8 32 9f 74 30 32 |;..Q.\.#kI.2.t02|
+000003a0 4d af af ef d5 55 2c ff 2b a0 45 17 03 03 00 93 |M....U,.+.E.....|
+000003b0 6e e0 6a f9 44 af c0 af 95 ab 1e ff fd 97 38 f5 |n.j.D.........8.|
+000003c0 7b 24 70 da e2 4e 8b dc 9b 49 84 fe 73 0a b0 7e |{$p..N...I..s..~|
+000003d0 cf 14 f7 8a 67 e7 74 bd ee 82 93 c6 27 a2 bd 1e |....g.t.....'...|
+000003e0 cb 71 06 af 65 dd f0 d9 91 81 b0 f8 21 34 48 d1 |.q..e.......!4H.|
+000003f0 c4 e0 e3 19 a8 b4 48 b7 3a be 52 e5 7c a8 a3 c2 |......H.:.R.|...|
+00000400 08 6c ac 66 4d 36 cf a1 9d 1f 72 c5 09 20 db 05 |.l.fM6....r.. ..|
+00000410 e5 0a 44 af 4a d8 32 38 19 7d 28 e3 05 23 99 66 |..D.J.28.}(..#.f|
+00000420 f6 ad 77 02 7e 00 67 c1 71 58 b9 89 3c 93 15 95 |..w.~.g.qX..<...|
+00000430 ee 38 e2 ea c0 73 fe da e4 75 6d 38 ca 54 0b bf |.8...s...um8.T..|
+00000440 f0 af 86 |...|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 23 02 12 13 f1 |..........5#....|
+00000010 db fa 70 c0 92 85 8a d3 fa 80 1b 5c a6 22 ff 20 |..p........\.". |
+00000020 5d bf 1d 61 58 34 c0 48 6f e1 26 a6 bf bc 76 c7 |]..aX4.Ho.&...v.|
+00000030 8b da ee 54 64 30 c4 5c b1 61 67 82 29 bb 3f 4b |...Td0.\.ag.).?K|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e 95 c0 53 e2 37 94 09 83 1e 7e 23 |.......S.7....~#|
+00000010 dc 9f 02 5e 91 19 b6 f9 72 0d 38 3f 25 ae b2 5f |...^....r.8?%.._|
+00000020 4b f2 78 17 03 03 00 13 d2 ad 73 d6 f3 21 ab 7c |K.x.......s..!.||
+00000030 02 dd 63 ff cf d7 34 ca 71 3d 70 |..c...4.q=p|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-Ed25519 b/src/crypto/tls/testdata/Server-TLSv13-Ed25519
new file mode 100644
index 0000000..a94597a
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-Ed25519
@@ -0,0 +1,76 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 ca 01 00 00 c6 03 03 a1 5b 14 56 ac |............[.V.|
+00000010 3f 2b b0 8e e9 0b ae 7e f7 3b 3b 20 90 b6 e4 06 |?+.....~.;; ....|
+00000020 c2 b9 71 88 e4 4c 01 28 41 b3 e8 20 49 01 f7 fc |..q..L.(A.. I...|
+00000030 ce 52 3e f4 58 60 56 7d 36 21 ba 23 87 21 f7 36 |.R>.X`V}6!.#.!.6|
+00000040 48 88 22 78 26 37 27 a4 fc 7a 8b ea 00 04 13 03 |H."x&7'..z......|
+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 f4 |-.....3.&.$... .|
+000000b0 2c db e8 c0 9e 7d 52 f6 fa 33 fe f7 9a 66 ca 5f |,....}R..3...f._|
+000000c0 a3 28 e9 80 21 28 b8 ef e9 9f 1e 26 9c cf 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 49 01 f7 fc |........... I...|
+00000030 ce 52 3e f4 58 60 56 7d 36 21 ba 23 87 21 f7 36 |.R>.X`V}6!.#.!.6|
+00000040 48 88 22 78 26 37 27 a4 fc 7a 8b ea 13 03 00 00 |H."x&7'..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 f9 df 7b 4f f9 a1 |............{O..|
+00000090 f7 78 eb 10 59 5c 4f ed 42 09 08 10 0f c7 a4 81 |.x..Y\O.B.......|
+000000a0 8b 17 03 03 01 50 38 d7 96 35 05 7d 3d 3a 60 02 |.....P8..5.}=:`.|
+000000b0 bf 93 37 f2 60 3e 64 cb 1a 6f 9c 69 af 06 ca 70 |..7.`>d..o.i...p|
+000000c0 94 e2 d1 7f 4a 5d c7 57 0e 11 c7 4e 24 c6 ba 57 |....J].W...N$..W|
+000000d0 9f d7 67 3a 0a 8b 93 08 d4 de c5 be 62 79 61 2a |..g:........bya*|
+000000e0 3d 4e 57 f9 98 e5 4f 5e 5a 74 52 5b a4 d0 07 ae |=NW...O^ZtR[....|
+000000f0 8c 2a cb 50 dd b3 76 ab 3a 61 5b 55 83 8e 37 8d |.*.P..v.:a[U..7.|
+00000100 39 e5 4f 58 7e 7a bc 80 26 f6 0f 47 8f 11 55 77 |9.OX~z..&..G..Uw|
+00000110 24 b1 a7 06 d8 d2 30 82 0d 99 39 04 5f 97 d8 1d |$.....0...9._...|
+00000120 99 67 99 89 f0 ee 4f 18 8b 49 24 d3 6a d0 65 c9 |.g....O..I$.j.e.|
+00000130 01 a2 48 54 8b d2 bb 56 d4 0a 73 62 88 fa 70 4e |..HT...V..sb..pN|
+00000140 7f dd 59 5b 14 7b 28 02 07 75 01 4d 41 ab 1d 7e |..Y[.{(..u.MA..~|
+00000150 ef 24 42 ee 85 7f fa 5f 9e f0 9f f2 7f 92 00 52 |.$B...._.......R|
+00000160 ca 73 8a 73 c6 d7 13 f5 9d 31 6f 76 75 db e7 53 |.s.s.....1ovu..S|
+00000170 4d 44 40 8f 47 be bd 0e 71 13 d0 f7 f2 72 67 3a |MD@.G...q....rg:|
+00000180 de b8 da b0 1d 84 85 d0 c2 c4 8d 16 87 68 c7 98 |.............h..|
+00000190 40 0a 92 c8 fb 8a 3a e4 7b 34 43 47 b7 4f 28 8e |@.....:.{4CG.O(.|
+000001a0 11 01 98 88 b6 cd ca aa d4 dc 52 5d f9 cf 55 bb |..........R]..U.|
+000001b0 f3 13 f2 ce dc 67 74 a7 4d 5e 65 6f 18 cd 82 4e |.....gt.M^eo...N|
+000001c0 fc 80 2c 14 17 99 08 6d 59 b3 3f 38 00 52 a2 a3 |..,....mY.?8.R..|
+000001d0 c1 98 84 15 91 82 3f e9 47 82 12 a0 94 dc 19 9e |......?.G.......|
+000001e0 2e b7 25 79 30 b9 81 d6 9f 33 8e 49 80 7a 4c a2 |..%y0....3.I.zL.|
+000001f0 b7 9a e6 17 2c 06 17 03 03 00 59 97 c7 4b ac c3 |....,.....Y..K..|
+00000200 ed b3 bd 82 7a c2 45 a0 18 70 7b 88 fe 8b fd 6b |....z.E..p{....k|
+00000210 83 f2 dd 77 15 74 9c f0 a6 27 22 bf ee 25 53 07 |...w.t...'"..%S.|
+00000220 81 95 3c 91 b3 89 3c ca f9 5b c7 cf bb 32 55 f8 |..<...<..[...2U.|
+00000230 3c 76 70 f6 11 ca 5d 92 aa 78 9e 8a 2f ab e0 6f |<vp...]..x../..o|
+00000240 c0 94 df 24 59 05 83 1a 28 c9 23 c8 e9 92 e1 bf |...$Y...(.#.....|
+00000250 9c 90 99 07 17 03 03 00 35 4c 01 d0 d9 5f b3 6a |........5L..._.j|
+00000260 a3 50 58 45 99 82 f4 a5 52 73 9e 7d 54 62 88 b1 |.PXE....Rs.}Tb..|
+00000270 2a 11 56 be be 57 9c 34 77 88 ab ca a6 48 c8 47 |*.V..W.4w....H.G|
+00000280 a8 25 ff 84 c6 e7 49 4e 9a dd 6f 7f 2c 4f 17 03 |.%....IN..o.,O..|
+00000290 03 00 93 72 a7 27 87 ee 0d f2 27 49 d1 8a 3f 9a |...r.'....'I..?.|
+000002a0 4b 8c 67 72 58 b0 cf 11 24 72 44 6e e1 53 06 1f |K.grX...$rDn.S..|
+000002b0 6a 70 ce c8 46 40 ca a0 6c fd 09 1d b1 58 2a 8f |jp..F@..l....X*.|
+000002c0 13 37 00 3d 02 c0 a8 e2 bc 77 39 83 43 f5 c1 c5 |.7.=.....w9.C...|
+000002d0 d8 5f 32 0a 16 b1 25 4b 74 b8 b8 09 d8 c8 dd 7e |._2...%Kt......~|
+000002e0 c7 6e 03 16 93 f2 1e a2 14 e1 ee 14 ec 8d 59 4f |.n............YO|
+000002f0 f4 b5 50 f0 68 d3 06 ea 22 78 94 18 52 e7 3d 98 |..P.h..."x..R.=.|
+00000300 41 8c 5a bb d0 08 f7 b1 16 91 ce c9 73 41 24 e0 |A.Z.........sA$.|
+00000310 6d ea 7b e5 3f 98 9c d7 3f 91 2c 51 5a 9f ab 82 |m.{.?...?.,QZ...|
+00000320 4a f7 b7 39 f1 b5 |J..9..|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 19 fa 19 c0 ce |..........5.....|
+00000010 09 87 c2 06 69 56 2a 0a a7 9c 79 76 03 1b 70 5e |....iV*...yv..p^|
+00000020 56 2d d4 a1 09 e3 99 f7 a9 7a e5 ba 3e 17 8b b2 |V-.......z..>...|
+00000030 fe da 70 81 d9 30 83 27 b1 da 2e df da 94 75 72 |..p..0.'......ur|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e 83 53 ed 09 07 d3 87 ab 37 a2 08 |......S......7..|
+00000010 a8 50 66 87 97 54 04 38 4b a6 25 f8 ab 75 ac 39 |.Pf..T.8K.%..u.9|
+00000020 52 e2 8d 17 03 03 00 13 86 58 ef 44 c1 59 5e 2e |R........X.D.Y^.|
+00000030 e4 2e df 93 6e 52 76 58 c1 9d 2a |....nRvX..*|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-ExportKeyingMaterial b/src/crypto/tls/testdata/Server-TLSv13-ExportKeyingMaterial
new file mode 100644
index 0000000..8267ca0
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-ExportKeyingMaterial
@@ -0,0 +1,99 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 ce 01 00 00 ca 03 03 26 86 8d 61 97 |...........&..a.|
+00000010 6c da 93 d7 43 5c b3 0c 06 5c c2 cb e0 89 46 9f |l...C\...\....F.|
+00000020 cc b0 a3 cf 41 3d cf 7a 9e 02 bc 20 a6 33 fe 0b |....A=.z... .3..|
+00000030 90 24 8b ed 69 48 86 9b d2 1a 5c 04 66 52 4f 5d |.$..iH....\.fRO]|
+00000040 a4 24 6b d2 84 08 c0 48 a9 55 ef 0c 00 04 13 03 |.$k....H.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 b9 ab 39 93 6b 9f aa 46 0a 61 c6 f8 58 |.. ..9.k..F.a..X|
+000000c0 45 26 16 6f b6 cb 42 52 e8 24 ab cc a4 2d b6 7a |E&.o..BR.$...-.z|
+000000d0 a5 90 67 |..g|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 7a 02 00 00 76 03 03 00 00 00 00 00 |....z...v.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 00 00 00 00 00 00 00 00 20 a6 33 fe 0b |........... .3..|
+00000030 90 24 8b ed 69 48 86 9b d2 1a 5c 04 66 52 4f 5d |.$..iH....\.fRO]|
+00000040 a4 24 6b d2 84 08 c0 48 a9 55 ef 0c 13 03 00 00 |.$k....H.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 e9 4c 8a ed 0c af |...........L....|
+00000090 04 d2 18 14 38 48 c1 71 da 59 db 46 f4 00 0d 19 |....8H.q.Y.F....|
+000000a0 1e 17 03 03 02 6d e0 d2 7b bf 0a 51 48 a9 67 46 |.....m..{..QH.gF|
+000000b0 25 3b 07 e9 68 da 4d cf 47 31 0f 7d ad 4e 0d 6d |%;..h.M.G1.}.N.m|
+000000c0 c3 ad 03 61 4a c0 ae 06 4d b7 84 29 1b 44 49 26 |...aJ...M..).DI&|
+000000d0 f4 99 fc 58 1e 5b f0 15 ee be 19 c3 b3 23 20 f0 |...X.[.......# .|
+000000e0 7a 10 e4 ab c8 00 f6 e4 93 d6 b3 2a fd 14 10 c9 |z..........*....|
+000000f0 72 b2 21 ba 93 50 08 4e d2 1f 3f 64 68 73 3c c7 |r.!..P.N..?dhs<.|
+00000100 11 3c f5 84 61 b0 2c 84 42 0c ef a9 03 a2 74 aa |.<..a.,.B.....t.|
+00000110 3b 07 e0 d5 f5 c4 d1 a8 8e f5 64 0e 52 41 b1 4d |;.........d.RA.M|
+00000120 aa 43 0d f3 6b 0c 19 36 66 fe 4c 73 cd 52 03 2f |.C..k..6f.Ls.R./|
+00000130 61 f1 9d 23 12 e2 b9 69 d9 48 92 07 1b 5d 6f 28 |a..#...i.H...]o(|
+00000140 e1 96 39 d8 59 19 9d 9c bf 99 3a af 03 68 bd 34 |..9.Y.....:..h.4|
+00000150 38 04 9d 8c 9a bf 75 67 74 dd 9c eb 89 13 6d 55 |8.....ugt.....mU|
+00000160 b4 c4 17 11 05 54 d7 f9 d7 5a ed ec d5 15 31 5e |.....T...Z....1^|
+00000170 2f ed 69 fa 99 23 57 e3 62 98 35 27 17 34 e1 c4 |/.i..#W.b.5'.4..|
+00000180 3c 95 3f 69 de 01 aa a9 66 55 4a 40 3a f1 4f 19 |<.?i....fUJ@:.O.|
+00000190 02 2f df 51 0c 69 ec 48 7a 60 f7 72 5e f6 f0 4d |./.Q.i.Hz`.r^..M|
+000001a0 a1 b2 7a 06 df 69 a1 19 42 29 56 5c 67 99 3d 0e |..z..i..B)V\g.=.|
+000001b0 5d da df 7b 93 8e 9a 26 6e 2e 09 c4 30 40 ad a9 |]..{...&n...0@..|
+000001c0 ee 4b bd 21 41 b6 cb fc 97 0f fc a2 cf 26 31 d6 |.K.!A........&1.|
+000001d0 d6 77 96 4e c6 a2 fd 5a 0e cb d5 31 a6 21 e8 76 |.w.N...Z...1.!.v|
+000001e0 a2 48 4d 43 d4 c9 18 b2 21 cc 13 13 84 f2 c2 cf |.HMC....!.......|
+000001f0 60 8f 2e 36 39 8a a8 26 03 1d 51 24 b4 08 c5 5d |`..69..&..Q$...]|
+00000200 96 b9 4a 46 02 41 1f 59 ea 47 a9 37 bc a0 c4 70 |..JF.A.Y.G.7...p|
+00000210 26 d6 8c 11 62 45 1d 92 5d ea 39 cd af af 13 38 |&...bE..].9....8|
+00000220 85 ca a8 74 1a 09 07 f2 7c d6 49 0d 2d ad 1c 9f |...t....|.I.-...|
+00000230 db 8b 56 91 45 51 32 db ca 9c f4 d2 72 09 8a fe |..V.EQ2.....r...|
+00000240 98 9e a8 b5 b2 49 9c 0b e9 3a 42 d0 53 e0 20 6c |.....I...:B.S. l|
+00000250 e3 07 36 ef cc 85 56 fd b4 6e ff d2 7c 96 52 27 |..6...V..n..|.R'|
+00000260 46 c9 3c b3 bf fb 16 0b 61 54 09 9c ac 3b 18 5f |F.<.....aT...;._|
+00000270 5a 01 4b 25 67 22 ef 19 86 a3 3a 80 f0 12 f5 60 |Z.K%g"....:....`|
+00000280 4c 77 cf bd a9 e8 a1 19 d4 8c e1 a8 b2 b8 19 b8 |Lw..............|
+00000290 98 85 c3 da 1a b8 4d 6e 1f 35 73 28 32 3c a0 44 |......Mn.5s(2<.D|
+000002a0 c9 77 46 b8 c6 54 4d 80 67 72 58 c4 e3 0b f3 6c |.wF..TM.grX....l|
+000002b0 43 eb e2 89 f1 30 cc 90 b4 e9 b8 ec e2 5f c1 31 |C....0......._.1|
+000002c0 a2 de 9d e9 fe 9c fe b0 83 b7 aa e9 2e 62 35 89 |.............b5.|
+000002d0 90 0d 36 79 8f 23 bb 7a ae dc db db 1c c3 96 5d |..6y.#.z.......]|
+000002e0 7c 06 e9 1c ee 82 58 46 7c 1b 90 9d cf 2d 31 54 ||.....XF|....-1T|
+000002f0 96 94 58 dc 95 26 85 c7 f4 c9 9c 2b 8a 2f ae b3 |..X..&.....+./..|
+00000300 70 10 bf f1 0e 66 ef f1 1c 66 da 6c 52 d8 6e aa |p....f...f.lR.n.|
+00000310 3a 14 d8 17 03 03 00 99 69 45 ee c3 c9 b3 4d 9a |:.......iE....M.|
+00000320 01 00 70 27 54 8c 12 bb 74 67 e8 88 07 ac 4e ab |..p'T...tg....N.|
+00000330 b1 41 f4 65 ee 3b 06 87 79 5d 9b 1d 70 df 2f f7 |.A.e.;..y]..p./.|
+00000340 e0 88 45 2b a1 b9 ca 67 88 65 65 33 51 41 c0 b2 |..E+...g.ee3QA..|
+00000350 da 6a 7a 7c bf 42 58 8d ae 7b 24 d0 8a f7 47 c0 |.jz|.BX..{$...G.|
+00000360 a9 45 da 24 82 03 a1 65 03 7c 3c 2a bf 48 e2 0d |.E.$...e.|<*.H..|
+00000370 fa cc 3f 00 53 63 5d f9 b4 a1 00 d2 a7 3c 81 64 |..?.Sc]......<.d|
+00000380 8a d5 90 4f b9 58 2b 1e 1d a7 7e ad 3e 8f d4 4a |...O.X+...~.>..J|
+00000390 7b 66 b7 4e 68 04 ac 66 24 6e 76 ed f4 5c aa 52 |{f.Nh..f$nv..\.R|
+000003a0 3d f8 f5 ea d0 0a 74 ba 39 da 21 e0 f1 03 80 cd |=.....t.9.!.....|
+000003b0 5b 17 03 03 00 35 7b 1f 6e 37 6c 15 5b 1b f7 ea |[....5{.n7l.[...|
+000003c0 bf 03 68 5f 15 1f e7 99 a8 64 f1 60 3d e0 b6 5e |..h_.....d.`=..^|
+000003d0 c1 60 18 61 e5 ea dc ab b5 d3 5f 10 1b 5c 3a 1b |.`.a......_..\:.|
+000003e0 c5 fe a6 d3 fc 45 6b db b1 27 60 17 03 03 00 93 |.....Ek..'`.....|
+000003f0 e3 f1 5f f1 18 a6 ab 67 88 e4 5a f9 fd 71 77 4b |.._....g..Z..qwK|
+00000400 6c 0d 98 ef 71 72 2a aa d2 0a 2d 72 ac 40 57 2d |l...qr*...-r.@W-|
+00000410 73 ad 77 cd 01 19 19 be e7 49 d4 6a aa 97 f9 40 |s.w......I.j...@|
+00000420 b1 85 cc bb 5c 57 1a 17 a8 48 65 d3 4d e9 a9 29 |....\W...He.M..)|
+00000430 4b 08 6b b3 33 2c 97 d0 89 0a 50 e2 66 06 c6 63 |K.k.3,....P.f..c|
+00000440 c3 6f 8d 5e ab a4 af 7a 6a 5e 25 8d 4a 17 ea aa |.o.^...zj^%.J...|
+00000450 67 8a ad af c3 1e d6 47 db a5 b5 db 32 1b 83 f8 |g......G....2...|
+00000460 2d f9 bc 99 28 07 0d d0 fe 34 bf 52 ae 59 27 40 |-...(....4.R.Y'@|
+00000470 cd 0e 4d 4d 12 28 21 01 30 38 b1 c3 df 63 e9 9e |..MM.(!.08...c..|
+00000480 34 91 84 |4..|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 1d d8 d0 a8 ec |..........5.....|
+00000010 04 45 13 43 a1 72 38 4e 54 85 7a a2 17 dc eb 39 |.E.C.r8NT.z....9|
+00000020 36 7d 50 25 5f d3 0d 7f c3 a7 75 93 e9 1e 17 0a |6}P%_.....u.....|
+00000030 a3 d7 a8 74 23 98 5e 3a 3a 4c 2c d3 78 b4 04 48 |...t#.^::L,.x..H|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e 53 e2 0d f2 62 e8 be 84 e0 33 1a |.....S...b....3.|
+00000010 56 bc 45 f9 0b 69 63 72 03 f3 34 c6 72 d8 f9 c4 |V.E..icr..4.r...|
+00000020 ba 53 3d 17 03 03 00 13 11 b5 0d 7f d4 e7 51 90 |.S=...........Q.|
+00000030 39 be 2b d8 d6 7c e8 12 ea 61 83 |9.+..|...a.|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-HelloRetryRequest b/src/crypto/tls/testdata/Server-TLSv13-HelloRetryRequest
new file mode 100644
index 0000000..95eefd2
--- /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 16 5e f5 e2 4e |............^..N|
+00000010 27 ce 8e 88 0b e9 13 6d 12 a6 6d 27 c9 ab 95 47 |'......m..m'...G|
+00000020 6f 9d 5d a0 92 64 35 c1 b6 70 90 20 ff 47 6f 67 |o.]..d5..p. .Gog|
+00000030 69 49 88 2a 84 69 79 48 fe cc 92 db 6e 9e ab 47 |iI.*.iyH....n..G|
+00000040 8e 47 10 58 db ad 22 8e da bb 86 e6 00 04 13 03 |.G.X..".........|
+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 7e a4 de 34 df 01 99 |3.&.$... ~..4...|
+000000b0 37 77 f7 de 6a e2 79 e7 63 eb 86 6c 62 61 fd b0 |7w..j.y.c..lba..|
+000000c0 c6 95 04 c8 63 29 cd 32 00 |....c).2.|
+>>> 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 ff 47 6f 67 |..^......3. .Gog|
+00000030 69 49 88 2a 84 69 79 48 fe cc 92 db 6e 9e ab 47 |iI.*.iyH....n..G|
+00000040 8e 47 10 58 db ad 22 8e da bb 86 e6 13 03 00 00 |.G.X..".........|
+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 16 5e f5 e2 4e 27 ce 8e 88 0b e9 13 6d 12 a6 |..^..N'......m..|
+00000020 6d 27 c9 ab 95 47 6f 9d 5d a0 92 64 35 c1 b6 70 |m'...Go.]..d5..p|
+00000030 90 20 ff 47 6f 67 69 49 88 2a 84 69 79 48 fe cc |. .GogiI.*.iyH..|
+00000040 92 db 6e 9e ab 47 8e 47 10 58 db ad 22 8e da bb |..n..G.G.X.."...|
+00000050 86 e6 00 04 13 03 00 ff 01 00 00 94 00 0b 00 04 |................|
+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 ca c3 69 88 b3 ed f4 ad 7f 9c 03 6c 7a 44 55 d6 |..i........lzDU.|
+000000c0 68 1d a4 27 67 57 d7 27 08 27 e8 b9 c9 32 49 a2 |h..'gW.'.'...2I.|
+000000d0 e4 f6 c2 f2 62 bd 74 67 77 f9 26 27 ee d7 a7 f0 |....b.tgw.&'....|
+000000e0 9c 9a 41 cd 8b bf 76 25 df ff 5a 9f 4e f5 41 95 |..A...v%..Z.N.A.|
+>>> 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 ff 47 6f 67 |........... .Gog|
+00000030 69 49 88 2a 84 69 79 48 fe cc 92 db 6e 9e ab 47 |iI.*.iyH....n..G|
+00000040 8e 47 10 58 db ad 22 8e da bb 86 e6 13 03 00 00 |.G.X..".........|
+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 c0 07 64 56 b1 bb f8 bf 36 6b df |.......dV....6k.|
+000000b0 e9 ee 72 cc 79 45 f5 8c b8 0c b3 5d 17 03 03 02 |..r.yE.....]....|
+000000c0 6d 2e ab b5 84 4f d7 9e 4e 0d 6e a0 42 c1 f0 a6 |m....O..N.n.B...|
+000000d0 62 a3 26 eb 9d 9a 42 a5 5d 1f 59 ad 37 a9 8a af |b.&...B.].Y.7...|
+000000e0 0d 7b 8f 5a d1 d5 d8 bc 15 5b 0d 0e d2 a9 bb 14 |.{.Z.....[......|
+000000f0 56 ed 30 4e 9b aa f9 5a 66 7d 4c 41 8e 6d 58 90 |V.0N...Zf}LA.mX.|
+00000100 52 4a f2 78 72 59 34 aa 58 7e 0c 44 1e bc 84 d8 |RJ.xrY4.X~.D....|
+00000110 50 17 bd aa 8c 4c d0 c5 e7 69 32 b8 c3 d6 e6 f9 |P....L...i2.....|
+00000120 70 93 99 1c 75 1b 13 f2 85 e0 b5 07 1b d8 5a 31 |p...u.........Z1|
+00000130 0a 1a 2e 97 86 ff 75 a1 db 45 b2 47 68 ed 88 d9 |......u..E.Gh...|
+00000140 fe 31 c9 c0 5e 37 f2 62 37 f7 01 81 11 07 a7 0f |.1..^7.b7.......|
+00000150 44 ec 17 3a 4a 38 b3 91 9f 77 6f f9 58 9e 9c 12 |D..:J8...wo.X...|
+00000160 6e 54 4c de 43 58 46 a5 f6 c7 58 7e df 33 d7 91 |nTL.CXF...X~.3..|
+00000170 e5 cb 9e 28 9d 7f a7 8a bd be 01 48 b7 b1 1e e2 |...(.......H....|
+00000180 7a 80 aa f9 cd 3f 62 0d a0 a0 63 0c ca 4b 5f a8 |z....?b...c..K_.|
+00000190 a9 5f 42 ac 44 57 67 b2 0f 5a b5 bb 59 a9 56 bd |._B.DWg..Z..Y.V.|
+000001a0 28 3c fb 5e 43 33 61 43 7b 60 48 7d 27 67 6a 06 |(<.^C3aC{`H}'gj.|
+000001b0 ac 0d db e4 d2 d4 b8 fa fb e8 32 f3 22 83 3a 63 |..........2.".:c|
+000001c0 f6 73 02 62 e0 d5 8a d2 61 a5 bf e1 2d 10 59 93 |.s.b....a...-.Y.|
+000001d0 55 60 be 32 ce 5c d5 5a f0 54 21 7d 8a 02 23 cf |U`.2.\.Z.T!}..#.|
+000001e0 38 2b 2b 67 50 22 72 f7 f7 bf 20 c2 34 df ae 3a |8++gP"r... .4..:|
+000001f0 44 b0 a6 2a 51 79 6f b1 7b ff d7 77 45 83 a9 fa |D..*Qyo.{..wE...|
+00000200 bf 3c de 34 e8 6a 33 74 6c 24 0b 85 39 ea 7c 13 |.<.4.j3tl$..9.|.|
+00000210 43 26 13 1b 61 56 85 0a 08 83 04 45 5f 5a 36 df |C&..aV.....E_Z6.|
+00000220 17 c0 59 e9 92 d8 6b 78 66 1f 43 a0 99 f8 4b b1 |..Y...kxf.C...K.|
+00000230 f0 8d 25 6f 0f 2e c7 f9 4d bb 79 74 b8 95 e6 b7 |..%o....M.yt....|
+00000240 41 0c de 2a d3 7e fc 0f 18 87 2d 21 dd 8d 5f 20 |A..*.~....-!.._ |
+00000250 4c 88 cb 63 f4 9c 07 64 14 02 0c 19 46 32 e5 1e |L..c...d....F2..|
+00000260 85 84 4a 71 b8 a5 50 92 ca 72 fe f4 9c 69 05 d4 |..Jq..P..r...i..|
+00000270 93 22 38 c1 09 e2 da 49 17 e8 e1 b3 f9 42 ee bf |."8....I.....B..|
+00000280 ea 40 b2 00 af b9 a8 f9 97 8e ef de 41 de 01 87 |.@..........A...|
+00000290 cc 13 23 64 8c a1 10 9a 91 38 9b cb fb 0b 04 66 |..#d.....8.....f|
+000002a0 fb 4b e3 77 e7 da 7a 75 5c 66 20 7e dc 22 a9 e6 |.K.w..zu\f ~."..|
+000002b0 6a 27 06 ed 3c fc 4c 30 ed f0 31 92 b2 eb a1 f3 |j'..<.L0..1.....|
+000002c0 a4 fd 83 20 37 62 71 95 ff 7c 65 e8 88 aa e7 c7 |... 7bq..|e.....|
+000002d0 3f 17 9c 94 6f 1a d9 c8 ac 00 8d ec 30 22 98 85 |?...o.......0"..|
+000002e0 da cc 69 41 f4 3a 66 1b e6 4c 38 62 8d 37 dc a1 |..iA.:f..L8b.7..|
+000002f0 08 cf 88 d4 26 7f 47 33 54 d8 aa d6 c5 02 fc 72 |....&.G3T......r|
+00000300 ff 50 19 9f 4a 0e 8b c8 32 6d 8e 15 e4 f1 ed 2e |.P..J...2m......|
+00000310 43 cb 9f 8c 7a 0e e1 a2 79 e2 f9 52 12 e4 2f a9 |C...z...y..R../.|
+00000320 c1 c5 0b 1f c2 21 c5 2e 21 de 3e 76 29 db 17 03 |.....!..!.>v)...|
+00000330 03 00 99 8a ee 54 88 93 d0 4b a0 31 18 ed 83 ff |.....T...K.1....|
+00000340 2c 44 78 ab 88 ea 72 d2 2a 27 71 a9 a1 ba 26 a5 |,Dx...r.*'q...&.|
+00000350 9a 9b 64 92 e8 c9 f8 02 47 b9 9f 53 95 a8 ad 5b |..d.....G..S...[|
+00000360 bd 81 17 87 69 0c 77 c1 0e d7 cb 5b 9f 2d 36 86 |....i.w....[.-6.|
+00000370 f5 fc 6d ba d8 f5 63 dd e4 f5 0a 61 8d b2 a9 bb |..m...c....a....|
+00000380 a5 a5 d6 41 d4 aa db 46 79 56 02 51 f4 ac d3 57 |...A...FyV.Q...W|
+00000390 57 b4 53 71 9f fe ea a6 76 f3 0f ca 39 93 f3 34 |W.Sq....v...9..4|
+000003a0 c6 96 96 09 8e 12 04 cc 1e 82 9f 78 6b 1c a2 fc |...........xk...|
+000003b0 0c 9d c6 00 3c 33 3a 92 c5 ce 96 15 50 1a 75 6d |....<3:.....P.um|
+000003c0 85 ec b6 64 12 2b eb 3a 52 8f 6d 35 17 03 03 00 |...d.+.:R.m5....|
+000003d0 35 7f 2b 30 fa e0 92 25 a2 1b 11 f8 cd 04 0d 57 |5.+0...%.......W|
+000003e0 01 42 cf e9 0c 92 7f d1 fd fa 26 61 0d 85 d7 d5 |.B........&a....|
+000003f0 3c fd cf 73 98 dc 88 a2 76 63 59 82 45 2d e3 bc |<..s....vcY.E-..|
+00000400 a2 c0 0b 83 41 75 17 03 03 00 93 f3 17 09 b2 e8 |....Au..........|
+00000410 53 11 9b 3e 3a 10 a0 e6 58 04 81 82 cb eb a5 19 |S..>:...X.......|
+00000420 0f a3 25 e2 eb ab 7c 07 2b e6 22 19 30 aa fc a6 |..%...|.+.".0...|
+00000430 bd c4 7d 69 33 38 2b 58 55 5b a7 27 29 86 af d5 |..}i38+XU[.')...|
+00000440 f9 5a b4 85 ad a0 73 ab f7 61 3f 2e 66 53 f5 8f |.Z....s..a?.fS..|
+00000450 c7 09 4b 01 99 d0 68 93 32 d1 2e 8f 89 e5 e1 ea |..K...h.2.......|
+00000460 ba f2 fb 07 ee 58 7c 28 ff 59 1d d7 f7 b3 e2 56 |.....X|(.Y.....V|
+00000470 98 56 cd 9d d1 4f 26 7e 77 0d a0 c1 92 c5 a0 83 |.V...O&~w.......|
+00000480 c9 7c d8 7d a8 91 d3 ae 71 41 1d 06 33 68 b8 52 |.|.}....qA..3h.R|
+00000490 ad 84 a7 21 80 8f e5 c6 37 11 da 6c 5a 3a |...!....7..lZ:|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 35 28 34 b9 16 07 9a c1 82 ad 9f b7 |....5(4.........|
+00000010 78 fa 1a d0 1f 57 98 95 37 86 cf 1d 67 19 47 48 |x....W..7...g.GH|
+00000020 e9 ab fe 0c ff 26 c6 78 88 1a ad 75 48 63 4b 6e |.....&.x...uHcKn|
+00000030 72 4a 44 4f 27 b6 9d 56 b6 43 |rJDO'..V.C|
+>>> Flow 6 (server to client)
+00000000 17 03 03 00 1e d9 1f 35 86 22 7e 10 f1 8d e5 82 |.......5."~.....|
+00000010 f2 f6 88 81 a3 66 da 6a 1e 2f 94 94 16 02 2a 52 |.....f.j./....*R|
+00000020 69 8b bb 17 03 03 00 13 3c 87 88 8c c0 78 64 18 |i.......<....xd.|
+00000030 9a 9e 07 fd ac d7 2d 5d ab bf a8 |......-]...|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-IssueTicket b/src/crypto/tls/testdata/Server-TLSv13-IssueTicket
new file mode 100644
index 0000000..fa1f801
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-IssueTicket
@@ -0,0 +1,99 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 ce 01 00 00 ca 03 03 bb e2 a4 a5 7e |...............~|
+00000010 63 65 5c a5 7f 3f 13 a1 9d 5f 53 3c d2 b1 84 bd |ce\..?..._S<....|
+00000020 51 0c 9a 14 e8 8a 5a 53 b8 27 88 20 e7 04 4d dc |Q.....ZS.'. ..M.|
+00000030 76 f3 7f bd 00 ce 46 d2 a6 58 26 99 02 91 88 bf |v.....F..X&.....|
+00000040 b5 6b 56 2b b6 bc 51 b2 e4 cd 82 8d 00 04 13 01 |.kV+..Q.........|
+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 b2 99 9c bb d1 4c c7 61 5f aa bf 2f 06 |.. .....L.a_../.|
+000000c0 a3 50 e7 49 7d 11 ae 68 9b b0 be be 82 6d 27 29 |.P.I}..h.....m')|
+000000d0 89 4c 4a |.LJ|
+>>> 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 e7 04 4d dc |........... ..M.|
+00000030 76 f3 7f bd 00 ce 46 d2 a6 58 26 99 02 91 88 bf |v.....F..X&.....|
+00000040 b5 6b 56 2b b6 bc 51 b2 e4 cd 82 8d 13 01 00 00 |.kV+..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 c6 67 93 be 69 04 |...........g..i.|
+00000090 58 4f 1d 93 b6 5c 1c 10 8a 91 d0 c0 db 0b d1 0a |XO...\..........|
+000000a0 d1 17 03 03 02 6d da d6 28 74 c7 60 d6 02 3e 28 |.....m..(t.`..>(|
+000000b0 29 17 50 b9 01 4b 9b 93 07 9d 09 f0 17 05 e0 88 |).P..K..........|
+000000c0 53 ec c3 28 f7 a6 4e 9b 80 a3 fd 20 db 97 51 6a |S..(..N.... ..Qj|
+000000d0 b1 7a 6d 93 26 61 c8 9c 6d 37 65 94 b4 74 a0 60 |.zm.&a..m7e..t.`|
+000000e0 b1 a1 38 4c eb 5e a9 c4 bd d4 29 ee e9 e3 ab 56 |..8L.^....)....V|
+000000f0 68 67 57 da b3 3d 85 bd 26 67 e1 52 83 a6 69 14 |hgW..=..&g.R..i.|
+00000100 3b 30 31 c7 71 83 fa 62 13 ea a3 a5 de 4b 32 3f |;01.q..b.....K2?|
+00000110 c6 48 0b 96 cd 4b da 96 6d e2 31 88 ca 96 5f 63 |.H...K..m.1..._c|
+00000120 cb 39 37 d8 fa 8f 1f b9 e2 c5 6b ae 60 05 5b ed |.97.......k.`.[.|
+00000130 e0 5d 83 fa 2b 22 f4 e8 33 27 48 e7 c4 3d 54 22 |.]..+"..3'H..=T"|
+00000140 5a 60 a9 7a 0d 9b 42 e2 50 28 0e 6c 13 16 a1 51 |Z`.z..B.P(.l...Q|
+00000150 60 81 8f 80 e2 1b 53 24 62 78 b7 0a 4a 9b 2f a7 |`.....S$bx..J./.|
+00000160 97 b3 ba e5 34 0d 76 a6 0e ea ec 91 f0 9c a9 6d |....4.v........m|
+00000170 57 47 ef a3 c4 7a 62 a8 1f c0 1a d7 ea 31 90 20 |WG...zb......1. |
+00000180 76 13 ae f1 24 9d 60 9f 30 9f 2b 2a 2f 0a 39 6c |v...$.`.0.+*/.9l|
+00000190 7a 47 fe 11 1c 78 42 a1 1c ed c3 cd d2 6a cd 4f |zG...xB......j.O|
+000001a0 66 1b 51 d4 43 4e 45 23 15 48 e4 84 3e 89 a3 55 |f.Q.CNE#.H..>..U|
+000001b0 7e b0 a6 c2 1c cd eb cf 88 6b e7 d2 07 25 ef 37 |~........k...%.7|
+000001c0 e1 8a a5 b9 03 7e 70 73 9c 23 1a 62 07 56 db ed |.....~ps.#.b.V..|
+000001d0 93 e3 8a 91 8b 90 74 14 14 cc ff 9e ea e5 45 dd |......t.......E.|
+000001e0 a6 2d dc e6 cb 8c 59 33 91 da e6 5c b4 73 4f 36 |.-....Y3...\.sO6|
+000001f0 f1 3c d9 6e ba 2c c4 51 de 4f 8a 69 62 c4 db b1 |.<.n.,.Q.O.ib...|
+00000200 9e 67 7a 5f 01 7b b7 b2 55 b1 14 c0 46 d1 43 16 |.gz_.{..U...F.C.|
+00000210 a0 70 84 7e b8 a3 04 ce e3 e0 0e 5e 5f 3f 95 7a |.p.~.......^_?.z|
+00000220 ef 79 8d 50 84 cd 02 f1 e0 e5 f9 26 cf 7a f9 da |.y.P.......&.z..|
+00000230 a3 7d 22 31 4d 61 82 f6 ff fd 69 23 07 53 07 df |.}"1Ma....i#.S..|
+00000240 5a eb 50 86 28 44 24 06 9b 21 ef ef 78 bc 67 13 |Z.P.(D$..!..x.g.|
+00000250 c5 27 d8 18 db c7 fa d5 a6 0c 40 09 e3 e5 17 0c |.'........@.....|
+00000260 61 ae bc 48 98 ab 7b 57 82 f7 87 a5 4b 96 25 77 |a..H..{W....K.%w|
+00000270 e4 59 53 d1 d3 7b 55 08 e0 1a 5d 9b 0f 2e 6f cd |.YS..{U...]...o.|
+00000280 96 9d 19 09 07 84 08 c1 cf bd 99 af 80 52 c0 f7 |.............R..|
+00000290 0c 50 85 14 7c fd cb 61 01 05 ee 92 60 bb ac 4c |.P..|..a....`..L|
+000002a0 b4 37 48 dc b1 34 9d 26 3a fd dc ae 21 2f d3 51 |.7H..4.&:...!/.Q|
+000002b0 84 c3 0e 8f e1 b4 fb 0b 2e 3b 51 a9 e8 c2 d9 d9 |.........;Q.....|
+000002c0 6b a5 af 90 30 97 a2 32 9a a3 9d 5d b3 75 c6 48 |k...0..2...].u.H|
+000002d0 4b ee a3 23 85 98 a5 b5 00 fd c5 3a 27 65 9e d0 |K..#.......:'e..|
+000002e0 19 a8 5a 8c 8b eb 49 c6 58 16 9a 88 67 54 82 a9 |..Z...I.X...gT..|
+000002f0 29 0a 98 82 e4 f8 f0 c9 17 a6 81 91 1b c1 2a b7 |).............*.|
+00000300 de c3 8b 2d a6 55 1f 61 89 90 84 15 c8 33 6e cb |...-.U.a.....3n.|
+00000310 5c f4 e2 17 03 03 00 99 49 e0 38 43 34 61 b9 37 |\.......I.8C4a.7|
+00000320 2c 3e d5 c7 8c d7 9b a6 6c 8e ef a6 28 13 3c 79 |,>......l...(.<y|
+00000330 36 35 3e ba 70 5b 4e 6b c3 f5 52 06 ae ff 68 1d |65>.p[Nk..R...h.|
+00000340 a0 07 ac c1 17 6e d1 11 76 1d d7 1e e2 26 3e 76 |.....n..v....&>v|
+00000350 2b f9 a4 55 67 0b 9c cd db ab 71 1a 84 33 74 eb |+..Ug.....q..3t.|
+00000360 b1 4b 26 d8 e8 1c 84 2b 62 c7 70 27 16 fb 16 ae |.K&....+b.p'....|
+00000370 9d 72 3a 42 c1 cb cd c8 d0 dd 9c f0 51 2e 33 c1 |.r:B........Q.3.|
+00000380 46 35 56 ad 3b ea be 6e 14 4d 05 d1 6d 85 93 86 |F5V.;..n.M..m...|
+00000390 cc 6a 1c bf 03 cf 8f 92 c9 18 74 e0 66 0a b6 9a |.j........t.f...|
+000003a0 38 ac 1a 73 f4 e0 70 ec 93 61 67 9f b8 12 6f 1f |8..s..p..ag...o.|
+000003b0 17 17 03 03 00 35 59 6b 86 a8 cc 89 c6 fa 4f 95 |.....5Yk......O.|
+000003c0 25 b6 90 08 ac bf 9f d5 c9 3c 6c e5 cd 0d 14 00 |%........<l.....|
+000003d0 20 c9 01 ca 44 bc 9f 66 e0 3d e9 a0 11 40 c7 72 | ...D..f.=...@.r|
+000003e0 57 c8 54 d2 30 65 34 a1 09 27 63 17 03 03 00 93 |W.T.0e4..'c.....|
+000003f0 34 b8 fe 42 51 8b 9a 39 66 52 ec 19 95 2d 38 84 |4..BQ..9fR...-8.|
+00000400 36 36 09 e8 7c 86 51 81 90 7c b8 3b ed ec 9e a9 |66..|.Q..|.;....|
+00000410 09 ef 3b ca 86 2c 4d 05 3c 83 62 1c 8c e2 73 a1 |..;..,M.<.b...s.|
+00000420 3b 99 97 d9 90 24 df be 94 67 73 36 ac 92 ce 10 |;....$...gs6....|
+00000430 7a be 6f 1f b8 9d 0c c5 31 90 47 95 02 4d bd 86 |z.o.....1.G..M..|
+00000440 1a 89 3c e7 b6 71 9a f0 5c 36 41 a2 8f b6 d3 5c |..<..q..\6A....\|
+00000450 3b 2f a2 0e c8 c5 ae eb d1 4a d2 ab 12 8c 86 3a |;/.......J.....:|
+00000460 51 ef 9a e0 44 6f 0a cc 17 61 5d 12 db 2c d7 9f |Q...Do...a]..,..|
+00000470 d1 a3 30 2e ad f2 4c c8 f8 1e 7f 4c a5 8c c6 f8 |..0...L....L....|
+00000480 3d cb 01 |=..|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 74 1e 4a 56 2c |..........5t.JV,|
+00000010 fc 14 0b 66 ab 2f 56 5b fd 33 fe c2 a4 df 0b 62 |...f./V[.3.....b|
+00000020 63 11 40 67 d2 11 1b 53 c5 b9 1e 0e 20 83 85 b0 |c.@g...S.... ...|
+00000030 3a 81 79 bc a7 9f 49 ab 22 bd 10 8d 3e c9 95 79 |:.y...I."...>..y|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e a4 83 3b 61 a1 00 d5 56 84 4c 83 |.......;a...V.L.|
+00000010 0a 8c 86 13 0c e7 95 71 aa 48 e0 d2 5f 11 5f 45 |.......q.H.._._E|
+00000020 41 7a 10 17 03 03 00 13 ca 8b f5 38 e5 5f e0 8a |Az.........8._..|
+00000030 e3 08 ba 7d 06 f6 b3 b4 6f e9 2b |...}....o.+|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-IssueTicketPreDisable b/src/crypto/tls/testdata/Server-TLSv13-IssueTicketPreDisable
new file mode 100644
index 0000000..a939822
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-IssueTicketPreDisable
@@ -0,0 +1,99 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 ce 01 00 00 ca 03 03 cd 51 e4 0b ee |............Q...|
+00000010 9c 83 0f a1 bd 1a c8 b4 94 17 5e 17 fb 63 43 31 |..........^..cC1|
+00000020 89 86 03 fa 82 d4 bb c5 ba 9d 60 20 a1 0b c7 9c |..........` ....|
+00000030 b0 3f d9 7a 52 bd c0 3f cd c5 21 54 40 a5 60 73 |.?.zR..?..!T@.`s|
+00000040 fd ff 07 99 75 59 0d f3 bd 57 f6 81 00 04 13 01 |....uY...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 04 16 08 0b 67 76 58 60 4a 32 c2 ea 1b |.. ....gvX`J2...|
+000000c0 4a 54 fa 55 9b 39 d8 80 c4 eb 42 cc 1a 84 fe d7 |JT.U.9....B.....|
+000000d0 0a 0d 43 |..C|
+>>> 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 a1 0b c7 9c |........... ....|
+00000030 b0 3f d9 7a 52 bd c0 3f cd c5 21 54 40 a5 60 73 |.?.zR..?..!T@.`s|
+00000040 fd ff 07 99 75 59 0d f3 bd 57 f6 81 13 01 00 00 |....uY...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 ec 4d 41 82 de 4f |...........MA..O|
+00000090 c6 cf 1e 56 06 65 0e a4 e7 66 34 1d 89 59 b3 c2 |...V.e...f4..Y..|
+000000a0 0a 17 03 03 02 6d 00 e1 17 f1 b3 5e a7 14 b3 f8 |.....m.....^....|
+000000b0 3a ab 85 d4 80 75 69 01 6c 91 3f 79 ab 8f 51 e0 |:....ui.l.?y..Q.|
+000000c0 f6 a5 65 ab 7e 72 e5 83 99 b2 cb cd f9 5f 27 db |..e.~r......._'.|
+000000d0 90 70 9c c1 e5 6d 80 3e 59 7c 4d fa f1 23 8a a7 |.p...m.>Y|M..#..|
+000000e0 f4 81 22 32 5b e2 4e d0 eb ab bd 96 05 42 05 5c |.."2[.N......B.\|
+000000f0 20 5c 8a 3e ca fd b8 aa dd f2 c4 3e dc 7e a5 ab | \.>.......>.~..|
+00000100 95 a4 20 03 0e 41 9b 14 55 91 1b 9c 3b 17 bc 2a |.. ..A..U...;..*|
+00000110 60 c0 ee b1 78 e9 37 c4 65 ef 8c 29 ec d9 10 81 |`...x.7.e..)....|
+00000120 a0 1d c9 ac cf e5 36 90 88 d3 70 6d 59 66 61 a8 |......6...pmYfa.|
+00000130 18 79 ad d8 c7 3e 1f a5 db dc b5 21 83 b0 ae 16 |.y...>.....!....|
+00000140 ce 8e 98 d4 8e 28 c1 d3 d2 ef 51 35 45 41 a7 b4 |.....(....Q5EA..|
+00000150 e1 15 bb 32 10 aa b1 27 be 53 5e 96 ef 0b bd 2f |...2...'.S^..../|
+00000160 81 66 18 f4 8b 9a cc be 67 c1 32 e3 c0 ea e5 c0 |.f......g.2.....|
+00000170 76 2c 36 7f 91 11 13 c1 a4 04 7e 8e 7b 60 a5 3d |v,6.......~.{`.=|
+00000180 fa 3c d8 68 9a 7e 4b 23 3d 18 1b a3 34 a9 81 a4 |.<.h.~K#=...4...|
+00000190 00 09 cd 56 eb f2 29 9f 17 8d 48 4d 21 a2 4e ec |...V..)...HM!.N.|
+000001a0 f0 a0 8d b1 ed d6 c7 01 d0 8e 2f 25 65 9f ac eb |........../%e...|
+000001b0 44 09 f2 75 db 37 a3 94 cb 70 29 59 37 97 71 63 |D..u.7...p)Y7.qc|
+000001c0 9b fa 0f 0f 33 75 0a 60 4f 78 97 9e 6a 2c 4b df |....3u.`Ox..j,K.|
+000001d0 54 cc c0 ac 57 4c f3 3a e3 79 01 b9 c3 8c 37 d2 |T...WL.:.y....7.|
+000001e0 8f d9 e7 cd 33 5a 0c bb 43 7e 39 5f 63 9f a5 11 |....3Z..C~9_c...|
+000001f0 f5 6e e0 95 1f 09 03 56 0f ec b9 7d 08 31 c5 57 |.n.....V...}.1.W|
+00000200 fa a6 57 15 6c 6b 91 d4 9f 5d c2 40 8b 3d 3a 57 |..W.lk...].@.=:W|
+00000210 c2 64 55 bd 88 bb 5e 24 7f fe 79 0c 88 f3 a7 1c |.dU...^$..y.....|
+00000220 f8 20 6f ba d6 ec fc b2 04 2a d7 b7 17 5e 4c 2e |. o......*...^L.|
+00000230 24 cd 1b 8a 04 fe 21 e0 5b 90 ec f4 30 df bf fe |$.....!.[...0...|
+00000240 a8 f9 2b 40 c1 23 15 f2 44 87 9a aa 30 80 70 27 |..+@.#..D...0.p'|
+00000250 80 6f 90 08 b5 47 2e 01 ea 77 3a ba a4 4b 77 8a |.o...G...w:..Kw.|
+00000260 12 b4 4e e1 a6 04 8a 01 31 60 27 35 bf 76 de 09 |..N.....1`'5.v..|
+00000270 aa 8a c4 c4 21 31 9f eb c2 92 05 be a1 b5 24 eb |....!1........$.|
+00000280 71 24 55 f9 aa 5c 62 59 49 bf 42 4c 69 01 4f f7 |q$U..\bYI.BLi.O.|
+00000290 b6 27 14 d4 cc 40 80 13 9b 8b 30 55 1f 32 c1 ee |.'...@....0U.2..|
+000002a0 51 bd 71 f7 63 3f c2 00 90 60 dc 13 0f 62 c3 06 |Q.q.c?...`...b..|
+000002b0 80 f6 4f cc 44 71 d7 5c 2e 18 82 45 ca 80 b7 0e |..O.Dq.\...E....|
+000002c0 0c 6f 75 1b 23 cb 86 c1 2d 1e 1b 02 2a 15 fa c7 |.ou.#...-...*...|
+000002d0 b2 af 80 5c 48 c2 b7 12 59 a3 e4 3c ed df 26 d0 |...\H...Y..<..&.|
+000002e0 85 9b 5a 2d 7b 66 e6 c4 b3 fe cd 4d 72 4d fb da |..Z-{f.....MrM..|
+000002f0 1c 0d 5c fb 2f 8a e3 70 98 ee 95 9c 12 1a fa c7 |..\./..p........|
+00000300 94 7a 8e ca 4d a4 bb 2f 70 3b 67 95 fb 23 fb 8f |.z..M../p;g..#..|
+00000310 8c 77 4c 17 03 03 00 99 8a 72 14 c7 82 18 d7 ed |.wL......r......|
+00000320 c7 5d 32 df 44 91 6b 40 3e 0b eb a1 74 da d9 3a |.]2.D.k@>...t..:|
+00000330 3c 7a 2e 7a 73 3b 63 72 33 c4 c5 27 29 33 f5 30 |<z.zs;cr3..')3.0|
+00000340 cf d3 e7 50 3f 44 33 79 6c 96 ed 80 32 02 5f 6b |...P?D3yl...2._k|
+00000350 d7 ec d7 67 df 2d 7d bc 2b dd f0 21 39 ef 54 9b |...g.-}.+..!9.T.|
+00000360 c3 55 1f f9 85 c4 4e 31 ce ba 28 a5 3d 68 64 60 |.U....N1..(.=hd`|
+00000370 9e 0a 99 76 a3 25 7c d6 4f 30 37 48 b4 93 6a 4f |...v.%|.O07H..jO|
+00000380 ff 0b df 83 ac 6f 27 9e ec d0 01 17 03 b9 a8 74 |.....o'........t|
+00000390 b9 b4 4c 59 ae da de 8a 18 16 54 18 ac 69 01 20 |..LY......T..i. |
+000003a0 6c f3 0b 93 8d 8c e7 70 79 d5 be 80 5e 87 5a 9c |l......py...^.Z.|
+000003b0 86 17 03 03 00 35 a7 cf 76 44 4f 48 f3 8c 9b 43 |.....5..vDOH...C|
+000003c0 a2 4e bf c5 e3 e7 08 43 d1 a4 4d 92 b3 3b f4 0a |.N.....C..M..;..|
+000003d0 06 2f b0 84 43 39 8e 29 a9 42 5d 63 c1 b2 f3 2d |./..C9.).B]c...-|
+000003e0 0e 57 8e c6 39 aa 29 45 d3 7e 78 17 03 03 00 93 |.W..9.)E.~x.....|
+000003f0 af 0d 9c 38 bd aa 63 fc de 80 59 28 32 11 0f f5 |...8..c...Y(2...|
+00000400 91 57 cd 15 f7 21 37 43 71 d8 32 7d 14 4b d2 28 |.W...!7Cq.2}.K.(|
+00000410 03 45 12 b5 cf f2 55 02 ae 47 34 ac f0 4c 6e d6 |.E....U..G4..Ln.|
+00000420 30 e4 eb 22 08 a8 10 8c bb 40 6e ec 96 68 b5 6b |0..".....@n..h.k|
+00000430 c2 a0 eb fb 53 49 4c 1d 73 b5 4d 80 18 b2 e4 af |....SIL.s.M.....|
+00000440 8b fa 85 f4 48 d4 e6 51 58 16 04 87 53 5c ff 93 |....H..QX...S\..|
+00000450 3d a8 e4 79 7e 82 79 e9 1f 6a dc ba 43 6f 15 b6 |=..y~.y..j..Co..|
+00000460 35 1b 84 72 a3 4c 65 3d f3 71 45 0b dc b9 74 13 |5..r.Le=.qE...t.|
+00000470 ed ce 9c fc dd b3 8c d8 ce 84 3e 95 d2 7e 62 60 |..........>..~b`|
+00000480 5d 0a 82 |]..|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 35 fd 9a 7d 02 |..........55..}.|
+00000010 fb b2 eb fa 51 27 3e 80 ab 60 f6 a1 54 31 13 2f |....Q'>..`..T1./|
+00000020 02 b9 19 ac 68 be 25 69 b3 c4 48 87 42 75 b0 93 |....h.%i..H.Bu..|
+00000030 66 3e 2e 0b 79 4f 0b 3a 59 ef 89 83 65 c9 10 9b |f>..yO.:Y...e...|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e 58 0f 73 e3 ba ff d3 19 0d 89 c9 |.....X.s........|
+00000010 94 8a fb 24 02 58 2a 2c eb 69 29 4e 57 d3 d2 5e |...$.X*,.i)NW..^|
+00000020 ba b2 75 17 03 03 00 13 9c 5c 46 44 71 dc 68 b8 |..u......\FDq.h.|
+00000030 39 cc e1 fd 2d 2a a1 a9 50 6c af |9...-*..Pl.|
diff --git a/src/crypto/tls/testdata/Server-TLSv13-P256 b/src/crypto/tls/testdata/Server-TLSv13-P256
new file mode 100644
index 0000000..dd8e0f4
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-P256
@@ -0,0 +1,102 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 e3 01 00 00 df 03 03 c8 5f 11 a2 29 |............_..)|
+00000010 7b c3 b7 72 5e ba e1 c5 83 45 c8 87 e1 51 27 d9 |{..r^....E...Q'.|
+00000020 33 0e 68 e0 71 76 9e 8f 4e f4 da 20 da fd c6 1d |3.h.qv..N.. ....|
+00000030 46 55 42 89 0a 80 e0 d3 e4 dd db 7d b1 3a 76 a3 |FUB........}.:v.|
+00000040 5b d9 2a c7 f1 1a 3b 0b 8c 24 dd 4d 00 04 13 03 |[.*...;..$.M....|
+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 04 48 71 9f a6 06 17 16 |G.E...A..Hq.....|
+000000b0 04 d2 b4 e7 6b 5c cf d8 9f ca 64 a7 39 9e 1a 22 |....k\....d.9.."|
+000000c0 aa fc b5 4c d9 d3 b3 37 e3 d4 e1 3b 5b 00 74 df |...L...7...;[.t.|
+000000d0 df e5 29 8f 7c f7 6b 02 f0 e7 fb 9b 43 6a 41 fb |..).|.k.....CjA.|
+000000e0 77 5b c2 6e 99 48 69 78 |w[.n.Hix|
+>>> 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 da fd c6 1d |........... ....|
+00000030 46 55 42 89 0a 80 e0 d3 e4 dd db 7d b1 3a 76 a3 |FUB........}.:v.|
+00000040 5b d9 2a c7 f1 1a 3b 0b 8c 24 dd 4d 13 03 00 00 |[.*...;..$.M....|
+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 81 b8 e3 25 04 |..............%.|
+000000b0 6c d8 f6 7c 04 a1 2c 8b 1f 0d cb de 29 1b e1 a3 |l..|..,.....)...|
+000000c0 6f 8c 17 03 03 02 6d 81 db bc b4 f8 02 f3 c5 4e |o.....m........N|
+000000d0 9e f7 5f 55 54 3e 25 a9 2f 03 06 62 2f 1e 7e d4 |.._UT>%./..b/.~.|
+000000e0 19 27 88 1e ac f2 44 87 29 84 08 69 2f 5d a3 ca |.'....D.)..i/]..|
+000000f0 de 8f 98 ad 25 6b c5 94 62 34 44 95 bc 17 ed e6 |....%k..b4D.....|
+00000100 fe 89 9c ef 46 c9 cb ee 16 d4 42 b6 d3 50 7b 3a |....F.....B..P{:|
+00000110 51 d8 20 23 02 3e 69 a8 1a 80 eb bf 7c 82 2b 1f |Q. #.>i.....|.+.|
+00000120 10 5a 30 85 dd bc ff 65 4d c6 4f 7b bc 3d 64 e2 |.Z0....eM.O{.=d.|
+00000130 93 2a 05 a0 af de b1 41 48 85 db 98 c9 a9 96 5c |.*.....AH......\|
+00000140 64 a4 70 2e f9 4e de 38 9f 48 f7 eb 6e 14 42 3f |d.p..N.8.H..n.B?|
+00000150 9f 86 0f 2d 70 6a 30 96 1c dd c6 11 28 6f 86 b6 |...-pj0.....(o..|
+00000160 da bb 5b 76 c8 56 18 4a 67 bf 59 db 56 46 f0 c7 |..[v.V.Jg.Y.VF..|
+00000170 80 2b 0f 0c 8a 02 58 a1 13 aa 2e 5d 61 e2 d5 23 |.+....X....]a..#|
+00000180 3c 1c 75 06 e4 e4 e1 39 eb 65 6a ff 38 21 28 c9 |<.u....9.ej.8!(.|
+00000190 c5 8b a5 12 21 18 2a 59 e7 4e 66 53 be d3 49 97 |....!.*Y.NfS..I.|
+000001a0 f9 b1 7d e2 75 44 37 38 36 35 af 78 27 f4 74 e0 |..}.uD7865.x'.t.|
+000001b0 45 ca fd 79 3c 39 65 00 46 58 4b 8b db f9 6e c0 |E..y<9e.FXK...n.|
+000001c0 69 ec 1e 25 87 66 e1 b8 d8 cc 16 5b 16 9e 90 2e |i..%.f.....[....|
+000001d0 16 0c 8f 25 04 cf 40 c8 50 dd c4 63 19 8f f1 76 |...%..@.P..c...v|
+000001e0 5e fa 24 1d 8a d2 c1 d4 98 49 48 f0 e6 fa f3 6e |^.$......IH....n|
+000001f0 63 0b a5 7a 2f f2 f0 47 0b c0 89 9f 7b 9f ef 48 |c..z/..G....{..H|
+00000200 df fd 38 5d a9 71 ce 0c 3c 6f 88 0b 1b d3 93 8c |..8].q..<o......|
+00000210 14 9a ff 8a db 3f 07 f7 46 54 fe c0 8c 06 7f e0 |.....?..FT......|
+00000220 de e9 c8 3c 4b cd 7b c3 59 11 63 01 8e 69 40 00 |...<K.{.Y.c..i@.|
+00000230 d5 e0 4c 01 00 12 89 3a 98 e3 3f e1 a3 69 f6 ee |..L....:..?..i..|
+00000240 e7 94 65 b1 61 58 08 07 4a d5 ab aa 43 3e cf 02 |..e.aX..J...C>..|
+00000250 96 5a 3c 97 8e 7b 47 b8 f0 58 16 12 05 69 69 a1 |.Z<..{G..X...ii.|
+00000260 36 7b ff dd 92 60 26 e2 f9 53 4c 3a 25 ac 88 dd |6{...`&..SL:%...|
+00000270 9a 81 7c 1f 58 27 33 14 68 44 06 e2 01 14 94 99 |..|.X'3.hD......|
+00000280 00 05 8f 64 47 ca 95 fa 92 57 a9 1a 53 d5 47 52 |...dG....W..S.GR|
+00000290 e8 c4 aa eb 0a f5 1b a9 09 72 92 37 f5 8d 90 b8 |.........r.7....|
+000002a0 4b 08 7f 55 19 2d a7 d8 7b d9 ba 7f 5e 56 bb 80 |K..U.-..{...^V..|
+000002b0 c7 d0 49 99 ae ce 2f a4 f0 ab d1 bd ba f3 0f 85 |..I.../.........|
+000002c0 f1 68 c1 9d 2a 37 ff de a4 0a 6f 58 27 1d 1d 2b |.h..*7....oX'..+|
+000002d0 87 9d 52 d3 70 37 a6 03 cd 77 61 9b 56 64 49 62 |..R.p7...wa.VdIb|
+000002e0 ef a1 ed fe 75 1a 61 4a 58 01 d6 80 2f ab ab fc |....u.aJX.../...|
+000002f0 b2 49 1f 51 b7 51 29 c1 a1 39 fc f4 0a 9b 0d 76 |.I.Q.Q)..9.....v|
+00000300 c6 d0 89 c9 8f 88 e9 ec 13 90 78 4f 0c f5 c9 7e |..........xO...~|
+00000310 d5 b3 13 ad 35 6d 53 d0 88 50 e8 47 15 a0 ca fc |....5mS..P.G....|
+00000320 5f 6e 98 23 46 6a 69 84 3c a9 3f eb d1 05 f5 97 |_n.#Fji.<.?.....|
+00000330 11 39 7f 39 17 03 03 00 99 84 8e 37 a9 57 78 12 |.9.9.......7.Wx.|
+00000340 8e 9a e7 8e 45 ee 55 61 66 24 ed 5a 36 19 e3 1c |....E.Uaf$.Z6...|
+00000350 22 3b 8b c0 4b c9 cd 2c 4c 17 d2 a9 40 2c 02 40 |";..K..,L...@,.@|
+00000360 74 ba 11 de a5 d4 01 11 ae 9d 71 76 4c f0 87 0f |t.........qvL...|
+00000370 5e 75 c0 67 c0 33 e7 3e 9b d3 a4 21 e8 40 a6 9f |^u.g.3.>...!.@..|
+00000380 d8 24 a7 d7 c1 99 cc 8d 33 10 91 0a 41 a6 05 1c |.$......3...A...|
+00000390 85 4c c5 a8 c9 dd 74 d0 5c 67 2e 2a 50 4e 30 c7 |.L....t.\g.*PN0.|
+000003a0 bb fa f8 65 ee 48 23 f5 c5 d3 a1 ec 4d 3f ac 4b |...e.H#.....M?.K|
+000003b0 ef 1e 8d 84 07 b9 69 2a 34 51 73 ba fb b5 7d 64 |......i*4Qs...}d|
+000003c0 1f fc 0e c8 33 d9 77 5e 41 00 65 25 ea 75 75 c9 |....3.w^A.e%.uu.|
+000003d0 2b 03 17 03 03 00 35 54 c2 06 55 7c 6f 92 8a d2 |+.....5T..U|o...|
+000003e0 d5 35 0c 4b 0d df cb d7 6e 5d 64 e1 2e cf 50 b8 |.5.K....n]d...P.|
+000003f0 d8 04 9a f4 ce 69 d3 ac bb 47 cd 57 ac 07 aa 40 |.....i...G.W...@|
+00000400 e3 fc 01 bc d6 a1 0e 16 4e 6b 04 cc 17 03 03 00 |........Nk......|
+00000410 93 b2 c3 64 29 13 07 75 b4 c4 84 f7 0e 99 d9 9f |...d)..u........|
+00000420 8d 5b fd 26 07 42 48 33 3a ab 6f 7d 07 8b f6 8a |.[.&.BH3:.o}....|
+00000430 22 a4 ce 64 0f 69 ea 61 95 70 6d d3 f8 5f 8b ad |"..d.i.a.pm.._..|
+00000440 02 43 94 41 51 f4 f8 0b 52 fc 58 c1 23 5e 22 a7 |.C.AQ...R.X.#^".|
+00000450 74 49 a1 46 e8 29 ab d6 ae 02 a4 7b e4 23 f1 89 |tI.F.).....{.#..|
+00000460 1c b1 74 86 92 1b 6a 7c 2f 55 2b 89 f6 01 fc e2 |..t...j|/U+.....|
+00000470 d6 15 b9 b1 64 1c 4a af f8 fe 3e e0 76 0f cf 08 |....d.J...>.v...|
+00000480 e1 2c db f6 1c 77 6f e4 a4 80 ad 13 74 3d 02 52 |.,...wo.....t=.R|
+00000490 a1 ff 3e 85 1d d3 77 bc f2 48 73 1c 45 09 62 34 |..>...w..Hs.E.b4|
+000004a0 80 09 21 41 |..!A|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 ab dd 69 66 c8 |..........5..if.|
+00000010 f9 eb e6 e6 b0 a9 9b 10 1d fc ad 89 ad 4d f5 2b |.............M.+|
+00000020 e4 d7 12 5b 1c 1e 81 12 df 24 ba ea 6b 3e 6f 82 |...[.....$..k>o.|
+00000030 dd 2f 38 a1 65 07 55 6a 4f 8e 99 5d 4f 35 b8 5d |./8.e.UjO..]O5.]|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e e5 f4 e6 14 79 8c b9 a9 77 6b c9 |.........y...wk.|
+00000010 ff ad 60 f3 03 cf 48 19 19 71 6c 85 da 92 cb 79 |..`...H..ql....y|
+00000020 2b 20 41 17 03 03 00 13 69 de ca 08 9c cf 70 37 |+ A.....i.....p7|
+00000030 5e fc 32 31 1c 93 d1 e4 01 f3 c6 |^.21.......|
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..db53ebb
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-RSA-RSAPSS
@@ -0,0 +1,97 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 b2 01 00 00 ae 03 03 4d a5 7b 2c da |...........M.{,.|
+00000010 67 11 9d 4d a0 92 2a 96 6c 85 ef 8c 52 0a 31 cf |g..M..*.l...R.1.|
+00000020 43 23 3e 8d 67 63 9b 7e 84 94 17 20 a2 a1 87 c6 |C#>.gc.~... ....|
+00000030 5e 64 34 75 da ac ee ba d4 d8 8f 2a a6 55 9f 4f |^d4u.......*.U.O|
+00000040 48 38 5a 29 61 a4 ef 7d 1d 74 a7 71 00 04 13 03 |H8Z)a..}.t.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 16 5e 23 ca e7 24 31 81 c2 |&.$... .^#..$1..|
+000000a0 78 21 3a ee 8a f3 61 8a 46 a0 56 ee a9 ed 82 3a |x!:...a.F.V....:|
+000000b0 87 b7 4a 0a 03 fe 59 |..J...Y|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 7a 02 00 00 76 03 03 00 00 00 00 00 |....z...v.......|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 00 00 00 00 00 00 00 00 20 a2 a1 87 c6 |........... ....|
+00000030 5e 64 34 75 da ac ee ba d4 d8 8f 2a a6 55 9f 4f |^d4u.......*.U.O|
+00000040 48 38 5a 29 61 a4 ef 7d 1d 74 a7 71 13 03 00 00 |H8Z)a..}.t.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 f8 7a 9c bc 58 8d |...........z..X.|
+00000090 ce cd ff e6 ae 2d c2 e0 40 33 4e c4 ec f5 90 dd |.....-..@3N.....|
+000000a0 ba 17 03 03 02 6d f3 65 a1 b4 fe ef 40 37 72 fa |.....m.e....@7r.|
+000000b0 a5 b8 10 ad 32 e3 08 e1 ac bb 14 f2 34 bf 25 19 |....2.......4.%.|
+000000c0 aa 2d 1a 78 cc 26 2f 5c 0b 7e 13 73 36 85 92 96 |.-.x.&/\.~.s6...|
+000000d0 0a 7a 27 f5 35 86 f1 ea 1a 5f 5c 3a 90 28 63 6a |.z'.5...._\:.(cj|
+000000e0 b3 7c e0 56 32 10 55 67 59 e0 65 d6 11 ef 7c 50 |.|.V2.UgY.e...|P|
+000000f0 0b 9e 88 0a 61 96 93 cf 05 51 47 33 c3 5c e3 82 |....a....QG3.\..|
+00000100 01 6d f1 f7 5c dc df b2 61 7c d7 9f de b4 3e c0 |.m..\...a|....>.|
+00000110 6d b5 52 39 3b f6 33 c2 03 65 2b 66 39 ed d6 f0 |m.R9;.3..e+f9...|
+00000120 83 46 61 db fc 27 a5 8a 68 d6 8a 85 5d 3f b1 46 |.Fa..'..h...]?.F|
+00000130 a2 3a 32 37 1f e0 76 a6 79 7f eb b2 81 52 e7 e0 |.:27..v.y....R..|
+00000140 4f b2 db 48 7d 20 61 52 d4 22 2a b7 81 2f da 5b |O..H} aR."*../.[|
+00000150 f6 e8 0a a6 91 b5 d1 f5 6b 5e 2b ad fd 70 cd a1 |........k^+..p..|
+00000160 f8 4d 73 31 3d 2a 49 d3 2e 6b b3 31 95 61 09 08 |.Ms1=*I..k.1.a..|
+00000170 c5 f9 eb db 42 b0 e1 5d 47 00 3e 7e 80 31 c6 d2 |....B..]G.>~.1..|
+00000180 37 dc 68 d7 36 05 ad 8a a4 05 87 7a 1c 12 f6 ab |7.h.6......z....|
+00000190 0e e1 5b 29 b1 1c 16 20 29 75 5a b0 59 24 59 df |..[)... )uZ.Y$Y.|
+000001a0 62 fe f2 26 ad ab bf 2b 25 d7 9e db 04 f6 26 96 |b..&...+%.....&.|
+000001b0 f7 5f 2c ff 2e 6d 85 c7 58 c8 15 9c d0 7d dd 8e |._,..m..X....}..|
+000001c0 1a 39 fc 3d 62 58 47 ce 83 7a ff fc 45 98 02 3d |.9.=bXG..z..E..=|
+000001d0 aa 37 b7 5e a7 7b 8e fa f2 05 8b 61 7f 04 08 f5 |.7.^.{.....a....|
+000001e0 af 1d 6e 55 18 d2 12 2e bd 8a 80 3d cb e6 0f cd |..nU.......=....|
+000001f0 3c d8 a5 38 db ee 07 c6 3b 75 55 c2 ee 2e 6a a3 |<..8....;uU...j.|
+00000200 fa 54 ce e3 45 92 c0 b9 8c 10 3d 2f 86 cb a5 c9 |.T..E.....=/....|
+00000210 af 37 f7 f6 6c 3e 4b 15 04 bd 46 98 31 5a b9 8c |.7..l>K...F.1Z..|
+00000220 ec 67 0d 97 9d 26 56 65 9c a7 74 bb 88 45 dc 4e |.g...&Ve..t..E.N|
+00000230 ce 70 a1 fc ce fc a7 d4 e1 7d a7 43 82 a6 e2 30 |.p.......}.C...0|
+00000240 e2 94 88 e5 1a 05 c5 28 06 14 7b 29 75 f9 4d 2c |.......(..{)u.M,|
+00000250 bb 54 ee f5 17 4e 2a bf 04 e6 38 f2 cf ed ab a2 |.T...N*...8.....|
+00000260 ef ae ac 3d 80 5e 03 71 74 70 0c 68 93 ca ea 93 |...=.^.qtp.h....|
+00000270 e5 b1 d1 18 80 98 0e c6 e8 f5 65 87 e7 9a 33 1d |..........e...3.|
+00000280 e6 3d e2 28 82 19 2a 9d 5f 1a a2 74 fa 27 8b d0 |.=.(..*._..t.'..|
+00000290 09 9a ba 1b c5 a6 4c 3b c3 02 12 61 a1 8a 20 d3 |......L;...a.. .|
+000002a0 a4 3c 3b aa f2 08 de e0 de 07 9f a0 13 b4 e8 23 |.<;............#|
+000002b0 d3 a5 ff 12 74 55 29 3a 57 f5 14 b3 af e6 28 ed |....tU):W.....(.|
+000002c0 b1 60 9c 6b 7d 55 a1 58 50 ab 42 71 5d 0e dc 76 |.`.k}U.XP.Bq]..v|
+000002d0 87 cd a1 d3 e4 26 25 c4 c1 23 1e 3b 31 13 3d f8 |.....&%..#.;1.=.|
+000002e0 b2 1b a8 07 f6 68 83 b4 7e 94 ca 84 95 55 38 d1 |.....h..~....U8.|
+000002f0 eb af 19 83 90 4a ab 0a 8d f6 48 9a 25 fa 59 97 |.....J....H.%.Y.|
+00000300 3c 5f 6a 2d 68 ec 29 d5 53 b4 9a 97 ea 59 fe 74 |<_j-h.).S....Y.t|
+00000310 81 0e b9 17 03 03 00 99 12 25 df 91 85 91 ac c0 |.........%......|
+00000320 60 4e 6e ed c4 b2 f0 f3 8b 66 53 75 11 07 29 d6 |`Nn......fSu..).|
+00000330 1f 01 81 60 de 5f b7 6b 5e 39 c8 ea f1 f8 2a 94 |...`._.k^9....*.|
+00000340 dd b6 c5 a9 31 be 87 a7 aa a9 64 03 16 40 df ef |....1.....d..@..|
+00000350 37 ac 66 4c 19 f1 60 d5 b4 88 93 a7 42 ac e3 81 |7.fL..`.....B...|
+00000360 c8 88 3f e2 30 a0 ff b7 d5 19 fc f2 72 a7 97 a8 |..?.0.......r...|
+00000370 31 ce 20 be 90 bc f5 8a 24 31 b1 c6 2b 2a ad c5 |1. .....$1..+*..|
+00000380 7a 34 69 eb a7 86 53 61 a1 88 4f 58 2a 65 a2 18 |z4i...Sa..OX*e..|
+00000390 7a 93 81 c6 bd c7 bc 84 5b ff 85 aa ff fc 68 50 |z.......[.....hP|
+000003a0 cb 57 37 54 a7 0f 2e 64 82 53 b7 dc ea c2 e3 49 |.W7T...d.S.....I|
+000003b0 fd 17 03 03 00 35 da 2a 8c 37 83 a5 a0 d4 06 c4 |.....5.*.7......|
+000003c0 ff f3 85 6f e4 11 1f 37 0f 06 35 45 e9 51 43 6f |...o...7..5E.QCo|
+000003d0 d2 a4 cb b7 ad f0 66 1c 20 40 c3 14 32 c0 57 71 |......f. @..2.Wq|
+000003e0 d3 8c 9c 7f 5b e6 50 a1 c2 e5 62 17 03 03 00 93 |....[.P...b.....|
+000003f0 30 b8 ab dc 3b df 60 aa b1 d2 25 5a 60 da b6 c8 |0...;.`...%Z`...|
+00000400 22 88 93 79 25 44 56 aa ec 93 e8 01 11 bf 69 ad |"..y%DV.......i.|
+00000410 b2 c9 43 67 33 aa 6d ae 73 a3 95 2b f0 86 ed a2 |..Cg3.m.s..+....|
+00000420 db df e3 dc 9b 16 1d 8d fc 2f a5 c4 41 d0 86 2f |........./..A../|
+00000430 cc a1 a1 ce 9a e5 e6 c8 a2 d1 a8 b2 a4 15 9c 69 |...............i|
+00000440 38 5a fa fd de d4 02 95 24 67 1b 61 76 1f c4 65 |8Z......$g.av..e|
+00000450 01 fc 36 2d ef 2d 0f 8e f0 5a 6d 04 07 b8 26 18 |..6-.-...Zm...&.|
+00000460 90 fc 82 1b 99 68 b0 13 7f 6e a1 9b c4 2a f3 b8 |.....h...n...*..|
+00000470 0b 6a 44 cd 04 e8 20 96 6d f5 48 cb 71 8a 04 10 |.jD... .m.H.q...|
+00000480 b8 8d 56 |..V|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 54 e5 3f f8 77 |..........5T.?.w|
+00000010 59 e3 8b 02 0b 80 8d 59 12 22 23 09 cb d9 93 67 |Y......Y."#....g|
+00000020 c7 35 b4 45 a0 54 49 fd 65 b5 ff e6 3e 3c b9 bf |.5.E.TI.e...><..|
+00000030 26 ca df 86 db a4 66 b5 3e 1f 36 69 a5 99 2b ed |&.....f.>.6i..+.|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e e3 b4 3e 81 ff 1a 36 f8 11 53 64 |.......>...6..Sd|
+00000010 b9 28 4e 68 de ee 9c b6 4d 71 21 fa 85 56 30 ad |.(Nh....Mq!..V0.|
+00000020 e9 c2 27 17 03 03 00 13 3d b8 13 b0 5f df 5a 05 |..'.....=..._.Z.|
+00000030 85 cf eb 48 86 fb c5 a0 67 f7 ee |...H....g..|
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..091ffc3
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-Resume
@@ -0,0 +1,60 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 01 6e 01 00 01 6a 03 03 b6 39 89 61 fd |....n...j...9.a.|
+00000010 11 84 b3 4b a9 18 23 b2 35 3d 82 85 75 5c e2 f3 |...K..#.5=..u\..|
+00000020 c9 f4 b0 2f 05 fb 5a 90 da 73 38 20 7f 06 81 e5 |.../..Z..s8 ....|
+00000030 d0 10 08 d1 b0 3c 3c 4b 28 39 34 9a 56 ca 47 4a |.....<<K(94.V.GJ|
+00000040 01 f9 03 2b 54 f1 14 53 bd 28 22 60 00 04 13 01 |...+T..S.("`....|
+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 83 a4 df 27 8d 52 a8 ce 3c af 7e 79 0c |.. ...'.R..<.~y.|
+000000c0 b7 30 5e 5f 8d d6 14 1c a1 65 72 40 73 bc 22 44 |.0^_.....er@s."D|
+000000d0 58 05 10 00 29 00 9c 00 77 00 71 50 46 ad c1 db |X...)...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 ab 26 c2 91 a9 01 83 |Q...h.B.\.&.....|
+00000110 13 26 8f 62 7c 89 c0 a2 b5 9b 6d 4f a4 c9 e2 49 |.&.b|.....mO...I|
+00000120 34 03 2c b2 7d d9 af eb 1a 99 76 3c a5 ef 70 78 |4.,.}.....v<..px|
+00000130 59 58 1c 45 80 c5 f1 b8 91 b2 54 71 3f bf 4f 2a |YX.E......Tq?.O*|
+00000140 b2 9d 9d 6f 6f 1c f1 3c 6c e6 a2 73 00 00 00 00 |...oo..<l..s....|
+00000150 00 21 20 95 92 91 9a 6d da d5 c4 94 f7 2e ed 1a |.! ....m........|
+00000160 5b cd 54 55 8f 87 25 ee 58 d6 92 94 a4 e7 c5 e3 |[.TU..%.X.......|
+00000170 58 4f bd |XO.|
+>>> 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 7f 06 81 e5 |........... ....|
+00000030 d0 10 08 d1 b0 3c 3c 4b 28 39 34 9a 56 ca 47 4a |.....<<K(94.V.GJ|
+00000040 01 f9 03 2b 54 f1 14 53 bd 28 22 60 13 01 00 00 |...+T..S.("`....|
+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 18 d7 0c 38 47 21 c2 8e 01 fe e7 1f 35 ee 7f 8f |...8G!......5...|
+000000a0 04 10 7a 06 61 1f 4d 17 03 03 00 35 b3 38 29 ce |..z.a.M....5.8).|
+000000b0 18 2b 22 5e 01 4d 07 04 87 65 68 85 9d 10 e9 9e |.+"^.M...eh.....|
+000000c0 5a a8 a5 cb 8d f9 48 fe 1b 17 30 04 be 55 92 ce |Z.....H...0..U..|
+000000d0 74 9b 8e 9c 6b 77 5d 09 ca 58 8e c0 ac 85 3b 4e |t...kw]..X....;N|
+000000e0 0b 17 03 03 00 93 90 64 70 a6 d7 20 8e 50 6d b7 |.......dp.. .Pm.|
+000000f0 53 3d ed eb 85 e0 2f fe a2 88 84 3d 26 8a 18 65 |S=..../....=&..e|
+00000100 d1 c0 d2 c4 66 2a 2e 8c 06 5f 46 ee fe 36 f7 00 |....f*..._F..6..|
+00000110 57 3f 95 b3 36 47 0c 1a 78 c4 e3 d6 c1 ae 2f 96 |W?..6G..x...../.|
+00000120 f0 e6 5e 61 86 d7 c1 d7 cc d2 a6 19 0c 29 f5 19 |..^a.........)..|
+00000130 d5 5e 75 6f 8b 49 4b 0b e9 c9 3c 69 87 ab b7 1d |.^uo.IK...<i....|
+00000140 38 84 28 0e 40 79 be 71 dc 61 68 72 c9 a6 83 a4 |8.(.@y.q.ahr....|
+00000150 79 c9 53 4d 43 98 0f e9 33 3c 63 d3 99 e2 97 46 |y.SMC...3<c....F|
+00000160 d1 c1 18 b6 b8 14 ee 19 df 56 94 43 34 b8 af 1f |.........V.C4...|
+00000170 4f f7 c1 e6 d5 17 13 6c bd |O......l.|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 69 08 b0 a0 71 |..........5i...q|
+00000010 1f 95 45 c4 b2 11 43 a9 b5 da ba 11 0a 2b 24 49 |..E...C......+$I|
+00000020 ac 3d 8e ec 32 c9 7f 3e cc 1b fc 9a 68 d0 22 cb |.=..2..>....h.".|
+00000030 37 0e 8f fe 4f 75 1a 62 44 20 60 c2 64 de 48 6d |7...Ou.bD `.d.Hm|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e d5 71 aa 53 2d 55 b7 76 11 45 b0 |......q.S-U.v.E.|
+00000010 f3 de f7 f1 78 0b 10 3f 49 7f ea 83 17 2e b9 50 |....x..?I......P|
+00000020 ec d2 0f 17 03 03 00 13 0a 22 58 66 d8 f7 ad fc |........."Xf....|
+00000030 9c f2 da d1 ae 02 f8 99 d2 26 63 |.........&c|
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..d0aa66a
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-Resume-HelloRetryRequest
@@ -0,0 +1,96 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 01 68 01 00 01 64 03 03 a0 27 b0 af b0 |....h...d...'...|
+00000010 15 2c ed 88 b2 e8 c5 67 2e db 0d 29 13 64 bb 58 |.,.....g...).d.X|
+00000020 3b 71 67 a9 47 65 8a 3c 09 44 29 20 46 fe 89 4b |;qg.Ge.<.D) F..K|
+00000030 f3 1d ed 40 2d 5c 1b 23 26 f5 72 6f d1 b4 77 f5 |...@-\.#&.ro..w.|
+00000040 1a 9f d1 98 34 46 fe 89 0b 2d c1 f9 00 04 13 01 |....4F...-......|
+00000050 00 ff 01 00 01 17 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 8c 7b 61 |....3.&.$... .{a|
+000000b0 71 c8 0b 1a 17 14 d9 eb 21 38 e6 2f c0 40 e9 2d |q.......!8./.@.-|
+000000c0 3c 91 c5 4e 9d bb dd af 40 bc 91 38 74 00 29 00 |<..N....@..8t.).|
+000000d0 9c 00 77 00 71 50 46 ad c1 db a8 38 86 7b 2b bb |..w.qPF....8.{+.|
+000000e0 fd d0 c3 42 3e 00 00 00 00 00 00 00 00 00 00 00 |...B>...........|
+000000f0 00 00 00 00 00 94 68 2c a3 82 51 ed 14 ef 68 ca |......h,..Q...h.|
+00000100 42 c5 5c ab 26 c2 91 a9 01 83 13 26 8f 62 7c 89 |B.\.&......&.b|.|
+00000110 c0 a2 b5 9b 6d 4f a4 c9 e2 49 34 03 2c b2 7d d9 |....mO...I4.,.}.|
+00000120 af eb 1a 99 76 3c a5 ef 70 78 59 58 1c 45 80 c5 |....v<..pxYX.E..|
+00000130 f1 b8 91 b2 54 71 3f bf 4f 2a b2 9d 9d 6f 6f 1c |....Tq?.O*...oo.|
+00000140 f1 3c 6c e6 a2 73 00 00 00 00 00 21 20 7b 6e 44 |.<l..s.....! {nD|
+00000150 ea e1 4c 20 9a d4 1c b5 32 0b d4 79 8e c7 50 fb |..L ....2..y..P.|
+00000160 4e 94 6e 02 1c d3 6a 4e 86 cb ae 2c 02 |N.n...jN...,.|
+>>> Flow 2 (server to client)
+00000000 16 03 03 00 58 02 00 00 54 03 03 cf 21 ad 74 e5 |....X...T...!.t.|
+00000010 9a 61 11 be 1d 8c 02 1e 65 b8 91 c2 a2 11 16 7a |.a......e......z|
+00000020 bb 8c 5e 07 9e 09 e2 c8 a8 33 9c 20 46 fe 89 4b |..^......3. F..K|
+00000030 f3 1d ed 40 2d 5c 1b 23 26 f5 72 6f d1 b4 77 f5 |...@-\.#&.ro..w.|
+00000040 1a 9f d1 98 34 46 fe 89 0b 2d c1 f9 13 01 00 00 |....4F...-......|
+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 89 01 00 01 85 03 |................|
+00000010 03 a0 27 b0 af b0 15 2c ed 88 b2 e8 c5 67 2e db |..'....,.....g..|
+00000020 0d 29 13 64 bb 58 3b 71 67 a9 47 65 8a 3c 09 44 |.).d.X;qg.Ge.<.D|
+00000030 29 20 46 fe 89 4b f3 1d ed 40 2d 5c 1b 23 26 f5 |) F..K...@-\.#&.|
+00000040 72 6f d1 b4 77 f5 1a 9f d1 98 34 46 fe 89 0b 2d |ro..w.....4F...-|
+00000050 c1 f9 00 04 13 01 00 ff 01 00 01 38 00 0b 00 04 |...........8....|
+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 6e 14 0d ac 3f 1a 2a 36 54 4f ec 9d |..A.n...?.*6TO..|
+000000c0 da 5b 93 12 42 eb 58 11 1b 4c 5c 39 a2 32 b8 5b |.[..B.X..L\9.2.[|
+000000d0 41 13 51 05 88 fe 45 d2 01 ef 8d 14 bc 96 de d3 |A.Q...E.........|
+000000e0 1c e3 eb 0c a0 a7 a3 7c 1c b1 9e 38 c2 dc f6 35 |.......|...8...5|
+000000f0 7b 5b 08 2e 00 29 00 9c 00 77 00 71 50 46 ad c1 |{[...)...w.qPF..|
+00000100 db a8 38 86 7b 2b bb fd d0 c3 42 3e 00 00 00 00 |..8.{+....B>....|
+00000110 00 00 00 00 00 00 00 00 00 00 00 00 94 68 2c a3 |.............h,.|
+00000120 82 51 ed 14 ef 68 ca 42 c5 5c ab 26 c2 91 a9 01 |.Q...h.B.\.&....|
+00000130 83 13 26 8f 62 7c 89 c0 a2 b5 9b 6d 4f a4 c9 e2 |..&.b|.....mO...|
+00000140 49 34 03 2c b2 7d d9 af eb 1a 99 76 3c a5 ef 70 |I4.,.}.....v<..p|
+00000150 78 59 58 1c 45 80 c5 f1 b8 91 b2 54 71 3f bf 4f |xYX.E......Tq?.O|
+00000160 2a b2 9d 9d 6f 6f 1c f1 3c 6c e6 a2 73 00 00 00 |*...oo..<l..s...|
+00000170 00 00 21 20 10 ac 47 8c dd 4f 9c ee f3 b2 0a 6b |..! ..G..O.....k|
+00000180 30 56 13 1e a9 53 5b 02 a8 a0 c0 db 1a 44 f7 43 |0V...S[......D.C|
+00000190 af a3 8f b8 |....|
+>>> Flow 4 (server to client)
+00000000 16 03 03 00 a1 02 00 00 9d 03 03 00 00 00 00 00 |................|
+00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+00000020 00 00 00 00 00 00 00 00 00 00 00 20 46 fe 89 4b |........... F..K|
+00000030 f3 1d ed 40 2d 5c 1b 23 26 f5 72 6f d1 b4 77 f5 |...@-\.#&.ro..w.|
+00000040 1a 9f d1 98 34 46 fe 89 0b 2d c1 f9 13 01 00 00 |....4F...-......|
+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 ea 86 30 48 65 |.)...........0He|
+000000b0 cf a6 d4 9d af f7 75 d4 d3 dd af 79 ce 3a 42 5b |......u....y.:B[|
+000000c0 68 7a 17 03 03 00 35 ef d6 22 53 ec 3c 27 84 c7 |hz....5.."S.<'..|
+000000d0 7f b2 81 8e 3e 70 51 25 95 b4 6a 79 01 15 60 c0 |....>pQ%..jy..`.|
+000000e0 39 eb 5b 90 7b 50 f5 3b 50 64 d2 b2 d6 c7 72 cf |9.[.{P.;Pd....r.|
+000000f0 35 f3 25 1c 86 4b 69 ab 6e 50 86 2e 17 03 03 00 |5.%..Ki.nP......|
+00000100 93 66 5a c1 de c6 92 96 95 92 48 90 e7 0f e1 08 |.fZ.......H.....|
+00000110 25 b2 72 a5 7f c5 17 6e 70 5d 6e 68 78 32 72 8d |%.r....np]nhx2r.|
+00000120 3a fa 7a 66 76 26 10 9e f9 92 ca 3b a7 6c 6c fa |:.zfv&.....;.ll.|
+00000130 72 d1 22 f4 b0 b9 2a 90 bd ce 58 e4 ff 1d 88 99 |r."...*...X.....|
+00000140 a4 8d f9 10 af c8 35 cd c4 6f 99 cd 9e 6c 95 b1 |......5..o...l..|
+00000150 b7 6e a4 48 9e 75 f1 d3 c0 b3 27 f1 61 83 ea 13 |.n.H.u....'.a...|
+00000160 06 7f 37 38 f1 31 9e 71 5a 97 15 b5 46 63 44 e8 |..78.1.qZ...FcD.|
+00000170 f4 a1 fc 81 5d f4 c7 65 be 76 da 79 bd fb e4 e6 |....]..e.v.y....|
+00000180 68 de ce f3 32 6b 0c ee 19 18 75 33 77 f2 34 3d |h...2k....u3w.4=|
+00000190 9e c3 da b7 |....|
+>>> Flow 5 (client to server)
+00000000 17 03 03 00 35 59 51 fe aa 0a 69 ef d5 0e ee e3 |....5YQ...i.....|
+00000010 0e 21 f7 e0 80 88 a0 da 23 7a 38 7f 73 e1 da e9 |.!......#z8.s...|
+00000020 7c 02 73 5e f2 64 e5 60 0e c6 d5 9e 7a 45 c2 0b ||.s^.d.`....zE..|
+00000030 6f 08 46 46 5b f1 5b 67 5d 42 |o.FF[.[g]B|
+>>> Flow 6 (server to client)
+00000000 17 03 03 00 1e 3c a5 86 73 ea 62 44 ee 3b 45 a2 |.....<..s.bD.;E.|
+00000010 2a 57 ed 27 0e 65 40 48 23 10 7f ff 27 e5 4e d1 |*W.'.e@H#...'.N.|
+00000020 99 9a e1 17 03 03 00 13 1e 78 1a 08 4b 24 1b fc |.........x..K$..|
+00000030 78 e5 ab fd 8f bf 53 26 f9 b7 c0 |x.....S&...|
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..0160c5a
--- /dev/null
+++ b/src/crypto/tls/testdata/Server-TLSv13-X25519
@@ -0,0 +1,98 @@
+>>> Flow 1 (client to server)
+00000000 16 03 01 00 c2 01 00 00 be 03 03 cb 53 78 a8 58 |............Sx.X|
+00000010 de 5b 75 c2 c5 b3 ac fa c3 6e 85 a7 e5 a3 a4 ca |.[u......n......|
+00000020 1f 82 95 38 fa 79 4c e2 c8 66 8a 20 be 7a 94 d6 |...8.yL..f. .z..|
+00000030 f4 82 e2 2f 3b 2c e4 5f ae c2 8b be d1 2f b6 67 |.../;,._...../.g|
+00000040 9e 78 7a 51 86 1f c1 d9 8f 43 2f 78 00 04 13 03 |.xzQ.....C/x....|
+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 7f 3e a2 2e 2f 88 8a e1 f3 |&.$... .>../....|
+000000b0 6a a4 47 d7 6d b7 3c 02 c4 bb f6 de 41 38 50 74 |j.G.m.<.....A8Pt|
+000000c0 29 21 f5 fe 9f 0b 6f |)!....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 be 7a 94 d6 |........... .z..|
+00000030 f4 82 e2 2f 3b 2c e4 5f ae c2 8b be d1 2f b6 67 |.../;,._...../.g|
+00000040 9e 78 7a 51 86 1f c1 d9 8f 43 2f 78 13 03 00 00 |.xzQ.....C/x....|
+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 fb 0e 8b 72 0d 35 |.............r.5|
+00000090 97 db e2 2e b8 20 be 96 27 6b cd ab 6b 24 5b c4 |..... ..'k..k$[.|
+000000a0 e9 17 03 03 02 6d 3a 21 03 ea 45 e9 4e f1 19 1e |.....m:!..E.N...|
+000000b0 33 37 04 5b 3e db 54 f0 27 6f c7 96 78 50 01 46 |37.[>.T.'o..xP.F|
+000000c0 d1 8b 8f 79 70 21 9d 62 97 b9 bf 6d 14 e5 82 f4 |...yp!.b...m....|
+000000d0 ad 89 90 77 12 1f 61 8e 1d 94 d3 27 0f 0e eb 77 |...w..a....'...w|
+000000e0 8d b2 2f fb 58 b4 ee 88 19 91 47 d1 3d 10 9e 4a |../.X.....G.=..J|
+000000f0 1e 41 b9 c6 41 8f 59 11 7f e0 ac e7 b9 d5 be 40 |.A..A.Y........@|
+00000100 cc aa bc ab 56 5a 2b a9 c9 cf df c0 dc 8f d2 9d |....VZ+.........|
+00000110 59 a7 88 36 98 2e 87 c6 1d af 26 a1 e8 08 2d bd |Y..6......&...-.|
+00000120 9b 5b 1c 4e 22 d2 a1 7c 4d 0b 0f af da 5d fe f7 |.[.N"..|M....]..|
+00000130 83 4d f6 54 c1 fe 03 73 6d c9 17 02 6b 78 09 91 |.M.T...sm...kx..|
+00000140 aa 61 9a 93 04 66 fa 6b e8 2e d7 18 d2 4d 6e 25 |.a...f.k.....Mn%|
+00000150 c3 01 2f a5 0e 1b da a1 64 67 e5 a5 c0 5b ef ec |../.....dg...[..|
+00000160 83 5a d3 0e 44 b7 d5 97 9c c7 c4 94 b4 4b 01 e6 |.Z..D........K..|
+00000170 48 28 21 cb 04 10 be b0 3b 53 df 15 47 12 67 ea |H(!.....;S..G.g.|
+00000180 24 65 a1 ce 0b af 05 5b c9 95 bf 28 2e 55 3c 21 |$e.....[...(.U<!|
+00000190 dc 6f 43 54 87 4d 2a b0 4a e8 01 01 e8 cf 07 6a |.oCT.M*.J......j|
+000001a0 09 d0 f7 ae 97 e1 68 78 ff 33 7e 07 e1 77 ee ec |......hx.3~..w..|
+000001b0 b8 1f d5 73 34 06 3f 32 57 e2 a4 52 82 31 86 cc |...s4.?2W..R.1..|
+000001c0 2f 1b 9c 77 78 64 de 01 ac 4c f4 b9 bc 3d 0e f8 |/..wxd...L...=..|
+000001d0 d1 b7 bd 9c 35 05 19 dc 1c 3b 05 c2 c0 66 e7 c3 |....5....;...f..|
+000001e0 68 0e 6d d0 83 92 46 d1 7b 81 9b 87 5b 3f 5b b9 |h.m...F.{...[?[.|
+000001f0 fa cc a5 cc 04 d3 01 54 39 a7 66 50 82 b8 64 a6 |.......T9.fP..d.|
+00000200 06 e3 24 34 62 80 79 28 74 15 1c 8d 91 00 b0 fa |..$4b.y(t.......|
+00000210 af 52 c3 6a fb c8 41 af 77 3d bd 67 d3 e6 2a 76 |.R.j..A.w=.g..*v|
+00000220 ab 63 90 bc 3c 56 31 2d 62 dd 84 98 3f 6a 6b e9 |.c..<V1-b...?jk.|
+00000230 af 2a ed 1a bf da b9 bd 23 f3 b0 5b a3 a3 72 21 |.*......#..[..r!|
+00000240 fb e9 0d 27 58 27 bd 11 60 49 4f f4 6a 38 a4 db |...'X'..`IO.j8..|
+00000250 ff 26 88 d6 1b 50 35 a6 02 d9 e8 c6 05 54 2d 62 |.&...P5......T-b|
+00000260 92 7a 45 86 e5 7d 61 93 05 d6 61 ae af b4 43 cf |.zE..}a...a...C.|
+00000270 21 40 d0 f1 7f 92 48 92 ed d5 bd 33 3c f9 69 0d |!@....H....3<.i.|
+00000280 bf 7c 72 c4 85 e0 c3 42 4d 69 30 d1 5a 2d 11 95 |.|r....BMi0.Z-..|
+00000290 ee 9f 69 9b 99 b9 0c 17 51 15 17 d7 ea fb c8 01 |..i.....Q.......|
+000002a0 22 ac 3e 54 9f 2c 95 9d 3f 98 d3 9c ec d9 ac d8 |".>T.,..?.......|
+000002b0 71 6a d6 0f 53 5e ea 92 53 e3 dd 96 be 38 61 74 |qj..S^..S....8at|
+000002c0 5d 74 ac c4 8c 72 c6 82 dc f4 22 fb 5c 64 0f 33 |]t...r....".\d.3|
+000002d0 b3 31 a1 a9 e0 6d 96 14 0b e1 00 7d 42 44 45 02 |.1...m.....}BDE.|
+000002e0 42 63 a1 15 14 73 b6 e4 18 a7 30 9e e0 df a9 ba |Bc...s....0.....|
+000002f0 44 72 64 ea 06 a4 a1 46 58 07 b1 a8 48 dc ea 73 |Drd....FX...H..s|
+00000300 35 d8 98 de 6c 13 93 bb 7a 64 fb df bf 93 cb 65 |5...l...zd.....e|
+00000310 a4 1a 3a 17 03 03 00 99 41 8d 8b b5 97 ae 6a fb |..:.....A.....j.|
+00000320 28 ae 10 17 a7 a7 bd a2 a2 54 61 33 ea 5c 3d 82 |(........Ta3.\=.|
+00000330 6c 7d fe 3e 3b 6f 92 6b 6a 0a ee fe 85 90 67 59 |l}.>;o.kj.....gY|
+00000340 df d9 fc c0 4a 9a 5b ae 57 29 5d fb ff 74 28 f1 |....J.[.W)]..t(.|
+00000350 27 f4 ab ee f9 e8 04 cf 2b 62 4d a8 6a 4f ac 85 |'.......+bM.jO..|
+00000360 ec a5 18 d7 88 74 9e 3e ea 79 8e 5d df f8 8a 1c |.....t.>.y.]....|
+00000370 10 1b 1d d3 4a cf 2a 56 f2 ca 90 1f 37 2c cc b7 |....J.*V....7,..|
+00000380 31 91 fb d7 7f bb 07 e2 ec 84 8a 6f 08 a1 7e 2e |1..........o..~.|
+00000390 62 8a 5c b9 76 d3 68 e5 d0 b8 73 92 86 80 e5 af |b.\.v.h...s.....|
+000003a0 b4 ef 13 ea 3c 09 2a 3f 7e be 16 72 1c 46 a0 29 |....<.*?~..r.F.)|
+000003b0 0a 17 03 03 00 35 a7 10 63 c4 a1 7f 26 17 ba b7 |.....5..c...&...|
+000003c0 e3 86 6e 52 36 00 8e 68 84 dc 51 8d a6 0c 21 ba |..nR6..h..Q...!.|
+000003d0 c3 d9 84 49 ed 57 78 98 68 be 78 a6 d1 f0 67 ac |...I.Wx.h.x...g.|
+000003e0 65 9e d2 d8 f3 b9 58 27 24 57 83 17 03 03 00 93 |e.....X'$W......|
+000003f0 00 54 de 7f 11 18 1d 12 83 10 77 b2 e9 fd a7 a4 |.T........w.....|
+00000400 46 c4 1c 15 0d 24 e0 94 f8 ff 84 19 45 ad 52 c8 |F....$......E.R.|
+00000410 85 0b c5 4a a7 6d a1 b0 12 cb 13 58 f6 44 a3 e2 |...J.m.....X.D..|
+00000420 b8 7a b5 8c 8f 8a 47 76 ef cb 2d 7b 6e 75 81 39 |.z....Gv..-{nu.9|
+00000430 3e 12 e8 b5 c6 2d cb e0 fd ac af 58 5a 01 70 32 |>....-.....XZ.p2|
+00000440 0e 12 32 95 10 70 94 28 ec 9b 50 e5 78 c4 b7 75 |..2..p.(..P.x..u|
+00000450 97 4a 54 97 bb 30 e6 19 8a 86 87 d7 50 02 8f a8 |.JT..0......P...|
+00000460 1b 97 d6 e7 bf 25 66 9a 5a cd 5c 84 33 42 f1 72 |.....%f.Z.\.3B.r|
+00000470 d2 44 f1 64 e1 3d 38 b7 7a 32 e3 e8 9a 49 19 90 |.D.d.=8.z2...I..|
+00000480 00 2b f6 |.+.|
+>>> Flow 3 (client to server)
+00000000 14 03 03 00 01 01 17 03 03 00 35 9d c7 a1 4d 5f |..........5...M_|
+00000010 7f 3a 04 b0 cf de 09 d5 84 c1 8f 9b 85 a6 a0 53 |.:.............S|
+00000020 c3 aa 19 5e a0 b2 a2 f1 22 f2 51 e0 25 c5 49 57 |...^....".Q.%.IW|
+00000030 52 de ad 75 ec e4 e3 36 84 78 22 c8 6c 80 88 8c |R..u...6.x".l...|
+>>> Flow 4 (server to client)
+00000000 17 03 03 00 1e 3f 0d f6 84 47 21 4e 37 7b df eb |.....?...G!N7{..|
+00000010 eb 38 af a5 ec b9 b6 20 24 f5 1a 1e 25 77 92 82 |.8..... $...%w..|
+00000020 97 88 9f 17 03 03 00 13 e2 80 d8 e1 2a bf d5 e3 |............*...|
+00000030 bc b7 82 2f 50 2c e5 b9 4b 8c d6 |.../P,..K..|
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..b82ccd1
--- /dev/null
+++ b/src/crypto/tls/ticket.go
@@ -0,0 +1,185 @@
+// 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"
+ "crypto/aes"
+ "crypto/cipher"
+ "crypto/hmac"
+ "crypto/sha256"
+ "crypto/subtle"
+ "errors"
+ "io"
+
+ "golang.org/x/crypto/cryptobyte"
+)
+
+// sessionState contains the information that is serialized into a session
+// ticket in order to later resume a connection.
+type sessionState struct {
+ vers uint16
+ cipherSuite uint16
+ createdAt uint64
+ masterSecret []byte // opaque master_secret<1..2^16-1>;
+ // struct { opaque certificate<1..2^24-1> } Certificate;
+ certificates [][]byte // Certificate certificate_list<0..2^24-1>;
+
+ // usedOldKey is true if the ticket from which this session came from
+ // was encrypted with an older key and thus should be refreshed.
+ usedOldKey bool
+}
+
+func (m *sessionState) marshal() ([]byte, error) {
+ var b cryptobyte.Builder
+ b.AddUint16(m.vers)
+ b.AddUint16(m.cipherSuite)
+ addUint64(&b, m.createdAt)
+ b.AddUint16LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(m.masterSecret)
+ })
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ for _, cert := range m.certificates {
+ b.AddUint24LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(cert)
+ })
+ }
+ })
+ return b.Bytes()
+}
+
+func (m *sessionState) unmarshal(data []byte) bool {
+ *m = sessionState{usedOldKey: m.usedOldKey}
+ s := cryptobyte.String(data)
+ if ok := s.ReadUint16(&m.vers) &&
+ s.ReadUint16(&m.cipherSuite) &&
+ readUint64(&s, &m.createdAt) &&
+ readUint16LengthPrefixed(&s, &m.masterSecret) &&
+ len(m.masterSecret) != 0; !ok {
+ return false
+ }
+ var certList cryptobyte.String
+ if !s.ReadUint24LengthPrefixed(&certList) {
+ return false
+ }
+ for !certList.Empty() {
+ var cert []byte
+ if !readUint24LengthPrefixed(&certList, &cert) {
+ return false
+ }
+ m.certificates = append(m.certificates, cert)
+ }
+ return s.Empty()
+}
+
+// sessionStateTLS13 is the content of a TLS 1.3 session ticket. Its first
+// version (revision = 0) doesn't carry any of the information needed for 0-RTT
+// validation and the nonce is always empty.
+type sessionStateTLS13 struct {
+ // uint8 version = 0x0304;
+ // uint8 revision = 0;
+ cipherSuite uint16
+ createdAt uint64
+ resumptionSecret []byte // opaque resumption_master_secret<1..2^8-1>;
+ certificate Certificate // CertificateEntry certificate_list<0..2^24-1>;
+}
+
+func (m *sessionStateTLS13) marshal() ([]byte, error) {
+ var b cryptobyte.Builder
+ b.AddUint16(VersionTLS13)
+ b.AddUint8(0) // revision
+ b.AddUint16(m.cipherSuite)
+ addUint64(&b, m.createdAt)
+ b.AddUint8LengthPrefixed(func(b *cryptobyte.Builder) {
+ b.AddBytes(m.resumptionSecret)
+ })
+ marshalCertificate(&b, m.certificate)
+ return b.Bytes()
+}
+
+func (m *sessionStateTLS13) unmarshal(data []byte) bool {
+ *m = sessionStateTLS13{}
+ s := cryptobyte.String(data)
+ var version uint16
+ var revision uint8
+ return s.ReadUint16(&version) &&
+ version == VersionTLS13 &&
+ s.ReadUint8(&revision) &&
+ revision == 0 &&
+ s.ReadUint16(&m.cipherSuite) &&
+ readUint64(&s, &m.createdAt) &&
+ readUint8LengthPrefixed(&s, &m.resumptionSecret) &&
+ len(m.resumptionSecret) != 0 &&
+ unmarshalCertificate(&s, &m.certificate) &&
+ s.Empty()
+}
+
+func (c *Conn) encryptTicket(state []byte) ([]byte, error) {
+ if len(c.ticketKeys) == 0 {
+ return nil, errors.New("tls: internal error: session ticket keys unavailable")
+ }
+
+ encrypted := make([]byte, ticketKeyNameLen+aes.BlockSize+len(state)+sha256.Size)
+ keyName := encrypted[:ticketKeyNameLen]
+ iv := encrypted[ticketKeyNameLen : ticketKeyNameLen+aes.BlockSize]
+ macBytes := encrypted[len(encrypted)-sha256.Size:]
+
+ if _, err := io.ReadFull(c.config.rand(), iv); err != nil {
+ return nil, err
+ }
+ key := c.ticketKeys[0]
+ copy(keyName, key.keyName[:])
+ 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(encrypted[ticketKeyNameLen+aes.BlockSize:], state)
+
+ mac := hmac.New(sha256.New, key.hmacKey[:])
+ mac.Write(encrypted[:len(encrypted)-sha256.Size])
+ mac.Sum(macBytes[:0])
+
+ return encrypted, nil
+}
+
+func (c *Conn) decryptTicket(encrypted []byte) (plaintext []byte, usedOldKey bool) {
+ if len(encrypted) < ticketKeyNameLen+aes.BlockSize+sha256.Size {
+ return nil, false
+ }
+
+ keyName := encrypted[:ticketKeyNameLen]
+ iv := encrypted[ticketKeyNameLen : ticketKeyNameLen+aes.BlockSize]
+ macBytes := encrypted[len(encrypted)-sha256.Size:]
+ ciphertext := encrypted[ticketKeyNameLen+aes.BlockSize : len(encrypted)-sha256.Size]
+
+ keyIndex := -1
+ for i, candidateKey := range c.ticketKeys {
+ if bytes.Equal(keyName, candidateKey.keyName[:]) {
+ keyIndex = i
+ break
+ }
+ }
+ if keyIndex == -1 {
+ return nil, false
+ }
+ key := &c.ticketKeys[keyIndex]
+
+ mac := hmac.New(sha256.New, key.hmacKey[:])
+ mac.Write(encrypted[:len(encrypted)-sha256.Size])
+ expected := mac.Sum(nil)
+
+ if subtle.ConstantTimeCompare(macBytes, expected) != 1 {
+ return nil, false
+ }
+
+ block, err := aes.NewCipher(key.aesKey[:])
+ if err != nil {
+ return nil, false
+ }
+ plaintext = make([]byte, len(ciphertext))
+ cipher.NewCTR(block, iv).XORKeyStream(plaintext, ciphertext)
+
+ return plaintext, keyIndex > 0
+}
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..d8a43ad
--- /dev/null
+++ b/src/crypto/tls/tls_test.go
@@ -0,0 +1,1611 @@
+// 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")
+ }
+ listener := newLocalListener(t)
+
+ addr := listener.Addr().String()
+ defer listener.Close()
+
+ complete := make(chan bool)
+ defer close(complete)
+
+ go func() {
+ conn, err := listener.Accept()
+ if err != nil {
+ t.Error(err)
+ return
+ }
+ <-complete
+ conn.Close()
+ }()
+
+ dialer := &net.Dialer{
+ Timeout: 10 * time.Millisecond,
+ }
+
+ var err error
+ if _, err = DialWithDialer(dialer, "tcp", addr, nil); err == nil {
+ t.Fatal("DialWithTimeout completed successfully")
+ }
+
+ if !isTimeoutError(err) {
+ t.Errorf("resulting error not a timeout: %v\nType %T: %#v", err, err, err)
+ }
+}
+
+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")
+ }
+ 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")
+ }
+}
+
+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 = 6
+ 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
+ },
+ }
+
+ c2 := c1.Clone()
+
+ c2.Time()
+ c2.GetCertificate(nil)
+ c2.GetClientCertificate(nil)
+ c2.GetConfigForClient(nil)
+ c2.VerifyPeerCertificate(nil, nil)
+ c2.VerifyConnection(ConnectionState{})
+
+ 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":
+ // 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")
+ }
+ }
+}
+
+// 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)
+ }
+}