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