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

View as plain text