1
2
3
4
5 package tls
6
7 import (
8 "bytes"
9 "crypto"
10 "crypto/ecdsa"
11 "crypto/ed25519"
12 "crypto/elliptic"
13 "crypto/mldsa"
14 "crypto/rsa"
15 "errors"
16 "fmt"
17 "hash"
18 "io"
19 "slices"
20 )
21
22
23 func verifyHandshakeSignature(sigType uint8, pubkey crypto.PublicKey, hashFunc crypto.Hash, signed, sig []byte) error {
24 if hashFunc != directSigning {
25 if !hashFunc.Available() {
26 return fmt.Errorf("hash function unavailable: %v", hashFunc)
27 }
28 h := hashFunc.New()
29 h.Write(signed)
30 signed = h.Sum(nil)
31 }
32 switch sigType {
33 case signatureECDSA:
34 pubKey, ok := pubkey.(*ecdsa.PublicKey)
35 if !ok {
36 return fmt.Errorf("expected an ECDSA public key, got %T", pubkey)
37 }
38 if !ecdsa.VerifyASN1(pubKey, signed, sig) {
39 return errors.New("ECDSA verification failure")
40 }
41 case signatureEd25519:
42 pubKey, ok := pubkey.(ed25519.PublicKey)
43 if !ok {
44 return fmt.Errorf("expected an Ed25519 public key, got %T", pubkey)
45 }
46 if !ed25519.Verify(pubKey, signed, sig) {
47 return errors.New("Ed25519 verification failure")
48 }
49 case signatureMLDSA:
50 pubKey, ok := pubkey.(*mldsa.PublicKey)
51 if !ok {
52 return fmt.Errorf("expected an ML-DSA public key, got %T", pubkey)
53 }
54 if err := mldsa.Verify(pubKey, signed, sig, nil); err != nil {
55 return fmt.Errorf("ML-DSA verification failure: %w", err)
56 }
57 case signaturePKCS1v15:
58 pubKey, ok := pubkey.(*rsa.PublicKey)
59 if !ok {
60 return fmt.Errorf("expected an RSA public key, got %T", pubkey)
61 }
62 if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, signed, sig); err != nil {
63 return err
64 }
65 case signatureRSAPSS:
66 pubKey, ok := pubkey.(*rsa.PublicKey)
67 if !ok {
68 return fmt.Errorf("expected an RSA public key, got %T", pubkey)
69 }
70 signOpts := &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash}
71 if err := rsa.VerifyPSS(pubKey, hashFunc, signed, sig, signOpts); err != nil {
72 return err
73 }
74 default:
75 return errors.New("internal error: unknown signature type")
76 }
77 return nil
78 }
79
80
81
82 func verifyLegacyHandshakeSignature(sigType uint8, pubkey crypto.PublicKey, hashFunc crypto.Hash, hashed, sig []byte) error {
83 switch sigType {
84 case signatureECDSA:
85 pubKey, ok := pubkey.(*ecdsa.PublicKey)
86 if !ok {
87 return fmt.Errorf("expected an ECDSA public key, got %T", pubkey)
88 }
89 if !ecdsa.VerifyASN1(pubKey, hashed, sig) {
90 return errors.New("ECDSA verification failure")
91 }
92 case signaturePKCS1v15:
93 pubKey, ok := pubkey.(*rsa.PublicKey)
94 if !ok {
95 return fmt.Errorf("expected an RSA public key, got %T", pubkey)
96 }
97 if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, hashed, sig); err != nil {
98 return err
99 }
100 default:
101 return errors.New("internal error: unknown signature type")
102 }
103 return nil
104 }
105
106 const (
107 serverSignatureContext = "TLS 1.3, server CertificateVerify\x00"
108 clientSignatureContext = "TLS 1.3, client CertificateVerify\x00"
109 )
110
111 var signaturePadding = []byte{
112 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
113 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
114 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
115 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
116 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
117 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
118 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
119 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
120 }
121
122
123
124 func signedMessage(context string, transcript hash.Hash) []byte {
125 const maxSize = 64 + len(serverSignatureContext) + 512/8
126 b := bytes.NewBuffer(make([]byte, 0, maxSize))
127 b.Write(signaturePadding)
128 io.WriteString(b, context)
129 b.Write(transcript.Sum(nil))
130 return b.Bytes()
131 }
132
133
134
135 func typeAndHashFromSignatureScheme(signatureAlgorithm SignatureScheme) (sigType uint8, hash crypto.Hash, err error) {
136 switch signatureAlgorithm {
137 case PKCS1WithSHA1, PKCS1WithSHA256, PKCS1WithSHA384, PKCS1WithSHA512:
138 sigType = signaturePKCS1v15
139 case PSSWithSHA256, PSSWithSHA384, PSSWithSHA512:
140 sigType = signatureRSAPSS
141 case ECDSAWithSHA1, ECDSAWithP256AndSHA256, ECDSAWithP384AndSHA384, ECDSAWithP521AndSHA512:
142 sigType = signatureECDSA
143 case Ed25519:
144 sigType = signatureEd25519
145 case MLDSA44, MLDSA65, MLDSA87:
146 sigType = signatureMLDSA
147 default:
148 return 0, 0, fmt.Errorf("unsupported signature algorithm: %v", signatureAlgorithm)
149 }
150 switch signatureAlgorithm {
151 case PKCS1WithSHA1, ECDSAWithSHA1:
152 hash = crypto.SHA1
153 case PKCS1WithSHA256, PSSWithSHA256, ECDSAWithP256AndSHA256:
154 hash = crypto.SHA256
155 case PKCS1WithSHA384, PSSWithSHA384, ECDSAWithP384AndSHA384:
156 hash = crypto.SHA384
157 case PKCS1WithSHA512, PSSWithSHA512, ECDSAWithP521AndSHA512:
158 hash = crypto.SHA512
159 case Ed25519:
160 hash = directSigning
161 case MLDSA44, MLDSA65, MLDSA87:
162 hash = directSigning
163 default:
164 return 0, 0, fmt.Errorf("unsupported signature algorithm: %v", signatureAlgorithm)
165 }
166 return sigType, hash, nil
167 }
168
169
170
171
172 func legacyTypeAndHashFromPublicKey(pub crypto.PublicKey) (sigType uint8, hash crypto.Hash, err error) {
173 switch pub.(type) {
174 case *rsa.PublicKey:
175 return signaturePKCS1v15, crypto.MD5SHA1, nil
176 case *ecdsa.PublicKey:
177 return signatureECDSA, crypto.SHA1, nil
178 case ed25519.PublicKey:
179
180
181
182
183 return 0, 0, fmt.Errorf("tls: Ed25519 public keys are not supported before TLS 1.2")
184 case *mldsa.PublicKey:
185 return 0, 0, fmt.Errorf("tls: ML-DSA public keys are not supported before TLS 1.3")
186 default:
187 return 0, 0, fmt.Errorf("tls: unsupported public key: %T", pub)
188 }
189 }
190
191 var rsaSignatureSchemes = []struct {
192 scheme SignatureScheme
193 minModulusBytes int
194 }{
195
196
197 {PSSWithSHA256, crypto.SHA256.Size()*2 + 2},
198 {PSSWithSHA384, crypto.SHA384.Size()*2 + 2},
199 {PSSWithSHA512, crypto.SHA512.Size()*2 + 2},
200
201
202 {PKCS1WithSHA256, 19 + crypto.SHA256.Size() + 11},
203 {PKCS1WithSHA384, 19 + crypto.SHA384.Size() + 11},
204 {PKCS1WithSHA512, 19 + crypto.SHA512.Size() + 11},
205 {PKCS1WithSHA1, 15 + crypto.SHA1.Size() + 11},
206 }
207
208 func signatureSchemesForPublicKey(version uint16, pub crypto.PublicKey) []SignatureScheme {
209 switch pub := pub.(type) {
210 case *ecdsa.PublicKey:
211 if version < VersionTLS13 {
212
213
214 return []SignatureScheme{
215 ECDSAWithP256AndSHA256,
216 ECDSAWithP384AndSHA384,
217 ECDSAWithP521AndSHA512,
218 ECDSAWithSHA1,
219 }
220 }
221 switch pub.Curve {
222 case elliptic.P256():
223 return []SignatureScheme{ECDSAWithP256AndSHA256}
224 case elliptic.P384():
225 return []SignatureScheme{ECDSAWithP384AndSHA384}
226 case elliptic.P521():
227 return []SignatureScheme{ECDSAWithP521AndSHA512}
228 default:
229 return nil
230 }
231 case *rsa.PublicKey:
232 size := pub.Size()
233 sigAlgs := make([]SignatureScheme, 0, len(rsaSignatureSchemes))
234 for _, candidate := range rsaSignatureSchemes {
235 if size >= candidate.minModulusBytes {
236 sigAlgs = append(sigAlgs, candidate.scheme)
237 }
238 }
239 return sigAlgs
240 case ed25519.PublicKey:
241 return []SignatureScheme{Ed25519}
242 case *mldsa.PublicKey:
243 switch pub.Parameters() {
244 case mldsa.MLDSA44():
245 return []SignatureScheme{MLDSA44}
246 case mldsa.MLDSA65():
247 return []SignatureScheme{MLDSA65}
248 case mldsa.MLDSA87():
249 return []SignatureScheme{MLDSA87}
250 default:
251 panic("tls: internal error: unknown ML-DSA parameter set: " + pub.Parameters().String())
252 }
253 default:
254 return nil
255 }
256 }
257
258
259
260
261 func selectSignatureScheme(vers uint16, c *Certificate, peerAlgs []SignatureScheme) (SignatureScheme, error) {
262 priv, ok := c.PrivateKey.(crypto.Signer)
263 if !ok {
264 return 0, unsupportedCertificateError(c)
265 }
266 supportedAlgs := signatureSchemesForPublicKey(vers, priv.Public())
267 if c.SupportedSignatureAlgorithms != nil {
268 supportedAlgs = slices.DeleteFunc(supportedAlgs, func(sigAlg SignatureScheme) bool {
269 return !isSupportedSignatureAlgorithm(sigAlg, c.SupportedSignatureAlgorithms)
270 })
271 }
272
273
274 supportedAlgs = slices.DeleteFunc(supportedAlgs, func(sigAlg SignatureScheme) bool {
275 return isDisabledSignatureAlgorithm(vers, sigAlg, false)
276 })
277 if len(supportedAlgs) == 0 {
278 return 0, unsupportedCertificateError(c)
279 }
280 if len(peerAlgs) == 0 && vers == VersionTLS12 {
281
282
283
284
285 if tlssha1.Value() != "1" {
286 return 0, errors.New("tls: missing signature_algorithms from TLS 1.2 peer")
287 }
288 peerAlgs = []SignatureScheme{PKCS1WithSHA1, ECDSAWithSHA1}
289 }
290
291
292 for _, preferredAlg := range peerAlgs {
293 if isSupportedSignatureAlgorithm(preferredAlg, supportedAlgs) {
294 return preferredAlg, nil
295 }
296 }
297 return 0, errors.New("tls: peer doesn't support any of the certificate's signature algorithms")
298 }
299
300
301
302 func unsupportedCertificateError(cert *Certificate) error {
303 switch cert.PrivateKey.(type) {
304 case rsa.PrivateKey, ecdsa.PrivateKey:
305 return fmt.Errorf("tls: unsupported certificate: private key is %T, expected *%T",
306 cert.PrivateKey, cert.PrivateKey)
307 case *ed25519.PrivateKey:
308 return fmt.Errorf("tls: unsupported certificate: private key is *ed25519.PrivateKey, expected ed25519.PrivateKey")
309 }
310
311 signer, ok := cert.PrivateKey.(crypto.Signer)
312 if !ok {
313 return fmt.Errorf("tls: certificate private key (%T) does not implement crypto.Signer",
314 cert.PrivateKey)
315 }
316
317 switch pub := signer.Public().(type) {
318 case *ecdsa.PublicKey:
319 switch pub.Curve {
320 case elliptic.P256():
321 case elliptic.P384():
322 case elliptic.P521():
323 default:
324 return fmt.Errorf("tls: unsupported certificate curve (%s)", pub.Curve.Params().Name)
325 }
326 case *rsa.PublicKey:
327 return fmt.Errorf("tls: certificate RSA key size too small for supported signature algorithms")
328 case ed25519.PublicKey:
329 case *mldsa.PublicKey:
330 return errors.New("tls: ML-DSA certificates require TLS 1.3")
331 default:
332 return fmt.Errorf("tls: unsupported certificate key (%T)", pub)
333 }
334
335 if cert.SupportedSignatureAlgorithms != nil {
336 return fmt.Errorf("tls: peer doesn't support the certificate custom signature algorithms")
337 }
338
339 return fmt.Errorf("tls: internal error: unsupported key (%T)", cert.PrivateKey)
340 }
341
View as plain text