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.
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.
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) {
34 if tlsVersion < VersionTLS12 {
35 return 0, signaturePKCS1v15, crypto.MD5SHA1, nil
37 return PKCS1WithSHA1, signaturePKCS1v15, crypto.SHA1, nil
39 case *ecdsa.PublicKey:
40 return ECDSAWithSHA1, signatureECDSA, crypto.SHA1, nil
42 return 0, 0, 0, fmt.Errorf("tls: unsupported public key: %T", pubkey)
45 for _, sigAlg := range peerSigAlgs {
46 if !isSupportedSignatureAlgorithm(sigAlg, ourSigAlgs) {
49 hashAlg, err := hashFromSignatureScheme(sigAlg)
51 panic("tls: supported signature algorithm has an unknown hash function")
53 sigType := signatureFromSignatureScheme(sigAlg)
54 switch pubkey.(type) {
56 if sigType == signaturePKCS1v15 || sigType == signatureRSAPSS {
57 return sigAlg, sigType, hashAlg, nil
59 case *ecdsa.PublicKey:
60 if sigType == signatureECDSA {
61 return sigAlg, sigType, hashAlg, nil
64 return 0, 0, 0, fmt.Errorf("tls: unsupported public key: %T", pubkey)
67 return 0, 0, 0, errors.New("tls: peer doesn't support any common signature algorithms")
70 // verifyHandshakeSignature verifies a signature against pre-hashed handshake
72 func verifyHandshakeSignature(sigType uint8, pubkey crypto.PublicKey, hashFunc crypto.Hash, digest, sig []byte) error {
75 pubKey, ok := pubkey.(*ecdsa.PublicKey)
77 return errors.New("tls: ECDSA signing requires a ECDSA public key")
79 ecdsaSig := new(ecdsaSignature)
80 if _, err := asn1.Unmarshal(sig, ecdsaSig); err != nil {
83 if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
84 return errors.New("tls: ECDSA signature contained zero or negative values")
86 if !ecdsa.Verify(pubKey, digest, ecdsaSig.R, ecdsaSig.S) {
87 return errors.New("tls: ECDSA verification failure")
89 case signaturePKCS1v15:
90 pubKey, ok := pubkey.(*rsa.PublicKey)
92 return errors.New("tls: RSA signing requires a RSA public key")
94 if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, digest, sig); err != nil {
98 pubKey, ok := pubkey.(*rsa.PublicKey)
100 return errors.New("tls: RSA signing requires a RSA public key")
102 signOpts := &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash}
103 if err := rsa.VerifyPSS(pubKey, hashFunc, digest, sig, signOpts); err != nil {
107 return errors.New("tls: unknown signature algorithm")
113 serverSignatureContext = "TLS 1.3, server CertificateVerify\x00"
114 clientSignatureContext = "TLS 1.3, client CertificateVerify\x00"
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,
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))
136 // signatureSchemesForCertificate returns the list of supported SignatureSchemes
137 // for a given certificate, based on the public key.
138 func signatureSchemesForCertificate(cert *Certificate) []SignatureScheme {
139 priv, ok := cert.PrivateKey.(crypto.Signer)
144 switch priv := priv.Public().(type) {
145 case *ecdsa.PublicKey:
147 case elliptic.P256():
148 return []SignatureScheme{ECDSAWithP256AndSHA256}
149 case elliptic.P384():
150 return []SignatureScheme{ECDSAWithP384AndSHA384}
151 case elliptic.P521():
152 return []SignatureScheme{ECDSAWithP521AndSHA512}
157 // RSA keys with RSA-PSS OID are not supported by crypto/x509.
158 return []SignatureScheme{