Source file
src/crypto/x509/boring_test.go
1
2
3
4
5
6
7 package x509
8
9 import (
10 "crypto/ecdsa"
11 "crypto/elliptic"
12 "crypto/internal/boring/fipstls"
13 "crypto/rand"
14 "crypto/rsa"
15 "crypto/x509/pkix"
16 "fmt"
17 "math/big"
18 "strings"
19 "testing"
20 "time"
21 )
22
23 const (
24 boringCertCA = iota
25 boringCertLeaf
26 boringCertFIPSOK = 0x80
27 )
28
29 func boringRSAKey(t *testing.T, size int) *rsa.PrivateKey {
30 t.Helper()
31 k, err := rsa.GenerateKey(rand.Reader, size)
32 if err != nil {
33 t.Fatal(err)
34 }
35 return k
36 }
37
38 func boringECDSAKey(t *testing.T, curve elliptic.Curve) *ecdsa.PrivateKey {
39 t.Helper()
40 k, err := ecdsa.GenerateKey(curve, rand.Reader)
41 if err != nil {
42 t.Fatal(err)
43 }
44 return k
45 }
46
47 type boringCertificate struct {
48 name string
49 org string
50 parentOrg string
51 der []byte
52 cert *Certificate
53 key interface{}
54 fipsOK bool
55 }
56
57 func TestBoringAllowCert(t *testing.T) {
58 R1 := testBoringCert(t, "R1", boringRSAKey(t, 2048), nil, boringCertCA|boringCertFIPSOK)
59 R2 := testBoringCert(t, "R2", boringRSAKey(t, 512), nil, boringCertCA)
60 R3 := testBoringCert(t, "R3", boringRSAKey(t, 4096), nil, boringCertCA|boringCertFIPSOK)
61
62 M1_R1 := testBoringCert(t, "M1_R1", boringECDSAKey(t, elliptic.P256()), R1, boringCertCA|boringCertFIPSOK)
63 M2_R1 := testBoringCert(t, "M2_R1", boringECDSAKey(t, elliptic.P224()), R1, boringCertCA)
64
65 I_R1 := testBoringCert(t, "I_R1", boringRSAKey(t, 3072), R1, boringCertCA|boringCertFIPSOK)
66 testBoringCert(t, "I_R2", I_R1.key, R2, boringCertCA|boringCertFIPSOK)
67 testBoringCert(t, "I_M1", I_R1.key, M1_R1, boringCertCA|boringCertFIPSOK)
68 testBoringCert(t, "I_M2", I_R1.key, M2_R1, boringCertCA|boringCertFIPSOK)
69
70 I_R3 := testBoringCert(t, "I_R3", boringRSAKey(t, 3072), R3, boringCertCA|boringCertFIPSOK)
71 testBoringCert(t, "I_R3", I_R3.key, R3, boringCertCA|boringCertFIPSOK)
72
73 testBoringCert(t, "L1_I", boringECDSAKey(t, elliptic.P384()), I_R1, boringCertLeaf|boringCertFIPSOK)
74 testBoringCert(t, "L2_I", boringRSAKey(t, 1024), I_R1, boringCertLeaf)
75 }
76
77 func testBoringCert(t *testing.T, name string, key interface{}, parent *boringCertificate, mode int) *boringCertificate {
78 org := name
79 parentOrg := ""
80 if i := strings.Index(org, "_"); i >= 0 {
81 org = org[:i]
82 parentOrg = name[i+1:]
83 }
84 tmpl := &Certificate{
85 SerialNumber: big.NewInt(1),
86 Subject: pkix.Name{
87 Organization: []string{org},
88 },
89 NotBefore: time.Unix(0, 0),
90 NotAfter: time.Unix(0, 0),
91
92 KeyUsage: KeyUsageKeyEncipherment | KeyUsageDigitalSignature,
93 ExtKeyUsage: []ExtKeyUsage{ExtKeyUsageServerAuth, ExtKeyUsageClientAuth},
94 BasicConstraintsValid: true,
95 }
96 if mode&^boringCertFIPSOK == boringCertLeaf {
97 tmpl.DNSNames = []string{"example.com"}
98 } else {
99 tmpl.IsCA = true
100 tmpl.KeyUsage |= KeyUsageCertSign
101 }
102
103 var pcert *Certificate
104 var pkey interface{}
105 if parent != nil {
106 pcert = parent.cert
107 pkey = parent.key
108 } else {
109 pcert = tmpl
110 pkey = key
111 }
112
113 var pub interface{}
114 var desc string
115 switch k := key.(type) {
116 case *rsa.PrivateKey:
117 pub = &k.PublicKey
118 desc = fmt.Sprintf("RSA-%d", k.N.BitLen())
119 case *ecdsa.PrivateKey:
120 pub = &k.PublicKey
121 desc = "ECDSA-" + k.Curve.Params().Name
122 default:
123 t.Fatalf("invalid key %T", key)
124 }
125
126 der, err := CreateCertificate(rand.Reader, tmpl, pcert, pub, pkey)
127 if err != nil {
128 t.Fatal(err)
129 }
130 cert, err := ParseCertificate(der)
131 if err != nil {
132 t.Fatal(err)
133 }
134
135
136 fipstls.Force()
137 defer fipstls.Abandon()
138
139 fipsOK := mode&boringCertFIPSOK != 0
140 if boringAllowCert(cert) != fipsOK {
141 t.Errorf("boringAllowCert(cert with %s key) = %v, want %v", desc, !fipsOK, fipsOK)
142 }
143 return &boringCertificate{name, org, parentOrg, der, cert, key, fipsOK}
144 }
145
View as plain text