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