github.com/icodeface/tls@v0.0.0-20230910023335-34df9250cd12/auth.go (about)

     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  	"crypto"
     9  	"crypto/ecdsa"
    10  	"crypto/elliptic"
    11  	"crypto/rsa"
    12  	"encoding/asn1"
    13  	"errors"
    14  	"fmt"
    15  	"hash"
    16  	"io"
    17  )
    18  
    19  // pickSignatureAlgorithm selects a signature algorithm that is compatible with
    20  // the given public key and the list of algorithms from the peer and this side.
    21  // The lists of signature algorithms (peerSigAlgs and ourSigAlgs) are ignored
    22  // for tlsVersion < VersionTLS12.
    23  //
    24  // The returned SignatureScheme codepoint is only meaningful for TLS 1.2,
    25  // previous TLS versions have a fixed hash function.
    26  func pickSignatureAlgorithm(pubkey crypto.PublicKey, peerSigAlgs, ourSigAlgs []SignatureScheme, tlsVersion uint16) (sigAlg SignatureScheme, sigType uint8, hashFunc crypto.Hash, err error) {
    27  	if tlsVersion < VersionTLS12 || len(peerSigAlgs) == 0 {
    28  		// For TLS 1.1 and before, the signature algorithm could not be
    29  		// negotiated and the hash is fixed based on the signature type. For TLS
    30  		// 1.2, if the client didn't send signature_algorithms extension then we
    31  		// can assume that it supports SHA1. See RFC 5246, Section 7.4.1.4.1.
    32  		switch pubkey.(type) {
    33  		case *rsa.PublicKey:
    34  			if tlsVersion < VersionTLS12 {
    35  				return 0, signaturePKCS1v15, crypto.MD5SHA1, nil
    36  			} else {
    37  				return PKCS1WithSHA1, signaturePKCS1v15, crypto.SHA1, nil
    38  			}
    39  		case *ecdsa.PublicKey:
    40  			return ECDSAWithSHA1, signatureECDSA, crypto.SHA1, nil
    41  		default:
    42  			return 0, 0, 0, fmt.Errorf("tls: unsupported public key: %T", pubkey)
    43  		}
    44  	}
    45  	for _, sigAlg := range peerSigAlgs {
    46  		if !isSupportedSignatureAlgorithm(sigAlg, ourSigAlgs) {
    47  			continue
    48  		}
    49  		hashAlg, err := hashFromSignatureScheme(sigAlg)
    50  		if err != nil {
    51  			panic("tls: supported signature algorithm has an unknown hash function")
    52  		}
    53  		sigType := signatureFromSignatureScheme(sigAlg)
    54  		switch pubkey.(type) {
    55  		case *rsa.PublicKey:
    56  			if sigType == signaturePKCS1v15 || sigType == signatureRSAPSS {
    57  				return sigAlg, sigType, hashAlg, nil
    58  			}
    59  		case *ecdsa.PublicKey:
    60  			if sigType == signatureECDSA {
    61  				return sigAlg, sigType, hashAlg, nil
    62  			}
    63  		default:
    64  			return 0, 0, 0, fmt.Errorf("tls: unsupported public key: %T", pubkey)
    65  		}
    66  	}
    67  	return 0, 0, 0, errors.New("tls: peer doesn't support any common signature algorithms")
    68  }
    69  
    70  // verifyHandshakeSignature verifies a signature against pre-hashed handshake
    71  // contents.
    72  func verifyHandshakeSignature(sigType uint8, pubkey crypto.PublicKey, hashFunc crypto.Hash, digest, sig []byte) error {
    73  	switch sigType {
    74  	case signatureECDSA:
    75  		pubKey, ok := pubkey.(*ecdsa.PublicKey)
    76  		if !ok {
    77  			return errors.New("tls: ECDSA signing requires a ECDSA public key")
    78  		}
    79  		ecdsaSig := new(ecdsaSignature)
    80  		if _, err := asn1.Unmarshal(sig, ecdsaSig); err != nil {
    81  			return err
    82  		}
    83  		if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
    84  			return errors.New("tls: ECDSA signature contained zero or negative values")
    85  		}
    86  		if !ecdsa.Verify(pubKey, digest, ecdsaSig.R, ecdsaSig.S) {
    87  			return errors.New("tls: ECDSA verification failure")
    88  		}
    89  	case signaturePKCS1v15:
    90  		pubKey, ok := pubkey.(*rsa.PublicKey)
    91  		if !ok {
    92  			return errors.New("tls: RSA signing requires a RSA public key")
    93  		}
    94  		if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, digest, sig); err != nil {
    95  			return err
    96  		}
    97  	case signatureRSAPSS:
    98  		pubKey, ok := pubkey.(*rsa.PublicKey)
    99  		if !ok {
   100  			return errors.New("tls: RSA signing requires a RSA public key")
   101  		}
   102  		signOpts := &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash}
   103  		if err := rsa.VerifyPSS(pubKey, hashFunc, digest, sig, signOpts); err != nil {
   104  			return err
   105  		}
   106  	default:
   107  		return errors.New("tls: unknown signature algorithm")
   108  	}
   109  	return nil
   110  }
   111  
   112  const (
   113  	serverSignatureContext = "TLS 1.3, server CertificateVerify\x00"
   114  	clientSignatureContext = "TLS 1.3, client CertificateVerify\x00"
   115  )
   116  
   117  var signaturePadding = []byte{
   118  	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   119  	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   120  	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   121  	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   122  	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   123  	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   124  	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   125  	0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   126  }
   127  
   128  // writeSignedMessage writes the content to be signed by certificate keys in TLS
   129  // 1.3 to sigHash. See RFC 8446, Section 4.4.3.
   130  func writeSignedMessage(sigHash io.Writer, context string, transcript hash.Hash) {
   131  	sigHash.Write(signaturePadding)
   132  	io.WriteString(sigHash, context)
   133  	sigHash.Write(transcript.Sum(nil))
   134  }
   135  
   136  // signatureSchemesForCertificate returns the list of supported SignatureSchemes
   137  // for a given certificate, based on the public key and the protocol version. It
   138  // does not support the crypto.Decrypter interface, so shouldn't be used on the
   139  // server side in TLS 1.2 and earlier.
   140  func signatureSchemesForCertificate(version uint16, cert *Certificate) []SignatureScheme {
   141  	priv, ok := cert.PrivateKey.(crypto.Signer)
   142  	if !ok {
   143  		return nil
   144  	}
   145  
   146  	switch pub := priv.Public().(type) {
   147  	case *ecdsa.PublicKey:
   148  		if version != VersionTLS13 {
   149  			// In TLS 1.2 and earlier, ECDSA algorithms are not
   150  			// constrained to a single curve.
   151  			return []SignatureScheme{
   152  				ECDSAWithP256AndSHA256,
   153  				ECDSAWithP384AndSHA384,
   154  				ECDSAWithP521AndSHA512,
   155  				ECDSAWithSHA1,
   156  			}
   157  		}
   158  		switch pub.Curve {
   159  		case elliptic.P256():
   160  			return []SignatureScheme{ECDSAWithP256AndSHA256}
   161  		case elliptic.P384():
   162  			return []SignatureScheme{ECDSAWithP384AndSHA384}
   163  		case elliptic.P521():
   164  			return []SignatureScheme{ECDSAWithP521AndSHA512}
   165  		default:
   166  			return nil
   167  		}
   168  	case *rsa.PublicKey:
   169  		if version != VersionTLS13 {
   170  			return []SignatureScheme{
   171  				PSSWithSHA256,
   172  				PSSWithSHA384,
   173  				PSSWithSHA512,
   174  				PKCS1WithSHA256,
   175  				PKCS1WithSHA384,
   176  				PKCS1WithSHA512,
   177  				PKCS1WithSHA1,
   178  			}
   179  		}
   180  		// RSA keys with RSA-PSS OID are not supported by crypto/x509.
   181  		return []SignatureScheme{
   182  			PSSWithSHA256,
   183  			PSSWithSHA384,
   184  			PSSWithSHA512,
   185  		}
   186  	default:
   187  		return nil
   188  	}
   189  }
   190  
   191  // unsupportedCertificateError returns a helpful error for certificates with
   192  // an unsupported private key.
   193  func unsupportedCertificateError(cert *Certificate) error {
   194  	switch cert.PrivateKey.(type) {
   195  	case rsa.PrivateKey, ecdsa.PrivateKey:
   196  		return fmt.Errorf("tls: unsupported certificate: private key is %T, expected *%T",
   197  			cert.PrivateKey, cert.PrivateKey)
   198  	}
   199  
   200  	signer, ok := cert.PrivateKey.(crypto.Signer)
   201  	if !ok {
   202  		return fmt.Errorf("tls: certificate private key (%T) does not implement crypto.Signer",
   203  			cert.PrivateKey)
   204  	}
   205  
   206  	switch pub := signer.Public().(type) {
   207  	case *ecdsa.PublicKey:
   208  		switch pub.Curve {
   209  		case elliptic.P256():
   210  		case elliptic.P384():
   211  		case elliptic.P521():
   212  		default:
   213  			return fmt.Errorf("tls: unsupported certificate curve (%s)", pub.Curve.Params().Name)
   214  		}
   215  	case *rsa.PublicKey:
   216  	default:
   217  		return fmt.Errorf("tls: unsupported certificate key (%T)", pub)
   218  	}
   219  
   220  	return fmt.Errorf("tls: internal error: unsupported key (%T)", cert.PrivateKey)
   221  }