1 package tlsconfig
2
3 import (
4 "bytes"
5 "crypto/tls"
6 "crypto/x509"
7 "encoding/pem"
8 "os"
9 "reflect"
10 "runtime"
11 "testing"
12 )
13
14
15
16
17
18 const (
19 systemRootTrustedCert = `
20 -----BEGIN CERTIFICATE-----
21 MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF
22 ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6
23 b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL
24 MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv
25 b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj
26 ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM
27 9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw
28 IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6
29 VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L
30 93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm
31 jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
32 AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA
33 A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI
34 U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs
35 N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv
36 o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU
37 5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy
38 rqXRfboQnoZsG4q5WTP468SQvvG5
39 -----END CERTIFICATE-----
40 `
41 rsaPrivateKeyFile = "fixtures/key.pem"
42 certificateFile = "fixtures/cert.pem"
43 multiCertificateFile = "fixtures/multi.pem"
44 rsaEncryptedPrivateKeyFile = "fixtures/encrypted_key.pem"
45 certificateOfEncryptedKeyFile = "fixtures/cert_of_encrypted_key.pem"
46 )
47
48
49
50 func getMultiCert() string {
51 return multiCertificateFile
52 }
53
54
55 func getCertAndKey() (string, string) {
56 return rsaPrivateKeyFile, certificateFile
57 }
58
59
60
61 func getCertAndEncryptedKey() (string, string) {
62 return rsaEncryptedPrivateKeyFile, certificateOfEncryptedKeyFile
63 }
64
65
66
67 func TestConfigServerTLSFailsIfUnableToLoadCerts(t *testing.T) {
68 key, cert := getCertAndKey()
69 ca := getMultiCert()
70
71 tempFile, err := os.CreateTemp("", "cert-test")
72 if err != nil {
73 t.Fatal("Unable to create temporary empty file")
74 }
75 defer os.RemoveAll(tempFile.Name())
76 tempFile.Close()
77
78 for _, badFile := range []string{"not-a-file", tempFile.Name()} {
79 for i := 0; i < 3; i++ {
80 files := []string{cert, key, ca}
81 files[i] = badFile
82
83 result, err := Server(Options{
84 CertFile: files[0],
85 KeyFile: files[1],
86 CAFile: files[2],
87 ClientAuth: tls.VerifyClientCertIfGiven,
88 })
89 if err == nil || result != nil {
90 t.Fatal("Expected a non-real file to error and return a nil TLS config")
91 }
92 }
93 }
94 }
95
96
97
98 func TestConfigServerTLSServerCertsOnly(t *testing.T) {
99 key, cert := getCertAndKey()
100
101 keypair, err := tls.LoadX509KeyPair(cert, key)
102 if err != nil {
103 t.Fatal("Unable to load the generated cert and key")
104 }
105
106 tlsConfig, err := Server(Options{
107 CertFile: cert,
108 KeyFile: key,
109 })
110 if err != nil || tlsConfig == nil {
111 t.Fatal("Unable to configure server TLS", err)
112 }
113
114 if len(tlsConfig.Certificates) != 1 {
115 t.Fatal("Unexpected server certificates")
116 }
117 if len(tlsConfig.Certificates[0].Certificate) != len(keypair.Certificate) {
118 t.Fatal("Unexpected server certificates")
119 }
120 for i, cert := range tlsConfig.Certificates[0].Certificate {
121 if !bytes.Equal(cert, keypair.Certificate[i]) {
122 t.Fatal("Unexpected server certificates")
123 }
124 }
125
126 if !reflect.DeepEqual(tlsConfig.CipherSuites, DefaultServerAcceptedCiphers) {
127 t.Fatal("Unexpected server cipher suites")
128 }
129 if !tlsConfig.PreferServerCipherSuites {
130 t.Fatal("Expected server to prefer cipher suites")
131 }
132 if tlsConfig.MinVersion != tls.VersionTLS12 {
133 t.Fatal("Unexpected server TLS version")
134 }
135 }
136
137
138
139 func TestConfigServerTLSClientCANotSetIfClientAuthTooLow(t *testing.T) {
140 key, cert := getCertAndKey()
141 ca := getMultiCert()
142
143 tlsConfig, err := Server(Options{
144 CertFile: cert,
145 KeyFile: key,
146 ClientAuth: tls.RequestClientCert,
147 CAFile: ca,
148 })
149
150 if err != nil || tlsConfig == nil {
151 t.Fatal("Unable to configure server TLS", err)
152 }
153
154 if len(tlsConfig.Certificates) != 1 {
155 t.Fatal("Unexpected server certificates")
156 }
157 if tlsConfig.ClientAuth != tls.RequestClientCert {
158 t.Fatal("ClientAuth was not set to what was in the options")
159 }
160 if tlsConfig.ClientCAs != nil {
161 t.Fatalf("Client CAs should never have been set")
162 }
163 }
164
165
166
167 func TestConfigServerTLSClientCASet(t *testing.T) {
168 key, cert := getCertAndKey()
169 ca := getMultiCert()
170
171 tlsConfig, err := Server(Options{
172 CertFile: cert,
173 KeyFile: key,
174 ClientAuth: tls.VerifyClientCertIfGiven,
175 CAFile: ca,
176 })
177
178 if err != nil || tlsConfig == nil {
179 t.Fatal("Unable to configure server TLS", err)
180 }
181
182 if len(tlsConfig.Certificates) != 1 {
183 t.Fatal("Unexpected server certificates")
184 }
185 if tlsConfig.ClientAuth != tls.VerifyClientCertIfGiven {
186 t.Fatal("ClientAuth was not set to what was in the options")
187 }
188 basePool, err := SystemCertPool()
189 if err != nil {
190 basePool = x509.NewCertPool()
191 }
192
193 if tlsConfig.ClientCAs == nil || len(tlsConfig.ClientCAs.Subjects()) != len(basePool.Subjects())+2 {
194 t.Fatalf("Client CAs were never set correctly")
195 }
196 }
197
198
199
200 func TestConfigServerExclusiveRootPools(t *testing.T) {
201 if runtime.GOOS == "windows" || runtime.GOOS == "darwin" {
202
203 t.Skip("FIXME: failing on Windows and darwin")
204 }
205 key, cert := getCertAndKey()
206 ca := getMultiCert()
207
208 caBytes, err := os.ReadFile(ca)
209 if err != nil {
210 t.Fatal("Unable to read CA certs", err)
211 }
212
213 var testCerts []*x509.Certificate
214 for _, pemBytes := range [][]byte{caBytes, []byte(systemRootTrustedCert)} {
215 pemBlock, _ := pem.Decode(pemBytes)
216 if pemBlock == nil {
217 t.Fatal("Malformed certificate")
218 }
219 cert, err := x509.ParseCertificate(pemBlock.Bytes)
220 if err != nil {
221 t.Fatal("Unable to parse certificate")
222 }
223 testCerts = append(testCerts, cert)
224 }
225
226
227
228 tlsConfig, err := Server(Options{
229 CertFile: cert,
230 KeyFile: key,
231 ClientAuth: tls.VerifyClientCertIfGiven,
232 CAFile: ca,
233 })
234
235 if err != nil || tlsConfig == nil {
236 t.Fatal("Unable to configure server TLS", err)
237 }
238
239 for i, cert := range testCerts {
240 if _, err := cert.Verify(x509.VerifyOptions{Roots: tlsConfig.ClientCAs}); err != nil {
241 t.Fatalf("Unable to verify certificate %d: %v", i, err)
242 }
243 }
244
245
246
247 tlsConfig, err = Server(Options{
248 CertFile: cert,
249 KeyFile: key,
250 ClientAuth: tls.VerifyClientCertIfGiven,
251 CAFile: ca,
252 ExclusiveRootPools: true,
253 })
254
255 if err != nil || tlsConfig == nil {
256 t.Fatal("Unable to configure server TLS", err)
257 }
258
259 for i, cert := range testCerts {
260 _, err := cert.Verify(x509.VerifyOptions{Roots: tlsConfig.ClientCAs})
261 switch {
262 case i == 0 && err != nil:
263 t.Fatal("Unable to verify custom certificate, even though the root pool should have only the custom CA", err)
264 case i == 1 && err == nil:
265 t.Fatal("Successfully verified system root-signed certificate though the root pool should have only the cusotm CA", err)
266 }
267 }
268
269
270 tlsConfig, err = Server(Options{
271 CertFile: cert,
272 KeyFile: key,
273 })
274
275 if err != nil || tlsConfig == nil {
276 t.Fatal("Unable to configure server TLS", err)
277 }
278
279 for i, cert := range testCerts {
280 _, err := cert.Verify(x509.VerifyOptions{Roots: tlsConfig.ClientCAs})
281 switch {
282 case i == 1 && err != nil:
283 t.Fatal("Unable to verify system root-signed certificate, even though the root pool should be the system pool only", err)
284 case i == 0 && err == nil:
285 t.Fatal("Successfully verified custom certificate though the root pool should be the system pool only", err)
286 }
287 }
288 }
289
290
291
292 func TestConfigServerDefaultWithTLSMinimumModifier(t *testing.T) {
293 tlsVersions := []uint16{
294 tls.VersionTLS11,
295 tls.VersionTLS12,
296 }
297
298 for _, tlsVersion := range tlsVersions {
299 servDefault := ServerDefault(func(c *tls.Config) {
300 c.MinVersion = tlsVersion
301 })
302
303 if servDefault.MinVersion != tlsVersion {
304 t.Fatalf("Unexpected min TLS version for default server TLS config: %d", servDefault.MinVersion)
305 }
306 }
307 }
308
309
310
311 func TestConfigClientDefaultWithTLSMinimumModifier(t *testing.T) {
312 tlsVersions := []uint16{
313 tls.VersionTLS11,
314 tls.VersionTLS12,
315 }
316
317 for _, tlsVersion := range tlsVersions {
318 clientDefault := ClientDefault(func(c *tls.Config) {
319 c.MinVersion = tlsVersion
320 })
321
322 if clientDefault.MinVersion != tlsVersion {
323 t.Fatalf("Unexpected min TLS version for default client TLS config: %d", clientDefault.MinVersion)
324 }
325 }
326 }
327
328
329
330 func TestConfigServerTLSMinVersionIsSetBasedOnOptions(t *testing.T) {
331 versions := []uint16{
332 tls.VersionTLS12,
333 }
334 key, cert := getCertAndKey()
335
336 for _, v := range versions {
337 tlsConfig, err := Server(Options{
338 MinVersion: v,
339 CertFile: cert,
340 KeyFile: key,
341 })
342
343 if err != nil || tlsConfig == nil {
344 t.Fatal("Unable to configure server TLS", err)
345 }
346
347 if tlsConfig.MinVersion != v {
348 t.Fatal("Unexpected minimum TLS version: ", tlsConfig.MinVersion)
349 }
350 }
351 }
352
353
354
355 func TestConfigServerTLSMinVersionNotSetIfMinVersionIsTooLow(t *testing.T) {
356 key, cert := getCertAndKey()
357
358 _, err := Server(Options{
359 MinVersion: tls.VersionTLS10,
360 CertFile: cert,
361 KeyFile: key,
362 })
363
364 if err == nil {
365 t.Fatal("Should have returned an error for minimum version below TLS10")
366 }
367 }
368
369
370
371 func TestConfigServerTLSMinVersionNotSetIfMinVersionIsInvalid(t *testing.T) {
372 key, cert := getCertAndKey()
373
374 _, err := Server(Options{
375 MinVersion: 1,
376 CertFile: cert,
377 KeyFile: key,
378 })
379
380 if err == nil {
381 t.Fatal("Should have returned error on invalid minimum version option")
382 }
383 }
384
385
386
387 func TestConfigClientTLSNoVerify(t *testing.T) {
388 ca := getMultiCert()
389
390 tlsConfig, err := Client(Options{CAFile: ca, InsecureSkipVerify: true})
391
392 if err != nil || tlsConfig == nil {
393 t.Fatal("Unable to configure client TLS", err)
394 }
395
396 if tlsConfig.RootCAs != nil {
397 t.Fatal("Should not have set Root CAs", err)
398 }
399
400 if !reflect.DeepEqual(tlsConfig.CipherSuites, clientCipherSuites) {
401 t.Fatal("Unexpected client cipher suites")
402 }
403 if tlsConfig.MinVersion != tls.VersionTLS12 {
404 t.Fatal("Unexpected client TLS version")
405 }
406
407 if tlsConfig.Certificates != nil {
408 t.Fatal("Somehow client certificates were set")
409 }
410 }
411
412
413
414 func TestConfigClientTLSNoRoot(t *testing.T) {
415 tlsConfig, err := Client(Options{})
416
417 if err != nil || tlsConfig == nil {
418 t.Fatal("Unable to configure client TLS", err)
419 }
420
421 if tlsConfig.RootCAs != nil {
422 t.Fatal("Should not have set Root CAs", err)
423 }
424
425 if !reflect.DeepEqual(tlsConfig.CipherSuites, clientCipherSuites) {
426 t.Fatal("Unexpected client cipher suites")
427 }
428 if tlsConfig.MinVersion != tls.VersionTLS12 {
429 t.Fatal("Unexpected client TLS version")
430 }
431
432 if tlsConfig.Certificates != nil {
433 t.Fatal("Somehow client certificates were set")
434 }
435 }
436
437
438 func TestConfigClientTLSRootCAFileWithOneCert(t *testing.T) {
439 ca := getMultiCert()
440
441 tlsConfig, err := Client(Options{CAFile: ca})
442
443 if err != nil || tlsConfig == nil {
444 t.Fatal("Unable to configure client TLS", err)
445 }
446 basePool, err := SystemCertPool()
447 if err != nil {
448 basePool = x509.NewCertPool()
449 }
450
451 if tlsConfig.RootCAs == nil || len(tlsConfig.RootCAs.Subjects()) != len(basePool.Subjects())+2 {
452 t.Fatal("Root CAs not set properly", err)
453 }
454 if tlsConfig.Certificates != nil {
455 t.Fatal("Somehow client certificates were set")
456 }
457 }
458
459
460 func TestConfigClientTLSNonexistentRootCAFile(t *testing.T) {
461 tlsConfig, err := Client(Options{CAFile: "nonexistent"})
462
463 if err == nil || tlsConfig != nil {
464 t.Fatal("Should not have been able to configure client TLS", err)
465 }
466 }
467
468
469
470 func TestConfigClientTLSClientCertOrKeyInvalid(t *testing.T) {
471 key, cert := getCertAndKey()
472
473 tempFile, err := os.CreateTemp("", "cert-test")
474 if err != nil {
475 t.Fatal("Unable to create temporary empty file")
476 }
477 defer os.Remove(tempFile.Name())
478 _ = tempFile.Close()
479
480 for i := 0; i < 2; i++ {
481 for _, invalid := range []string{"not-a-file", "", tempFile.Name()} {
482 files := []string{cert, key}
483 files[i] = invalid
484
485 tlsConfig, err := Client(Options{CertFile: files[0], KeyFile: files[1]})
486 if err == nil || tlsConfig != nil {
487 t.Fatal("Should not have been able to configure client TLS", err)
488 }
489 }
490 }
491 }
492
493
494
495 func TestConfigClientTLSValidClientCertAndKey(t *testing.T) {
496 key, cert := getCertAndKey()
497
498 keypair, err := tls.LoadX509KeyPair(cert, key)
499 if err != nil {
500 t.Fatal("Unable to load the generated cert and key")
501 }
502
503 tlsConfig, err := Client(Options{CertFile: cert, KeyFile: key})
504
505 if err != nil || tlsConfig == nil {
506 t.Fatal("Unable to configure client TLS", err)
507 }
508
509 if len(tlsConfig.Certificates) != 1 {
510 t.Fatal("Unexpected client certificates")
511 }
512 if len(tlsConfig.Certificates[0].Certificate) != len(keypair.Certificate) {
513 t.Fatal("Unexpected client certificates")
514 }
515 for i, cert := range tlsConfig.Certificates[0].Certificate {
516 if !bytes.Equal(cert, keypair.Certificate[i]) {
517 t.Fatal("Unexpected client certificates")
518 }
519 }
520
521 if tlsConfig.RootCAs != nil {
522 t.Fatal("Root CAs should not have been set", err)
523 }
524 }
525
526
527
528 func TestConfigClientTLSValidClientCertAndEncryptedKey(t *testing.T) {
529 key, cert := getCertAndEncryptedKey()
530
531 tlsConfig, err := Client(Options{
532 CertFile: cert,
533 KeyFile: key,
534 Passphrase: "FooBar123",
535 })
536
537 if err != nil || tlsConfig == nil {
538 t.Fatal("Unable to configure client TLS", err)
539 }
540
541 if len(tlsConfig.Certificates) != 1 {
542 t.Fatal("Unexpected client certificates")
543 }
544 }
545
546
547
548 func TestConfigClientTLSNotSetWithInvalidPassphrase(t *testing.T) {
549 key, cert := getCertAndEncryptedKey()
550
551 tlsConfig, err := Client(Options{
552 CertFile: cert,
553 KeyFile: key,
554 Passphrase: "InvalidPassphrase",
555 })
556
557 if !IsErrEncryptedKey(err) || tlsConfig != nil {
558 t.Fatal("Expected failure due to incorrect passphrase.")
559 }
560 }
561
562
563
564 func TestConfigClientExclusiveRootPools(t *testing.T) {
565 if runtime.GOOS == "windows" || runtime.GOOS == "darwin" {
566
567 t.Skip("FIXME: failing on Windows and darwin")
568 }
569 ca := getMultiCert()
570
571 caBytes, err := os.ReadFile(ca)
572 if err != nil {
573 t.Fatal("Unable to read CA certs", err)
574 }
575
576 var testCerts []*x509.Certificate
577 for _, pemBytes := range [][]byte{caBytes, []byte(systemRootTrustedCert)} {
578 pemBlock, _ := pem.Decode(pemBytes)
579 if pemBlock == nil {
580 t.Fatal("Malformed certificate")
581 }
582 cert, err := x509.ParseCertificate(pemBlock.Bytes)
583 if err != nil {
584 t.Fatal("Unable to parse certificate")
585 }
586 testCerts = append(testCerts, cert)
587 }
588
589
590
591 tlsConfig, err := Client(Options{CAFile: ca})
592
593 if err != nil || tlsConfig == nil {
594 t.Fatal("Unable to configure client TLS", err)
595 }
596
597 for i, cert := range testCerts {
598 if _, err := cert.Verify(x509.VerifyOptions{Roots: tlsConfig.RootCAs}); err != nil {
599 t.Fatalf("Unable to verify certificate %d: %v", i, err)
600 }
601 }
602
603
604
605 tlsConfig, err = Client(Options{
606 CAFile: ca,
607 ExclusiveRootPools: true,
608 })
609
610 if err != nil || tlsConfig == nil {
611 t.Fatal("Unable to configure client TLS", err)
612 }
613
614 for i, cert := range testCerts {
615 _, err := cert.Verify(x509.VerifyOptions{Roots: tlsConfig.RootCAs})
616 switch {
617 case i == 0 && err != nil:
618 t.Fatal("Unable to verify custom certificate, even though the root pool should have only the custom CA", err)
619 case i == 1 && err == nil:
620 t.Fatal("Successfully verified system root-signed certificate though the root pool should have only the cusotm CA", err)
621 }
622 }
623
624
625 tlsConfig, err = Client(Options{})
626
627 if err != nil || tlsConfig == nil {
628 t.Fatal("Unable to configure client TLS", err)
629 }
630
631 for i, cert := range testCerts {
632 _, err := cert.Verify(x509.VerifyOptions{Roots: tlsConfig.RootCAs})
633 switch {
634 case i == 1 && err != nil:
635 t.Fatal("Unable to verify system root-signed certificate, even though the root pool should be the system pool only", err)
636 case i == 0 && err == nil:
637 t.Fatal("Successfully verified custom certificate though the root pool should be the system pool only", err)
638 }
639 }
640 }
641
642
643
644 func TestConfigClientTLSMinVersionIsSetBasedOnOptions(t *testing.T) {
645 key, cert := getCertAndKey()
646
647 tlsConfig, err := Client(Options{
648 MinVersion: tls.VersionTLS12,
649 CertFile: cert,
650 KeyFile: key,
651 })
652
653 if err != nil || tlsConfig == nil {
654 t.Fatal("Unable to configure client TLS", err)
655 }
656
657 if tlsConfig.MinVersion != tls.VersionTLS12 {
658 t.Fatal("Unexpected minimum TLS version: ", tlsConfig.MinVersion)
659 }
660 }
661
662
663
664 func TestConfigClientTLSMinVersionNotSetIfMinVersionIsTooLow(t *testing.T) {
665 key, cert := getCertAndKey()
666
667 _, err := Client(Options{
668 MinVersion: tls.VersionTLS11,
669 CertFile: cert,
670 KeyFile: key,
671 })
672
673 if err == nil {
674 t.Fatal("Should have returned an error for minimum version below TLS12")
675 }
676 }
677
678
679
680 func TestConfigClientTLSMinVersionNotSetIfMinVersionIsInvalid(t *testing.T) {
681 key, cert := getCertAndKey()
682
683 _, err := Client(Options{
684 MinVersion: 1,
685 CertFile: cert,
686 KeyFile: key,
687 })
688
689 if err == nil {
690 t.Fatal("Should have returned error on invalid minimum version option")
691 }
692 }
693
View as plain text