Source file
src/crypto/x509/hybrid_pool_test.go
1
2
3
4
5 package x509_test
6
7 import (
8 "crypto/ecdsa"
9 "crypto/elliptic"
10 "crypto/rand"
11 "crypto/tls"
12 "crypto/x509"
13 "crypto/x509/pkix"
14 "internal/testenv"
15 "math/big"
16 "runtime"
17 "testing"
18 "time"
19 )
20
21 func TestHybridPool(t *testing.T) {
22 t.Parallel()
23 if !(runtime.GOOS == "windows" || runtime.GOOS == "darwin" || runtime.GOOS == "ios") {
24 t.Skipf("platform verifier not available on %s", runtime.GOOS)
25 }
26 if !testenv.HasExternalNetwork() {
27 t.Skip()
28 }
29 if runtime.GOOS == "windows" {
30
31
32
33
34
35
36
37
38
39
40
41 deadline := time.Now().Add(time.Second * 10)
42 nextSleep := 10 * time.Millisecond
43 for i := 0; ; i++ {
44 c, err := tls.Dial("tcp", "google.com:443", nil)
45 if err == nil {
46 c.Close()
47 break
48 }
49 nextSleep = nextSleep * time.Duration(i)
50 if time.Until(deadline) < nextSleep {
51 t.Fatal("windows root pool appears to be in an uninitialized state (missing root that chains to google.com)")
52 }
53 time.Sleep(nextSleep)
54 }
55 }
56
57
58
59 c, err := tls.Dial("tcp", "google.com:443", &tls.Config{InsecureSkipVerify: true})
60 if err != nil {
61 t.Fatalf("tls connection failed: %s", err)
62 }
63 googChain := c.ConnectionState().PeerCertificates
64
65 rootTmpl := &x509.Certificate{
66 SerialNumber: big.NewInt(1),
67 Subject: pkix.Name{CommonName: "Go test root"},
68 IsCA: true,
69 BasicConstraintsValid: true,
70 NotBefore: time.Now().Add(-time.Hour),
71 NotAfter: time.Now().Add(time.Hour * 10),
72 }
73 k, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
74 if err != nil {
75 t.Fatalf("failed to generate test key: %s", err)
76 }
77 rootDER, err := x509.CreateCertificate(rand.Reader, rootTmpl, rootTmpl, k.Public(), k)
78 if err != nil {
79 t.Fatalf("failed to create test cert: %s", err)
80 }
81 root, err := x509.ParseCertificate(rootDER)
82 if err != nil {
83 t.Fatalf("failed to parse test cert: %s", err)
84 }
85
86 pool, err := x509.SystemCertPool()
87 if err != nil {
88 t.Fatalf("SystemCertPool failed: %s", err)
89 }
90 opts := x509.VerifyOptions{Roots: pool}
91
92 _, err = googChain[0].Verify(opts)
93 if err != nil {
94 t.Fatalf("verification failed for google.com chain (system only pool): %s", err)
95 }
96
97 pool.AddCert(root)
98
99 _, err = googChain[0].Verify(opts)
100 if err != nil {
101 t.Fatalf("verification failed for google.com chain (hybrid pool): %s", err)
102 }
103
104 certTmpl := &x509.Certificate{
105 SerialNumber: big.NewInt(1),
106 NotBefore: time.Now().Add(-time.Hour),
107 NotAfter: time.Now().Add(time.Hour * 10),
108 DNSNames: []string{"example.com"},
109 }
110 certDER, err := x509.CreateCertificate(rand.Reader, certTmpl, rootTmpl, k.Public(), k)
111 if err != nil {
112 t.Fatalf("failed to create test cert: %s", err)
113 }
114 cert, err := x509.ParseCertificate(certDER)
115 if err != nil {
116 t.Fatalf("failed to parse test cert: %s", err)
117 }
118
119 _, err = cert.Verify(opts)
120 if err != nil {
121 t.Fatalf("verification failed for custom chain (hybrid pool): %s", err)
122 }
123 }
124
View as plain text