Source file
src/crypto/x509/root_unix_test.go
1
2
3
4
5
6
7
8 package x509
9
10 import (
11 "bytes"
12 "fmt"
13 "os"
14 "path/filepath"
15 "reflect"
16 "strings"
17 "testing"
18 )
19
20 const (
21 testDir = "testdata"
22 testDirCN = "test-dir"
23 testFile = "test-file.crt"
24 testFileCN = "test-file"
25 testMissing = "missing"
26 )
27
28 func TestEnvVars(t *testing.T) {
29 testCases := []struct {
30 name string
31 fileEnv string
32 dirEnv string
33 files []string
34 dirs []string
35 cns []string
36 }{
37 {
38
39 name: "override-defaults",
40 fileEnv: testMissing,
41 dirEnv: testMissing,
42 files: []string{testFile},
43 dirs: []string{testDir},
44 cns: nil,
45 },
46 {
47
48 name: "file",
49 fileEnv: testFile,
50 dirEnv: "",
51 files: nil,
52 dirs: nil,
53 cns: []string{testFileCN},
54 },
55 {
56
57 name: "dir",
58 fileEnv: "",
59 dirEnv: testDir,
60 files: nil,
61 dirs: nil,
62 cns: []string{testDirCN},
63 },
64 {
65
66 name: "file+dir",
67 fileEnv: testFile,
68 dirEnv: testDir,
69 files: nil,
70 dirs: nil,
71 cns: []string{testFileCN, testDirCN},
72 },
73 {
74
75 name: "empty-fall-through",
76 fileEnv: "",
77 dirEnv: "",
78 files: []string{testFile},
79 dirs: []string{testDir},
80 cns: []string{testFileCN, testDirCN},
81 },
82 }
83
84
85 origCertFiles, origCertDirectories := certFiles, certDirectories
86 origFile, origDir := os.Getenv(certFileEnv), os.Getenv(certDirEnv)
87 defer func() {
88 certFiles = origCertFiles
89 certDirectories = origCertDirectories
90 os.Setenv(certFileEnv, origFile)
91 os.Setenv(certDirEnv, origDir)
92 }()
93
94 for _, tc := range testCases {
95 t.Run(tc.name, func(t *testing.T) {
96 if err := os.Setenv(certFileEnv, tc.fileEnv); err != nil {
97 t.Fatalf("setenv %q failed: %v", certFileEnv, err)
98 }
99 if err := os.Setenv(certDirEnv, tc.dirEnv); err != nil {
100 t.Fatalf("setenv %q failed: %v", certDirEnv, err)
101 }
102
103 certFiles, certDirectories = tc.files, tc.dirs
104
105 r, err := loadSystemRoots()
106 if err != nil {
107 t.Fatal("unexpected failure:", err)
108 }
109
110 if r == nil {
111 t.Fatal("nil roots")
112 }
113
114
115 for i, cn := range tc.cns {
116 if i >= r.len() {
117 t.Errorf("missing cert %v @ %v", cn, i)
118 } else if r.mustCert(t, i).Subject.CommonName != cn {
119 fmt.Printf("%#v\n", r.mustCert(t, 0).Subject)
120 t.Errorf("unexpected cert common name %q, want %q", r.mustCert(t, i).Subject.CommonName, cn)
121 }
122 }
123 if r.len() > len(tc.cns) {
124 t.Errorf("got %v certs, which is more than %v wanted", r.len(), len(tc.cns))
125 }
126 })
127 }
128 }
129
130
131
132
133
134 func TestLoadSystemCertsLoadColonSeparatedDirs(t *testing.T) {
135 origFile, origDir := os.Getenv(certFileEnv), os.Getenv(certDirEnv)
136 origCertFiles := certFiles[:]
137
138
139
140
141 certFiles = certFiles[:0]
142 os.Setenv(certFileEnv, "")
143
144 defer func() {
145 certFiles = origCertFiles[:]
146 os.Setenv(certDirEnv, origDir)
147 os.Setenv(certFileEnv, origFile)
148 }()
149
150 tmpDir := t.TempDir()
151
152 rootPEMs := []string{
153 geoTrustRoot,
154 googleLeaf,
155 startComRoot,
156 }
157
158 var certDirs []string
159 for i, certPEM := range rootPEMs {
160 certDir := filepath.Join(tmpDir, fmt.Sprintf("cert-%d", i))
161 if err := os.MkdirAll(certDir, 0755); err != nil {
162 t.Fatalf("Failed to create certificate dir: %v", err)
163 }
164 certOutFile := filepath.Join(certDir, "cert.crt")
165 if err := os.WriteFile(certOutFile, []byte(certPEM), 0655); err != nil {
166 t.Fatalf("Failed to write certificate to file: %v", err)
167 }
168 certDirs = append(certDirs, certDir)
169 }
170
171
172 if g, w := len(certDirs), len(rootPEMs); g != w {
173 t.Fatalf("Failed sanity check: len(certsDir)=%d is not equal to len(rootsPEMS)=%d", g, w)
174 }
175
176
177 colonConcatCertDirs := strings.Join(certDirs, ":")
178 os.Setenv(certDirEnv, colonConcatCertDirs)
179 gotPool, err := loadSystemRoots()
180 if err != nil {
181 t.Fatalf("Failed to load system roots: %v", err)
182 }
183 subjects := gotPool.Subjects()
184
185 if g, w := len(subjects), len(rootPEMs); g != w {
186 t.Fatalf("Invalid number of subjects: got %d want %d", g, w)
187 }
188
189 wantPool := NewCertPool()
190 for _, certPEM := range rootPEMs {
191 wantPool.AppendCertsFromPEM([]byte(certPEM))
192 }
193 strCertPool := func(p *CertPool) string {
194 return string(bytes.Join(p.Subjects(), []byte("\n")))
195 }
196
197 if !certPoolEqual(gotPool, wantPool) {
198 g, w := strCertPool(gotPool), strCertPool(wantPool)
199 t.Fatalf("Mismatched certPools\nGot:\n%s\n\nWant:\n%s", g, w)
200 }
201 }
202
203 func TestReadUniqueDirectoryEntries(t *testing.T) {
204 tmp := t.TempDir()
205 temp := func(base string) string { return filepath.Join(tmp, base) }
206 if f, err := os.Create(temp("file")); err != nil {
207 t.Fatal(err)
208 } else {
209 f.Close()
210 }
211 if err := os.Symlink("target-in", temp("link-in")); err != nil {
212 t.Fatal(err)
213 }
214 if err := os.Symlink("../target-out", temp("link-out")); err != nil {
215 t.Fatal(err)
216 }
217 got, err := readUniqueDirectoryEntries(tmp)
218 if err != nil {
219 t.Fatal(err)
220 }
221 gotNames := []string{}
222 for _, fi := range got {
223 gotNames = append(gotNames, fi.Name())
224 }
225 wantNames := []string{"file", "link-out"}
226 if !reflect.DeepEqual(gotNames, wantNames) {
227 t.Errorf("got %q; want %q", gotNames, wantNames)
228 }
229 }
230
View as plain text