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