• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2016 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
5package runner
6
7import (
8	"crypto"
9	"crypto/ecdsa"
10	"crypto/elliptic"
11	"crypto/md5"
12	"crypto/rsa"
13	"crypto/sha1"
14	_ "crypto/sha256"
15	_ "crypto/sha512"
16	"encoding/asn1"
17	"errors"
18	"fmt"
19	"math/big"
20)
21
22type signer interface {
23	supportsKey(key crypto.PrivateKey) bool
24	signMessage(key crypto.PrivateKey, config *Config, msg []byte) ([]byte, error)
25	verifyMessage(key crypto.PublicKey, msg, sig []byte) error
26}
27
28func selectSignatureAlgorithm(version uint16, key crypto.PrivateKey, config *Config, peerSigAlgs []signatureAlgorithm) (signatureAlgorithm, error) {
29	// If the client didn't specify any signature_algorithms extension then
30	// we can assume that it supports SHA1. See
31	// http://tools.ietf.org/html/rfc5246#section-7.4.1.4.1
32	if len(peerSigAlgs) == 0 {
33		peerSigAlgs = []signatureAlgorithm{signatureRSAPKCS1WithSHA1, signatureECDSAWithSHA1}
34	}
35
36	for _, sigAlg := range config.signSignatureAlgorithms() {
37		if !isSupportedSignatureAlgorithm(sigAlg, peerSigAlgs) {
38			continue
39		}
40
41		signer, err := getSigner(version, key, config, sigAlg)
42		if err != nil {
43			continue
44		}
45
46		if signer.supportsKey(key) {
47			return sigAlg, nil
48		}
49	}
50	return 0, errors.New("tls: no common signature algorithms")
51}
52
53func signMessage(version uint16, key crypto.PrivateKey, config *Config, sigAlg signatureAlgorithm, msg []byte) ([]byte, error) {
54	if config.Bugs.InvalidSignature {
55		newMsg := make([]byte, len(msg))
56		copy(newMsg, msg)
57		newMsg[0] ^= 0x80
58		msg = newMsg
59	}
60
61	signer, err := getSigner(version, key, config, sigAlg)
62	if err != nil {
63		return nil, err
64	}
65
66	return signer.signMessage(key, config, msg)
67}
68
69func verifyMessage(version uint16, key crypto.PublicKey, config *Config, sigAlg signatureAlgorithm, msg, sig []byte) error {
70	if version >= VersionTLS12 && !isSupportedSignatureAlgorithm(sigAlg, config.verifySignatureAlgorithms()) {
71		return errors.New("tls: unsupported signature algorithm")
72	}
73
74	signer, err := getSigner(version, key, config, sigAlg)
75	if err != nil {
76		return err
77	}
78
79	return signer.verifyMessage(key, msg, sig)
80}
81
82type rsaPKCS1Signer struct {
83	hash crypto.Hash
84}
85
86func (r *rsaPKCS1Signer) computeHash(msg []byte) []byte {
87	if r.hash == crypto.MD5SHA1 {
88		// crypto.MD5SHA1 is not a real hash function.
89		hashMD5 := md5.New()
90		hashMD5.Write(msg)
91		hashSHA1 := sha1.New()
92		hashSHA1.Write(msg)
93		return hashSHA1.Sum(hashMD5.Sum(nil))
94	}
95
96	h := r.hash.New()
97	h.Write(msg)
98	return h.Sum(nil)
99}
100
101func (r *rsaPKCS1Signer) supportsKey(key crypto.PrivateKey) bool {
102	_, ok := key.(*rsa.PrivateKey)
103	return ok
104}
105
106func (r *rsaPKCS1Signer) signMessage(key crypto.PrivateKey, config *Config, msg []byte) ([]byte, error) {
107	rsaKey, ok := key.(*rsa.PrivateKey)
108	if !ok {
109		return nil, errors.New("invalid key type for RSA-PKCS1")
110	}
111
112	return rsa.SignPKCS1v15(config.rand(), rsaKey, r.hash, r.computeHash(msg))
113}
114
115func (r *rsaPKCS1Signer) verifyMessage(key crypto.PublicKey, msg, sig []byte) error {
116	rsaKey, ok := key.(*rsa.PublicKey)
117	if !ok {
118		return errors.New("invalid key type for RSA-PKCS1")
119	}
120
121	return rsa.VerifyPKCS1v15(rsaKey, r.hash, r.computeHash(msg), sig)
122}
123
124type ecdsaSigner struct {
125	version uint16
126	config  *Config
127	curve   elliptic.Curve
128	hash    crypto.Hash
129}
130
131func (e *ecdsaSigner) isCurveValid(curve elliptic.Curve) bool {
132	if e.config.Bugs.SkipECDSACurveCheck {
133		return true
134	}
135	if e.version <= VersionTLS12 {
136		return true
137	}
138	return e.curve != nil && curve == e.curve
139}
140
141func (e *ecdsaSigner) supportsKey(key crypto.PrivateKey) bool {
142	ecdsaKey, ok := key.(*ecdsa.PrivateKey)
143	return ok && e.isCurveValid(ecdsaKey.Curve)
144}
145
146func maybeCorruptECDSAValue(n *big.Int, typeOfCorruption BadValue, limit *big.Int) *big.Int {
147	switch typeOfCorruption {
148	case BadValueNone:
149		return n
150	case BadValueNegative:
151		return new(big.Int).Neg(n)
152	case BadValueZero:
153		return big.NewInt(0)
154	case BadValueLimit:
155		return limit
156	case BadValueLarge:
157		bad := new(big.Int).Set(limit)
158		return bad.Lsh(bad, 20)
159	default:
160		panic("unknown BadValue type")
161	}
162}
163
164func (e *ecdsaSigner) signMessage(key crypto.PrivateKey, config *Config, msg []byte) ([]byte, error) {
165	ecdsaKey, ok := key.(*ecdsa.PrivateKey)
166	if !ok {
167		return nil, errors.New("invalid key type for ECDSA")
168	}
169	if !e.isCurveValid(ecdsaKey.Curve) {
170		return nil, errors.New("invalid curve for ECDSA")
171	}
172
173	h := e.hash.New()
174	h.Write(msg)
175	digest := h.Sum(nil)
176
177	r, s, err := ecdsa.Sign(config.rand(), ecdsaKey, digest)
178	if err != nil {
179		return nil, errors.New("failed to sign ECDHE parameters: " + err.Error())
180	}
181	order := ecdsaKey.Curve.Params().N
182	r = maybeCorruptECDSAValue(r, config.Bugs.BadECDSAR, order)
183	s = maybeCorruptECDSAValue(s, config.Bugs.BadECDSAS, order)
184	return asn1.Marshal(ecdsaSignature{r, s})
185}
186
187func (e *ecdsaSigner) verifyMessage(key crypto.PublicKey, msg, sig []byte) error {
188	ecdsaKey, ok := key.(*ecdsa.PublicKey)
189	if !ok {
190		return errors.New("invalid key type for ECDSA")
191	}
192	if !e.isCurveValid(ecdsaKey.Curve) {
193		return errors.New("invalid curve for ECDSA")
194	}
195
196	ecdsaSig := new(ecdsaSignature)
197	if _, err := asn1.Unmarshal(sig, ecdsaSig); err != nil {
198		return err
199	}
200	if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
201		return errors.New("ECDSA signature contained zero or negative values")
202	}
203
204	h := e.hash.New()
205	h.Write(msg)
206	if !ecdsa.Verify(ecdsaKey, h.Sum(nil), ecdsaSig.R, ecdsaSig.S) {
207		return errors.New("ECDSA verification failure")
208	}
209	return nil
210}
211
212var pssOptions = rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash}
213
214type rsaPSSSigner struct {
215	hash crypto.Hash
216}
217
218func (r *rsaPSSSigner) supportsKey(key crypto.PrivateKey) bool {
219	_, ok := key.(*rsa.PrivateKey)
220	return ok
221}
222
223func (r *rsaPSSSigner) signMessage(key crypto.PrivateKey, config *Config, msg []byte) ([]byte, error) {
224	rsaKey, ok := key.(*rsa.PrivateKey)
225	if !ok {
226		return nil, errors.New("invalid key type for RSA-PSS")
227	}
228
229	h := r.hash.New()
230	h.Write(msg)
231	return rsa.SignPSS(config.rand(), rsaKey, r.hash, h.Sum(nil), &pssOptions)
232}
233
234func (r *rsaPSSSigner) verifyMessage(key crypto.PublicKey, msg, sig []byte) error {
235	rsaKey, ok := key.(*rsa.PublicKey)
236	if !ok {
237		return errors.New("invalid key type for RSA-PSS")
238	}
239
240	h := r.hash.New()
241	h.Write(msg)
242	return rsa.VerifyPSS(rsaKey, r.hash, h.Sum(nil), sig, &pssOptions)
243}
244
245func getSigner(version uint16, key interface{}, config *Config, sigAlg signatureAlgorithm) (signer, error) {
246	// TLS 1.1 and below use legacy signature algorithms.
247	if version < VersionTLS12 {
248		switch key.(type) {
249		case *rsa.PrivateKey, *rsa.PublicKey:
250			return &rsaPKCS1Signer{crypto.MD5SHA1}, nil
251		case *ecdsa.PrivateKey, *ecdsa.PublicKey:
252			return &ecdsaSigner{version, config, nil, crypto.SHA1}, nil
253		default:
254			return nil, errors.New("unknown key type")
255		}
256	}
257
258	// TODO(davidben): Forbid RSASSA-PKCS1-v1_5 in TLS 1.3.
259	switch sigAlg {
260	case signatureRSAPKCS1WithMD5:
261		if version < VersionTLS13 || config.Bugs.IgnoreSignatureVersionChecks {
262			return &rsaPKCS1Signer{crypto.MD5}, nil
263		}
264	case signatureRSAPKCS1WithSHA1:
265		if version < VersionTLS13 || config.Bugs.IgnoreSignatureVersionChecks {
266			return &rsaPKCS1Signer{crypto.SHA1}, nil
267		}
268	case signatureRSAPKCS1WithSHA256:
269		if version < VersionTLS13 || config.Bugs.IgnoreSignatureVersionChecks {
270			return &rsaPKCS1Signer{crypto.SHA256}, nil
271		}
272	case signatureRSAPKCS1WithSHA384:
273		if version < VersionTLS13 || config.Bugs.IgnoreSignatureVersionChecks {
274			return &rsaPKCS1Signer{crypto.SHA384}, nil
275		}
276	case signatureRSAPKCS1WithSHA512:
277		if version < VersionTLS13 || config.Bugs.IgnoreSignatureVersionChecks {
278			return &rsaPKCS1Signer{crypto.SHA512}, nil
279		}
280	case signatureECDSAWithSHA1:
281		return &ecdsaSigner{version, config, nil, crypto.SHA1}, nil
282	case signatureECDSAWithP256AndSHA256:
283		return &ecdsaSigner{version, config, elliptic.P256(), crypto.SHA256}, nil
284	case signatureECDSAWithP384AndSHA384:
285		return &ecdsaSigner{version, config, elliptic.P384(), crypto.SHA384}, nil
286	case signatureECDSAWithP521AndSHA512:
287		return &ecdsaSigner{version, config, elliptic.P521(), crypto.SHA512}, nil
288	case signatureRSAPSSWithSHA256:
289		return &rsaPSSSigner{crypto.SHA256}, nil
290	case signatureRSAPSSWithSHA384:
291		return &rsaPSSSigner{crypto.SHA384}, nil
292	case signatureRSAPSSWithSHA512:
293		return &rsaPSSSigner{crypto.SHA512}, nil
294	}
295
296	return nil, fmt.Errorf("unsupported signature algorithm %04x", sigAlg)
297}
298