@marcel91200 / caddy Mirror · read-only
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 11, 01:00 UTC

master
go 314 lines 8.81 KB
Raw
1 // Copyright 2015 Matthew Holt and The Caddy Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 package caddypki
16
17 import (
18 "crypto/rand"
19 "crypto/x509"
20 "crypto/x509/pkix"
21 "encoding/pem"
22 "os"
23 "path/filepath"
24 "testing"
25 "time"
26
27 "go.step.sm/crypto/keyutil"
28 "go.step.sm/crypto/pemutil"
29 )
30
31 func TestKeyPair_Load(t *testing.T) {
32 rootSigner, err := keyutil.GenerateDefaultSigner()
33 if err != nil {
34 t.Fatalf("Failed creating signer: %v", err)
35 }
36
37 tmpl := &x509.Certificate{
38 Subject: pkix.Name{CommonName: "test-root"},
39 IsCA: true,
40 MaxPathLen: 3,
41 }
42 rootBytes, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, rootSigner.Public(), rootSigner)
43 if err != nil {
44 t.Fatalf("Creating root certificate failed: %v", err)
45 }
46
47 root, err := x509.ParseCertificate(rootBytes)
48 if err != nil {
49 t.Fatalf("Parsing root certificate failed: %v", err)
50 }
51
52 intermediateSigner, err := keyutil.GenerateDefaultSigner()
53 if err != nil {
54 t.Fatalf("Creating intermedaite signer failed: %v", err)
55 }
56
57 intermediateBytes, err := x509.CreateCertificate(rand.Reader, &x509.Certificate{
58 Subject: pkix.Name{CommonName: "test-first-intermediate"},
59 IsCA: true,
60 MaxPathLen: 2,
61 NotAfter: time.Now().Add(time.Hour),
62 }, root, intermediateSigner.Public(), rootSigner)
63 if err != nil {
64 t.Fatalf("Creating intermediate certificate failed: %v", err)
65 }
66
67 intermediate, err := x509.ParseCertificate(intermediateBytes)
68 if err != nil {
69 t.Fatalf("Parsing intermediate certificate failed: %v", err)
70 }
71
72 var chainContents []byte
73 chain := []*x509.Certificate{intermediate, root}
74 for _, cert := range chain {
75 b, err := pemutil.Serialize(cert)
76 if err != nil {
77 t.Fatalf("Failed serializing intermediate certificate: %v", err)
78 }
79 chainContents = append(chainContents, pem.EncodeToMemory(b)...)
80 }
81
82 dir := t.TempDir()
83 rootCertFile := filepath.Join(dir, "root.pem")
84 if _, err = pemutil.Serialize(root, pemutil.WithFilename(rootCertFile)); err != nil {
85 t.Fatalf("Failed serializing root certificate: %v", err)
86 }
87 rootKeyFile := filepath.Join(dir, "root.key")
88 if _, err = pemutil.Serialize(rootSigner, pemutil.WithFilename(rootKeyFile)); err != nil {
89 t.Fatalf("Failed serializing root key: %v", err)
90 }
91 intermediateCertFile := filepath.Join(dir, "intermediate.pem")
92 if _, err = pemutil.Serialize(intermediate, pemutil.WithFilename(intermediateCertFile)); err != nil {
93 t.Fatalf("Failed serializing intermediate certificate: %v", err)
94 }
95 intermediateKeyFile := filepath.Join(dir, "intermediate.key")
96 if _, err = pemutil.Serialize(intermediateSigner, pemutil.WithFilename(intermediateKeyFile)); err != nil {
97 t.Fatalf("Failed serializing intermediate key: %v", err)
98 }
99 chainFile := filepath.Join(dir, "chain.pem")
100 if err := os.WriteFile(chainFile, chainContents, 0644); err != nil {
101 t.Fatalf("Failed writing intermediate chain: %v", err)
102 }
103
104 t.Run("ok/single-certificate-without-signer", func(t *testing.T) {
105 kp := KeyPair{
106 Certificate: rootCertFile,
107 }
108 chain, signer, err := kp.Load()
109 if err != nil {
110 t.Fatalf("Failed loading KeyPair: %v", err)
111 }
112 if len(chain) != 1 {
113 t.Errorf("Expected 1 certificate in chain; got %d", len(chain))
114 }
115 if signer != nil {
116 t.Error("Expected no signer to be returned")
117 }
118 })
119
120 t.Run("ok/single-certificate-with-signer", func(t *testing.T) {
121 kp := KeyPair{
122 Certificate: rootCertFile,
123 PrivateKey: rootKeyFile,
124 }
125 chain, signer, err := kp.Load()
126 if err != nil {
127 t.Fatalf("Failed loading KeyPair: %v", err)
128 }
129 if len(chain) != 1 {
130 t.Errorf("Expected 1 certificate in chain; got %d", len(chain))
131 }
132 if signer == nil {
133 t.Error("Expected signer to be returned")
134 }
135 })
136
137 t.Run("ok/multiple-certificates-with-signer", func(t *testing.T) {
138 kp := KeyPair{
139 Certificate: chainFile,
140 PrivateKey: intermediateKeyFile,
141 }
142 chain, signer, err := kp.Load()
143 if err != nil {
144 t.Fatalf("Failed loading KeyPair: %v", err)
145 }
146 if len(chain) != 2 {
147 t.Errorf("Expected 2 certificates in chain; got %d", len(chain))
148 }
149 if signer == nil {
150 t.Error("Expected signer to be returned")
151 }
152 })
153
154 t.Run("fail/non-matching-public-key", func(t *testing.T) {
155 kp := KeyPair{
156 Certificate: intermediateCertFile,
157 PrivateKey: rootKeyFile,
158 }
159 chain, signer, err := kp.Load()
160 if err == nil {
161 t.Error("Expected loading KeyPair to return an error")
162 }
163 if chain != nil {
164 t.Error("Expected no chain to be returned")
165 }
166 if signer != nil {
167 t.Error("Expected no signer to be returned")
168 }
169 })
170 }
171
172 func Test_pemDecodeCertificate(t *testing.T) {
173 signer, err := keyutil.GenerateDefaultSigner()
174 if err != nil {
175 t.Fatalf("Failed creating signer: %v", err)
176 }
177
178 tmpl := &x509.Certificate{
179 Subject: pkix.Name{CommonName: "test-cert"},
180 IsCA: true,
181 MaxPathLen: 3,
182 }
183 derBytes, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, signer.Public(), signer)
184 if err != nil {
185 t.Fatalf("Creating root certificate failed: %v", err)
186 }
187 cert, err := x509.ParseCertificate(derBytes)
188 if err != nil {
189 t.Fatalf("Parsing root certificate failed: %v", err)
190 }
191
192 pemBlock, err := pemutil.Serialize(cert)
193 if err != nil {
194 t.Fatalf("Failed serializing certificate: %v", err)
195 }
196 pemData := pem.EncodeToMemory(pemBlock)
197
198 t.Run("ok", func(t *testing.T) {
199 cert, err := pemDecodeCertificate(pemData)
200 if err != nil {
201 t.Fatalf("Failed decoding PEM data: %v", err)
202 }
203 if cert == nil {
204 t.Errorf("Expected a certificate in PEM data")
205 }
206 })
207
208 t.Run("fail/no-pem-data", func(t *testing.T) {
209 cert, err := pemDecodeCertificate(nil)
210 if err == nil {
211 t.Fatalf("Expected pemDecodeCertificate to return an error")
212 }
213 if cert != nil {
214 t.Errorf("Expected pemDecodeCertificate to return nil")
215 }
216 })
217
218 t.Run("fail/multiple", func(t *testing.T) {
219 multiplePEMData := append(pemData, pemData...)
220 cert, err := pemDecodeCertificate(multiplePEMData)
221 if err == nil {
222 t.Fatalf("Expected pemDecodeCertificate to return an error")
223 }
224 if cert != nil {
225 t.Errorf("Expected pemDecodeCertificate to return nil")
226 }
227 })
228
229 t.Run("fail/no-pem-certificate", func(t *testing.T) {
230 pkData := pem.EncodeToMemory(&pem.Block{
231 Type: "PRIVATE KEY",
232 Bytes: []byte("some-bogus-private-key"),
233 })
234 cert, err := pemDecodeCertificate(pkData)
235 if err == nil {
236 t.Fatalf("Expected pemDecodeCertificate to return an error")
237 }
238 if cert != nil {
239 t.Errorf("Expected pemDecodeCertificate to return nil")
240 }
241 })
242 }
243
244 func Test_pemDecodeCertificateChain(t *testing.T) {
245 signer, err := keyutil.GenerateDefaultSigner()
246 if err != nil {
247 t.Fatalf("Failed creating signer: %v", err)
248 }
249
250 tmpl := &x509.Certificate{
251 Subject: pkix.Name{CommonName: "test-cert"},
252 IsCA: true,
253 MaxPathLen: 3,
254 }
255 derBytes, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, signer.Public(), signer)
256 if err != nil {
257 t.Fatalf("Creating root certificate failed: %v", err)
258 }
259 cert, err := x509.ParseCertificate(derBytes)
260 if err != nil {
261 t.Fatalf("Parsing root certificate failed: %v", err)
262 }
263
264 pemBlock, err := pemutil.Serialize(cert)
265 if err != nil {
266 t.Fatalf("Failed serializing certificate: %v", err)
267 }
268 pemData := pem.EncodeToMemory(pemBlock)
269
270 t.Run("ok/single", func(t *testing.T) {
271 certs, err := pemDecodeCertificateChain(pemData)
272 if err != nil {
273 t.Fatalf("Failed decoding PEM data: %v", err)
274 }
275 if len(certs) != 1 {
276 t.Errorf("Expected 1 certificate in PEM data; got %d", len(certs))
277 }
278 })
279
280 t.Run("ok/multiple", func(t *testing.T) {
281 multiplePEMData := append(pemData, pemData...)
282 certs, err := pemDecodeCertificateChain(multiplePEMData)
283 if err != nil {
284 t.Fatalf("Failed decoding PEM data: %v", err)
285 }
286 if len(certs) != 2 {
287 t.Errorf("Expected 2 certificates in PEM data; got %d", len(certs))
288 }
289 })
290
291 t.Run("fail/no-pem-certificate", func(t *testing.T) {
292 pkData := pem.EncodeToMemory(&pem.Block{
293 Type: "PRIVATE KEY",
294 Bytes: []byte("some-bogus-private-key"),
295 })
296 certs, err := pemDecodeCertificateChain(pkData)
297 if err == nil {
298 t.Fatalf("Expected pemDecodeCertificateChain to return an error")
299 }
300 if len(certs) != 0 {
301 t.Errorf("Expected 0 certificates in PEM data; got %d", len(certs))
302 }
303 })
304
305 t.Run("fail/no-der-certificate", func(t *testing.T) {
306 certs, err := pemDecodeCertificateChain([]byte("invalid-der-data"))
307 if err == nil {
308 t.Fatalf("Expected pemDecodeCertificateChain to return an error")
309 }
310 if len(certs) != 0 {
311 t.Errorf("Expected 0 certificates in PEM data; got %d", len(certs))
312 }
313 })
314 }