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