]> Cypherpunks.ru repositories - gostls13.git/blob - src/crypto/tls/auth.go
[dev.boringcrypto] all: merge master into dev.boringcrypto
[gostls13.git] / 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         "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.
138 func signatureSchemesForCertificate(cert *Certificate) []SignatureScheme {
139         priv, ok := cert.PrivateKey.(crypto.Signer)
140         if !ok {
141                 return nil
142         }
143
144         switch priv := priv.Public().(type) {
145         case *ecdsa.PublicKey:
146                 switch priv.Curve {
147                 case elliptic.P256():
148                         return []SignatureScheme{ECDSAWithP256AndSHA256}
149                 case elliptic.P384():
150                         return []SignatureScheme{ECDSAWithP384AndSHA384}
151                 case elliptic.P521():
152                         return []SignatureScheme{ECDSAWithP521AndSHA512}
153                 default:
154                         return nil
155                 }
156         case *rsa.PublicKey:
157                 // RSA keys with RSA-PSS OID are not supported by crypto/x509.
158                 return []SignatureScheme{
159                         PSSWithSHA256,
160                         PSSWithSHA384,
161                         PSSWithSHA512,
162                 }
163         default:
164                 return nil
165         }
166 }