Source file src/crypto/tls/auth.go

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

View as plain text