1
16
17 package certs
18
19 import (
20 "crypto"
21 "crypto/rsa"
22 "crypto/x509"
23 "net"
24 "path/filepath"
25 "testing"
26
27 certutil "k8s.io/client-go/util/cert"
28 "k8s.io/client-go/util/keyutil"
29
30 "k8s.io/kubernetes/cmd/kubeadm/app/util/pkiutil"
31 )
32
33
34
35 func SetupCertificateAuthority(t *testing.T) (*x509.Certificate, crypto.Signer) {
36 caCert, caKey, err := pkiutil.NewCertificateAuthority(&pkiutil.CertConfig{
37 Config: certutil.Config{CommonName: "kubernetes"},
38 })
39 if err != nil {
40 t.Fatalf("failure while generating CA certificate and key: %v", err)
41 }
42
43 return caCert, caKey
44 }
45
46
47
48 func AssertCertificateIsSignedByCa(t *testing.T, cert *x509.Certificate, signingCa *x509.Certificate) {
49 if err := cert.CheckSignatureFrom(signingCa); err != nil {
50 t.Error("cert is not signed by signing CA as expected")
51 }
52 }
53
54
55
56 func AssertCertificateHasCommonName(t *testing.T, cert *x509.Certificate, commonName string) {
57 if cert.Subject.CommonName != commonName {
58 t.Errorf("cert has Subject.CommonName %s, expected %s", cert.Subject.CommonName, commonName)
59 }
60 }
61
62
63
64 func AssertCertificateHasOrganizations(t *testing.T, cert *x509.Certificate, organizations ...string) {
65 if len(cert.Subject.Organization) != len(organizations) {
66 t.Fatalf("cert contains a different number of Subject.Organization, expected %v, got %v", organizations, cert.Subject.Organization)
67 }
68 for _, organization := range organizations {
69 found := false
70 for i := range cert.Subject.Organization {
71 if cert.Subject.Organization[i] == organization {
72 found = true
73 }
74 }
75 if !found {
76 t.Errorf("cert does not contain Subject.Organization %s as expected", organization)
77 }
78 }
79 }
80
81
82
83 func AssertCertificateHasClientAuthUsage(t *testing.T, cert *x509.Certificate) {
84 for i := range cert.ExtKeyUsage {
85 if cert.ExtKeyUsage[i] == x509.ExtKeyUsageClientAuth {
86 return
87 }
88 }
89 t.Error("cert has not ClientAuth usage as expected")
90 }
91
92
93
94 func AssertCertificateHasServerAuthUsage(t *testing.T, cert *x509.Certificate) {
95 for i := range cert.ExtKeyUsage {
96 if cert.ExtKeyUsage[i] == x509.ExtKeyUsageServerAuth {
97 return
98 }
99 }
100 t.Error("cert is not a ServerAuth")
101 }
102
103
104
105 func AssertCertificateHasDNSNames(t *testing.T, cert *x509.Certificate, DNSNames ...string) {
106 for _, DNSName := range DNSNames {
107 found := false
108 for _, val := range cert.DNSNames {
109 if val == DNSName {
110 found = true
111 break
112 }
113 }
114
115 if !found {
116 t.Errorf("cert does not contain DNSName %s", DNSName)
117 }
118 }
119 }
120
121
122
123 func AssertCertificateHasIPAddresses(t *testing.T, cert *x509.Certificate, IPAddresses ...net.IP) {
124 for _, IPAddress := range IPAddresses {
125 found := false
126 for _, val := range cert.IPAddresses {
127 if val.Equal(IPAddress) {
128 found = true
129 break
130 }
131 }
132
133 if !found {
134 t.Errorf("cert does not contain IPAddress %s", IPAddress)
135 }
136 }
137 }
138
139
140 func CreateCACert(t *testing.T) (*x509.Certificate, crypto.Signer) {
141 certCfg := &pkiutil.CertConfig{Config: certutil.Config{CommonName: "kubernetes"}}
142 cert, key, err := pkiutil.NewCertificateAuthority(certCfg)
143 if err != nil {
144 t.Fatalf("couldn't create CA: %v", err)
145 }
146 return cert, key
147 }
148
149
150 func CreateTestCert(t *testing.T, caCert *x509.Certificate, caKey crypto.Signer, altNames certutil.AltNames) (*x509.Certificate, crypto.Signer, *pkiutil.CertConfig) {
151 config := &pkiutil.CertConfig{
152 Config: certutil.Config{
153 CommonName: "testCert",
154 Usages: []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
155 AltNames: altNames,
156 },
157 }
158 cert, key, err := pkiutil.NewCertAndKey(caCert, caKey, config)
159 if err != nil {
160 t.Fatalf("couldn't create test cert: %v", err)
161 }
162 return cert, key, config
163 }
164
165
166 type CertTestCase struct {
167 Name string
168 Files PKIFiles
169 ExpectError bool
170 }
171
172
173 func GetSparseCertTestCases(t *testing.T) []CertTestCase {
174
175 caCert, caKey := CreateCACert(t)
176 fpCACert, fpCAKey := CreateCACert(t)
177 etcdCACert, etcdCAKey := CreateCACert(t)
178
179 fpCert, fpKey, _ := CreateTestCert(t, fpCACert, fpCAKey, certutil.AltNames{})
180
181 return []CertTestCase{
182 {
183 Name: "nothing present",
184 },
185 {
186 Name: "CAs already exist",
187 Files: PKIFiles{
188 "ca.crt": caCert,
189 "ca.key": caKey,
190 "front-proxy-ca.crt": fpCACert,
191 "front-proxy-ca.key": fpCAKey,
192 "etcd/ca.crt": etcdCACert,
193 "etcd/ca.key": etcdCAKey,
194 },
195 },
196 {
197 Name: "CA certs only",
198 Files: PKIFiles{
199 "ca.crt": caCert,
200 "front-proxy-ca.crt": fpCACert,
201 "etcd/ca.crt": etcdCACert,
202 },
203 ExpectError: true,
204 },
205 {
206 Name: "FrontProxyCA with certs",
207 Files: PKIFiles{
208 "ca.crt": caCert,
209 "ca.key": caKey,
210 "front-proxy-ca.crt": fpCACert,
211 "front-proxy-client.crt": fpCert,
212 "front-proxy-client.key": fpKey,
213 "etcd/ca.crt": etcdCACert,
214 "etcd/ca.key": etcdCAKey,
215 },
216 },
217 {
218 Name: "FrontProxy certs missing CA",
219 Files: PKIFiles{
220 "front-proxy-client.crt": fpCert,
221 "front-proxy-client.key": fpKey,
222 },
223 ExpectError: true,
224 },
225 }
226 }
227
228
229 type PKIFiles map[string]interface{}
230
231
232 func WritePKIFiles(t *testing.T, dir string, files PKIFiles) {
233 for filename, body := range files {
234 switch body := body.(type) {
235 case *x509.Certificate:
236 if err := certutil.WriteCert(filepath.Join(dir, filename), pkiutil.EncodeCertPEM(body)); err != nil {
237 t.Errorf("unable to write certificate to file %q: [%v]", dir, err)
238 }
239 case *rsa.PublicKey:
240 publicKeyBytes, err := pkiutil.EncodePublicKeyPEM(body)
241 if err != nil {
242 t.Errorf("unable to write public key to file %q: [%v]", filename, err)
243 }
244 if err := keyutil.WriteKey(filepath.Join(dir, filename), publicKeyBytes); err != nil {
245 t.Errorf("unable to write public key to file %q: [%v]", filename, err)
246 }
247 case *rsa.PrivateKey:
248 privateKey, err := keyutil.MarshalPrivateKeyToPEM(body)
249 if err != nil {
250 t.Errorf("unable to write private key to file %q: [%v]", filename, err)
251 }
252 if err := keyutil.WriteKey(filepath.Join(dir, filename), privateKey); err != nil {
253 t.Errorf("unable to write private key to file %q: [%v]", filename, err)
254 }
255 }
256 }
257 }
258
View as plain text