...

Source file src/crypto/tls/auth.go

Documentation: crypto/tls

		 1  // Copyright 2017 The Go Authors. All rights reserved.
		 2  // Use of this source code is governed by a BSD-style
		 3  // license that can be found in the LICENSE file.
		 4  
		 5  package tls
		 6  
		 7  import (
		 8  	"bytes"
		 9  	"crypto"
		10  	"crypto/ecdsa"
		11  	"crypto/ed25519"
		12  	"crypto/elliptic"
		13  	"crypto/rsa"
		14  	"errors"
		15  	"fmt"
		16  	"hash"
		17  	"io"
		18  )
		19  
		20  // verifyHandshakeSignature verifies a signature against pre-hashed
		21  // (if required) handshake contents.
		22  func verifyHandshakeSignature(sigType uint8, pubkey crypto.PublicKey, hashFunc crypto.Hash, signed, sig []byte) error {
		23  	switch sigType {
		24  	case signatureECDSA:
		25  		pubKey, ok := pubkey.(*ecdsa.PublicKey)
		26  		if !ok {
		27  			return fmt.Errorf("expected an ECDSA public key, got %T", pubkey)
		28  		}
		29  		if !ecdsa.VerifyASN1(pubKey, signed, sig) {
		30  			return errors.New("ECDSA verification failure")
		31  		}
		32  	case signatureEd25519:
		33  		pubKey, ok := pubkey.(ed25519.PublicKey)
		34  		if !ok {
		35  			return fmt.Errorf("expected an Ed25519 public key, got %T", pubkey)
		36  		}
		37  		if !ed25519.Verify(pubKey, signed, sig) {
		38  			return errors.New("Ed25519 verification failure")
		39  		}
		40  	case signaturePKCS1v15:
		41  		pubKey, ok := pubkey.(*rsa.PublicKey)
		42  		if !ok {
		43  			return fmt.Errorf("expected an RSA public key, got %T", pubkey)
		44  		}
		45  		if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, signed, sig); err != nil {
		46  			return err
		47  		}
		48  	case signatureRSAPSS:
		49  		pubKey, ok := pubkey.(*rsa.PublicKey)
		50  		if !ok {
		51  			return fmt.Errorf("expected an RSA public key, got %T", pubkey)
		52  		}
		53  		signOpts := &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash}
		54  		if err := rsa.VerifyPSS(pubKey, hashFunc, signed, sig, signOpts); err != nil {
		55  			return err
		56  		}
		57  	default:
		58  		return errors.New("internal error: unknown signature type")
		59  	}
		60  	return nil
		61  }
		62  
		63  const (
		64  	serverSignatureContext = "TLS 1.3, server CertificateVerify\x00"
		65  	clientSignatureContext = "TLS 1.3, client CertificateVerify\x00"
		66  )
		67  
		68  var signaturePadding = []byte{
		69  	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
		70  	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
		71  	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
		72  	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
		73  	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
		74  	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
		75  	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
		76  	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
		77  }
		78  
		79  // signedMessage returns the pre-hashed (if necessary) message to be signed by
		80  // certificate keys in TLS 1.3. See RFC 8446, Section 4.4.3.
		81  func signedMessage(sigHash crypto.Hash, context string, transcript hash.Hash) []byte {
		82  	if sigHash == directSigning {
		83  		b := &bytes.Buffer{}
		84  		b.Write(signaturePadding)
		85  		io.WriteString(b, context)
		86  		b.Write(transcript.Sum(nil))
		87  		return b.Bytes()
		88  	}
		89  	h := sigHash.New()
		90  	h.Write(signaturePadding)
		91  	io.WriteString(h, context)
		92  	h.Write(transcript.Sum(nil))
		93  	return h.Sum(nil)
		94  }
		95  
		96  // typeAndHashFromSignatureScheme returns the corresponding signature type and
		97  // crypto.Hash for a given TLS SignatureScheme.
		98  func typeAndHashFromSignatureScheme(signatureAlgorithm SignatureScheme) (sigType uint8, hash crypto.Hash, err error) {
		99  	switch signatureAlgorithm {
	 100  	case PKCS1WithSHA1, PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512:
	 101  		sigType = signaturePKCS1v15
	 102  	case PSSWithSHA256, PSSWithSHA384, PSSWithSHA512:
	 103  		sigType = signatureRSAPSS
	 104  	case ECDSAWithSHA1, ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512:
	 105  		sigType = signatureECDSA
	 106  	case Ed25519:
	 107  		sigType = signatureEd25519
	 108  	default:
	 109  		return 0, 0, fmt.Errorf("unsupported signature algorithm: %v", signatureAlgorithm)
	 110  	}
	 111  	switch signatureAlgorithm {
	 112  	case PKCS1WithSHA1, ECDSAWithSHA1:
	 113  		hash = crypto.SHA1
	 114  	case PKCS1WithSHA256, PSSWithSHA256, ECDSAWithP256AndSHA256:
	 115  		hash = crypto.SHA256
	 116  	case PKCS1WithSHA384, PSSWithSHA384, ECDSAWithP384AndSHA384:
	 117  		hash = crypto.SHA384
	 118  	case PKCS1WithSHA512, PSSWithSHA512, ECDSAWithP521AndSHA512:
	 119  		hash = crypto.SHA512
	 120  	case Ed25519:
	 121  		hash = directSigning
	 122  	default:
	 123  		return 0, 0, fmt.Errorf("unsupported signature algorithm: %v", signatureAlgorithm)
	 124  	}
	 125  	return sigType, hash, nil
	 126  }
	 127  
	 128  // legacyTypeAndHashFromPublicKey returns the fixed signature type and crypto.Hash for
	 129  // a given public key used with TLS 1.0 and 1.1, before the introduction of
	 130  // signature algorithm negotiation.
	 131  func legacyTypeAndHashFromPublicKey(pub crypto.PublicKey) (sigType uint8, hash crypto.Hash, err error) {
	 132  	switch pub.(type) {
	 133  	case *rsa.PublicKey:
	 134  		return signaturePKCS1v15, crypto.MD5SHA1, nil
	 135  	case *ecdsa.PublicKey:
	 136  		return signatureECDSA, crypto.SHA1, nil
	 137  	case ed25519.PublicKey:
	 138  		// RFC 8422 specifies support for Ed25519 in TLS 1.0 and 1.1,
	 139  		// but it requires holding on to a handshake transcript to do a
	 140  		// full signature, and not even OpenSSL bothers with the
	 141  		// complexity, so we can't even test it properly.
	 142  		return 0, 0, fmt.Errorf("tls: Ed25519 public keys are not supported before TLS 1.2")
	 143  	default:
	 144  		return 0, 0, fmt.Errorf("tls: unsupported public key: %T", pub)
	 145  	}
	 146  }
	 147  
	 148  var rsaSignatureSchemes = []struct {
	 149  	scheme					SignatureScheme
	 150  	minModulusBytes int
	 151  	maxVersion			uint16
	 152  }{
	 153  	// RSA-PSS is used with PSSSaltLengthEqualsHash, and requires
	 154  	//		emLen >= hLen + sLen + 2
	 155  	{PSSWithSHA256, crypto.SHA256.Size()*2 + 2, VersionTLS13},
	 156  	{PSSWithSHA384, crypto.SHA384.Size()*2 + 2, VersionTLS13},
	 157  	{PSSWithSHA512, crypto.SHA512.Size()*2 + 2, VersionTLS13},
	 158  	// PKCS #1 v1.5 uses prefixes from hashPrefixes in crypto/rsa, and requires
	 159  	//		emLen >= len(prefix) + hLen + 11
	 160  	// TLS 1.3 dropped support for PKCS #1 v1.5 in favor of RSA-PSS.
	 161  	{PKCS1WithSHA256, 19 + crypto.SHA256.Size() + 11, VersionTLS12},
	 162  	{PKCS1WithSHA384, 19 + crypto.SHA384.Size() + 11, VersionTLS12},
	 163  	{PKCS1WithSHA512, 19 + crypto.SHA512.Size() + 11, VersionTLS12},
	 164  	{PKCS1WithSHA1, 15 + crypto.SHA1.Size() + 11, VersionTLS12},
	 165  }
	 166  
	 167  // signatureSchemesForCertificate returns the list of supported SignatureSchemes
	 168  // for a given certificate, based on the public key and the protocol version,
	 169  // and optionally filtered by its explicit SupportedSignatureAlgorithms.
	 170  //
	 171  // This function must be kept in sync with supportedSignatureAlgorithms.
	 172  func signatureSchemesForCertificate(version uint16, cert *Certificate) []SignatureScheme {
	 173  	priv, ok := cert.PrivateKey.(crypto.Signer)
	 174  	if !ok {
	 175  		return nil
	 176  	}
	 177  
	 178  	var sigAlgs []SignatureScheme
	 179  	switch pub := priv.Public().(type) {
	 180  	case *ecdsa.PublicKey:
	 181  		if version != VersionTLS13 {
	 182  			// In TLS 1.2 and earlier, ECDSA algorithms are not
	 183  			// constrained to a single curve.
	 184  			sigAlgs = []SignatureScheme{
	 185  				ECDSAWithP256AndSHA256,
	 186  				ECDSAWithP384AndSHA384,
	 187  				ECDSAWithP521AndSHA512,
	 188  				ECDSAWithSHA1,
	 189  			}
	 190  			break
	 191  		}
	 192  		switch pub.Curve {
	 193  		case elliptic.P256():
	 194  			sigAlgs = []SignatureScheme{ECDSAWithP256AndSHA256}
	 195  		case elliptic.P384():
	 196  			sigAlgs = []SignatureScheme{ECDSAWithP384AndSHA384}
	 197  		case elliptic.P521():
	 198  			sigAlgs = []SignatureScheme{ECDSAWithP521AndSHA512}
	 199  		default:
	 200  			return nil
	 201  		}
	 202  	case *rsa.PublicKey:
	 203  		size := pub.Size()
	 204  		sigAlgs = make([]SignatureScheme, 0, len(rsaSignatureSchemes))
	 205  		for _, candidate := range rsaSignatureSchemes {
	 206  			if size >= candidate.minModulusBytes && version <= candidate.maxVersion {
	 207  				sigAlgs = append(sigAlgs, candidate.scheme)
	 208  			}
	 209  		}
	 210  	case ed25519.PublicKey:
	 211  		sigAlgs = []SignatureScheme{Ed25519}
	 212  	default:
	 213  		return nil
	 214  	}
	 215  
	 216  	if cert.SupportedSignatureAlgorithms != nil {
	 217  		var filteredSigAlgs []SignatureScheme
	 218  		for _, sigAlg := range sigAlgs {
	 219  			if isSupportedSignatureAlgorithm(sigAlg, cert.SupportedSignatureAlgorithms) {
	 220  				filteredSigAlgs = append(filteredSigAlgs, sigAlg)
	 221  			}
	 222  		}
	 223  		return filteredSigAlgs
	 224  	}
	 225  	return sigAlgs
	 226  }
	 227  
	 228  // selectSignatureScheme picks a SignatureScheme from the peer's preference list
	 229  // that works with the selected certificate. It's only called for protocol
	 230  // versions that support signature algorithms, so TLS 1.2 and 1.3.
	 231  func selectSignatureScheme(vers uint16, c *Certificate, peerAlgs []SignatureScheme) (SignatureScheme, error) {
	 232  	supportedAlgs := signatureSchemesForCertificate(vers, c)
	 233  	if len(supportedAlgs) == 0 {
	 234  		return 0, unsupportedCertificateError(c)
	 235  	}
	 236  	if len(peerAlgs) == 0 && vers == VersionTLS12 {
	 237  		// For TLS 1.2, if the client didn't send signature_algorithms then we
	 238  		// can assume that it supports SHA1. See RFC 5246, Section 7.4.1.4.1.
	 239  		peerAlgs = []SignatureScheme{PKCS1WithSHA1, ECDSAWithSHA1}
	 240  	}
	 241  	// Pick signature scheme in the peer's preference order, as our
	 242  	// preference order is not configurable.
	 243  	for _, preferredAlg := range peerAlgs {
	 244  		if isSupportedSignatureAlgorithm(preferredAlg, supportedAlgs) {
	 245  			return preferredAlg, nil
	 246  		}
	 247  	}
	 248  	return 0, errors.New("tls: peer doesn't support any of the certificate's signature algorithms")
	 249  }
	 250  
	 251  // unsupportedCertificateError returns a helpful error for certificates with
	 252  // an unsupported private key.
	 253  func unsupportedCertificateError(cert *Certificate) error {
	 254  	switch cert.PrivateKey.(type) {
	 255  	case rsa.PrivateKey, ecdsa.PrivateKey:
	 256  		return fmt.Errorf("tls: unsupported certificate: private key is %T, expected *%T",
	 257  			cert.PrivateKey, cert.PrivateKey)
	 258  	case *ed25519.PrivateKey:
	 259  		return fmt.Errorf("tls: unsupported certificate: private key is *ed25519.PrivateKey, expected ed25519.PrivateKey")
	 260  	}
	 261  
	 262  	signer, ok := cert.PrivateKey.(crypto.Signer)
	 263  	if !ok {
	 264  		return fmt.Errorf("tls: certificate private key (%T) does not implement crypto.Signer",
	 265  			cert.PrivateKey)
	 266  	}
	 267  
	 268  	switch pub := signer.Public().(type) {
	 269  	case *ecdsa.PublicKey:
	 270  		switch pub.Curve {
	 271  		case elliptic.P256():
	 272  		case elliptic.P384():
	 273  		case elliptic.P521():
	 274  		default:
	 275  			return fmt.Errorf("tls: unsupported certificate curve (%s)", pub.Curve.Params().Name)
	 276  		}
	 277  	case *rsa.PublicKey:
	 278  		return fmt.Errorf("tls: certificate RSA key size too small for supported signature algorithms")
	 279  	case ed25519.PublicKey:
	 280  	default:
	 281  		return fmt.Errorf("tls: unsupported certificate key (%T)", pub)
	 282  	}
	 283  
	 284  	if cert.SupportedSignatureAlgorithms != nil {
	 285  		return fmt.Errorf("tls: peer doesn't support the certificate custom signature algorithms")
	 286  	}
	 287  
	 288  	return fmt.Errorf("tls: internal error: unsupported key (%T)", cert.PrivateKey)
	 289  }
	 290  

View as plain text