diff options
Diffstat (limited to 'libgo/go/crypto/tls')
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. |