Source file
src/crypto/tls/certificates_generator_test.go
1
2
3
4
5 package tls
6
7
8
9 import (
10 "bytes"
11 "crypto/ecdsa"
12 "crypto/ed25519"
13 "crypto/elliptic"
14 icryptotest "crypto/internal/cryptotest"
15 "crypto/mldsa"
16 "crypto/rand"
17 "crypto/rsa"
18 "crypto/x509"
19 "crypto/x509/pkix"
20 "encoding/pem"
21 "flag"
22 "fmt"
23 "internal/testenv"
24 "math/big"
25 "os"
26 "strings"
27 "testing"
28 "testing/cryptotest"
29 "time"
30 )
31
32 var generate = flag.Bool("generate", false, "regenerate certificates_test.go")
33
34 func TestGenerateCertificates(t *testing.T) {
35 testenv.MustHaveSource(t)
36
37 icryptotest.MustMinimumFIPS140ModuleVersion(t, "v1.28.0")
38 if testing.Short() && !*generate {
39 t.Skip("set -generate to regenerate certificates_test.go, or run without -short to check")
40 }
41
42
43 testenv.SetGODEBUG(t, "rsa1024min=0")
44
45 cryptotest.SetGlobalRandom(t, 0)
46
47 notBefore := time.Unix(1476984729, 0).Add(-100 * 24 * time.Hour)
48 notAfter := time.Unix(1476984729, 0).Add(100 * 24 * time.Hour)
49 serial := int64(0)
50 nextSerial := func() *big.Int {
51 serial++
52 return big.NewInt(serial)
53 }
54
55
56 rootKey, err := rsa.GenerateKey(rand.Reader, 2048)
57 if err != nil {
58 t.Fatal(err)
59 }
60 rootTemplate := &x509.Certificate{
61 SerialNumber: nextSerial(),
62 Subject: pkix.Name{CommonName: "Root"},
63 NotBefore: notBefore,
64 NotAfter: notAfter,
65 KeyUsage: x509.KeyUsageCertSign,
66 BasicConstraintsValid: true,
67 IsCA: true,
68 }
69 rootDER, err := x509.CreateCertificate(rand.Reader, rootTemplate, rootTemplate, &rootKey.PublicKey, rootKey)
70 if err != nil {
71 t.Fatal(err)
72 }
73 rootCert, err := x509.ParseCertificate(rootDER)
74 if err != nil {
75 t.Fatal(err)
76 }
77
78
79 clientRootKey, err := rsa.GenerateKey(rand.Reader, 2048)
80 if err != nil {
81 t.Fatal(err)
82 }
83 clientRootTemplate := &x509.Certificate{
84 SerialNumber: nextSerial(),
85 Subject: pkix.Name{CommonName: "Client Root"},
86 NotBefore: notBefore,
87 NotAfter: notAfter,
88 KeyUsage: x509.KeyUsageCertSign,
89 BasicConstraintsValid: true,
90 IsCA: true,
91 }
92 clientRootDER, err := x509.CreateCertificate(rand.Reader, clientRootTemplate, clientRootTemplate, &clientRootKey.PublicKey, clientRootKey)
93 if err != nil {
94 t.Fatal(err)
95 }
96 clientRootCert, err := x509.ParseCertificate(clientRootDER)
97 if err != nil {
98 t.Fatal(err)
99 }
100
101
102 serverLeaf := func(cn string, san string) *x509.Certificate {
103 return &x509.Certificate{
104 SerialNumber: nextSerial(),
105 Subject: pkix.Name{CommonName: cn},
106 NotBefore: notBefore,
107 NotAfter: notAfter,
108 KeyUsage: x509.KeyUsageDigitalSignature,
109 ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
110 BasicConstraintsValid: true,
111 DNSNames: []string{san},
112 }
113 }
114 clientLeaf := func(cn string, san string) *x509.Certificate {
115 return &x509.Certificate{
116 SerialNumber: nextSerial(),
117 Subject: pkix.Name{CommonName: cn},
118 NotBefore: notBefore,
119 NotAfter: notAfter,
120 KeyUsage: x509.KeyUsageDigitalSignature,
121 ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
122 BasicConstraintsValid: true,
123 DNSNames: []string{san},
124 }
125 }
126
127 type certKeyPair struct {
128 name string
129 comment string
130 certPEM string
131 keyPEM string
132 keyType string
133 }
134 var pairs []certKeyPair
135
136 emit := func(name, comment string, certDER []byte, key any) {
137 keyDER, err := x509.MarshalPKCS8PrivateKey(key)
138 if err != nil {
139 t.Fatal(err)
140 }
141 certPEM := string(pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER}))
142 keyPEM := string(pem.EncodeToMemory(&pem.Block{Type: "TESTING KEY", Bytes: keyDER}))
143 pairs = append(pairs, certKeyPair{name, comment, strings.TrimSpace(certPEM), strings.TrimSpace(keyPEM), fmt.Sprintf("%T", key)})
144 }
145
146
147 emit("testRoot", "Self-signed RSA 2048 root CA, CN=Root.", rootDER, rootKey)
148 emit("testClientRoot", "Self-signed RSA 2048 root CA, CN=Client Root.", clientRootDER, clientRootKey)
149
150
151
152
153 ecdsaP256Key, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
154 if err != nil {
155 t.Fatal(err)
156 }
157 tmpl := serverLeaf("ECDSA P-256", "test.golang.example")
158 der, err := x509.CreateCertificate(rand.Reader, tmpl, rootCert, &ecdsaP256Key.PublicKey, rootKey)
159 if err != nil {
160 t.Fatal(err)
161 }
162 emit("testECDSAP256", "ECDSA P-256 server leaf, SAN=test.golang.example, issued by Root.", der, ecdsaP256Key)
163
164
165 rsa2048Key, err := rsa.GenerateKey(rand.Reader, 2048)
166 if err != nil {
167 t.Fatal(err)
168 }
169 tmpl = serverLeaf("RSA 2048", "test.golang.example")
170 der, err = x509.CreateCertificate(rand.Reader, tmpl, rootCert, &rsa2048Key.PublicKey, rootKey)
171 if err != nil {
172 t.Fatal(err)
173 }
174 emit("testRSA2048", "RSA 2048 server leaf, SAN=test.golang.example, issued by Root.", der, rsa2048Key)
175
176
177 ecdsaP384Key, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
178 if err != nil {
179 t.Fatal(err)
180 }
181 tmpl = serverLeaf("ECDSA P-384", "test.golang.example")
182 der, err = x509.CreateCertificate(rand.Reader, tmpl, rootCert, &ecdsaP384Key.PublicKey, rootKey)
183 if err != nil {
184 t.Fatal(err)
185 }
186 emit("testECDSAP384", "ECDSA P-384 server leaf, SAN=test.golang.example, issued by Root.", der, ecdsaP384Key)
187
188
189 ecdsaP521Key, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
190 if err != nil {
191 t.Fatal(err)
192 }
193 tmpl = serverLeaf("ECDSA P-521", "test.golang.example")
194 der, err = x509.CreateCertificate(rand.Reader, tmpl, rootCert, &ecdsaP521Key.PublicKey, rootKey)
195 if err != nil {
196 t.Fatal(err)
197 }
198 emit("testECDSAP521", "ECDSA P-521 server leaf, SAN=test.golang.example, issued by Root.", der, ecdsaP521Key)
199
200
201 ed25519Pub, ed25519Key, err := ed25519.GenerateKey(rand.Reader)
202 if err != nil {
203 t.Fatal(err)
204 }
205 tmpl = serverLeaf("Ed25519", "test.golang.example")
206 der, err = x509.CreateCertificate(rand.Reader, tmpl, rootCert, ed25519Pub, rootKey)
207 if err != nil {
208 t.Fatal(err)
209 }
210 emit("testEd25519", "Ed25519 server leaf, SAN=test.golang.example, issued by Root.", der, ed25519Key)
211
212
213
214
215 rsaPSSKey, err := rsa.GenerateKey(rand.Reader, 2048)
216 if err != nil {
217 t.Fatal(err)
218 }
219 tmpl = serverLeaf("RSA-PSS", "test.golang.example")
220 tmpl.SignatureAlgorithm = x509.SHA512WithRSAPSS
221 der, err = x509.CreateCertificate(rand.Reader, tmpl, rootCert, &rsaPSSKey.PublicKey, rootKey)
222 if err != nil {
223 t.Fatal(err)
224 }
225 emit("testRSAPSS", "RSA 2048 server leaf, SAN=test.golang.example, issued by Root.\n\t// Signature algorithm is SHA512WithRSAPSS (rsaEncryption SPKI, rsassaPss signature).", der, rsaPSSKey)
226
227
228
229
230 rsa1024Key, err := rsa.GenerateKey(rand.Reader, 1024)
231 if err != nil {
232 t.Fatal(err)
233 }
234 tmpl = serverLeaf("RSA 1024", "test.golang.example")
235 der, err = x509.CreateCertificate(rand.Reader, tmpl, rootCert, &rsa1024Key.PublicKey, rootKey)
236 if err != nil {
237 t.Fatal(err)
238 }
239 emit("testRSA1024", "RSA 1024 server leaf, SAN=test.golang.example, issued by Root.\n\t// Key is too small for rsa_pss_rsae_sha512; used by TestHandshakeServerRSAPSS.", der, rsa1024Key)
240
241
242
243
244 rsa512Key, err := rsa.GenerateKey(rand.Reader, 512)
245 if err != nil {
246 t.Fatal(err)
247 }
248 tmpl = serverLeaf("RSA 512", "test.golang.example")
249 der, err = x509.CreateCertificate(rand.Reader, tmpl, rootCert, &rsa512Key.PublicKey, rootKey)
250 if err != nil {
251 t.Fatal(err)
252 }
253 emit("testRSA512", "RSA 512 server leaf, SAN=test.golang.example, issued by Root.\n\t// Key is too small for any rsa_pss_rsae_*; used by TestKeyTooSmallForRSAPSS.", der, rsa512Key)
254
255
256 sniKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
257 if err != nil {
258 t.Fatal(err)
259 }
260 tmpl = serverLeaf("different.example.com", "different.example.com")
261 der, err = x509.CreateCertificate(rand.Reader, tmpl, rootCert, &sniKey.PublicKey, rootKey)
262 if err != nil {
263 t.Fatal(err)
264 }
265 emit("testSNI", "ECDSA P-256 server leaf, SAN=different.example.com, issued by Root.", der, sniKey)
266
267
268
269 clientRSAKey, err := rsa.GenerateKey(rand.Reader, 2048)
270 if err != nil {
271 t.Fatal(err)
272 }
273 tmpl = clientLeaf("clientAuth RSA 2048", "test.golang.example")
274 der, err = x509.CreateCertificate(rand.Reader, tmpl, clientRootCert, &clientRSAKey.PublicKey, clientRootKey)
275 if err != nil {
276 t.Fatal(err)
277 }
278 emit("testClientRSA2048", "RSA 2048 client leaf, SAN=test.golang.example, issued by Client Root.", der, clientRSAKey)
279
280 clientECDSAKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
281 if err != nil {
282 t.Fatal(err)
283 }
284 tmpl = clientLeaf("clientAuth ECDSA P-256", "test.golang.example")
285 der, err = x509.CreateCertificate(rand.Reader, tmpl, clientRootCert, &clientECDSAKey.PublicKey, clientRootKey)
286 if err != nil {
287 t.Fatal(err)
288 }
289 emit("testClientECDSAP256", "ECDSA P-256 client leaf, SAN=test.golang.example, issued by Client Root.", der, clientECDSAKey)
290
291 clientEd25519Pub, clientEd25519Key, err := ed25519.GenerateKey(rand.Reader)
292 if err != nil {
293 t.Fatal(err)
294 }
295 tmpl = clientLeaf("clientAuth Ed25519", "test.golang.example")
296 der, err = x509.CreateCertificate(rand.Reader, tmpl, clientRootCert, clientEd25519Pub, clientRootKey)
297 if err != nil {
298 t.Fatal(err)
299 }
300 emit("testClientEd25519", "Ed25519 client leaf, SAN=test.golang.example, issued by Client Root.", der, clientEd25519Key)
301
302
303
304 clientRSAPSSKey, err := rsa.GenerateKey(rand.Reader, 2048)
305 if err != nil {
306 t.Fatal(err)
307 }
308 tmpl = clientLeaf("clientAuth RSA-PSS", "test.golang.example")
309 tmpl.SignatureAlgorithm = x509.SHA512WithRSAPSS
310 der, err = x509.CreateCertificate(rand.Reader, tmpl, clientRootCert, &clientRSAPSSKey.PublicKey, clientRootKey)
311 if err != nil {
312 t.Fatal(err)
313 }
314 emit("testClientRSAPSS", "RSA 2048 client leaf, SAN=test.golang.example, issued by Client Root.\n\t// Signature algorithm is SHA512WithRSAPSS (rsaEncryption SPKI, rsassaPss signature).", der, clientRSAPSSKey)
315
316
317 mldsa44Key, err := mldsa.GenerateKey(mldsa.MLDSA44())
318 if err != nil {
319 t.Fatal(err)
320 }
321 tmpl = serverLeaf("ML-DSA-44", "test.golang.example")
322 der, err = x509.CreateCertificate(rand.Reader, tmpl, rootCert, mldsa44Key.PublicKey(), rootKey)
323 if err != nil {
324 t.Fatal(err)
325 }
326 emit("testMLDSA44", "ML-DSA-44 server leaf, SAN=test.golang.example, issued by Root.", der, mldsa44Key)
327
328
329 mldsa65Key, err := mldsa.GenerateKey(mldsa.MLDSA65())
330 if err != nil {
331 t.Fatal(err)
332 }
333 tmpl = serverLeaf("ML-DSA-65", "test.golang.example")
334 der, err = x509.CreateCertificate(rand.Reader, tmpl, rootCert, mldsa65Key.PublicKey(), rootKey)
335 if err != nil {
336 t.Fatal(err)
337 }
338 emit("testMLDSA65", "ML-DSA-65 server leaf, SAN=test.golang.example, issued by Root.", der, mldsa65Key)
339
340
341 mldsa87Key, err := mldsa.GenerateKey(mldsa.MLDSA87())
342 if err != nil {
343 t.Fatal(err)
344 }
345 tmpl = serverLeaf("ML-DSA-87", "test.golang.example")
346 der, err = x509.CreateCertificate(rand.Reader, tmpl, rootCert, mldsa87Key.PublicKey(), rootKey)
347 if err != nil {
348 t.Fatal(err)
349 }
350 emit("testMLDSA87", "ML-DSA-87 server leaf, SAN=test.golang.example, issued by Root.", der, mldsa87Key)
351
352
353 clientMLDSA44Key, err := mldsa.GenerateKey(mldsa.MLDSA44())
354 if err != nil {
355 t.Fatal(err)
356 }
357 tmpl = clientLeaf("clientAuth ML-DSA-44", "test.golang.example")
358 der, err = x509.CreateCertificate(rand.Reader, tmpl, clientRootCert, clientMLDSA44Key.PublicKey(), clientRootKey)
359 if err != nil {
360 t.Fatal(err)
361 }
362 emit("testClientMLDSA44", "ML-DSA-44 client leaf, SAN=test.golang.example, issued by Client Root.", der, clientMLDSA44Key)
363
364
365 clientMLDSA65Key, err := mldsa.GenerateKey(mldsa.MLDSA65())
366 if err != nil {
367 t.Fatal(err)
368 }
369 tmpl = clientLeaf("clientAuth ML-DSA-65", "test.golang.example")
370 der, err = x509.CreateCertificate(rand.Reader, tmpl, clientRootCert, clientMLDSA65Key.PublicKey(), clientRootKey)
371 if err != nil {
372 t.Fatal(err)
373 }
374 emit("testClientMLDSA65", "ML-DSA-65 client leaf, SAN=test.golang.example, issued by Client Root.", der, clientMLDSA65Key)
375
376
377 clientMLDSA87Key, err := mldsa.GenerateKey(mldsa.MLDSA87())
378 if err != nil {
379 t.Fatal(err)
380 }
381 tmpl = clientLeaf("clientAuth ML-DSA-87", "test.golang.example")
382 der, err = x509.CreateCertificate(rand.Reader, tmpl, clientRootCert, clientMLDSA87Key.PublicKey(), clientRootKey)
383 if err != nil {
384 t.Fatal(err)
385 }
386 emit("testClientMLDSA87", "ML-DSA-87 client leaf, SAN=test.golang.example, issued by Client Root.", der, clientMLDSA87Key)
387
388
389 var buf bytes.Buffer
390 fmt.Fprint(&buf, `// Code generated by certificates_generator_test.go; DO NOT EDIT.
391 // To regenerate, run: go generate
392
393 package tls
394
395 import (
396 "crypto/ecdsa"
397 "crypto/ed25519"
398 "crypto/mldsa"
399 "crypto/rsa"
400 "crypto/x509"
401 "encoding/pem"
402 )
403
404 `)
405
406 fmt.Fprint(&buf, `var (
407 `)
408 for _, p := range pairs {
409 fmt.Fprintf(&buf, "\t// %s\n", p.comment)
410 fmt.Fprintf(&buf, "\t%sCert = parseTestCert(%sCertPEM, %sKeyPEM)\n",
411 p.name, p.name, p.name)
412
413
414
415 if p.keyType == "*mldsa.PrivateKey" {
416 fmt.Fprintf(&buf, "\t%sKey, _ = %sCert.PrivateKey.(%s)\n\n",
417 p.name, p.name, p.keyType)
418 } else {
419 fmt.Fprintf(&buf, "\t%sKey = %sCert.PrivateKey.(%s)\n\n",
420 p.name, p.name, p.keyType)
421 }
422 }
423 fmt.Fprint(&buf, ` // x509.CertPool containing testRootCert.
424 testRootCertPool = newTestCertPool(testRootCertPEM)
425 // x509.CertPool containing testClientRootCert.
426 testClientRootCertPool = newTestCertPool(testClientRootCertPEM)
427 )
428
429 `)
430
431 for _, p := range pairs {
432 fmt.Fprintf(&buf, "const %sCertPEM = `\n%s`\n\n", p.name, p.certPEM)
433 fmt.Fprintf(&buf, "const %sKeyPEM = `\n%s`\n\n", p.name, p.keyPEM)
434 }
435
436 fmt.Fprint(&buf, `func parseTestCert(certPEM, keyPEM string) Certificate {
437 var cert Certificate
438 block, _ := pem.Decode([]byte(certPEM))
439 if block == nil {
440 panic("failed to parse certificate PEM")
441 }
442 cert.Certificate = [][]byte{block.Bytes}
443 cert.Leaf, _ = x509.ParseCertificate(block.Bytes)
444 if cert.Leaf == nil {
445 panic("failed to parse certificate")
446 }
447 // Don't parse the private key for ML-DSA certificates with FIPS 140-3 module v1.0.0.
448 if cert.Leaf.PublicKeyAlgorithm != x509.UnknownPublicKeyAlgorithm {
449 block, _ = pem.Decode([]byte(keyPEM))
450 if block == nil {
451 panic("failed to parse key PEM")
452 }
453 cert.PrivateKey, _ = x509.ParsePKCS8PrivateKey(block.Bytes)
454 if cert.PrivateKey == nil {
455 panic("failed to parse private key")
456 }
457 }
458 return cert
459 }
460
461 func newTestCertPool(certPEM string) *x509.CertPool {
462 pool := x509.NewCertPool()
463 if !pool.AppendCertsFromPEM([]byte(certPEM)) {
464 panic("failed to parse certificate for pool")
465 }
466 return pool
467 }
468 `)
469
470 if *generate {
471 if err := os.WriteFile("certificates_test.go", buf.Bytes(), 0644); err != nil {
472 t.Fatal(err)
473 }
474 t.Log("wrote certificates_test.go")
475 } else {
476
477 existing, err := os.ReadFile("certificates_test.go")
478 if err != nil {
479 t.Fatal(err)
480 }
481 if !bytes.Equal(existing, buf.Bytes()) {
482 t.Fatal("certificates_test.go is out of date; run go generate to update it")
483 }
484 }
485 }
486
View as plain text