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