فهرست منبع

Update vendored utls

Rod Hynes 6 سال پیش
والد
کامیت
4e006fe0c8

+ 59 - 4
vendor/github.com/refraction-networking/utls/auth.go

@@ -134,16 +134,28 @@ func writeSignedMessage(sigHash io.Writer, context string, transcript hash.Hash)
 }
 
 // signatureSchemesForCertificate returns the list of supported SignatureSchemes
-// for a given certificate, based on the public key.
-func signatureSchemesForCertificate(cert *Certificate) []SignatureScheme {
+// for a given certificate, based on the public key and the protocol version. It
+// does not support the crypto.Decrypter interface, so shouldn't be used on the
+// server side in TLS 1.2 and earlier.
+func signatureSchemesForCertificate(version uint16, cert *Certificate) []SignatureScheme {
 	priv, ok := cert.PrivateKey.(crypto.Signer)
 	if !ok {
 		return nil
 	}
 
-	switch priv := priv.Public().(type) {
+	switch pub := priv.Public().(type) {
 	case *ecdsa.PublicKey:
-		switch priv.Curve {
+		if version != VersionTLS13 {
+			// In TLS 1.2 and earlier, ECDSA algorithms are not
+			// constrained to a single curve.
+			return []SignatureScheme{
+				ECDSAWithP256AndSHA256,
+				ECDSAWithP384AndSHA384,
+				ECDSAWithP521AndSHA512,
+				ECDSAWithSHA1,
+			}
+		}
+		switch pub.Curve {
 		case elliptic.P256():
 			return []SignatureScheme{ECDSAWithP256AndSHA256}
 		case elliptic.P384():
@@ -154,6 +166,17 @@ func signatureSchemesForCertificate(cert *Certificate) []SignatureScheme {
 			return nil
 		}
 	case *rsa.PublicKey:
+		if version != VersionTLS13 {
+			return []SignatureScheme{
+				PSSWithSHA256,
+				PSSWithSHA384,
+				PSSWithSHA512,
+				PKCS1WithSHA256,
+				PKCS1WithSHA384,
+				PKCS1WithSHA512,
+				PKCS1WithSHA1,
+			}
+		}
 		// RSA keys with RSA-PSS OID are not supported by crypto/x509.
 		return []SignatureScheme{
 			PSSWithSHA256,
@@ -164,3 +187,35 @@ func signatureSchemesForCertificate(cert *Certificate) []SignatureScheme {
 		return nil
 	}
 }
+
+// unsupportedCertificateError returns a helpful error for certificates with
+// an unsupported private key.
+func unsupportedCertificateError(cert *Certificate) error {
+	switch cert.PrivateKey.(type) {
+	case rsa.PrivateKey, ecdsa.PrivateKey:
+		return fmt.Errorf("tls: unsupported certificate: private key is %T, expected *%T",
+			cert.PrivateKey, cert.PrivateKey)
+	}
+
+	signer, ok := cert.PrivateKey.(crypto.Signer)
+	if !ok {
+		return fmt.Errorf("tls: certificate private key (%T) does not implement crypto.Signer",
+			cert.PrivateKey)
+	}
+
+	switch pub := signer.Public().(type) {
+	case *ecdsa.PublicKey:
+		switch pub.Curve {
+		case elliptic.P256():
+		case elliptic.P384():
+		case elliptic.P521():
+		default:
+			return fmt.Errorf("tls: unsupported certificate curve (%s)", pub.Curve.Params().Name)
+		}
+	case *rsa.PublicKey:
+	default:
+		return fmt.Errorf("tls: unsupported certificate key (%T)", pub)
+	}
+
+	return fmt.Errorf("tls: internal error: unsupported key (%T)", cert.PrivateKey)
+}

+ 59 - 12
vendor/github.com/refraction-networking/utls/common.go

@@ -15,6 +15,7 @@ import (
 	"io"
 	"math/big"
 	"net"
+	"os"
 	"strings"
 	"sync"
 	"time"
@@ -161,7 +162,7 @@ const (
 )
 
 // supportedSignatureAlgorithms contains the signature and hash algorithms that
-// the code advertises as supported in a TLS 1.2 ClientHello and in a TLS 1.2
+// the code advertises as supported in a TLS 1.2+ ClientHello and in a TLS 1.2+
 // CertificateRequest. The two fields are merged to match with TLS 1.3.
 // Note that in TLS 1.2, the ECDSA algorithms are not constrained to P-256, etc.
 var supportedSignatureAlgorithms = []SignatureScheme{
@@ -200,7 +201,7 @@ 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_RSA_WITH_RC4_128_SHA, ...)
+	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)
@@ -241,7 +242,7 @@ const (
 	RequireAndVerifyClientCert
 )
 
-// requiresClientCert returns whether the ClientAuthType requires a client
+// requiresClientCert reports whether the ClientAuthType requires a client
 // certificate to be provided.
 func requiresClientCert(c ClientAuthType) bool {
 	switch c {
@@ -292,7 +293,7 @@ type ClientSessionCache interface {
 type SignatureScheme uint16
 
 const (
-	PKCS1WithSHA1   SignatureScheme = 0x0201
+	// RSASSA-PKCS1-v1_5 algorithms.
 	PKCS1WithSHA256 SignatureScheme = 0x0401
 	PKCS1WithSHA384 SignatureScheme = 0x0501
 	PKCS1WithSHA512 SignatureScheme = 0x0601
@@ -302,11 +303,13 @@ const (
 	PSSWithSHA384 SignatureScheme = 0x0805
 	PSSWithSHA512 SignatureScheme = 0x0806
 
+	// ECDSA algorithms. Only constrained to a specific curve in TLS 1.3.
 	ECDSAWithP256AndSHA256 SignatureScheme = 0x0403
 	ECDSAWithP384AndSHA384 SignatureScheme = 0x0503
 	ECDSAWithP521AndSHA512 SignatureScheme = 0x0603
 
 	// Legacy signature and hash algorithms for TLS 1.2.
+	PKCS1WithSHA1 SignatureScheme = 0x0201
 	ECDSAWithSHA1 SignatureScheme = 0x0203
 )
 
@@ -314,7 +317,7 @@ const (
 // guide certificate selection in the GetCertificate callback.
 type ClientHelloInfo struct {
 	// CipherSuites lists the CipherSuites supported by the client (e.g.
-	// TLS_RSA_WITH_RC4_128_SHA).
+	// TLS_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256).
 	CipherSuites []uint16
 
 	// ServerName indicates the name of the server requested by the client
@@ -520,8 +523,11 @@ type Config struct {
 	// This should be used only for testing.
 	InsecureSkipVerify bool
 
-	// CipherSuites is a list of supported cipher suites. If CipherSuites
-	// is nil, TLS uses a list of suites supported by the implementation.
+	// CipherSuites is a list of supported cipher suites for TLS versions up to
+	// TLS 1.2. If CipherSuites is nil, a default list of secure cipher suites
+	// is used, with a preference order based on hardware performance. The
+	// default cipher suites might change over Go versions. Note that TLS 1.3
+	// ciphersuites are not configurable.
 	CipherSuites []uint16
 
 	// PreferServerCipherSuites controls whether the server selects the
@@ -771,11 +777,53 @@ func (c *Config) supportedVersions(isClient bool) []uint16 {
 		if isClient && v < VersionTLS10 {
 			continue
 		}
+		// TLS 1.3 is opt-out in Go 1.13.
+		if v == VersionTLS13 && !isTLS13Supported() {
+			continue
+		}
 		versions = append(versions, v)
 	}
 	return versions
 }
 
+// tls13Support caches the result for isTLS13Supported.
+var tls13Support struct {
+	sync.Once
+	cached bool
+}
+
+// isTLS13Supported returns whether the program enabled TLS 1.3 by not opting
+// out with GODEBUG=tls13=0. It's cached after the first execution.
+func isTLS13Supported() bool {
+	tls13Support.Do(func() {
+		tls13Support.cached = goDebugString("tls13") != "0"
+	})
+	return tls13Support.cached
+}
+
+// goDebugString returns the value of the named GODEBUG key.
+// GODEBUG is of the form "key=val,key2=val2".
+func goDebugString(key string) string {
+	s := os.Getenv("GODEBUG")
+	for i := 0; i < len(s)-len(key)-1; i++ {
+		if i > 0 && s[i-1] != ',' {
+			continue
+		}
+		afterKey := s[i+len(key):]
+		if afterKey[0] != '=' || s[i:i+len(key)] != key {
+			continue
+		}
+		val := afterKey[1:]
+		for i, b := range val {
+			if b == ',' {
+				return val[:i]
+			}
+		}
+		return val
+	}
+	return ""
+}
+
 func (c *Config) maxSupportedVersion(isClient bool) uint16 {
 	supportedVersions := c.supportedVersions(isClient)
 	if len(supportedVersions) == 0 {
@@ -918,11 +966,10 @@ var writerMutex sync.Mutex
 // A Certificate is a chain of one or more certificates, leaf first.
 type Certificate struct {
 	Certificate [][]byte
-	// PrivateKey contains the private key corresponding to the public key
-	// in Leaf. For a server, this must implement crypto.Signer and/or
-	// crypto.Decrypter, with an RSA or ECDSA PublicKey. For a client
-	// (performing client authentication), this must be a crypto.Signer
-	// with an RSA or ECDSA PublicKey.
+	// PrivateKey contains the private key corresponding to the public key in
+	// Leaf. This must implement crypto.Signer with an RSA or ECDSA PublicKey.
+	// For a server up to TLS 1.2, it can also implement crypto.Decrypter with
+	// an RSA PublicKey.
 	PrivateKey crypto.PrivateKey
 	// OCSPStaple contains an optional OCSP response which will be served
 	// to clients that request it.

+ 20 - 1
vendor/github.com/refraction-networking/utls/conn.go

@@ -274,6 +274,17 @@ func extractPadding(payload []byte) (toRemove int, good byte) {
 	good &= good << 1
 	good = uint8(int8(good) >> 7)
 
+	// Zero the padding length on error. This ensures any unchecked bytes
+	// are included in the MAC. Otherwise, an attacker that could
+	// distinguish MAC failures from padding failures could mount an attack
+	// similar to POODLE in SSL 3.0: given a good ciphertext that uses a
+	// full block's worth of padding, replace the final block with another
+	// block. If the MAC check passed but the padding check failed, the
+	// last byte of that block decrypted to the block size.
+	//
+	// See also macAndPaddingGood logic below.
+	paddingLen &= good
+
 	toRemove = int(paddingLen) + 1
 	return
 }
@@ -416,7 +427,15 @@ func (hc *halfConn) decrypt(record []byte) ([]byte, recordType, error) {
 		remoteMAC := payload[n : n+macSize]
 		localMAC := hc.mac.MAC(hc.seq[0:], record[:recordHeaderLen], payload[:n], payload[n+macSize:])
 
-		if subtle.ConstantTimeCompare(localMAC, remoteMAC) != 1 || paddingGood != 255 {
+		// This is equivalent to checking the MACs and paddingGood
+		// separately, but in constant-time to prevent distinguishing
+		// padding failures from MAC failures. Depending on what value
+		// of paddingLen was returned on bad padding, distinguishing
+		// bad MAC from bad padding can lead to an attack.
+		//
+		// See also the logic at the end of extractPadding.
+		macAndPaddingGood := subtle.ConstantTimeCompare(localMAC, remoteMAC) & int(paddingGood)
+		if macAndPaddingGood != 1 {
 			return nil, 0, alertBadRecordMAC
 		}
 

+ 4 - 9
vendor/github.com/refraction-networking/utls/handshake_client.go

@@ -87,7 +87,6 @@ func (c *Conn) makeClientHello() (*clientHelloMsg, ecdheParameters, error) {
 	possibleCipherSuites := config.cipherSuites()
 	hello.cipherSuites = make([]uint16, 0, len(possibleCipherSuites))
 
-NextCipherSuite:
 	for _, suiteId := range possibleCipherSuites {
 		for _, suite := range cipherSuites {
 			if suite.id != suiteId {
@@ -96,10 +95,10 @@ NextCipherSuite:
 			// Don't advertise TLS 1.2-only cipher suites unless
 			// we're attempting TLS 1.2.
 			if hello.vers < VersionTLS12 && suite.flags&suiteTLS12 != 0 {
-				continue
+				break
 			}
 			hello.cipherSuites = append(hello.cipherSuites, suiteId)
-			continue NextCipherSuite
+			break
 		}
 	}
 
@@ -833,11 +832,7 @@ func (c *Conn) verifyServerCertificate(certificates [][]byte) error {
 			DNSName:       c.config.ServerName,
 			Intermediates: x509.NewCertPool(),
 		}
-
-		for i, cert := range certs {
-			if i == 0 {
-				continue
-			}
+		for _, cert := range certs[1:] {
 			opts.Intermediates.AddCert(cert)
 		}
 		var err error
@@ -940,7 +935,7 @@ func (c *Conn) getClientCertificate(cri *CertificateRequestInfo) (*Certificate,
 	// Issuer is in AcceptableCAs.
 	for i, chain := range c.config.Certificates {
 		sigOK := false
-		for _, alg := range signatureSchemesForCertificate(&chain) {
+		for _, alg := range signatureSchemesForCertificate(c.vers, &chain) {
 			if isSupportedSignatureAlgorithm(alg, cri.SignatureSchemes) {
 				sigOK = true
 				break

+ 10 - 7
vendor/github.com/refraction-networking/utls/handshake_client_tls13.go

@@ -613,7 +613,7 @@ func (hs *clientHandshakeStateTLS13) sendClientCertificate() error {
 		return err
 	}
 
-	// If the client is sending an empty certificate message, skip the CertificateVerify.
+	// If we sent an empty certificate message, skip the CertificateVerify.
 	if len(cert.Certificate) == 0 {
 		return nil
 	}
@@ -621,10 +621,10 @@ func (hs *clientHandshakeStateTLS13) sendClientCertificate() error {
 	certVerifyMsg := new(certificateVerifyMsg)
 	certVerifyMsg.hasSignatureAlgorithm = true
 
-	supportedAlgs := signatureSchemesForCertificate(cert)
+	supportedAlgs := signatureSchemesForCertificate(c.vers, cert)
 	if supportedAlgs == nil {
 		c.sendAlert(alertInternalError)
-		return fmt.Errorf("tls: unsupported certificate key (%T)", cert.PrivateKey)
+		return unsupportedCertificateError(cert)
 	}
 	// Pick signature scheme in server preference order, as the client
 	// preference order is not configurable.
@@ -634,14 +634,17 @@ func (hs *clientHandshakeStateTLS13) sendClientCertificate() error {
 			break
 		}
 	}
+	if certVerifyMsg.signatureAlgorithm == 0 {
+		// getClientCertificate returned a certificate incompatible with the
+		// CertificateRequestInfo supported signature algorithms.
+		c.sendAlert(alertHandshakeFailure)
+		return errors.New("tls: server doesn't support selected certificate")
+	}
 
 	sigType := signatureFromSignatureScheme(certVerifyMsg.signatureAlgorithm)
 	sigHash, err := hashFromSignatureScheme(certVerifyMsg.signatureAlgorithm)
 	if sigType == 0 || err != nil {
-		// getClientCertificate returned a certificate incompatible with the
-		// CertificateRequestInfo supported signature algorithms.
-		c.sendAlert(alertInternalError)
-		return err
+		return c.sendAlert(alertInternalError)
 	}
 	h := sigHash.New()
 	writeSignedMessage(h, clientSignatureContext, hs.transcript)

+ 1 - 1
vendor/github.com/refraction-networking/utls/handshake_messages.go

@@ -321,7 +321,7 @@ func (m *clientHelloMsg) marshalWithoutBinders() []byte {
 }
 
 // updateBinders updates the m.pskBinders field, if necessary updating the
-// cached marshalled representation. The supplied binders must have the same
+// cached marshaled representation. The supplied binders must have the same
 // length as the current m.pskBinders.
 func (m *clientHelloMsg) updateBinders(pskBinders [][]byte) {
 	if len(pskBinders) != len(m.pskBinders) {

+ 13 - 9
vendor/github.com/refraction-networking/utls/handshake_server_tls13.go

@@ -10,7 +10,6 @@ import (
 	"crypto/hmac"
 	"crypto/rsa"
 	"errors"
-	"fmt"
 	"hash"
 	"io"
 	"sync/atomic"
@@ -369,10 +368,10 @@ func (hs *serverHandshakeStateTLS13) pickCertificate() error {
 		c.sendAlert(alertInternalError)
 		return err
 	}
-	supportedAlgs := signatureSchemesForCertificate(certificate)
+	supportedAlgs := signatureSchemesForCertificate(c.vers, certificate)
 	if supportedAlgs == nil {
 		c.sendAlert(alertInternalError)
-		return fmt.Errorf("tls: unsupported certificate key (%T)", certificate.PrivateKey)
+		return unsupportedCertificateError(certificate)
 	}
 	// Pick signature scheme in client preference order, as the server
 	// preference order is not configurable.
@@ -383,6 +382,8 @@ func (hs *serverHandshakeStateTLS13) pickCertificate() error {
 		}
 	}
 	if hs.sigAlg == 0 {
+		// getCertificate returned a certificate incompatible with the
+		// ClientHello supported signature algorithms.
 		c.sendAlert(alertHandshakeFailure)
 		return errors.New("tls: client doesn't support selected certificate")
 	}
@@ -463,7 +464,7 @@ func (hs *serverHandshakeStateTLS13) doHelloRetryRequest(selectedGroup CurveID)
 	return nil
 }
 
-// illegalClientHelloChange returns whether the two ClientHello messages are
+// illegalClientHelloChange reports whether the two ClientHello messages are
 // different, with the exception of the changes allowed before and after a
 // HelloRetryRequest. See RFC 8446, Section 4.1.2.
 func illegalClientHelloChange(ch, ch1 *clientHelloMsg) bool {
@@ -623,10 +624,7 @@ func (hs *serverHandshakeStateTLS13) sendServerCertificate() error {
 	sigType := signatureFromSignatureScheme(hs.sigAlg)
 	sigHash, err := hashFromSignatureScheme(hs.sigAlg)
 	if sigType == 0 || err != nil {
-		// getCertificate returned a certificate incompatible with the
-		// ClientHello supported signature algorithms.
-		c.sendAlert(alertInternalError)
-		return err
+		return c.sendAlert(alertInternalError)
 	}
 	h := sigHash.New()
 	writeSignedMessage(h, serverSignatureContext, hs.transcript)
@@ -637,7 +635,13 @@ func (hs *serverHandshakeStateTLS13) sendServerCertificate() error {
 	}
 	sig, err := hs.cert.PrivateKey.(crypto.Signer).Sign(c.config.rand(), h.Sum(nil), signOpts)
 	if err != nil {
-		c.sendAlert(alertInternalError)
+		public := hs.cert.PrivateKey.(crypto.Signer).Public()
+		if rsaKey, ok := public.(*rsa.PublicKey); ok && sigType == signatureRSAPSS &&
+			rsaKey.N.BitLen()/8 < sigHash.Size()*2+2 { // key too small for RSA-PSS
+			c.sendAlert(alertHandshakeFailure)
+		} else {
+			c.sendAlert(alertInternalError)
+		}
 		return errors.New("tls: failed to sign handshake: " + err.Error())
 	}
 	certVerifyMsg.signature = sig

+ 6 - 12
vendor/github.com/refraction-networking/utls/key_agreement.go

@@ -106,19 +106,19 @@ func md5SHA1Hash(slices [][]byte) []byte {
 // hashForServerKeyExchange hashes the given slices and returns their digest
 // using the given hash function (for >= TLS 1.2) or using a default based on
 // the sigType (for earlier TLS versions).
-func hashForServerKeyExchange(sigType uint8, hashFunc crypto.Hash, version uint16, slices ...[]byte) ([]byte, error) {
+func hashForServerKeyExchange(sigType uint8, hashFunc crypto.Hash, version uint16, slices ...[]byte) []byte {
 	if version >= VersionTLS12 {
 		h := hashFunc.New()
 		for _, slice := range slices {
 			h.Write(slice)
 		}
 		digest := h.Sum(nil)
-		return digest, nil
+		return digest
 	}
 	if sigType == signatureECDSA {
-		return sha1Hash(slices), nil
+		return sha1Hash(slices)
 	}
-	return md5SHA1Hash(slices), nil
+	return md5SHA1Hash(slices)
 }
 
 // ecdheKeyAgreement implements a TLS key agreement where the server
@@ -185,10 +185,7 @@ NextCandidate:
 		return nil, errors.New("tls: certificate cannot be used with the selected cipher suite")
 	}
 
-	digest, err := hashForServerKeyExchange(sigType, hashFunc, ka.version, clientHello.random, hello.random, serverECDHParams)
-	if err != nil {
-		return nil, err
-	}
+	digest := hashForServerKeyExchange(sigType, hashFunc, ka.version, clientHello.random, hello.random, serverECDHParams)
 
 	signOpts := crypto.SignerOpts(hashFunc)
 	if sigType == signatureRSAPSS {
@@ -297,10 +294,7 @@ func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHell
 	}
 	sig = sig[2:]
 
-	digest, err := hashForServerKeyExchange(sigType, hashFunc, ka.version, clientHello.random, serverHello.random, serverECDHParams)
-	if err != nil {
-		return err
-	}
+	digest := hashForServerKeyExchange(sigType, hashFunc, ka.version, clientHello.random, serverHello.random, serverECDHParams)
 	return verifyHandshakeSignature(sigType, cert.PublicKey, hashFunc, digest, sig)
 }
 

+ 4 - 0
vendor/github.com/refraction-networking/utls/tls.go

@@ -4,6 +4,10 @@
 
 // Package tls partially implements TLS 1.2, as specified in RFC 5246,
 // and TLS 1.3, as specified in RFC 8446.
+//
+// TLS 1.3 is available on an opt-out basis in Go 1.13. To disable
+// it, set the GODEBUG environment variable (comma-separated key=value
+// options) such that it includes "tls13=0".
 package tls
 
 // BUG(agl): The crypto/tls package only implements some countermeasures

+ 3 - 3
vendor/vendor.json

@@ -500,10 +500,10 @@
 			"revisionTime": "2019-09-09T20:29:46Z"
 		},
 		{
-			"checksumSHA1": "S5FV5qBbMksx0vxajWD94J2KeHw=",
+			"checksumSHA1": "lovHeRrkvnia8JnLwyeIBYLa1Zk=",
 			"path": "github.com/refraction-networking/utls",
-			"revision": "1552a980cef9b4c9b088a1c8fe33c774c031c295",
-			"revisionTime": "2019-08-22T22:33:47Z"
+			"revision": "43c36d3c1f57546d5cbb05c066df7b5a78686c51",
+			"revisionTime": "2019-09-09T20:06:33Z"
 		},
 		{
 			"checksumSHA1": "Fn9JW8u40ABN9Uc9wuvquuyOB+8=",