aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/crypto/tls
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/crypto/tls')
-rw-r--r--libgo/go/crypto/tls/alert.go120
-rw-r--r--libgo/go/crypto/tls/auth.go18
-rw-r--r--libgo/go/crypto/tls/auth_test.go14
-rw-r--r--libgo/go/crypto/tls/common.go324
-rw-r--r--libgo/go/crypto/tls/common_string.go116
-rw-r--r--libgo/go/crypto/tls/conn.go84
-rw-r--r--libgo/go/crypto/tls/example_test.go122
-rw-r--r--libgo/go/crypto/tls/generate_cert.go12
-rw-r--r--libgo/go/crypto/tls/handshake_client.go126
-rw-r--r--libgo/go/crypto/tls/handshake_client_test.go535
-rw-r--r--libgo/go/crypto/tls/handshake_client_tls13.go88
-rw-r--r--libgo/go/crypto/tls/handshake_messages_test.go9
-rw-r--r--libgo/go/crypto/tls/handshake_server.go87
-rw-r--r--libgo/go/crypto/tls/handshake_server_test.go22
-rw-r--r--libgo/go/crypto/tls/handshake_server_tls13.go17
-rw-r--r--libgo/go/crypto/tls/key_agreement.go2
-rw-r--r--libgo/go/crypto/tls/key_schedule.go7
-rw-r--r--libgo/go/crypto/tls/link_test.go121
-rw-r--r--libgo/go/crypto/tls/testdata/Server-TLSv10-ExportKeyingMaterial83
-rw-r--r--libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN83
-rw-r--r--libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch83
-rw-r--r--libgo/go/crypto/tls/testdata/Server-TLSv12-ExportKeyingMaterial81
-rw-r--r--libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicket167
-rw-r--r--libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicketPreDisable167
-rw-r--r--libgo/go/crypto/tls/testdata/Server-TLSv12-Resume82
-rw-r--r--libgo/go/crypto/tls/ticket.go119
-rw-r--r--libgo/go/crypto/tls/tls.go106
-rw-r--r--libgo/go/crypto/tls/tls_test.go174
28 files changed, 2075 insertions, 894 deletions
diff --git a/libgo/go/crypto/tls/alert.go b/libgo/go/crypto/tls/alert.go
index 22b3eca..4790b73 100644
--- a/libgo/go/crypto/tls/alert.go
+++ b/libgo/go/crypto/tls/alert.go
@@ -15,63 +15,75 @@ const (
)
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
- alertProtocolVersion alert = 70
- alertInsufficientSecurity alert = 71
- alertInternalError alert = 80
- alertInappropriateFallback alert = 86
- alertUserCanceled alert = 90
- alertNoRenegotiation alert = 100
- alertMissingExtension alert = 109
- alertUnsupportedExtension alert = 110
- alertUnrecognizedName alert = 112
- alertNoApplicationProtocol alert = 120
+ 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",
- 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",
- alertUnrecognizedName: "unrecognized name",
- alertNoApplicationProtocol: "no application protocol",
+ 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 {
diff --git a/libgo/go/crypto/tls/auth.go b/libgo/go/crypto/tls/auth.go
index 009f8d3..a9df0da 100644
--- a/libgo/go/crypto/tls/auth.go
+++ b/libgo/go/crypto/tls/auth.go
@@ -11,7 +11,6 @@ import (
"crypto/ed25519"
"crypto/elliptic"
"crypto/rsa"
- "encoding/asn1"
"errors"
"fmt"
"hash"
@@ -27,14 +26,7 @@ func verifyHandshakeSignature(sigType uint8, pubkey crypto.PublicKey, hashFunc c
if !ok {
return fmt.Errorf("expected an ECDSA public key, got %T", pubkey)
}
- ecdsaSig := new(ecdsaSignature)
- if _, err := asn1.Unmarshal(sig, ecdsaSig); err != nil {
- return err
- }
- if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
- return errors.New("ECDSA signature contained zero or negative values")
- }
- if !ecdsa.Verify(pubKey, signed, ecdsaSig.R, ecdsaSig.S) {
+ if !ecdsa.VerifyASN1(pubKey, signed, sig) {
return errors.New("ECDSA verification failure")
}
case signatureEd25519:
@@ -114,7 +106,7 @@ func typeAndHashFromSignatureScheme(signatureAlgorithm SignatureScheme) (sigType
case Ed25519:
sigType = signatureEd25519
default:
- return 0, 0, fmt.Errorf("unsupported signature algorithm: %#04x", signatureAlgorithm)
+ return 0, 0, fmt.Errorf("unsupported signature algorithm: %v", signatureAlgorithm)
}
switch signatureAlgorithm {
case PKCS1WithSHA1, ECDSAWithSHA1:
@@ -128,7 +120,7 @@ func typeAndHashFromSignatureScheme(signatureAlgorithm SignatureScheme) (sigType
case Ed25519:
hash = directSigning
default:
- return 0, 0, fmt.Errorf("unsupported signature algorithm: %#04x", signatureAlgorithm)
+ return 0, 0, fmt.Errorf("unsupported signature algorithm: %v", signatureAlgorithm)
}
return sigType, hash, nil
}
@@ -163,9 +155,9 @@ var rsaSignatureSchemes = []struct {
{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
+ // 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.
+ // 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},
diff --git a/libgo/go/crypto/tls/auth_test.go b/libgo/go/crypto/tls/auth_test.go
index c8d8c8f..c42e349 100644
--- a/libgo/go/crypto/tls/auth_test.go
+++ b/libgo/go/crypto/tls/auth_test.go
@@ -62,7 +62,7 @@ func TestSignatureSelection(t *testing.T) {
t.Errorf("test[%d]: unexpected selectSignatureScheme error: %v", testNo, err)
}
if test.expectedSigAlg != sigAlg {
- t.Errorf("test[%d]: expected signature scheme %#x, got %#x", testNo, 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 {
@@ -115,7 +115,7 @@ func TestSignatureSelection(t *testing.T) {
for testNo, test := range badTests {
sigAlg, err := selectSignatureScheme(test.tlsVersion, test.cert, test.peerSigAlgs)
if err == nil {
- t.Errorf("test[%d]: unexpected success, got %#x", testNo, sigAlg)
+ t.Errorf("test[%d]: unexpected success, got %v", testNo, sigAlg)
}
}
}
@@ -129,7 +129,7 @@ func TestLegacyTypeAndHash(t *testing.T) {
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, sigType)
+ t.Errorf("RSA: expected hash %#x, got %#x", expectedHashFunc, hashFunc)
}
sigType, hashFunc, err = legacyTypeAndHashFromPublicKey(testECDSAPrivateKey.Public())
@@ -140,7 +140,7 @@ func TestLegacyTypeAndHash(t *testing.T) {
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, sigType)
+ t.Errorf("ECDSA: expected hash %#x, got %#x", expectedHashFunc, hashFunc)
}
// Ed25519 is not supported by TLS 1.0 and 1.1.
@@ -156,13 +156,13 @@ func TestSupportedSignatureAlgorithms(t *testing.T) {
for _, sigAlg := range supportedSignatureAlgorithms {
sigType, hash, err := typeAndHashFromSignatureScheme(sigAlg)
if err != nil {
- t.Errorf("%#04x: unexpected error: %v", sigAlg, err)
+ t.Errorf("%v: unexpected error: %v", sigAlg, err)
}
if sigType == 0 {
- t.Errorf("%#04x: missing signature type", sigAlg)
+ t.Errorf("%v: missing signature type", sigAlg)
}
if hash == 0 && sigAlg != Ed25519 {
- t.Errorf("%#04x: missing hash", sigAlg)
+ t.Errorf("%v: missing hash", sigAlg)
}
}
}
diff --git a/libgo/go/crypto/tls/common.go b/libgo/go/crypto/tls/common.go
index c3de0b3..e8d0091 100644
--- a/libgo/go/crypto/tls/common.go
+++ b/libgo/go/crypto/tls/common.go
@@ -19,7 +19,6 @@ import (
"fmt"
"internal/cpu"
"io"
- "math/big"
"net"
"strings"
"sync"
@@ -208,30 +207,78 @@ const (
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 uint16 // TLS version used by the connection (e.g. VersionTLS12)
- HandshakeComplete bool // TLS handshake is complete
- DidResume bool // connection resumes a previous TLS connection
- CipherSuite uint16 // cipher suite in use (TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, ...)
- NegotiatedProtocol string // negotiated next protocol (not guaranteed to be from Config.NextProtos)
- NegotiatedProtocolIsMutual bool // negotiated protocol was advertised by server (client side only)
- ServerName string // server name requested by client, if any (server side only)
- PeerCertificates []*x509.Certificate // certificate chain presented by remote peer
- VerifiedChains [][]*x509.Certificate // verified chains built from PeerCertificates
- SignedCertificateTimestamps [][]byte // SCTs from the peer, if any
- OCSPResponse []byte // stapled OCSP response from peer, if any
+ // Version is the TLS version used by the connection (e.g. VersionTLS12).
+ Version uint16
- // ekm is a closure exposed via ExportKeyingMaterial.
- ekm func(label string, context []byte, length int) ([]byte, error)
+ // 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.
+ //
+ // Note that on the client side, this is currently not guaranteed to be from
+ // Config.NextProtos.
+ 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
- // TLSUnique contains the "tls-unique" channel binding value (see RFC
- // 5929, section 3). For resumed sessions this value will be nil
- // because resumption does not include enough context (see
- // https://mitls.org/pages/attacks/3SHAKE#channelbindings). This will
- // change in future versions of Go once the TLS master-secret fix has
- // been standardized and implemented. It is not defined in TLS 1.3.
+ // 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
@@ -275,6 +322,8 @@ type ClientSessionState struct {
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
@@ -300,6 +349,8 @@ type ClientSessionCache interface {
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
@@ -496,15 +547,10 @@ type Config struct {
// If GetConfigForClient is nil, the Config passed to Server() will be
// used for all connections.
//
- // Uniquely for the fields in the returned Config, session ticket keys
- // will be duplicated from the original Config if not set.
- // Specifically, if SetSessionTicketKeys was called on the original
- // config but not on the returned config then the ticket keys from the
- // original config will be copied into the new config before use.
- // Otherwise, if SessionTicketKey was set in the original config but
- // not in the returned config then it will be copied into the returned
- // config before use. If neither of those cases applies then the key
- // material from the returned config will be used for session tickets.
+ // 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
@@ -520,6 +566,16 @@ type Config struct {
// 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.
@@ -544,12 +600,12 @@ type Config struct {
// 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, TLS accepts any certificate
- // presented by the server and any host name in that certificate.
- // In this mode, TLS is susceptible to man-in-the-middle attacks.
- // This should be used only for testing.
+ // 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 supported cipher suites for TLS versions up to
@@ -574,10 +630,10 @@ type Config struct {
// See RFC 5077 and the PSK mode of RFC 8446. If zero, it will be filled
// with random data before the first server handshake.
//
- // If multiple servers are terminating connections for the same host
- // they should all have the same SessionTicketKey. If the
- // SessionTicketKey leaks, previously recorded and future TLS
- // connections using that key might be compromised.
+ // 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
@@ -617,20 +673,32 @@ type Config struct {
// used for debugging.
KeyLogWriter io.Writer
- serverInitOnce sync.Once // guards calling (*Config).serverInit
-
- // mutex protects sessionTicketKeys.
+ // mutex protects sessionTicketKeys and autoSessionTicketKeys.
mutex sync.RWMutex
- // sessionTicketKeys contains zero or more ticket keys. If the length
- // is zero, SessionTicketsDisabled must be true. The first key is used
- // for new tickets and any subsequent keys can be used to decrypt old
- // tickets.
+ // 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
}
-// 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.
-const ticketKeyNameLen = 16
+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 {
@@ -639,16 +707,19 @@ type ticketKey struct {
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 ticketKeyFromBytes(b [32]byte) (key ticketKey) {
+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
}
@@ -659,15 +730,8 @@ const maxSessionTicketLifetime = 7 * 24 * time.Hour
// Clone returns a shallow clone of c. It is safe to clone a Config that is
// being used concurrently by a TLS client or server.
func (c *Config) Clone() *Config {
- // Running serverInit ensures that it's safe to read
- // SessionTicketsDisabled.
- c.serverInitOnce.Do(func() { c.serverInit(nil) })
-
- var sessionTicketKeys []ticketKey
c.mutex.RLock()
- sessionTicketKeys = c.sessionTicketKeys
- c.mutex.RUnlock()
-
+ defer c.mutex.RUnlock()
return &Config{
Rand: c.Rand,
Time: c.Time,
@@ -677,6 +741,7 @@ func (c *Config) Clone() *Config {
GetClientCertificate: c.GetClientCertificate,
GetConfigForClient: c.GetConfigForClient,
VerifyPeerCertificate: c.VerifyPeerCertificate,
+ VerifyConnection: c.VerifyConnection,
RootCAs: c.RootCAs,
NextProtos: c.NextProtos,
ServerName: c.ServerName,
@@ -694,58 +759,122 @@ func (c *Config) Clone() *Config {
DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled,
Renegotiation: c.Renegotiation,
KeyLogWriter: c.KeyLogWriter,
- sessionTicketKeys: sessionTicketKeys,
+ sessionTicketKeys: c.sessionTicketKeys,
+ autoSessionTicketKeys: c.autoSessionTicketKeys,
}
}
-// serverInit is run under c.serverInitOnce to do initialization of c. If c was
-// returned by a GetConfigForClient callback then the argument should be the
-// Config that was passed to Server, otherwise it should be nil.
-func (c *Config) serverInit(originalConfig *Config) {
- if c.SessionTicketsDisabled || len(c.ticketKeys()) != 0 {
+// 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
}
- alreadySet := false
- for _, b := range c.SessionTicketKey {
- if b != 0 {
- alreadySet = true
- break
+ // 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)}
}
- if !alreadySet {
- if originalConfig != nil {
- copy(c.SessionTicketKey[:], originalConfig.SessionTicketKey[:])
- } else if _, err := io.ReadFull(c.rand(), c.SessionTicketKey[:]); err != nil {
- c.SessionTicketsDisabled = true
- return
+}
+
+// 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()
}
- if originalConfig != nil {
- originalConfig.mutex.RLock()
- c.sessionTicketKeys = originalConfig.sessionTicketKeys
- originalConfig.mutex.RUnlock()
- } else {
- c.sessionTicketKeys = []ticketKey{ticketKeyFromBytes(c.SessionTicketKey)}
+ 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
}
-}
-func (c *Config) ticketKeys() []ticketKey {
- c.mutex.RLock()
- // c.sessionTicketKeys is constant once created. SetSessionTicketKeys
- // will only update it by replacing it with a new value.
- ret := c.sessionTicketKeys
+ // autoSessionTicketKeys are managed by auto-rotation.
c.mutex.RUnlock()
- return ret
+ 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.
+// 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")
@@ -753,7 +882,7 @@ func (c *Config) SetSessionTicketKeys(keys [][32]byte) {
newKeys := make([]ticketKey, len(keys))
for i, bytes := range keys {
- newKeys[i] = ticketKeyFromBytes(bytes)
+ newKeys[i] = c.ticketKeyFromBytes(bytes)
}
c.mutex.Lock()
@@ -1264,13 +1393,6 @@ func (c *lruSessionCache) Get(sessionKey string) (*ClientSessionState, bool) {
return nil, false
}
-// TODO(jsing): Make these available to both crypto/x509 and crypto/tls.
-type dsaSignature struct {
- R, S *big.Int
-}
-
-type ecdsaSignature dsaSignature
-
var emptyConfig Config
func defaultConfig() *Config {
diff --git a/libgo/go/crypto/tls/common_string.go b/libgo/go/crypto/tls/common_string.go
new file mode 100644
index 0000000..2381088
--- /dev/null
+++ b/libgo/go/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/libgo/go/crypto/tls/conn.go b/libgo/go/crypto/tls/conn.go
index fac4b91..edcfecf 100644
--- a/libgo/go/crypto/tls/conn.go
+++ b/libgo/go/crypto/tls/conn.go
@@ -24,8 +24,9 @@ import (
// It implements the net.Conn interface.
type Conn struct {
// constant
- conn net.Conn
- isClient bool
+ conn net.Conn
+ isClient bool
+ handshakeFn func() error // (*Conn).clientHandshake or serverHandshake
// handshakeStatus is 1 if the connection is currently transferring
// application data (i.e. is not currently processing a handshake).
@@ -61,6 +62,11 @@ type Conn struct {
// 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
@@ -162,9 +168,22 @@ type halfConn struct {
trafficSecret []byte // current TLS 1.3 traffic secret
}
+type permamentError struct {
+ err net.Error
+}
+
+func (e *permamentError) Error() string { return e.err.Error() }
+func (e *permamentError) Unwrap() error { return e.err }
+func (e *permamentError) Timeout() bool { return e.err.Timeout() }
+func (e *permamentError) Temporary() bool { return false }
+
func (hc *halfConn) setErrorLocked(err error) error {
- hc.err = err
- return err
+ if e, ok := err.(net.Error); ok {
+ hc.err = &permamentError{err: e}
+ } else {
+ hc.err = err
+ }
+ return hc.err
}
// prepareCipherSpec sets the encryption and MAC states
@@ -1320,8 +1339,12 @@ func (c *Conn) closeNotify() error {
// 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.
+//
+// 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
+// the Dialer's DialContext method.
func (c *Conn) Handshake() error {
c.handshakeMutex.Lock()
defer c.handshakeMutex.Unlock()
@@ -1336,11 +1359,7 @@ func (c *Conn) Handshake() error {
c.in.Lock()
defer c.in.Unlock()
- if c.isClient {
- c.handshakeErr = c.clientHandshake()
- } else {
- c.handshakeErr = c.serverHandshake()
- }
+ c.handshakeErr = c.handshakeFn()
if c.handshakeErr == nil {
c.handshakes++
} else {
@@ -1360,35 +1379,34 @@ func (c *Conn) Handshake() error {
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 = !c.clientProtocolFallback
state.ServerName = c.serverName
-
- if state.HandshakeComplete {
- state.Version = c.vers
- state.NegotiatedProtocol = c.clientProtocol
- state.DidResume = c.didResume
- state.NegotiatedProtocolIsMutual = !c.clientProtocolFallback
- 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
+ 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.ekm = c.ekm
+ state.TLSUnique = c.serverFinished[:]
}
}
-
+ if c.config.Renegotiation != RenegotiateNever {
+ state.ekm = noExportedKeyingMaterial
+ } else {
+ state.ekm = c.ekm
+ }
return state
}
diff --git a/libgo/go/crypto/tls/example_test.go b/libgo/go/crypto/tls/example_test.go
index c88f8ad..6389fd7 100644
--- a/libgo/go/crypto/tls/example_test.go
+++ b/libgo/go/crypto/tls/example_test.go
@@ -7,7 +7,6 @@ package tls_test
import (
"crypto/tls"
"crypto/x509"
- "errors"
"log"
"net/http"
"net/http/httptest"
@@ -30,29 +29,28 @@ func ExampleDial() {
// Connecting with a custom root-certificate set.
const rootPEM = `
+-- GlobalSign Root R2, valid until Dec 15, 2021
-----BEGIN CERTIFICATE-----
-MIIEBDCCAuygAwIBAgIDAjppMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
-MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
-YWwgQ0EwHhcNMTMwNDA1MTUxNTU1WhcNMTUwNDA0MTUxNTU1WjBJMQswCQYDVQQG
-EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy
-bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
-AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP
-VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv
-h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE
-ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ
-EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC
-DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB+zCB+DAfBgNVHSMEGDAWgBTAephojYn7
-qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wEgYD
-VR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMwMTAvoC2g
-K4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9ndGdsb2JhbC5jcmwwPQYI
-KwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwOi8vZ3RnbG9iYWwtb2NzcC5n
-ZW90cnVzdC5jb20wFwYDVR0gBBAwDjAMBgorBgEEAdZ5AgUBMA0GCSqGSIb3DQEB
-BQUAA4IBAQA21waAESetKhSbOHezI6B1WLuxfoNCunLaHtiONgaX4PCVOzf9G0JY
-/iLIa704XtE7JW4S615ndkZAkNoUyHgN7ZVm2o6Gb4ChulYylYbc3GrKBIxbf/a/
-zG+FA1jDaFETzf3I93k9mTXwVqO94FntT0QJo544evZG0R0SnU++0ED8Vf4GXjza
-HFa9llF7b1cq26KqltyMdMKVvvBulRP/F/A8rLIQjcxz++iPAsbw+zOzlTvjwsto
-WHPbqCRiOwY1nQ2pM714A5AuTHhdUDqB1O6gyHA43LL5Z/qHQF1hwFGPa4NrzQU6
-yuGnBXj8ytqU0CwIPX4WecigUCAkVDNx
+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
@@ -185,54 +183,50 @@ EKTcWGekdmdDPsHloRNtsiCa697B2O9IFA==
log.Fatal(srv.ListenAndServeTLS("", ""))
}
-func ExampleConfig_verifyPeerCertificate() {
- // VerifyPeerCertificate can be used to replace and customize certificate
- // verification. This example shows a VerifyPeerCertificate implementation
- // that will be approximately equivalent to what crypto/tls does normally.
+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.
- config := &tls.Config{
+ // Client side configuration.
+ _ = &tls.Config{
// Set InsecureSkipVerify to skip the default validation we are
- // replacing. This will not disable VerifyPeerCertificate.
+ // replacing. This will not disable VerifyConnection.
InsecureSkipVerify: true,
-
- // While packages like net/http will implicitly set ServerName, the
- // VerifyPeerCertificate callback can't access that value, so it has to be set
- // explicitly here or in VerifyPeerCertificate on the client side. If in
- // an http.Transport DialTLS callback, this can be obtained by passing
- // the addr argument to net.SplitHostPort.
- ServerName: "example.com",
-
- // On the server side, set ClientAuth to require client certificates (or
- // VerifyPeerCertificate will run anyway and panic accessing certs[0])
- // but not verify them with the default verifier.
- // ClientAuth: tls.RequireAnyClientCert,
+ 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
+ },
}
- config.VerifyPeerCertificate = func(certificates [][]byte, _ [][]*x509.Certificate) error {
- certs := make([]*x509.Certificate, len(certificates))
- for i, asn1Data := range certificates {
- cert, err := x509.ParseCertificate(asn1Data)
- if err != nil {
- return errors.New("tls: failed to parse certificate from server: " + err.Error())
+ // 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)
}
- certs[i] = cert
- }
-
- opts := x509.VerifyOptions{
- Roots: config.RootCAs, // On the server side, use config.ClientCAs.
- DNSName: config.ServerName,
- Intermediates: x509.NewCertPool(),
- // On the server side, set KeyUsages to ExtKeyUsageClientAuth. The
- // default value is appropriate for clients side verification.
- // KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
- }
- for _, cert := range certs[1:] {
- opts.Intermediates.AddCert(cert)
- }
- _, err := certs[0].Verify(opts)
- return err
+ _, err := cs.PeerCertificates[0].Verify(opts)
+ return err
+ },
}
- // Note that when InsecureSkipVerify and VerifyPeerCertificate are in use,
+ // Note that when certificates are not handled by the default verifier
// ConnectionState.VerifiedChains will be nil.
}
diff --git a/libgo/go/crypto/tls/generate_cert.go b/libgo/go/crypto/tls/generate_cert.go
index f1d69c4..1857185 100644
--- a/libgo/go/crypto/tls/generate_cert.go
+++ b/libgo/go/crypto/tls/generate_cert.go
@@ -81,6 +81,16 @@ func main() {
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()
@@ -107,7 +117,7 @@ func main() {
NotBefore: notBefore,
NotAfter: notAfter,
- KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
+ KeyUsage: keyUsage,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
}
diff --git a/libgo/go/crypto/tls/handshake_client.go b/libgo/go/crypto/tls/handshake_client.go
index 4fb528c..46b0a77 100644
--- a/libgo/go/crypto/tls/handshake_client.go
+++ b/libgo/go/crypto/tls/handshake_client.go
@@ -54,7 +54,7 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, ecdheParameters, error) {
return nil, nil, errors.New("tls: no supported versions satisfy MinVersion and MaxVersion")
}
- clientHelloVersion := supportedVersions[0]
+ clientHelloVersion := config.maxSupportedVersion()
// 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.
@@ -146,6 +146,7 @@ func (c *Conn) clientHandshake() (err error) {
if err != nil {
return err
}
+ c.serverName = hello.serverName
cacheKey, session, earlySecret, binderKey := c.loadSession(hello)
if cacheKey != "" && session != nil {
@@ -181,6 +182,18 @@ func (c *Conn) clientHandshake() (err error) {
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()
+ 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,
@@ -376,6 +389,7 @@ func (hs *clientHandshakeState) handshake() error {
hs.finishedHash.Write(hs.serverHello.marshal())
c.buffering = true
+ c.didResume = isResume
if isResume {
if err := hs.establishKeys(); err != nil {
return err
@@ -387,6 +401,15 @@ func (hs *clientHandshakeState) handshake() error {
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
}
@@ -416,7 +439,6 @@ func (hs *clientHandshakeState) handshake() error {
}
c.ekm = ekmFromMasterSecret(c.vers, hs.suite, hs.masterSecret, hs.hello.random, hs.serverHello.random)
- c.didResume = isResume
atomic.StoreUint32(&c.handshakeStatus, 1)
return nil
@@ -446,25 +468,6 @@ func (hs *clientHandshakeState) doFullHandshake() error {
}
hs.finishedHash.Write(certMsg.marshal())
- 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")
- }
- }
-
msg, err = c.readHandshake()
if err != nil {
return err
@@ -493,6 +496,25 @@ func (hs *clientHandshakeState) doFullHandshake() error {
}
}
+ 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)
@@ -706,10 +728,17 @@ func (hs *clientHandshakeState) processServerHello() (bool, error) {
return false, errors.New("tls: server resumed a session with a different cipher suite")
}
- // Restore masterSecret and peerCerts from previous state
+ // 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
}
@@ -766,6 +795,8 @@ func (hs *clientHandshakeState) readSessionTicket() error {
serverCertificates: c.peerCertificates,
verifiedChains: c.verifiedChains,
receivedAt: c.config.time(),
+ ocspResponse: c.ocspResponse,
+ scts: c.scts,
}
return nil
@@ -819,13 +850,6 @@ func (c *Conn) verifyServerCertificate(certificates [][]byte) error {
}
}
- if c.config.VerifyPeerCertificate != nil {
- if err := c.config.VerifyPeerCertificate(certificates, c.verifiedChains); err != nil {
- c.sendAlert(alertBadCertificate)
- return err
- }
- }
-
switch certs[0].PublicKey.(type) {
case *rsa.PublicKey, *ecdsa.PublicKey, ed25519.PublicKey:
break
@@ -836,17 +860,23 @@ func (c *Conn) verifyServerCertificate(certificates [][]byte) error {
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
}
-// tls11SignatureSchemes contains the signature schemes that we synthesise for
-// a TLS <= 1.1 connection, based on the supported certificate types.
-var (
- tls11SignatureSchemes = []SignatureScheme{ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512, PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512, PKCS1WithSHA1}
- tls11SignatureSchemesECDSA = tls11SignatureSchemes[:3]
- tls11SignatureSchemesRSA = tls11SignatureSchemes[3:]
-)
-
// certificateRequestInfoFromMsg generates a CertificateRequestInfo from a TLS
// <= 1.2 CertificateRequest, making an effort to fill in missing information.
func certificateRequestInfoFromMsg(vers uint16, certReq *certificateRequestMsg) *CertificateRequestInfo {
@@ -866,17 +896,25 @@ func certificateRequestInfoFromMsg(vers uint16, certReq *certificateRequestMsg)
}
if !certReq.hasSignatureAlgorithm {
- // Prior to TLS 1.2, the signature schemes were not
- // included in the certificate request message. In this
- // case we use a plausible list based on the acceptable
- // certificate types.
+ // 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 = tls11SignatureSchemes
+ cri.SignatureSchemes = []SignatureScheme{
+ ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512,
+ PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512, PKCS1WithSHA1,
+ }
case rsaAvail:
- cri.SignatureSchemes = tls11SignatureSchemesRSA
+ cri.SignatureSchemes = []SignatureScheme{
+ PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512, PKCS1WithSHA1,
+ }
case ecAvail:
- cri.SignatureSchemes = tls11SignatureSchemesECDSA
+ cri.SignatureSchemes = []SignatureScheme{
+ ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512,
+ }
}
return cri
}
diff --git a/libgo/go/crypto/tls/handshake_client_test.go b/libgo/go/crypto/tls/handshake_client_test.go
index 6bd3c37..12b0254 100644
--- a/libgo/go/crypto/tls/handshake_client_test.go
+++ b/libgo/go/crypto/tls/handshake_client_test.go
@@ -19,6 +19,7 @@ import (
"os"
"os/exec"
"path/filepath"
+ "reflect"
"strconv"
"strings"
"testing"
@@ -907,6 +908,9 @@ func testResumption(t *testing.T, version uint16) {
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 {
@@ -937,6 +941,21 @@ func testResumption(t *testing.T, version uint16) {
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})
@@ -952,6 +971,39 @@ func testResumption(t *testing.T, version uint16) {
}
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{
@@ -1413,6 +1465,228 @@ func TestServerSelectingUnconfiguredCipherSuite(t *testing.T) {
}
}
+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 Responce 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 Responce 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 Responce 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) })
@@ -1431,7 +1705,7 @@ func testVerifyPeerCertificate(t *testing.T, version uint16) {
sentinelErr := errors.New("TestVerifyPeerCertificate")
- verifyCallback := func(called *bool, rawCerts [][]byte, validatedChains [][]*x509.Certificate) error {
+ 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)
}
@@ -1441,6 +1715,19 @@ func testVerifyPeerCertificate(t *testing.T, version uint16) {
*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)
@@ -1451,13 +1738,13 @@ func testVerifyPeerCertificate(t *testing.T, version uint16) {
configureServer: func(config *Config, called *bool) {
config.InsecureSkipVerify = false
config.VerifyPeerCertificate = func(rawCerts [][]byte, validatedChains [][]*x509.Certificate) error {
- return verifyCallback(called, rawCerts, validatedChains)
+ return verifyPeerCertificateCallback(called, rawCerts, validatedChains)
}
},
configureClient: func(config *Config, called *bool) {
config.InsecureSkipVerify = false
config.VerifyPeerCertificate = func(rawCerts [][]byte, validatedChains [][]*x509.Certificate) error {
- return verifyCallback(called, rawCerts, validatedChains)
+ return verifyPeerCertificateCallback(called, rawCerts, validatedChains)
}
},
validate: func(t *testing.T, testNo int, clientCalled, serverCalled bool, clientErr, serverErr error) {
@@ -1538,6 +1825,116 @@ func testVerifyPeerCertificate(t *testing.T, version uint16) {
}
},
},
+ {
+ 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 {
@@ -1553,6 +1950,11 @@ func testVerifyPeerCertificate(t *testing.T, version uint16) {
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()
@@ -1748,7 +2150,7 @@ func TestHandshakeRace(t *testing.T) {
startWrite := make(chan struct{})
startRead := make(chan struct{})
- readDone := make(chan struct{})
+ readDone := make(chan struct{}, 1)
client := Client(c, testConfig)
go func() {
@@ -1984,3 +2386,128 @@ func TestCloseClientConnectionOnIdleServer(t *testing.T) {
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)
+ }
+}
diff --git a/libgo/go/crypto/tls/handshake_client_tls13.go b/libgo/go/crypto/tls/handshake_client_tls13.go
index 8994591..9c61105 100644
--- a/libgo/go/crypto/tls/handshake_client_tls13.go
+++ b/libgo/go/crypto/tls/handshake_client_tls13.go
@@ -176,51 +176,62 @@ func (hs *clientHandshakeStateTLS13) processHelloRetryRequest() error {
c := hs.c
// The first ClientHello gets double-hashed into the transcript upon a
- // HelloRetryRequest. See RFC 8446, Section 4.4.1.
+ // 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)
hs.transcript.Write(hs.serverHello.marshal())
+ // 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")
}
- curveID := hs.serverHello.selectedGroup
- if curveID == 0 {
- c.sendAlert(alertMissingExtension)
- return errors.New("tls: received HelloRetryRequest without selected group")
- }
- curveOK := false
- for _, id := range hs.hello.supportedCurves {
- if id == curveID {
- curveOK = true
- break
+ // 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()}}
}
- 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 message")
- }
- 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.cookie = hs.serverHello.cookie
hs.hello.raw = nil
if len(hs.hello.pskIdentities) > 0 {
@@ -323,6 +334,8 @@ func (hs *clientHandshakeStateTLS13) processServerHello() error {
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
}
@@ -396,6 +409,15 @@ func (hs *clientHandshakeStateTLS13) readServerCertificate() error {
// 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
}
@@ -646,6 +668,8 @@ func (c *Conn) handleNewSessionTicket(msg *newSessionTicketMsgTLS13) error {
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)
diff --git a/libgo/go/crypto/tls/handshake_messages_test.go b/libgo/go/crypto/tls/handshake_messages_test.go
index bef7570..bb8aea8 100644
--- a/libgo/go/crypto/tls/handshake_messages_test.go
+++ b/libgo/go/crypto/tls/handshake_messages_test.go
@@ -308,11 +308,10 @@ 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), rand)
- numCerts := rand.Intn(20)
- s.certificates = make([][]byte, numCerts)
- for i := 0; i < numCerts; i++ {
- s.certificates[i] = randomBytes(rand.Intn(10)+1, rand)
+ 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)
}
diff --git a/libgo/go/crypto/tls/handshake_server.go b/libgo/go/crypto/tls/handshake_server.go
index b16415a..16d3e64 100644
--- a/libgo/go/crypto/tls/handshake_server.go
+++ b/libgo/go/crypto/tls/handshake_server.go
@@ -15,6 +15,7 @@ import (
"fmt"
"io"
"sync/atomic"
+ "time"
)
// serverHandshakeState contains details of a server handshake in progress.
@@ -36,10 +37,6 @@ type serverHandshakeState struct {
// serverHandshake performs a TLS handshake as a server.
func (c *Conn) serverHandshake() error {
- // If this is the first server handshake, we generate a random key to
- // encrypt the tickets with.
- c.config.serverInitOnce.Do(func() { c.config.serverInit(nil) })
-
clientHello, err := c.readClientHello()
if err != nil {
return err
@@ -71,19 +68,15 @@ func (hs *serverHandshakeState) handshake() error {
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
}
- // 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 {
- if err := hs.sendSessionTicket(); err != nil {
- return err
- }
+ if err := hs.sendSessionTicket(); err != nil {
+ return err
}
if err := hs.sendFinished(c.serverFinished[:]); err != nil {
return err
@@ -95,7 +88,6 @@ func (hs *serverHandshakeState) handshake() error {
if err := hs.readFinished(nil); err != nil {
return err
}
- c.didResume = true
} else {
// The client didn't include a session ticket, or it wasn't
// valid so we do a full handshake.
@@ -142,16 +134,18 @@ func (c *Conn) readClientHello() (*clientHelloMsg, error) {
return nil, unexpectedMessageError(clientHello, msg)
}
+ var configForClient *Config
+ originalConfig := c.config
if c.config.GetConfigForClient != nil {
chi := clientHelloInfo(c, clientHello)
- if newConfig, err := c.config.GetConfigForClient(chi); err != nil {
+ if configForClient, err = c.config.GetConfigForClient(chi); err != nil {
c.sendAlert(alertInternalError)
return nil, err
- } else if newConfig != nil {
- newConfig.serverInitOnce.Do(func() { newConfig.serverInit(c.config) })
- c.config = newConfig
+ } else if configForClient != nil {
+ c.config = configForClient
}
}
+ c.ticketKeys = originalConfig.ticketKeys(configForClient)
clientVersions := clientHello.supportedVersions
if len(clientHello.supportedVersions) == 0 {
@@ -193,7 +187,7 @@ func (hs *serverHandshakeState) processClientHello() error {
serverRandom := hs.hello.random
// Downgrade protection canaries. See RFC 8446, Section 4.1.3.
maxVers := c.config.maxSupportedVersion()
- if maxVers >= VersionTLS12 && c.vers < maxVers {
+ if maxVers >= VersionTLS12 && c.vers < maxVers || testingOnlyForceDowngradeCanary {
if c.vers == VersionTLS12 {
copy(serverRandom[24:], downgradeCanaryTLS12)
} else {
@@ -314,6 +308,7 @@ func (hs *serverHandshakeState) pickCipherSuite() error {
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 {
@@ -368,6 +363,11 @@ func (hs *serverHandshakeState) checkForResumption() bool {
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
@@ -408,6 +408,7 @@ 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
@@ -426,6 +427,13 @@ func (hs *serverHandshakeState) doResumeHandshake() error {
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
@@ -550,6 +558,12 @@ func (hs *serverHandshakeState) doFullHandshake() error {
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)
@@ -675,6 +689,9 @@ func (hs *serverHandshakeState) readFinished(out []byte) error {
}
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
}
@@ -682,6 +699,13 @@ func (hs *serverHandshakeState) sendSessionTicket() error {
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)
@@ -689,6 +713,7 @@ func (hs *serverHandshakeState) sendSessionTicket() error {
state := sessionState{
vers: c.vers,
cipherSuite: hs.suite.id,
+ createdAt: createdAt,
masterSecret: hs.masterSecret,
certificates: certsFromClient,
}
@@ -720,7 +745,6 @@ func (hs *serverHandshakeState) sendFinished(out []byte) error {
return err
}
- c.cipherSuite = hs.suite.id
copy(out, finished.verifyData)
return nil
@@ -766,6 +790,19 @@ func (c *Conn) processCertsFromClient(certificate Certificate) 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)
@@ -773,20 +810,6 @@ func (c *Conn) processCertsFromClient(certificate Certificate) error {
}
}
- if len(certs) == 0 {
- return nil
- }
-
- 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)
- }
-
- c.peerCertificates = certs
- c.ocspResponse = certificate.OCSPStaple
- c.scts = certificate.SignedCertificateTimestamps
return nil
}
diff --git a/libgo/go/crypto/tls/handshake_server_test.go b/libgo/go/crypto/tls/handshake_server_test.go
index 1e5da1e..a7a5324 100644
--- a/libgo/go/crypto/tls/handshake_server_test.go
+++ b/libgo/go/crypto/tls/handshake_server_test.go
@@ -182,7 +182,7 @@ func TestRenegotiationExtension(t *testing.T) {
cipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
}
- bufChan := make(chan []byte)
+ bufChan := make(chan []byte, 1)
c, s := localPipe(t)
go func() {
@@ -355,7 +355,8 @@ func TestAlertForwarding(t *testing.T) {
err := Server(s, testConfig).Handshake()
s.Close()
- if e, ok := err.(*net.OpError); !ok || e.Err != error(alertUnknownCA) {
+ var opErr *net.OpError
+ if !errors.As(err, &opErr) || opErr.Err != error(alertUnknownCA) {
t.Errorf("Got error: %s; expected: %s", err, error(alertUnknownCA))
}
}
@@ -575,11 +576,12 @@ func (test *serverTest) connFromCommand() (conn *recordingConn, child *exec.Cmd,
return nil, nil, err
}
- connChan := make(chan interface{})
+ connChan := make(chan interface{}, 1)
go func() {
tcpConn, err := l.Accept()
if err != nil {
connChan <- err
+ return
}
connChan <- tcpConn
}()
@@ -1494,12 +1496,8 @@ var getConfigForClientTests = []struct {
},
"",
func(config *Config) error {
- // The value of SessionTicketKey should have been
- // duplicated into the per-connection Config.
- for i := range config.SessionTicketKey {
- if b := config.SessionTicketKey[i]; b != byte(i) {
- return fmt.Errorf("SessionTicketKey was not duplicated from original Config: byte %d has value %d", i, b)
- }
+ if config.SessionTicketKey == [32]byte{} {
+ return fmt.Errorf("expected SessionTicketKey to be set")
}
return nil
},
@@ -1520,10 +1518,8 @@ var getConfigForClientTests = []struct {
},
"",
func(config *Config) error {
- // The session ticket keys should have been duplicated
- // into the per-connection Config.
- if l := len(config.sessionTicketKeys); l != 1 {
- return fmt.Errorf("got len(sessionTicketKeys) == %d, wanted 1", l)
+ if config.SessionTicketKey == [32]byte{} {
+ return fmt.Errorf("expected SessionTicketKey to be set")
}
return nil
},
diff --git a/libgo/go/crypto/tls/handshake_server_tls13.go b/libgo/go/crypto/tls/handshake_server_tls13.go
index 5432145..92d55e0 100644
--- a/libgo/go/crypto/tls/handshake_server_tls13.go
+++ b/libgo/go/crypto/tls/handshake_server_tls13.go
@@ -306,6 +306,7 @@ func (hs *serverHandshakeStateTLS13) checkForResumption() error {
return errors.New("tls: invalid PSK binder")
}
+ c.didResume = true
if err := c.processCertsFromClient(sessionState.certificate); err != nil {
return err
}
@@ -313,7 +314,6 @@ func (hs *serverHandshakeStateTLS13) checkForResumption() error {
hs.hello.selectedIdentityPresent = true
hs.hello.selectedIdentity = uint16(i)
hs.usingPSK = true
- c.didResume = true
return nil
}
@@ -753,6 +753,14 @@ 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
}
@@ -775,6 +783,13 @@ func (hs *serverHandshakeStateTLS13) readClientCertificate() error {
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 {
msg, err = c.readHandshake()
if err != nil {
diff --git a/libgo/go/crypto/tls/key_agreement.go b/libgo/go/crypto/tls/key_agreement.go
index 03aa861..7e6534b 100644
--- a/libgo/go/crypto/tls/key_agreement.go
+++ b/libgo/go/crypto/tls/key_agreement.go
@@ -40,7 +40,7 @@ func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, cert *Certifi
if !ok {
return nil, errors.New("tls: certificate private key does not implement crypto.Decrypter")
}
- // Perform constant time RSA PKCS#1 v1.5 decryption
+ // 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
diff --git a/libgo/go/crypto/tls/key_schedule.go b/libgo/go/crypto/tls/key_schedule.go
index 2aab323..3140169 100644
--- a/libgo/go/crypto/tls/key_schedule.go
+++ b/libgo/go/crypto/tls/key_schedule.go
@@ -173,11 +173,8 @@ func (p *nistParameters) SharedKey(peerPublicKey []byte) []byte {
}
xShared, _ := curve.ScalarMult(x, y, p.privateKey)
- sharedKey := make([]byte, (curve.Params().BitSize+7)>>3)
- xBytes := xShared.Bytes()
- copy(sharedKey[len(sharedKey)-len(xBytes):], xBytes)
-
- return sharedKey
+ sharedKey := make([]byte, (curve.Params().BitSize+7)/8)
+ return xShared.FillBytes(sharedKey)
}
type x25519Parameters struct {
diff --git a/libgo/go/crypto/tls/link_test.go b/libgo/go/crypto/tls/link_test.go
new file mode 100644
index 0000000..c1fb57e
--- /dev/null
+++ b/libgo/go/crypto/tls/link_test.go
@@ -0,0 +1,121 @@
+// 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"
+ "io/ioutil"
+ "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: "only_conn",
+ program: `package main
+import "crypto/tls"
+var c = new(tls.Conn)
+func main() {}
+`,
+ want: []string{"tls.(*Conn)"},
+ bad: []string{
+ "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 := ioutil.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/libgo/go/crypto/tls/testdata/Server-TLSv10-ExportKeyingMaterial b/libgo/go/crypto/tls/testdata/Server-TLSv10-ExportKeyingMaterial
index 5f80cb3..a5d9ee4 100644
--- a/libgo/go/crypto/tls/testdata/Server-TLSv10-ExportKeyingMaterial
+++ b/libgo/go/crypto/tls/testdata/Server-TLSv10-ExportKeyingMaterial
@@ -1,12 +1,11 @@
>>> Flow 1 (client to server)
-00000000 16 03 01 00 75 01 00 00 71 03 01 a0 fd 51 a6 77 |....u...q....Q.w|
-00000010 69 ee 39 14 8d 0f be a6 9c f7 95 aa 63 14 d2 90 |i.9.........c...|
-00000020 1e 39 34 2c df d8 e4 92 2b a0 36 00 00 12 c0 0a |.94,....+.6.....|
+00000000 16 03 01 00 63 01 00 00 5f 03 01 7a df fa af 20 |....c..._..z... |
+00000010 74 5a 83 3b 91 95 b4 9b 57 d8 6b f2 88 2a 68 e8 |tZ.;....W.k..*h.|
+00000020 b8 9e e7 88 a6 c5 e7 59 08 ff 9b 00 00 12 c0 0a |.......Y........|
00000030 c0 14 00 39 c0 09 c0 13 00 33 00 35 00 2f 00 ff |...9.....3.5./..|
-00000040 01 00 00 36 00 00 00 0e 00 0c 00 00 09 31 32 37 |...6.........127|
-00000050 2e 30 2e 30 2e 31 00 0b 00 04 03 00 01 02 00 0a |.0.0.1..........|
-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 |..........|
+00000040 01 00 00 24 00 0b 00 04 03 00 01 02 00 0a 00 0c |...$............|
+00000050 00 0a 00 1d 00 17 00 1e 00 19 00 18 00 23 00 00 |.............#..|
+00000060 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 |................|
@@ -52,43 +51,43 @@
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 00 9f b3 |......_X.;t.....|
-000002d0 fa c1 71 14 e3 1a 6c 3f b6 61 15 e2 7b 99 c5 4c |..q...l?.a..{..L|
-000002e0 39 e0 45 f8 9d d3 84 1a c4 fc 7c 51 32 3d 67 0b |9.E.......|Q2=g.|
-000002f0 28 b8 8c 6d 66 7e ab 82 c9 f6 d0 49 62 96 2c af |(..mf~.....Ib.,.|
-00000300 4f 0a d1 21 54 b8 3e ae 09 fd d8 85 10 cb da c4 |O..!T.>.........|
-00000310 6f 42 16 cd 70 cd 33 b0 a5 e5 a1 c7 9a 35 41 3f |oB..p.3......5A?|
-00000320 59 db a1 b3 f4 ae f6 72 9c a8 db f5 86 99 43 b3 |Y......r......C.|
-00000330 8f bc 0f d9 0a 50 49 58 3b 17 fa 51 27 11 e9 95 |.....PIX;..Q'...|
-00000340 8c bb 1a 31 11 bc a2 fa 2c 6b c2 6a 40 16 03 01 |...1....,k.j@...|
+000002c0 c4 cf c2 ed 90 99 5f 58 cb 3b 74 00 80 bb 96 fe |......_X.;t.....|
+000002d0 bf a0 81 24 bc 40 b4 e2 37 b1 c9 66 2d c3 c1 bb |...$.@..7..f-...|
+000002e0 89 fb 28 23 60 76 b1 e6 2c c1 e9 06 d0 95 c5 10 |..(#`v..,.......|
+000002f0 17 ce 79 36 c2 14 e0 1d 1d 0d 0e 49 3e b9 7f 00 |..y6.......I>...|
+00000300 ad e3 1d 37 ab ce 2c 37 dc eb be aa 6c 28 33 05 |...7..,7....l(3.|
+00000310 53 fd 06 17 b4 85 b9 b8 35 1c a7 3c bb 07 3f 4b |S.......5..<..?K|
+00000320 53 98 00 4d 8e 49 bd 35 55 64 92 d0 a0 db 05 80 |S..M.I.5Ud......|
+00000330 57 24 78 cd 10 ed ae f0 6a 83 bc b4 4d 77 79 ba |W$x.....j...Mwy.|
+00000340 6e e7 2e 8f ac 9e 98 34 36 9d a9 27 f0 16 03 01 |n......46..'....|
00000350 00 04 0e 00 00 00 |......|
>>> Flow 3 (client to server)
-00000000 16 03 01 00 25 10 00 00 21 20 bf 0c 33 f5 6a 06 |....%...! ..3.j.|
-00000010 18 0a 74 ad 8b bd ef 9c 00 a3 c0 03 20 5b ea 69 |..t......... [.i|
-00000020 09 18 b8 4a 30 13 c7 10 30 3a 14 03 01 00 01 01 |...J0...0:......|
-00000030 16 03 01 00 30 04 6d f7 66 e9 7f 72 80 32 24 93 |....0.m.f..r.2$.|
-00000040 2f 74 5e 34 c5 fb 19 a0 64 31 1e cb 63 03 fb 51 |/t^4....d1..c..Q|
-00000050 5c d9 17 a8 b0 8a b6 74 e8 84 86 a5 33 d2 75 4a |\......t....3.uJ|
-00000060 c0 bb 6a bb f3 |..j..|
+00000000 16 03 01 00 25 10 00 00 21 20 00 ad c5 2b 21 7f |....%...! ...+!.|
+00000010 8e 44 f2 f5 32 22 c8 c2 c6 de 2c 0b 7a a9 24 b6 |.D..2"....,.z.$.|
+00000020 03 20 c0 cc 79 2e 11 2f d3 43 14 03 01 00 01 01 |. ..y../.C......|
+00000030 16 03 01 00 30 78 5c 32 72 a1 c8 3b 9c 7b 77 0b |....0x\2r..;.{w.|
+00000040 a0 28 52 55 17 16 d5 39 89 d0 43 bf 67 29 85 6f |.(RU...9..C.g).o|
+00000050 b5 1e 83 fa 22 96 78 e3 5c 45 5a 3d fe 2b d5 b7 |....".x.\EZ=.+..|
+00000060 3d 64 44 8c a8 |=dD..|
>>> Flow 4 (server to client)
-00000000 16 03 01 00 82 04 00 00 7e 00 00 00 00 00 78 50 |........~.....xP|
+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 61 28 8e b8 1b 0e dd 7d 71 4a 36 c3 |m...a(.....}qJ6.|
-00000040 6d cb c7 88 ed 19 c5 08 72 b9 25 fb 6c 29 b8 b2 |m.......r.%.l)..|
-00000050 72 f8 27 c0 1e f2 86 16 54 0f 72 a9 6e 15 69 9e |r.'.....T.r.n.i.|
-00000060 66 fe d1 05 20 33 94 32 40 82 bb e3 61 47 3a 8e |f... 3.2@...aG:.|
-00000070 b7 45 92 8a 5c 84 64 eb 6c 1a 3c bb 2f be ce b2 |.E..\.d.l.<./...|
-00000080 5f cb c9 be c4 ff d6 14 03 01 00 01 01 16 03 01 |_...............|
-00000090 00 30 5e ff 91 82 d5 30 a4 fb cd 20 90 c1 2d 08 |.0^....0... ..-.|
-000000a0 aa 19 d6 72 fa 74 07 95 df 14 eb 59 bb 0c 81 3f |...r.t.....Y...?|
-000000b0 75 77 45 96 d8 3e 45 a7 42 1c f1 82 c0 04 4d 2e |uwE..>E.B.....M.|
-000000c0 3f 07 17 03 01 00 20 54 90 60 76 16 5f 6b d0 3e |?..... T.`v._k.>|
-000000d0 f6 bf f3 0a 5c b9 3b 19 cb df a6 94 28 04 24 ea |....\.;.....(.$.|
-000000e0 73 1f 49 5e 23 f6 91 17 03 01 00 30 b5 97 eb 85 |s.I^#......0....|
-000000f0 cc 17 86 b0 0d 24 bf 64 6d 4f 16 55 b0 f3 64 7c |.....$.dmO.U..d||
-00000100 75 3f e4 16 94 41 56 64 12 50 0e 7c 0c 1c e7 58 |u?...AVd.P.|...X|
-00000110 4d 9c 82 d8 f5 5a 61 a3 d8 3c f5 04 15 03 01 00 |M....Za..<......|
-00000120 20 59 6c e6 9e 4e 14 94 5d 61 94 b2 ba 0f eb 18 | Yl..N..]a......|
-00000130 cf 10 5b f6 90 27 58 8e 10 54 36 d4 c7 52 37 2e |..[..'X..T6..R7.|
-00000140 a0 |.|
+00000030 6d ec a4 83 51 ed 14 ef 68 ca 42 c5 4c 5f bb 3b |m...Q...h.B.L_.;|
+00000040 9c c8 3c 7e 1c cf dc da e4 35 83 03 13 95 82 5f |..<~.....5....._|
+00000050 32 77 8a cf dc e9 10 65 9b 97 d4 5d ff 43 57 14 |2w.....e...].CW.|
+00000060 a3 25 e0 fa c8 26 0c ff 71 67 9b 32 2f 49 38 16 |.%...&..qg.2/I8.|
+00000070 aa ea b9 fa 99 86 4c b9 db 7a ef bc 87 43 e8 db |......L..z...C..|
+00000080 26 27 73 76 80 77 59 c4 fb 7d 56 e9 7e 23 03 75 |&'sv.wY..}V.~#.u|
+00000090 14 03 01 00 01 01 16 03 01 00 30 80 8f 8e 11 b5 |..........0.....|
+000000a0 f4 a0 8c 4a ae 3f 25 17 66 93 1c c5 a5 10 57 e3 |...J.?%.f.....W.|
+000000b0 24 7a c1 a9 72 74 4f fd 20 5e 5b 58 4d bd 5d f0 |$z..rtO. ^[XM.].|
+000000c0 05 8e 06 61 0a 98 19 a0 a8 73 02 17 03 01 00 20 |...a.....s..... |
+000000d0 d9 dd 86 e6 55 55 df 2c 0d 1e 5f 0e 9e 1e 76 51 |....UU.,.._...vQ|
+000000e0 98 e0 2b 09 f9 44 4d 4d 22 97 0d 1e 95 7b b9 41 |..+..DMM"....{.A|
+000000f0 17 03 01 00 30 74 82 1c 35 9b 87 cd 5e 29 95 e1 |....0t..5...^)..|
+00000100 18 e3 76 32 94 b5 1b d0 06 d2 ec 49 40 24 73 d3 |..v2.......I@$s.|
+00000110 fc 5d 1a 26 59 5b 33 d8 5a 30 d5 92 30 bc 80 e0 |.].&Y[3.Z0..0...|
+00000120 ed 85 e8 14 01 15 03 01 00 20 ec 69 2f 9d 29 4f |......... .i/.)O|
+00000130 1f 8e e6 34 f0 87 66 40 e8 13 14 02 74 c4 1d aa |...4..f@....t...|
+00000140 65 72 43 50 6e 71 9c 2e b6 3a |erCPnq...:|
diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN b/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN
index f6ddb97..d9e7e83 100644
--- a/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN
+++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN
@@ -1,19 +1,18 @@
>>> Flow 1 (client to server)
-00000000 16 03 01 00 e3 01 00 00 df 03 03 e7 33 0d 6a 2d |............3.j-|
-00000010 87 bc b4 a1 11 ee 1a 4e 91 f5 fb ad 29 70 d4 6d |.......N....)p.m|
-00000020 05 be ec f3 e2 b1 0d 4e da a4 b5 00 00 38 c0 2c |.......N.....8.,|
+00000000 16 03 01 00 d1 01 00 00 cd 03 03 50 99 a9 e9 80 |...........P....|
+00000010 87 f1 0a 5a bc 9d a6 53 6d 08 36 4a 79 f8 48 c3 |...Z...Sm.6Jy.H.|
+00000020 fe c1 b4 02 d9 66 b2 cc f9 8d d4 00 00 38 c0 2c |.....f.......8.,|
00000030 c0 30 00 9f cc a9 cc a8 cc aa c0 2b c0 2f 00 9e |.0.........+./..|
00000040 c0 24 c0 28 00 6b c0 23 c0 27 00 67 c0 0a c0 14 |.$.(.k.#.'.g....|
00000050 00 39 c0 09 c0 13 00 33 00 9d 00 9c 00 3d 00 3c |.9.....3.....=.<|
-00000060 00 35 00 2f 00 ff 01 00 00 7e 00 00 00 0e 00 0c |.5./.....~......|
-00000070 00 00 09 31 32 37 2e 30 2e 30 2e 31 00 0b 00 04 |...127.0.0.1....|
-00000080 03 00 01 02 00 0a 00 0c 00 0a 00 1d 00 17 00 1e |................|
-00000090 00 19 00 18 00 23 00 00 00 10 00 10 00 0e 06 70 |.....#.........p|
-000000a0 72 6f 74 6f 32 06 70 72 6f 74 6f 31 00 16 00 00 |roto2.proto1....|
-000000b0 00 17 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 |.......0........|
-000000c0 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 |................|
-000000d0 04 01 05 01 06 01 03 03 02 03 03 01 02 01 03 02 |................|
-000000e0 02 02 04 02 05 02 06 02 |........|
+00000060 00 35 00 2f 00 ff 01 00 00 6c 00 0b 00 04 03 00 |.5./.....l......|
+00000070 01 02 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 |................|
+00000080 00 18 00 23 00 00 00 10 00 10 00 0e 06 70 72 6f |...#.........pro|
+00000090 74 6f 32 06 70 72 6f 74 6f 31 00 16 00 00 00 17 |to2.proto1......|
+000000a0 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 08 07 |.....0..........|
+000000b0 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 |................|
+000000c0 05 01 06 01 03 03 02 03 03 01 02 01 03 02 02 02 |................|
+000000d0 04 02 05 02 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 |................|
@@ -60,38 +59,38 @@
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 b6 a2 61 f9 |..._X.;t......a.|
-000002e0 30 40 0b 5c 2c 92 b4 7b e3 42 79 00 11 4d 6b 85 |0@.\,..{.By..Mk.|
-000002f0 df 2e 19 c2 fc a8 bc 16 0b c0 8d 02 55 99 a7 06 |............U...|
-00000300 fa 4c 4d 4c 27 de 6d 3d 1e 7a 6f 2c fc eb 9e 15 |.LML'.m=.zo,....|
-00000310 40 6f 0c 81 b3 e1 4d 78 b7 38 c6 50 8f 5b 63 ac |@o....Mx.8.P.[c.|
-00000320 20 4f a6 06 aa 00 84 f5 01 f4 68 7a 5a 16 c5 da | O........hzZ...|
-00000330 71 b2 4f 04 6e 59 88 14 8c 81 01 91 a8 e8 c1 18 |q.O.nY..........|
-00000340 a8 07 e8 7a f4 dc b9 e7 7f c5 ce 2c 32 8d fe d6 |...z.......,2...|
-00000350 1f 0e a5 f0 f4 c7 dd 39 13 a1 ca 6d 16 03 03 00 |.......9...m....|
+000002d0 ed 90 99 5f 58 cb 3b 74 08 04 00 80 cb 03 45 70 |..._X.;t......Ep|
+000002e0 f5 51 af d7 cf db 26 79 d1 57 c2 06 4c 49 e6 ea |.Q....&y.W..LI..|
+000002f0 e7 f4 b8 2c 23 52 8a 1f bd 8e a3 9e 79 d4 8e 66 |...,#R......y..f|
+00000300 ee 92 39 97 cc ec 46 03 76 f9 59 b7 2e 6f e4 88 |..9...F.v.Y..o..|
+00000310 fd 39 65 59 88 c2 7e 7a bc de 86 49 98 45 a6 44 |.9eY..~z...I.E.D|
+00000320 82 41 19 94 53 3d 34 4b 73 52 5a af b2 3d 92 5e |.A..S=4KsRZ..=.^|
+00000330 f3 5b e8 fa 23 a7 71 5c 64 1b 43 bb bd 8e 01 2a |.[..#.q\d.C....*|
+00000340 59 2d 3b 73 0f b9 3d 02 9a 09 4a fc 0e 4b 65 07 |Y-;s..=...J..Ke.|
+00000350 82 f9 e1 ad ec 64 27 a4 07 60 c7 32 16 03 03 00 |.....d'..`.2....|
00000360 04 0e 00 00 00 |.....|
>>> Flow 3 (client to server)
-00000000 16 03 03 00 25 10 00 00 21 20 d7 fa 22 66 b4 c8 |....%...! .."f..|
-00000010 67 2c 45 93 bf 38 3a 13 21 45 d5 29 95 5b 0d 5c |g,E..8:.!E.).[.\|
-00000020 79 d2 d6 9b ef bd 7d eb a9 21 14 03 03 00 01 01 |y.....}..!......|
-00000030 16 03 03 00 28 a2 81 84 32 29 01 69 28 f9 56 cc |....(...2).i(.V.|
-00000040 c9 72 51 5c 22 38 51 12 e1 55 a1 d6 8c cf 66 75 |.rQ\"8Q..U....fu|
-00000050 b4 bd 49 60 d0 e4 7e 9e fe 56 d1 62 36 |..I`..~..V.b6|
+00000000 16 03 03 00 25 10 00 00 21 20 f6 5d 24 8e fc 1c |....%...! .]$...|
+00000010 39 bb 01 fc 23 ef f4 86 8b aa 2c 39 2a a1 4d e6 |9...#.....,9*.M.|
+00000020 7c 21 74 cc ed 2c 9b 4b f2 01 14 03 03 00 01 01 ||!t..,.K........|
+00000030 16 03 03 00 28 96 9c a6 78 4b 94 24 e2 31 5a 25 |....(...xK.$.1Z%|
+00000040 68 5e 6a 51 03 5d 9d cf 45 b1 78 17 0b bf ff c6 |h^jQ.]..E.x.....|
+00000050 72 5b e9 f0 a1 b1 46 ab a5 e1 3f 4d 67 |r[....F...?Mg|
>>> Flow 4 (server to client)
-00000000 16 03 03 00 82 04 00 00 7e 00 00 00 00 00 78 50 |........~.....xP|
+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 ec 80 83 61 cf 87 48 45 0d 9d a5 bf 38 b4 9f |o...a..HE....8..|
-00000040 19 a9 cd ca 63 79 2d c3 ae 70 74 56 44 99 fb cc |....cy-..ptVD...|
-00000050 7d 31 c2 67 75 fe 57 1b fd 6b 2f cd df ec fa 5b |}1.gu.W..k/....[|
-00000060 23 47 19 7e 84 33 94 d7 de e2 b9 ff 75 7d dc 80 |#G.~.3......u}..|
-00000070 9e 55 94 8e 15 94 70 8f b5 21 0e 4e f7 4c e6 44 |.U....p..!.N.L.D|
-00000080 01 a3 9d 67 5f 05 73 14 03 03 00 01 01 16 03 03 |...g_.s.........|
-00000090 00 28 00 00 00 00 00 00 00 00 3a 49 dc e2 aa ce |.(........:I....|
-000000a0 a8 43 27 08 a8 6b 7c ae 3f 07 18 e1 04 a9 e6 24 |.C'..k|.?......$|
-000000b0 0e 9e 0a 0f af a4 c3 6e 90 2d 17 03 03 00 25 00 |.......n.-....%.|
-000000c0 00 00 00 00 00 00 01 41 e1 9b 4c 8a 1a e8 10 bf |.......A..L.....|
-000000d0 9f fd 76 e4 43 c2 cf 04 ee 68 6a 02 3c 97 fc ec |..v.C....hj.<...|
-000000e0 c4 0a 74 1d 15 03 03 00 1a 00 00 00 00 00 00 00 |..t.............|
-000000f0 02 1c 9b b1 b6 07 fa 33 a8 70 03 d9 27 29 ea 61 |.......3.p..').a|
-00000100 96 c2 48 |..H|
+00000030 6f ec 80 83 51 ed 14 ef 68 ca 42 c5 4c 4a f5 b1 |o...Q...h.B.LJ..|
+00000040 56 86 3e f2 10 79 9e f3 a0 ed 07 6d 09 fc 77 63 |V.>..y.....m..wc|
+00000050 86 68 42 99 7b 13 c3 35 cf 5b a6 3a fa aa c2 ec |.hB.{..5.[.:....|
+00000060 80 a2 27 e4 97 24 07 48 2c 70 30 fc d6 49 38 16 |..'..$.H,p0..I8.|
+00000070 60 d5 b0 4c ec 4b 74 48 03 2a 5e fb 14 43 6c 5f |`..L.KtH.*^..Cl_|
+00000080 35 9c 1b a8 7d 62 f8 42 68 27 cb 6d 15 38 e7 8e |5...}b.Bh'.m.8..|
+00000090 14 03 03 00 01 01 16 03 03 00 28 00 00 00 00 00 |..........(.....|
+000000a0 00 00 00 8d 7a 5a 66 3b c9 fe 51 c2 71 ef a5 8b |....zZf;..Q.q...|
+000000b0 42 7d 79 33 4e 6d 66 12 cc e7 46 4f c3 30 12 8f |B}y3Nmf...FO.0..|
+000000c0 0c 57 60 17 03 03 00 25 00 00 00 00 00 00 00 01 |.W`....%........|
+000000d0 83 aa 62 fe a3 73 ed 67 87 c0 19 1c fa f0 2c 26 |..b..s.g......,&|
+000000e0 4b 16 44 9c a7 f8 c3 e1 ba 6a 85 8f 84 15 03 03 |K.D......j......|
+000000f0 00 1a 00 00 00 00 00 00 00 02 a8 b3 b2 dd 4b a6 |..............K.|
+00000100 ba 05 dc 8f ac 98 ae 01 10 60 9a 62 |.........`.b|
diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch b/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch
index f8b88a6..589189c 100644
--- a/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch
+++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-ALPN-NoMatch
@@ -1,19 +1,18 @@
>>> Flow 1 (client to server)
-00000000 16 03 01 00 e3 01 00 00 df 03 03 ed dd 7f 68 1d |..............h.|
-00000010 9e 83 bc 08 01 39 8e 97 76 91 cb cb 24 73 15 f5 |.....9..v...$s..|
-00000020 17 17 db 78 69 ca e1 ed 0f fc bc 00 00 38 c0 2c |...xi........8.,|
+00000000 16 03 01 00 d1 01 00 00 cd 03 03 44 a5 b9 48 dd |...........D..H.|
+00000010 ca 91 9a c6 72 06 b3 dd a7 95 18 c6 95 0b f2 32 |....r..........2|
+00000020 84 37 78 12 0f 66 c7 6e e6 61 81 00 00 38 c0 2c |.7x..f.n.a...8.,|
00000030 c0 30 00 9f cc a9 cc a8 cc aa c0 2b c0 2f 00 9e |.0.........+./..|
00000040 c0 24 c0 28 00 6b c0 23 c0 27 00 67 c0 0a c0 14 |.$.(.k.#.'.g....|
00000050 00 39 c0 09 c0 13 00 33 00 9d 00 9c 00 3d 00 3c |.9.....3.....=.<|
-00000060 00 35 00 2f 00 ff 01 00 00 7e 00 00 00 0e 00 0c |.5./.....~......|
-00000070 00 00 09 31 32 37 2e 30 2e 30 2e 31 00 0b 00 04 |...127.0.0.1....|
-00000080 03 00 01 02 00 0a 00 0c 00 0a 00 1d 00 17 00 1e |................|
-00000090 00 19 00 18 00 23 00 00 00 10 00 10 00 0e 06 70 |.....#.........p|
-000000a0 72 6f 74 6f 32 06 70 72 6f 74 6f 31 00 16 00 00 |roto2.proto1....|
-000000b0 00 17 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 |.......0........|
-000000c0 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 |................|
-000000d0 04 01 05 01 06 01 03 03 02 03 03 01 02 01 03 02 |................|
-000000e0 02 02 04 02 05 02 06 02 |........|
+00000060 00 35 00 2f 00 ff 01 00 00 6c 00 0b 00 04 03 00 |.5./.....l......|
+00000070 01 02 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 |................|
+00000080 00 18 00 23 00 00 00 10 00 10 00 0e 06 70 72 6f |...#.........pro|
+00000090 74 6f 32 06 70 72 6f 74 6f 31 00 16 00 00 00 17 |to2.proto1......|
+000000a0 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 08 07 |.....0..........|
+000000b0 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 |................|
+000000c0 05 01 06 01 03 03 02 03 03 01 02 01 03 02 02 02 |................|
+000000d0 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 |................|
@@ -59,38 +58,38 @@
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 59 |......_X.;t....Y|
-000002d0 85 20 dc b1 4c d2 17 4d 20 73 1a a7 f7 ab 40 52 |. ..L..M s....@R|
-000002e0 73 e7 02 21 eb 55 e2 c9 73 c0 c2 8a ed a3 fd 07 |s..!.U..s.......|
-000002f0 0b 5b 30 c2 1e 63 a1 c2 27 41 6c 5a ca 6e 12 d3 |.[0..c..'AlZ.n..|
-00000300 4a 87 15 29 7f 44 06 3d 14 76 98 45 e5 27 84 09 |J..).D.=.v.E.'..|
-00000310 44 be f3 c4 ce 79 31 e9 92 06 b6 d2 d9 19 d1 24 |D....y1........$|
-00000320 7d 44 6a 57 ea 9d 12 e3 e7 a1 16 86 10 fc 7a 66 |}DjW..........zf|
-00000330 00 3a f0 f0 ed e7 7c 20 82 0a 26 5d 92 79 8a 5b |.:....| ..&].y.[|
-00000340 55 98 fc 1a c1 2f c0 07 ce b8 03 3a 01 da 62 16 |U..../.....:..b.|
+000002c0 c4 cf c2 ed 90 99 5f 58 cb 3b 74 08 04 00 80 1d |......_X.;t.....|
+000002d0 ae 16 b9 7e 58 bb d5 1b 9e 51 09 a2 d1 a8 3f 1d |...~X....Q....?.|
+000002e0 f4 09 72 a5 c6 cc 9a 53 46 1c 9f 58 36 cd 91 39 |..r....SF..X6..9|
+000002f0 44 ca 56 da 50 77 d5 56 10 14 45 ad 98 b8 2f 44 |D.V.Pw.V..E.../D|
+00000300 33 ae a9 b1 b6 a6 2a ab 0a 0a 39 75 2c 4d 4c 51 |3.....*...9u,MLQ|
+00000310 71 07 83 bf ad 8b 37 c5 59 dd 8f d7 b8 85 2e 04 |q.....7.Y.......|
+00000320 9e 39 e6 e5 a5 48 9a 24 63 b3 a7 46 73 b2 5c 10 |.9...H.$c..Fs.\.|
+00000330 cc 4c e5 55 dd 97 b0 42 4e 8b fb 0d cd 47 e9 09 |.L.U...BN....G..|
+00000340 20 88 96 5e 76 0d 9b b1 91 3f 27 a1 f3 0d 77 16 | ..^v....?'...w.|
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 d9 f2 e4 c5 cf 38 |....%...! .....8|
-00000010 23 30 2e b6 d9 0f 3b a2 d7 2f eb d5 74 a8 29 12 |#0....;../..t.).|
-00000020 5f 27 bc 81 96 6b 12 5a bb 2f 14 03 03 00 01 01 |_'...k.Z./......|
-00000030 16 03 03 00 28 4b a1 12 ce 11 2a 0f 79 7c 56 eb |....(K....*.y|V.|
-00000040 bb 9f 7d 91 c7 53 25 d6 ae 0b 98 f1 b5 ea ef 51 |..}..S%........Q|
-00000050 8b 3a fb d1 6c ae 3d bb b7 67 d9 ba 36 |.:..l.=..g..6|
+00000000 16 03 03 00 25 10 00 00 21 20 89 8e 03 11 92 ab |....%...! ......|
+00000010 51 f5 d7 dc 27 87 fd 38 eb 45 3d cc 75 1a 1e 07 |Q...'..8.E=.u...|
+00000020 d6 0f 2b 92 df 5a 7c 24 30 56 14 03 03 00 01 01 |..+..Z|$0V......|
+00000030 16 03 03 00 28 fa 24 69 6d 65 2f 34 35 47 9b 83 |....(.$ime/45G..|
+00000040 65 0f fd c1 33 61 1d 47 cf ec 87 6f 48 71 63 7d |e...3a.G...oHqc}|
+00000050 e8 aa bc 2e cd 7d 2e 4b d5 0f 4f 66 14 |.....}.K..Of.|
>>> Flow 4 (server to client)
-00000000 16 03 03 00 82 04 00 00 7e 00 00 00 00 00 78 50 |........~.....xP|
+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 ec 80 83 61 40 f9 2b 9e a7 30 60 fb 46 36 c4 |o...a@.+..0`.F6.|
-00000040 0e b3 2a c4 73 64 2e 12 6c 0d f5 b9 6f 05 ae 27 |..*.sd..l...o..'|
-00000050 d7 a3 47 c5 67 31 3e 95 84 bf 42 e1 b9 0d 90 40 |..G.g1>...B....@|
-00000060 01 50 0d 32 4b 33 94 5c a3 1d b9 db e5 c5 24 02 |.P.2K3.\......$.|
-00000070 48 31 ad 70 8e c7 e9 60 a5 7e ea 91 7b 01 79 06 |H1.p...`.~..{.y.|
-00000080 66 f9 c4 9d bd 65 a5 14 03 03 00 01 01 16 03 03 |f....e..........|
-00000090 00 28 00 00 00 00 00 00 00 00 32 be b5 c5 4d 83 |.(........2...M.|
-000000a0 41 97 f6 26 0f aa 06 35 d5 9e f8 12 1c 04 f7 b6 |A..&...5........|
-000000b0 16 9f f9 a4 43 b8 56 ea 4a 82 17 03 03 00 25 00 |....C.V.J.....%.|
-000000c0 00 00 00 00 00 00 01 1a 8e 6b 4a 69 02 56 46 eb |.........kJi.VF.|
-000000d0 26 12 47 a3 9d 9a 8a 09 20 4a 6c b2 d0 6a 14 48 |&.G..... Jl..j.H|
-000000e0 be d5 f0 48 15 03 03 00 1a 00 00 00 00 00 00 00 |...H............|
-000000f0 02 0e 01 9d 60 90 01 60 99 a0 f5 df 6d 38 e5 76 |....`..`....m8.v|
-00000100 4d d7 d7 |M..|
+00000030 6f ec 80 83 51 ed 14 ef 68 ca 42 c5 4c 60 05 16 |o...Q...h.B.L`..|
+00000040 33 5b f7 bd 83 9c 69 80 c2 fe 5c 73 32 05 67 97 |3[....i...\s2.g.|
+00000050 fd 6b 3a d3 b4 6d a5 5e 18 c0 1e ba d5 2c 44 ad |.k:..m.^.....,D.|
+00000060 54 24 65 be 14 90 ab 6d a1 de d1 98 1e 49 38 16 |T$e....m.....I8.|
+00000070 f0 fe 8d 49 6d e1 5a 6d 10 30 26 64 5f 10 ad ab |...Im.Zm.0&d_...|
+00000080 d7 c9 3a bc 6a 3f 32 78 4b fe f1 38 08 2c 15 e7 |..:.j?2xK..8.,..|
+00000090 14 03 03 00 01 01 16 03 03 00 28 00 00 00 00 00 |..........(.....|
+000000a0 00 00 00 e9 3d 4c 8b 59 78 8c 49 77 08 3b c1 de |....=L.Yx.Iw.;..|
+000000b0 4c 78 9a d7 c6 1a 66 fb 43 de bd cb 8b ca a2 32 |Lx....f.C......2|
+000000c0 a2 26 1e 17 03 03 00 25 00 00 00 00 00 00 00 01 |.&.....%........|
+000000d0 47 c9 3a 0d 8d 8b d1 b7 66 17 8e 83 31 02 ed 51 |G.:.....f...1..Q|
+000000e0 e8 cb 1d 4a 42 d6 f9 ee b8 6d fd d0 4b 15 03 03 |...JB....m..K...|
+000000f0 00 1a 00 00 00 00 00 00 00 02 f3 00 56 6d fc 23 |............Vm.#|
+00000100 49 bb 65 00 b0 ae cd c7 62 ac 47 1f |I.e.....b.G.|
diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-ExportKeyingMaterial b/libgo/go/crypto/tls/testdata/Server-TLSv12-ExportKeyingMaterial
index ecf765b..c9f0c5c 100644
--- a/libgo/go/crypto/tls/testdata/Server-TLSv12-ExportKeyingMaterial
+++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-ExportKeyingMaterial
@@ -1,18 +1,17 @@
>>> Flow 1 (client to server)
-00000000 16 03 01 00 cf 01 00 00 cb 03 03 62 4c 73 03 fd |...........bLs..|
-00000010 24 98 d0 f6 41 49 83 94 04 c8 17 51 3e 18 5d 6d |$...AI.....Q>.]m|
-00000020 8a b8 52 c0 cf 0b 60 1e 02 53 d2 00 00 38 c0 2c |..R...`..S...8.,|
+00000000 16 03 01 00 bd 01 00 00 b9 03 03 7e 75 ea 1f ec |...........~u...|
+00000010 47 ee de 51 9d 11 00 77 5b 1b fb 7e 05 22 0a 7a |G..Q...w[..~.".z|
+00000020 74 bc 6a d1 8a 67 03 a1 ae c9 23 00 00 38 c0 2c |t.j..g....#..8.,|
00000030 c0 30 00 9f cc a9 cc a8 cc aa c0 2b c0 2f 00 9e |.0.........+./..|
00000040 c0 24 c0 28 00 6b c0 23 c0 27 00 67 c0 0a c0 14 |.$.(.k.#.'.g....|
00000050 00 39 c0 09 c0 13 00 33 00 9d 00 9c 00 3d 00 3c |.9.....3.....=.<|
-00000060 00 35 00 2f 00 ff 01 00 00 6a 00 00 00 0e 00 0c |.5./.....j......|
-00000070 00 00 09 31 32 37 2e 30 2e 30 2e 31 00 0b 00 04 |...127.0.0.1....|
-00000080 03 00 01 02 00 0a 00 0c 00 0a 00 1d 00 17 00 1e |................|
-00000090 00 19 00 18 00 23 00 00 00 16 00 00 00 17 00 00 |.....#..........|
-000000a0 00 0d 00 30 00 2e 04 03 05 03 06 03 08 07 08 08 |...0............|
-000000b0 08 09 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 |................|
-000000c0 06 01 03 03 02 03 03 01 02 01 03 02 02 02 04 02 |................|
-000000d0 05 02 06 02 |....|
+00000060 00 35 00 2f 00 ff 01 00 00 58 00 0b 00 04 03 00 |.5./.....X......|
+00000070 01 02 00 0a 00 0c 00 0a 00 1d 00 17 00 1e 00 19 |................|
+00000080 00 18 00 23 00 00 00 16 00 00 00 17 00 00 00 0d |...#............|
+00000090 00 30 00 2e 04 03 05 03 06 03 08 07 08 08 08 09 |.0..............|
+000000a0 08 0a 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 |................|
+000000b0 03 03 02 03 03 01 02 01 03 02 02 02 04 02 05 02 |................|
+000000c0 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 |................|
@@ -58,38 +57,38 @@
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 2d |......_X.;t....-|
-000002d0 54 87 fa c9 e5 97 ad a0 6d 54 89 b1 37 24 af df |T.......mT..7$..|
-000002e0 0f 3e ef 34 f7 6a 5f 1b 06 a5 b9 b4 6d 46 7f b1 |.>.4.j_.....mF..|
-000002f0 ab e4 5c dd c1 3f 98 93 61 e5 81 8a 6c 3d 2f b3 |..\..?..a...l=/.|
-00000300 3c 59 b9 78 45 ba bd 02 b1 a0 72 cb c3 59 b1 55 |<Y.xE.....r..Y.U|
-00000310 da a3 a8 ea ac b2 8a c0 23 e7 e7 ca c9 9f 5d 1b |........#.....].|
-00000320 a8 b4 7c c3 9f cf c5 3c 5f 07 d8 49 8c 95 f1 ce |..|....<_..I....|
-00000330 27 d0 d1 3f 74 44 df e4 12 ea e2 0e 43 6e d2 53 |'..?tD......Cn.S|
-00000340 7e 39 41 d7 71 c1 3c 2c a6 0b 4e e3 4d 9a 02 16 |~9A.q.<,..N.M...|
+000002c0 c4 cf c2 ed 90 99 5f 58 cb 3b 74 08 04 00 80 d9 |......_X.;t.....|
+000002d0 5f d9 85 1f 13 34 60 85 c8 eb 27 79 14 ed 84 77 |_....4`...'y...w|
+000002e0 98 60 72 ce ee b9 92 87 50 4b 4a f8 25 7f 8d 92 |.`r.....PKJ.%...|
+000002f0 16 2a 19 65 96 b4 30 af fd 1b fe 1c 02 1f f4 77 |.*.e..0........w|
+00000300 6f 63 53 7c 54 a0 89 5d e9 32 b3 a9 5f e6 4b 60 |ocS|T..].2.._.K`|
+00000310 8b b1 c8 d2 61 8b 19 59 f3 5a b4 e2 71 16 b8 32 |....a..Y.Z..q..2|
+00000320 1f 8c 74 e2 4e 17 56 7e 69 01 39 8c c1 cf c7 0b |..t.N.V~i.9.....|
+00000330 56 c6 f6 c0 37 7b 3d 65 48 40 6b a0 67 e6 cd 70 |V...7{=eH@k.g..p|
+00000340 ce 8c 73 d4 e9 ba c0 04 18 b3 37 06 71 66 72 16 |..s.......7.qfr.|
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 37 47 1b 8d ef 6c |....%...! 7G...l|
-00000010 dc 59 b2 a5 a2 f6 8e 1b f6 1b ab da ec 9c a7 ff |.Y..............|
-00000020 4a f9 0e 9b 02 b0 8f bc a1 55 14 03 03 00 01 01 |J........U......|
-00000030 16 03 03 00 28 a2 53 52 8b df 86 63 d9 f8 a8 7e |....(.SR...c...~|
-00000040 f5 b4 19 1a 5d 02 9a 48 94 68 6d a2 90 13 93 42 |....]..H.hm....B|
-00000050 87 52 92 50 7c 45 91 b9 91 49 83 66 a6 |.R.P|E...I.f.|
+00000000 16 03 03 00 25 10 00 00 21 20 d5 13 c6 90 e0 4a |....%...! .....J|
+00000010 25 2f 5d cd 02 d8 fd 14 61 78 dd fc 42 57 ce bd |%/].....ax..BW..|
+00000020 e0 47 b8 cf 42 59 1c 7f 1f 1e 14 03 03 00 01 01 |.G..BY..........|
+00000030 16 03 03 00 28 96 2c 78 25 ee 20 88 53 69 57 96 |....(.,x%. .SiW.|
+00000040 d9 d2 53 6c 5b 5b e9 db 7d 0a 7c f9 16 27 43 df |..Sl[[..}.|..'C.|
+00000050 a9 e2 a6 e5 be c5 e9 d5 ff df 66 6b 81 |..........fk.|
>>> Flow 4 (server to client)
-00000000 16 03 03 00 82 04 00 00 7e 00 00 00 00 00 78 50 |........~.....xP|
+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 ec 80 83 61 a2 90 f4 4c 03 c8 09 b9 a6 c6 6f |o...a...L......o|
-00000040 c7 52 57 3f 3f 92 71 f3 f8 02 43 69 19 f0 bf 78 |.RW??.q...Ci...x|
-00000050 6a 00 cc 0a 96 6f 80 5d 62 42 9b 6b 7c 00 e0 26 |j....o.]bB.k|..&|
-00000060 90 ef d9 26 f1 33 94 6e 13 9a ec be 91 00 1e 64 |...&.3.n.......d|
-00000070 eb 12 ae b9 74 f9 85 d1 b7 91 bd e1 e2 da ac b0 |....t...........|
-00000080 71 ca 1b 65 1a e7 83 14 03 03 00 01 01 16 03 03 |q..e............|
-00000090 00 28 00 00 00 00 00 00 00 00 fa e4 1b 3b 28 9b |.(...........;(.|
-000000a0 f8 28 d7 26 d7 6a 67 33 1f 4a 39 d9 ac 59 6f fc |.(.&.jg3.J9..Yo.|
-000000b0 2b 84 6c b9 73 70 9b 30 8c d0 17 03 03 00 25 00 |+.l.sp.0......%.|
-000000c0 00 00 00 00 00 00 01 0c 6e 13 cf 3d 10 65 2f e5 |........n..=.e/.|
-000000d0 4f fd f9 b6 34 11 c2 05 60 d5 16 66 68 65 29 fa |O...4...`..fhe).|
-000000e0 e6 97 e4 dc 15 03 03 00 1a 00 00 00 00 00 00 00 |................|
-000000f0 02 58 9a 0d 41 6f 0f 72 c7 43 16 46 83 dd 26 5f |.X..Ao.r.C.F..&_|
-00000100 3a ee 1a |:..|
+00000030 6f ec 80 83 51 ed 14 ef 68 ca 42 c5 4c c7 ea d3 |o...Q...h.B.L...|
+00000040 9f e6 77 db 30 96 5c e3 bc f8 b7 c7 74 9d 0e 97 |..w.0.\.....t...|
+00000050 cf 3c ec 76 c8 9e ad 0c 49 86 9e 4f 4d 56 ce 95 |.<.v....I..OMV..|
+00000060 7f 75 79 aa dd 8e 66 8f 1f d8 01 2d c1 49 38 16 |.uy...f....-.I8.|
+00000070 b3 7a 6b 8d 3d ba 2b 81 4c 1c 75 c3 06 bb 8c 1e |.zk.=.+.L.u.....|
+00000080 df 59 35 29 5b d1 54 cc 5c 6b 37 74 29 19 0f 8b |.Y5)[.T.\k7t)...|
+00000090 14 03 03 00 01 01 16 03 03 00 28 00 00 00 00 00 |..........(.....|
+000000a0 00 00 00 c7 19 9a c9 cc 16 3b 8f b7 52 de 4c ab |.........;..R.L.|
+000000b0 90 83 b1 b5 60 0d c0 49 c4 28 f7 1d 1f e9 e0 b1 |....`..I.(......|
+000000c0 21 a1 49 17 03 03 00 25 00 00 00 00 00 00 00 01 |!.I....%........|
+000000d0 46 fe 03 14 ad 32 d5 ff 89 1f 08 15 6b 44 4f 2d |F....2......kDO-|
+000000e0 5e d6 f1 35 d9 c4 c4 cc bf 5a 26 df a6 15 03 03 |^..5.....Z&.....|
+000000f0 00 1a 00 00 00 00 00 00 00 02 4f 7b 8e 22 3c 85 |..........O{."<.|
+00000100 5c 41 f5 17 0d dd c8 41 b5 ef 5a 4c |\A.....A..ZL|
diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicket b/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicket
index 42cbc34..73d0158 100644
--- a/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicket
+++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicket
@@ -1,92 +1,91 @@
>>> Flow 1 (client to server)
-00000000 16 03 01 00 9b 01 00 00 97 03 03 22 89 61 60 36 |...........".a`6|
-00000010 06 c6 00 3f af 09 28 13 d8 7e ae 18 55 40 4a 4e |...?..(..~..U@JN|
-00000020 40 13 e2 f8 43 5f be e5 f6 51 04 00 00 04 00 2f |@...C_...Q...../|
-00000030 00 ff 01 00 00 6a 00 00 00 0e 00 0c 00 00 09 31 |.....j.........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 00 0d 00 30 |.#.............0|
-00000070 00 2e 04 03 05 03 06 03 08 07 08 08 08 09 08 0a |................|
-00000080 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 03 03 |................|
-00000090 02 03 03 01 02 01 03 02 02 02 04 02 05 02 06 02 |................|
+00000000 16 03 01 00 71 01 00 00 6d 03 03 60 fd 9b 74 aa |....q...m..`..t.|
+00000010 16 9f 07 32 7e 57 d0 91 86 ea 59 b7 f3 38 bb 4f |...2~W....Y..8.O|
+00000020 7f 2c 36 eb 67 21 57 f2 12 2b 38 00 00 04 00 2f |.,6.g!W..+8..../|
+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 3b 02 00 00 37 03 03 00 00 00 00 00 |....;...7.......|
+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 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 04 0e 00 00 00 |.......|
+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 d0 71 60 6a 92 |............q`j.|
-00000010 9b 01 87 1b d3 7d 28 a8 50 aa b9 c3 0e a3 b0 2d |.....}(.P......-|
-00000020 2f 29 1d f1 42 39 6f 65 bb 1a 0e bc 82 43 e9 c6 |/)..B9oe.....C..|
-00000030 c6 cc df 4e c6 f2 2b 85 26 cb 63 12 f7 a1 84 a1 |...N..+.&.c.....|
-00000040 25 8b 8f 02 f2 c1 fe 09 79 89 ba da b7 b1 32 4c |%.......y.....2L|
-00000050 56 4e d6 02 14 1a ed 03 87 ad d1 3e f1 5d 41 c5 |VN.........>.]A.|
-00000060 c0 fe 8e ce 6c c2 ce 2e 4a f6 4f a0 f9 d7 a9 2d |....l...J.O....-|
-00000070 22 62 78 5a a6 cb bb 62 98 20 fe f6 3d d3 b6 f8 |"bxZ...b. ..=...|
-00000080 7f 1a 5a e5 59 32 93 bd f0 82 e5 14 03 03 00 01 |..Z.Y2..........|
-00000090 01 16 03 03 00 40 96 3c c7 3f 87 d7 2e fb fb 2f |.....@.<.?...../|
-000000a0 a0 0f 60 fc a9 9c 27 c2 0d e0 a6 f9 76 8c 94 59 |..`...'.....v..Y|
-000000b0 02 ae 5c a3 b2 20 6f c7 a5 a3 ad 98 87 cf 29 02 |..\.. o.......).|
-000000c0 87 ce db 09 ee b7 eb f4 81 59 37 13 15 5b 91 fe |.........Y7..[..|
-000000d0 e7 b3 6f 69 fd d2 |..oi..|
+00000000 16 03 03 00 86 10 00 00 82 00 80 2c d6 6d 84 0c |...........,.m..|
+00000010 d9 ef 52 bb cc 0b 41 47 d7 64 c7 a6 b0 fa 3c 6f |..R...AG.d....<o|
+00000020 c3 31 95 bc ab 4b c6 72 45 ef fb 49 6f fc 5c 63 |.1...K.rE..Io.\c|
+00000030 48 d6 db 97 3b 9e 8b d9 a6 f4 59 ae 27 07 6d 1d |H...;.....Y.'.m.|
+00000040 3b 56 72 a7 5c 6f 9d 84 e2 ea ed e9 ce 8a d1 9f |;Vr.\o..........|
+00000050 bf b6 89 c9 36 be 76 cb 3f f2 40 7d b6 b8 af 4c |....6.v.?.@}...L|
+00000060 35 85 40 b8 02 7b 53 0a 33 21 fa 49 ce af 85 27 |5.@..{S.3!.I...'|
+00000070 7f ae 03 ec a2 62 5a e3 f3 41 d5 bd 8e dc e8 81 |.....bZ..A......|
+00000080 79 f0 63 95 47 bf a0 55 22 4f 42 14 03 03 00 01 |y.c.G..U"OB.....|
+00000090 01 16 03 03 00 40 63 27 d9 ca 1e 88 7d 52 6a 2c |.....@c'....}Rj,|
+000000a0 06 db f7 db 18 28 ec 4b ff 57 76 8c 3b 3d de a7 |.....(.K.Wv.;=..|
+000000b0 7b 11 75 59 61 69 3d 6d 5a 90 c4 3b b4 a7 e8 38 |{.uYai=mZ..;...8|
+000000c0 81 06 96 ca af c0 5b 42 ba 05 4b 61 82 dd eb 04 |......[B..Ka....|
+000000d0 07 81 7a 58 30 a4 |..zX0.|
>>> Flow 4 (server to client)
-00000000 16 03 03 00 82 04 00 00 7e 00 00 00 00 00 78 50 |........~.....xP|
+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 61 5c 5f 43 13 c2 76 91 3a c1 1a 8c |o,..a\_C..v.:...|
-00000040 51 00 5c a0 93 a9 06 e2 0c b0 65 e3 8c 0d 4b 7b |Q.\.......e...K{|
-00000050 7e 52 32 b8 3c b3 76 c5 bf 95 4d 29 71 50 81 e3 |~R2.<.v...M)qP..|
-00000060 2b 6f 4a 32 dc 33 94 15 c5 fe 38 b4 0a fc 03 38 |+oJ2.3....8....8|
-00000070 90 32 db c0 7f 99 62 a9 89 15 d0 f6 79 64 79 38 |.2....b.....ydy8|
-00000080 b0 e2 19 07 82 82 0a 14 03 03 00 01 01 16 03 03 |................|
-00000090 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |.@..............|
-000000a0 00 00 69 6f c8 63 ce 7b d5 82 6e f8 5f 59 ab ad |..io.c.{..n._Y..|
-000000b0 55 0c 76 8b 11 56 77 ea 33 20 fd 0b 33 9d 72 12 |U.v..Vw.3 ..3.r.|
-000000c0 85 fe 99 38 2a 70 49 fe 27 35 9d 43 5b 32 2b 77 |...8*pI.'5.C[2+w|
-000000d0 31 66 17 03 03 00 40 00 00 00 00 00 00 00 00 00 |1f....@.........|
-000000e0 00 00 00 00 00 00 00 05 36 d1 49 58 00 4d 5c bc |........6.IX.M\.|
-000000f0 a8 c4 be 76 5d f7 cc 88 c7 5a 44 8c f6 d0 30 e6 |...v]....ZD...0.|
-00000100 87 03 84 77 60 6c 47 70 2a 80 51 38 a8 8a fb 9f |...w`lGp*.Q8....|
-00000110 31 45 f0 ab c9 e5 94 15 03 03 00 30 00 00 00 00 |1E.........0....|
-00000120 00 00 00 00 00 00 00 00 00 00 00 00 19 f0 c7 ce |................|
-00000130 92 87 25 dd 5b c3 68 3b dd ec 5c 26 c6 90 36 31 |..%.[.h;..\&..61|
-00000140 a5 3c 9a 89 be 49 30 37 3b a5 5f 13 |.<...I07;._.|
+00000030 6f 2c 9f 83 51 ed 14 ef 68 ca 42 c5 4c 92 cc 13 |o,..Q...h.B.L...|
+00000040 05 4e 15 de 98 0a 74 d5 a9 2e 80 89 98 89 72 39 |.N....t.......r9|
+00000050 5f fe 49 56 66 ac 4d 73 b1 5b 4b 81 db 25 a7 5b |_.IVf.Ms.[K..%.[|
+00000060 54 5b 10 13 3d 96 71 d7 b7 23 53 ea 62 49 38 16 |T[..=.q..#S.bI8.|
+00000070 cc 4f 0d 9d 80 99 6e 0f 01 b3 d7 e4 8a 75 d1 b6 |.O....n......u..|
+00000080 7b 74 80 b2 b8 06 a9 71 6b 31 2a fd cf 6e 44 dc |{t.....qk1*..nD.|
+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 76 c4 85 3d 05 |...........v..=.|
+000000b0 60 a2 b3 ce 38 7f 1c f9 e3 19 87 b0 e1 af 08 b7 |`...8...........|
+000000c0 15 90 50 b9 51 85 c4 88 90 52 cd 6d b6 69 ee b5 |..P.Q....R.m.i..|
+000000d0 36 a8 0c 61 c4 78 09 6a 49 4d e9 17 03 03 00 40 |6..a.x.jIM.....@|
+000000e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+000000f0 76 31 e3 05 f8 b3 05 ca e2 55 84 b9 15 85 5d 4a |v1.......U....]J|
+00000100 83 a5 76 db b0 5f b9 65 b4 21 3e 00 36 9a e8 d7 |..v.._.e.!>.6...|
+00000110 02 81 23 83 19 13 c8 9c cd 02 ae 10 b9 cf 75 96 |..#...........u.|
+00000120 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
+00000130 00 00 00 00 00 f9 ae b4 16 27 75 dc 72 4d 39 0e |.........'u.rM9.|
+00000140 ba 1f 31 b2 39 ec 99 36 bc 41 34 03 54 9b de 7b |..1.9..6.A4.T..{|
+00000150 4b 65 ef 99 a6 |Ke...|
diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicketPreDisable b/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicketPreDisable
index cc1b6b0..c50fbce 100644
--- a/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicketPreDisable
+++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-IssueTicketPreDisable
@@ -1,92 +1,91 @@
>>> Flow 1 (client to server)
-00000000 16 03 01 00 9b 01 00 00 97 03 03 55 4e 24 f5 fd |...........UN$..|
-00000010 2b 70 d1 b4 9c fd eb 53 1d 2f 7e f7 59 fe 20 c6 |+p.....S./~.Y. .|
-00000020 4f 47 72 0f 7a 01 71 48 8a 21 9a 00 00 04 00 2f |OGr.z.qH.!...../|
-00000030 00 ff 01 00 00 6a 00 00 00 0e 00 0c 00 00 09 31 |.....j.........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 00 0d 00 30 |.#.............0|
-00000070 00 2e 04 03 05 03 06 03 08 07 08 08 08 09 08 0a |................|
-00000080 08 0b 08 04 08 05 08 06 04 01 05 01 06 01 03 03 |................|
-00000090 02 03 03 01 02 01 03 02 02 02 04 02 05 02 06 02 |................|
+00000000 16 03 01 00 71 01 00 00 6d 03 03 98 eb fe 13 a7 |....q...m.......|
+00000010 81 d8 8b 0b c6 78 c3 44 ce f7 7b 63 d1 7c 61 4d |.....x.D..{c.|aM|
+00000020 be fe 52 5f c0 24 88 c2 85 d1 40 00 00 04 00 2f |..R_.$....@..../|
+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 3b 02 00 00 37 03 03 00 00 00 00 00 |....;...7.......|
+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 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 04 0e 00 00 00 |.......|
+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 29 31 85 e2 ce |...........)1...|
-00000010 42 63 7f 16 3a 0b 67 19 64 da bb 7a bc fe c7 a9 |Bc..:.g.d..z....|
-00000020 fb f1 d0 c1 7e 3d 2e 69 f8 97 43 7e 73 8a eb 9a |....~=.i..C~s...|
-00000030 e4 f4 d0 e8 93 47 ec c1 89 a0 d3 93 65 47 1c 33 |.....G......eG.3|
-00000040 75 af 90 07 bb 46 27 09 c6 0c 4f 43 10 87 c9 a6 |u....F'...OC....|
-00000050 da 58 02 a7 61 4b 67 40 05 72 9b 07 aa 9b 04 18 |.X..aKg@.r......|
-00000060 6a 35 d1 54 f8 fc 08 f5 9f 49 8d aa aa 4c 2c bf |j5.T.....I...L,.|
-00000070 55 85 ed 6b ae 7e cd 77 a2 9b e3 a7 03 8d 9e d9 |U..k.~.w........|
-00000080 12 12 ce 1c c4 ba 10 f3 d5 f4 c2 14 03 03 00 01 |................|
-00000090 01 16 03 03 00 40 2c 57 5d 8b 73 4f 31 ed 16 e5 |.....@,W].sO1...|
-000000a0 17 bd 08 a9 26 95 51 0d f6 0c 82 af f2 26 9e 5e |....&.Q......&.^|
-000000b0 31 71 e5 7c dc 41 62 10 da d5 20 f1 dc 00 ea 25 |1q.|.Ab... ....%|
-000000c0 5a 4b 15 e1 ba 46 c1 5f 64 a6 59 58 55 2a 01 41 |ZK...F._d.YXU*.A|
-000000d0 3e 6b 22 b8 79 27 |>k".y'|
+00000000 16 03 03 00 86 10 00 00 82 00 80 11 4c a1 a0 ba |............L...|
+00000010 12 83 63 98 3c 1a 5d df a2 01 b6 6c 05 ec a1 1e |..c.<.]....l....|
+00000020 dc a5 6b b9 97 c3 76 51 06 45 4b 74 9e 1b 61 0f |..k...vQ.EKt..a.|
+00000030 9e d3 c7 db 7f d3 ee 23 1a 32 66 0f 2f 2c d3 52 |.......#.2f./,.R|
+00000040 e0 ec cc 31 71 d4 e6 2b b6 95 78 0b eb c9 70 b1 |...1q..+..x...p.|
+00000050 77 09 6f 8d 6d 8d 1b d7 b2 38 96 d3 f0 a2 94 37 |w.o.m....8.....7|
+00000060 14 ed d8 d6 b5 1e bc 71 b2 35 68 76 5b 10 dc 8f |.......q.5hv[...|
+00000070 de 9d 1d b5 59 d0 f1 04 70 9b 74 a9 af 7f b6 6b |....Y...p.t....k|
+00000080 de 29 5a fd 8f 95 cd 2c d6 b9 18 14 03 03 00 01 |.)Z....,........|
+00000090 01 16 03 03 00 40 02 70 cb 83 3c 42 32 58 9f 05 |.....@.p..<B2X..|
+000000a0 36 b7 3b 47 1d 58 ec cf 3f 2a ae 23 ac e6 d0 4c |6.;G.X..?*.#...L|
+000000b0 91 53 0f e8 7c c9 19 a9 e9 1c 6d fc 21 bd a0 51 |.S..|.....m.!..Q|
+000000c0 0a b2 f5 9d 34 22 30 24 bc fe 44 e0 b2 23 51 9d |....4"0$..D..#Q.|
+000000d0 c5 a8 d4 60 a3 bd |...`..|
>>> Flow 4 (server to client)
-00000000 16 03 03 00 82 04 00 00 7e 00 00 00 00 00 78 50 |........~.....xP|
+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 61 31 33 93 70 cd 6a 19 a2 67 e8 7d |o,..a13.p.j..g.}|
-00000040 cb a4 dc bb 80 d9 23 20 05 4d 53 1f b6 9f 48 01 |......# .MS...H.|
-00000050 e4 84 75 10 25 f9 ed 98 bb 39 7e fc 8b 16 d8 bc |..u.%....9~.....|
-00000060 c7 e9 88 e8 1c 33 94 10 13 6b d4 3d fa d7 73 b2 |.....3...k.=..s.|
-00000070 d4 ea 89 58 ed 38 f8 f3 6a e0 5f 1e f7 49 ed f7 |...X.8..j._..I..|
-00000080 5f 64 39 6b b5 6c fb 14 03 03 00 01 01 16 03 03 |_d9k.l..........|
-00000090 00 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |.@..............|
-000000a0 00 00 fa f3 aa 48 54 5f 5b 88 69 fb 01 75 2a 90 |.....HT_[.i..u*.|
-000000b0 49 46 7c 6a 3a aa 72 4e 35 db 8f 38 a3 4d 05 53 |IF|j:.rN5..8.M.S|
-000000c0 38 93 63 ae 0d b9 e0 b4 81 2e ee 40 d5 2b 58 2a |8.c........@.+X*|
-000000d0 18 9b 17 03 03 00 40 00 00 00 00 00 00 00 00 00 |......@.........|
-000000e0 00 00 00 00 00 00 00 3c 84 3f 45 03 b0 60 ed 8f |.......<.?E..`..|
-000000f0 d2 e5 10 98 03 1a 00 8a aa 19 d0 e9 03 fb 42 fc |..............B.|
-00000100 cd 4d 13 3e 7d 39 0b 5f cf 2d b7 87 3a bf 43 d4 |.M.>}9._.-..:.C.|
-00000110 ac 71 68 29 bf f8 ac 15 03 03 00 30 00 00 00 00 |.qh).......0....|
-00000120 00 00 00 00 00 00 00 00 00 00 00 00 81 49 eb 3b |.............I.;|
-00000130 28 e7 88 94 8b 6a cc 67 4d c4 03 66 80 af d7 c2 |(....j.gM..f....|
-00000140 07 37 36 3b f0 a4 5d 16 2b 5f 5b 27 |.76;..].+_['|
+00000030 6f 2c 9f 83 51 ed 14 ef 68 ca 42 c5 4c 3e 73 fe |o,..Q...h.B.L>s.|
+00000040 72 ef 06 25 96 ef 3d 89 51 22 e3 10 57 02 e5 69 |r..%..=.Q"..W..i|
+00000050 aa d0 6d ad 66 b3 4c 07 fc ba a4 1e 3a ad a2 3b |..m.f.L.....:..;|
+00000060 40 f7 7d 9a 11 8e a0 9e 54 c5 7c 53 7d 49 38 16 |@.}.....T.|S}I8.|
+00000070 43 a6 1b 37 8e aa 02 78 25 9b 06 54 13 54 de 6a |C..7...x%..T.T.j|
+00000080 ae 62 72 97 47 1d f8 0a 32 c3 86 93 0e 64 cc 04 |.br.G...2....d..|
+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 ac 24 92 7d 6c |............$.}l|
+000000b0 d5 fe a8 a7 b7 45 fe 58 f6 13 02 ed de c8 ba 44 |.....E.X.......D|
+000000c0 18 59 1e f9 06 82 2f 42 22 62 5a 82 4d 70 9a c3 |.Y..../B"bZ.Mp..|
+000000d0 41 55 b0 66 ae e2 b1 1d d9 38 0a 17 03 03 00 40 |AU.f.....8.....@|
+000000e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
+000000f0 bd 16 9e 9c f2 9b 0d f8 f1 42 ba f3 38 64 69 ac |.........B..8di.|
+00000100 4a c9 25 d7 03 0b ec 8f 53 14 26 68 da b7 43 34 |J.%.....S.&h..C4|
+00000110 18 cd 66 dc 36 5e f5 16 ca 18 78 37 89 8a d5 9d |..f.6^....x7....|
+00000120 15 03 03 00 30 00 00 00 00 00 00 00 00 00 00 00 |....0...........|
+00000130 00 00 00 00 00 64 f9 5c df db 60 b7 22 15 77 29 |.....d.\..`.".w)|
+00000140 33 6f 93 22 81 c4 e5 71 af 27 60 e5 76 5f a6 f6 |3o."...q.'`.v_..|
+00000150 e0 73 87 9f ed |.s...|
diff --git a/libgo/go/crypto/tls/testdata/Server-TLSv12-Resume b/libgo/go/crypto/tls/testdata/Server-TLSv12-Resume
index d1dba66..e8205b7 100644
--- a/libgo/go/crypto/tls/testdata/Server-TLSv12-Resume
+++ b/libgo/go/crypto/tls/testdata/Server-TLSv12-Resume
@@ -1,48 +1,46 @@
>>> Flow 1 (client to server)
-00000000 16 03 01 01 33 01 00 01 2f 03 03 c0 ac ee 47 eb |....3.../.....G.|
-00000010 75 70 12 a9 b7 d9 29 03 ba dd 0c 26 ef 07 cd c1 |up....)....&....|
-00000020 ac 2b b5 14 8a 59 3a d7 58 7d 20 20 eb 74 37 f4 |.+...Y:.X} .t7.|
-00000030 79 3b 34 ed e4 b1 51 00 b9 09 04 bc 48 82 07 a2 |y;4...Q.....H...|
-00000040 cc 47 2d dc 16 54 a6 02 0c 5e f2 23 00 04 00 2f |.G-..T...^.#.../|
-00000050 00 ff 01 00 00 e2 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 23 00 78 50 46 ad c1 db a8 38 86 7b 2b bb fd |.#.xPF....8.{+..|
-00000090 d0 c3 42 3e 00 00 00 00 00 00 00 00 00 00 00 00 |..B>............|
-000000a0 00 00 00 00 94 6f 2c 9f 83 61 5c 5f 43 13 c2 76 |.....o,..a\_C..v|
-000000b0 91 3a c1 1a 8c 51 00 5c a0 93 a9 06 e2 0c b0 65 |.:...Q.\.......e|
-000000c0 e3 8c 0d 4b 7b 7e 52 32 b8 3c b3 76 c5 bf 95 4d |...K{~R2.<.v...M|
-000000d0 29 71 50 81 e3 2b 6f 4a 32 dc 33 94 15 c5 fe 38 |)qP..+oJ2.3....8|
-000000e0 b4 0a fc 03 38 90 32 db c0 7f 99 62 a9 89 15 d0 |....8.2....b....|
-000000f0 f6 79 64 79 38 b0 e2 19 07 82 82 0a 00 16 00 00 |.ydy8...........|
-00000100 00 17 00 00 00 0d 00 30 00 2e 04 03 05 03 06 03 |.......0........|
-00000110 08 07 08 08 08 09 08 0a 08 0b 08 04 08 05 08 06 |................|
-00000120 04 01 05 01 06 01 03 03 02 03 03 01 02 01 03 02 |................|
-00000130 02 02 04 02 05 02 06 02 |........|
+00000000 16 03 01 01 12 01 00 01 0e 03 03 3e 4f b2 97 44 |...........>O..D|
+00000010 64 a4 e1 33 32 21 98 ea c1 8c 3f 7b 5f 47 e6 54 |d..32!....?{_G.T|
+00000020 bf f1 a9 fd fb 5c 1e c9 23 7a 12 20 42 f6 4f a1 |.....\..#z. B.O.|
+00000030 85 90 ad 50 2b 3b 24 f7 2e 48 1f 2d 5b 0d fe 77 |...P+;$..H.-[..w|
+00000040 07 2b cb e9 03 23 d9 24 04 05 4e 26 00 04 00 2f |.+...#.$..N&.../|
+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 92 cc 13 05 4e 15 de 98 |...h.B.L....N...|
+00000090 0a 74 d5 a9 2e 80 89 98 89 72 39 5f fe 49 56 66 |.t.......r9_.IVf|
+000000a0 ac 4d 73 b1 5b 4b 81 db 25 a7 5b 54 5b 10 13 3d |.Ms.[K..%.[T[..=|
+000000b0 96 71 d7 b7 23 53 ea 62 49 38 16 cc 4f 0d 9d 80 |.q..#S.bI8..O...|
+000000c0 99 6e 0f 01 b3 d7 e4 8a 75 d1 b6 7b 74 80 b2 b8 |.n......u..{t...|
+000000d0 06 a9 71 6b 31 2a fd cf 6e 44 dc 00 16 00 00 00 |..qk1*..nD......|
+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 57 02 00 00 53 03 03 00 00 00 00 00 |....W...S.......|
+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 eb 74 37 f4 |...DOWNGRD. .t7.|
-00000030 79 3b 34 ed e4 b1 51 00 b9 09 04 bc 48 82 07 a2 |y;4...Q.....H...|
-00000040 cc 47 2d dc 16 54 a6 02 0c 5e f2 23 00 2f 00 00 |.G-..T...^.#./..|
-00000050 0b ff 01 00 01 00 00 0b 00 02 01 00 14 03 03 00 |................|
-00000060 01 01 16 03 03 00 40 00 00 00 00 00 00 00 00 00 |......@.........|
-00000070 00 00 00 00 00 00 00 a6 49 4b 9d e0 3c e1 58 b4 |........IK..<.X.|
-00000080 f9 50 e6 a6 32 ce 65 74 14 95 07 05 0c ef be 7d |.P..2.et.......}|
-00000090 74 8c 46 3e 2a 07 de 5f 7a 08 b9 a0 80 f0 52 90 |t.F>*.._z.....R.|
-000000a0 d4 6b c5 0f c5 ae 54 |.k....T|
+00000020 00 00 00 44 4f 57 4e 47 52 44 01 20 42 f6 4f a1 |...DOWNGRD. B.O.|
+00000030 85 90 ad 50 2b 3b 24 f7 2e 48 1f 2d 5b 0d fe 77 |...P+;$..H.-[..w|
+00000040 07 2b cb e9 03 23 d9 24 04 05 4e 26 00 2f 00 00 |.+...#.$..N&./..|
+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 dc 9b ca 90 7b f0 70 bc 17 76 9c fb a7 74 49 |.....{.p..v...tI|
+00000080 0c 9f 3c 31 76 77 9b af 6a e0 00 a6 54 81 4a d5 |..<1vw..j...T.J.|
+00000090 de fa 75 cb d6 b4 b2 6c bc f4 30 7a a1 56 0a f5 |..u....l..0z.V..|
+000000a0 5c |\|
>>> Flow 3 (client to server)
-00000000 14 03 03 00 01 01 16 03 03 00 40 8c 59 48 06 01 |..........@.YH..|
-00000010 a4 c6 35 ad a6 f5 a9 d3 31 ea 58 64 0e 45 91 4c |..5.....1.Xd.E.L|
-00000020 fb e7 c6 6e 27 e8 92 a9 9c c3 c6 29 e9 6c 55 3a |...n'......).lU:|
-00000030 2a fe 0f 40 d9 aa 3e fe ab 66 e1 38 91 d1 db ac |*..@..>..f.8....|
-00000040 58 13 f0 3c 5e f1 a9 9c fd 07 04 |X..<^......|
+00000000 14 03 03 00 01 01 16 03 03 00 40 cb 74 dc ec f5 |..........@.t...|
+00000010 ad ab c5 8e dc da 50 89 28 7b cc 0f 06 87 9a 19 |......P.({......|
+00000020 dd 4e 40 38 1d 8f 95 6f 0e 62 5f cb 7c db ab 24 |.N@8...o.b_.|..$|
+00000030 df 03 ef 7c 83 12 0e 3d 25 e8 de cf d0 aa 0e 91 |...|...=%.......|
+00000040 20 9b 38 39 4e 39 70 3c 0a ce c8 | .89N9p<...|
>>> 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 a6 4f 7a f8 b0 6e 25 13 fb b6 68 |......Oz..n%...h|
-00000020 2d 1e 22 1b 95 93 63 e8 e1 9c 93 3e 53 78 bb aa |-."...c....>Sx..|
-00000030 9f 6e 84 56 28 31 a0 ed a9 a3 06 fd e6 f9 c4 c4 |.n.V(1..........|
-00000040 56 5f 5f c2 fb 15 03 03 00 30 00 00 00 00 00 00 |V__......0......|
-00000050 00 00 00 00 00 00 00 00 00 00 c9 98 24 06 26 73 |............$.&s|
-00000060 87 27 73 bd 7a 30 b5 85 28 f7 c4 b6 7a b0 96 9f |.'s.z0..(...z...|
-00000070 a8 d4 43 1d 8e f5 a5 9f f3 f3 |..C.......|
+00000010 00 00 00 00 00 d1 5b 42 2c 10 9b 48 97 cf 8e 69 |......[B,..H...i|
+00000020 a4 b4 62 65 d9 f1 1f 86 07 f1 6c cd 5b 18 6e c7 |..be......l.[.n.|
+00000030 8d 57 20 3d f9 3f 68 1b 12 7b 29 13 b9 8d fe 7b |.W =.?h..{)....{|
+00000040 ad 52 22 c4 94 15 03 03 00 30 00 00 00 00 00 00 |.R"......0......|
+00000050 00 00 00 00 00 00 00 00 00 00 31 ae ae 06 b7 2c |..........1....,|
+00000060 5f a4 fc 8f a6 33 2b 42 1a f5 d5 b9 ad a4 fc a0 |_....3+B........|
+00000070 bc e9 c8 5d 4d 26 83 38 ca 57 |...]M&.8.W|
diff --git a/libgo/go/crypto/tls/ticket.go b/libgo/go/crypto/tls/ticket.go
index c873e43..6c1d20d 100644
--- a/libgo/go/crypto/tls/ticket.go
+++ b/libgo/go/crypto/tls/ticket.go
@@ -12,8 +12,9 @@ import (
"crypto/sha256"
"crypto/subtle"
"errors"
- "golang.org/x/crypto/cryptobyte"
"io"
+
+ "golang.org/x/crypto/cryptobyte"
)
// sessionState contains the information that is serialized into a session
@@ -21,88 +22,56 @@ import (
type sessionState struct {
vers uint16
cipherSuite uint16
- masterSecret []byte
- certificates [][]byte
+ 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 (s *sessionState) marshal() []byte {
- length := 2 + 2 + 2 + len(s.masterSecret) + 2
- for _, cert := range s.certificates {
- length += 4 + len(cert)
- }
-
- ret := make([]byte, length)
- x := ret
- x[0] = byte(s.vers >> 8)
- x[1] = byte(s.vers)
- x[2] = byte(s.cipherSuite >> 8)
- x[3] = byte(s.cipherSuite)
- x[4] = byte(len(s.masterSecret) >> 8)
- x[5] = byte(len(s.masterSecret))
- x = x[6:]
- copy(x, s.masterSecret)
- x = x[len(s.masterSecret):]
-
- x[0] = byte(len(s.certificates) >> 8)
- x[1] = byte(len(s.certificates))
- x = x[2:]
-
- for _, cert := range s.certificates {
- x[0] = byte(len(cert) >> 24)
- x[1] = byte(len(cert) >> 16)
- x[2] = byte(len(cert) >> 8)
- x[3] = byte(len(cert))
- copy(x[4:], cert)
- x = x[4+len(cert):]
- }
-
- return ret
+func (m *sessionState) marshal() []byte {
+ 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.BytesOrPanic()
}
-func (s *sessionState) unmarshal(data []byte) bool {
- if len(data) < 8 {
- return false
- }
-
- s.vers = uint16(data[0])<<8 | uint16(data[1])
- s.cipherSuite = uint16(data[2])<<8 | uint16(data[3])
- masterSecretLen := int(data[4])<<8 | int(data[5])
- data = data[6:]
- if len(data) < masterSecretLen {
+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
}
-
- s.masterSecret = data[:masterSecretLen]
- data = data[masterSecretLen:]
-
- if len(data) < 2 {
+ var certList cryptobyte.String
+ if !s.ReadUint24LengthPrefixed(&certList) {
return false
}
-
- numCerts := int(data[0])<<8 | int(data[1])
- data = data[2:]
-
- s.certificates = make([][]byte, numCerts)
- for i := range s.certificates {
- if len(data) < 4 {
+ for !certList.Empty() {
+ var cert []byte
+ if !readUint24LengthPrefixed(&certList, &cert) {
return false
}
- certLen := int(data[0])<<24 | int(data[1])<<16 | int(data[2])<<8 | int(data[3])
- data = data[4:]
- if certLen < 0 {
- return false
- }
- if len(data) < certLen {
- return false
- }
- s.certificates[i] = data[:certLen]
- data = data[certLen:]
+ m.certificates = append(m.certificates, cert)
}
-
- return len(data) == 0
+ return s.Empty()
}
// sessionStateTLS13 is the content of a TLS 1.3 session ticket. Its first
@@ -148,6 +117,10 @@ func (m *sessionStateTLS13) unmarshal(data []byte) bool {
}
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]
@@ -156,7 +129,7 @@ func (c *Conn) encryptTicket(state []byte) ([]byte, error) {
if _, err := io.ReadFull(c.config.rand(), iv); err != nil {
return nil, err
}
- key := c.config.ticketKeys()[0]
+ key := c.ticketKeys[0]
copy(keyName, key.keyName[:])
block, err := aes.NewCipher(key.aesKey[:])
if err != nil {
@@ -181,19 +154,17 @@ func (c *Conn) decryptTicket(encrypted []byte) (plaintext []byte, usedOldKey boo
macBytes := encrypted[len(encrypted)-sha256.Size:]
ciphertext := encrypted[ticketKeyNameLen+aes.BlockSize : len(encrypted)-sha256.Size]
- keys := c.config.ticketKeys()
keyIndex := -1
- for i, candidateKey := range keys {
+ for i, candidateKey := range c.ticketKeys {
if bytes.Equal(keyName, candidateKey.keyName[:]) {
keyIndex = i
break
}
}
-
if keyIndex == -1 {
return nil, false
}
- key := &keys[keyIndex]
+ key := &c.ticketKeys[keyIndex]
mac := hmac.New(sha256.New, key.hmacKey[:])
mac.Write(encrypted[:len(encrypted)-sha256.Size])
diff --git a/libgo/go/crypto/tls/tls.go b/libgo/go/crypto/tls/tls.go
index af44485..454aa0b 100644
--- a/libgo/go/crypto/tls/tls.go
+++ b/libgo/go/crypto/tls/tls.go
@@ -13,6 +13,7 @@ package tls
import (
"bytes"
+ "context"
"crypto"
"crypto/ecdsa"
"crypto/ed25519"
@@ -32,7 +33,12 @@ import (
// 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 {
- return &Conn{conn: conn, config: config}
+ c := &Conn{
+ conn: conn,
+ config: config,
+ }
+ c.handshakeFn = c.serverHandshake
+ return c
}
// Client returns a new TLS client side connection
@@ -40,7 +46,13 @@ func Server(conn net.Conn, config *Config) *Conn {
// The config cannot be nil: users must set either ServerName or
// InsecureSkipVerify in the config.
func Client(conn net.Conn, config *Config) *Conn {
- return &Conn{conn: conn, config: config, isClient: true}
+ 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.
@@ -100,29 +112,35 @@ func (timeoutError) Temporary() bool { return true }
// DialWithDialer interprets a nil configuration as equivalent to the zero
// configuration; see the documentation of Config for the defaults.
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) {
// We want the Timeout and Deadline values from dialer to cover the
// whole process: TCP connection and TLS handshake. This means that we
// also need to start our own timers now.
- timeout := dialer.Timeout
+ timeout := netDialer.Timeout
- if !dialer.Deadline.IsZero() {
- deadlineTimeout := time.Until(dialer.Deadline)
+ if !netDialer.Deadline.IsZero() {
+ deadlineTimeout := time.Until(netDialer.Deadline)
if timeout == 0 || deadlineTimeout < timeout {
timeout = deadlineTimeout
}
}
- var errChannel chan error
-
+ // hsErrCh is non-nil if we might not wait for Handshake to complete.
+ var hsErrCh chan error
+ if timeout != 0 || ctx.Done() != nil {
+ hsErrCh = make(chan error, 2)
+ }
if timeout != 0 {
- errChannel = make(chan error, 2)
timer := time.AfterFunc(timeout, func() {
- errChannel <- timeoutError{}
+ hsErrCh <- timeoutError{}
})
defer timer.Stop()
}
- rawConn, err := dialer.Dial(network, addr)
+ rawConn, err := netDialer.DialContext(ctx, network, addr)
if err != nil {
return nil, err
}
@@ -147,14 +165,26 @@ func DialWithDialer(dialer *net.Dialer, network, addr string, config *Config) (*
conn := Client(rawConn, config)
- if timeout == 0 {
+ if hsErrCh == nil {
err = conn.Handshake()
} else {
go func() {
- errChannel <- conn.Handshake()
+ hsErrCh <- conn.Handshake()
}()
- err = <-errChannel
+ select {
+ case <-ctx.Done():
+ err = ctx.Err()
+ case err = <-hsErrCh:
+ if err != nil {
+ // If the error was due to the context
+ // closing, prefer the context's error, rather
+ // than some random network teardown error.
+ if e := ctx.Err(); e != nil {
+ err = e
+ }
+ }
+ }
}
if err != nil {
@@ -175,6 +205,54 @@ 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.
+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
@@ -287,7 +365,7 @@ func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (Certificate, error) {
}
// 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.
+// 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 {
diff --git a/libgo/go/crypto/tls/tls_test.go b/libgo/go/crypto/tls/tls_test.go
index 178b519..1984234 100644
--- a/libgo/go/crypto/tls/tls_test.go
+++ b/libgo/go/crypto/tls/tls_test.go
@@ -6,6 +6,7 @@ package tls
import (
"bytes"
+ "context"
"crypto"
"crypto/x509"
"encoding/json"
@@ -201,6 +202,118 @@ func TestDialTimeout(t *testing.T) {
}
}
+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()
@@ -294,7 +407,11 @@ func TestTLSUniqueMatches(t *testing.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 {
@@ -308,7 +425,11 @@ func TestTLSUniqueMatches(t *testing.T) {
t.Error(err)
return
}
- serverTLSUniques <- srv.ConnectionState().TLSUnique
+ select {
+ case <-parentDone:
+ return
+ case serverTLSUniques <- srv.ConnectionState().TLSUnique:
+ }
}
}()
@@ -318,7 +439,15 @@ func TestTLSUniqueMatches(t *testing.T) {
if err != nil {
t.Fatal(err)
}
- if !bytes.Equal(conn.ConnectionState().TLSUnique, <-serverTLSUniques) {
+
+ 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()
@@ -331,7 +460,14 @@ func TestTLSUniqueMatches(t *testing.T) {
if !conn.ConnectionState().DidResume {
t.Error("second session did not use resumption")
}
- if !bytes.Equal(conn.ConnectionState().TLSUnique, <-serverTLSUniques) {
+
+ 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")
}
}
@@ -598,7 +734,7 @@ func TestWarningAlertFlood(t *testing.T) {
}
func TestCloneFuncFields(t *testing.T) {
- const expectedCount = 5
+ const expectedCount = 6
called := 0
c1 := Config{
@@ -622,6 +758,10 @@ func TestCloneFuncFields(t *testing.T) {
called |= 1 << 4
return nil
},
+ VerifyConnection: func(ConnectionState) error {
+ called |= 1 << 5
+ return nil
+ },
}
c2 := c1.Clone()
@@ -631,6 +771,7 @@ func TestCloneFuncFields(t *testing.T) {
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)
@@ -644,17 +785,12 @@ func TestCloneNonFuncFields(t *testing.T) {
typ := v.Type()
for i := 0; i < typ.NumField(); i++ {
f := v.Field(i)
- if !f.CanSet() {
- // unexported field; not cloned.
- continue
- }
-
// 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", "GetClientCertificate":
+ 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
@@ -689,17 +825,17 @@ func TestCloneNonFuncFields(t *testing.T) {
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()
- // DeepEqual also compares unexported fields, thus c2 needs to have run
- // serverInit in order to be DeepEqual to c1. Cloning it and discarding
- // the result is sufficient.
- c2.Clone()
-
if !reflect.DeepEqual(&c1, c2) {
t.Errorf("clone failed to copy a field")
}
@@ -980,8 +1116,8 @@ func TestConnectionState(t *testing.T) {
if ss.ServerName != serverName {
t.Errorf("Got server name %q, expected %q", ss.ServerName, serverName)
}
- if cs.ServerName != "" {
- t.Errorf("Got unexpected server name on the client side")
+ 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 {
@@ -1307,7 +1443,7 @@ func (s brokenSigner) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts
}
// 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.
+// 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{{
@@ -1315,7 +1451,7 @@ func TestPKCS1OnlyCert(t *testing.T) {
PrivateKey: brokenSigner{testRSAPrivateKey},
}}
serverConfig := testConfig.Clone()
- serverConfig.MaxVersion = VersionTLS12 // TLS 1.3 doesn't support PKCS#1 v1.5
+ 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.