auth.mx raw

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