1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package fixchain
16
17 import (
18 "net/http"
19 "sync"
20 "testing"
21
22 "github.com/google/certificate-transparency-go/x509"
23 )
24
25
26 func TestNewFixer(t *testing.T) {
27 chains := make(chan []*x509.Certificate)
28 errors := make(chan *FixError)
29
30 var expectedChains [][]string
31 var expectedErrs []errorType
32 for _, test := range handleChainTests {
33 expectedChains = append(expectedChains, test.expectedChains...)
34 expectedErrs = append(expectedErrs, test.expectedErrs...)
35 }
36
37 var wg sync.WaitGroup
38 wg.Add(2)
39 go func() {
40 defer wg.Done()
41 testChains(t, 0, expectedChains, chains)
42 }()
43 go func() {
44 defer wg.Done()
45 testErrors(t, 0, expectedErrs, errors)
46 }()
47
48 f := NewFixer(10, chains, errors, &http.Client{Transport: &testRoundTripper{}}, false)
49 for _, test := range handleChainTests {
50 f.QueueChain(GetTestCertificateFromPEM(t, test.cert),
51 extractTestChain(t, 0, test.chain), extractTestRoots(t, 0, test.roots))
52 }
53 f.Wait()
54
55 close(chains)
56 close(errors)
57 wg.Wait()
58 }
59
60
61 func TestFixServer(t *testing.T) {
62 cache := &urlCache{cache: newLockedCache(), client: &http.Client{Transport: &testRoundTripper{}}}
63 f := &Fixer{cache: cache}
64
65 var wg sync.WaitGroup
66 fixServerTests := handleChainTests
67
68
69
70 for i, fst := range fixServerTests {
71 chains := make(chan []*x509.Certificate)
72 errors := make(chan *FixError)
73 f.toFix = make(chan *toFix)
74 f.chains = chains
75 f.errors = errors
76
77 wg.Add(2)
78 go func() {
79 defer wg.Done()
80 testChains(t, i, fst.expectedChains, chains)
81 }()
82 go func() {
83 defer wg.Done()
84 testErrors(t, i, fst.expectedErrs, errors)
85 }()
86
87 f.wg.Add(1)
88 go f.fixServer()
89 f.QueueChain(GetTestCertificateFromPEM(t, fst.cert),
90 extractTestChain(t, i, fst.chain), extractTestRoots(t, i, fst.roots))
91 f.Wait()
92
93 close(chains)
94 close(errors)
95 wg.Wait()
96 }
97
98
99
100 chains := make(chan []*x509.Certificate)
101 errors := make(chan *FixError)
102 f.toFix = make(chan *toFix)
103 f.chains = chains
104 f.errors = errors
105
106 var expectedChains [][]string
107 var expectedErrs []errorType
108 for _, fst := range fixServerTests {
109 expectedChains = append(expectedChains, fst.expectedChains...)
110 expectedErrs = append(expectedErrs, fst.expectedErrs...)
111 }
112
113 i := len(fixServerTests)
114 wg.Add(2)
115 go func() {
116 defer wg.Done()
117 testChains(t, i, expectedChains, chains)
118 }()
119 go func() {
120 defer wg.Done()
121 testErrors(t, i, expectedErrs, errors)
122 }()
123
124 f.wg.Add(1)
125 go f.fixServer()
126 for _, fst := range fixServerTests {
127 f.QueueChain(GetTestCertificateFromPEM(t, fst.cert),
128 extractTestChain(t, i, fst.chain), extractTestRoots(t, i, fst.roots))
129 }
130 f.Wait()
131
132 close(chains)
133 close(errors)
134 wg.Wait()
135 }
136
137 func TestRemoveSuperChains(t *testing.T) {
138 superChainsTests := []struct {
139 chains [][]string
140 expectedChains [][]string
141 }{
142 {
143 chains: [][]string{
144 {googleLeaf, thawteIntermediate},
145 {googleLeaf},
146 },
147 expectedChains: [][]string{
148 {"Google"},
149 },
150 },
151 {
152 chains: [][]string{
153 {googleLeaf, verisignRoot},
154 {googleLeaf, thawteIntermediate},
155 {googleLeaf},
156 },
157 expectedChains: [][]string{
158 {"Google"},
159 },
160 },
161 {
162 chains: [][]string{
163 {googleLeaf, thawteIntermediate, verisignRoot},
164 {googleLeaf, thawteIntermediate},
165 {googleLeaf},
166 },
167 expectedChains: [][]string{
168 {"Google"},
169 },
170 },
171 {
172 chains: [][]string{
173 {googleLeaf, thawteIntermediate, verisignRoot},
174 {googleLeaf},
175 },
176 expectedChains: [][]string{
177 {"Google"},
178 },
179 },
180 {
181 chains: [][]string{
182 {googleLeaf, thawteIntermediate, verisignRoot},
183 {googleLeaf, verisignRoot},
184 {googleLeaf, thawteIntermediate},
185 },
186 expectedChains: [][]string{
187 {"Google", "Thawte"},
188 {"Google", "VeriSign"},
189 },
190 },
191 {
192 chains: [][]string{
193 {testLeaf, testIntermediate2},
194 {googleLeaf, thawteIntermediate, verisignRoot},
195 {testLeaf, testIntermediate2, testIntermediate1, testRoot},
196 {googleLeaf, verisignRoot},
197 {testLeaf, testIntermediate2, testIntermediate1},
198 {googleLeaf, thawteIntermediate},
199 {testLeaf, googleLeaf, thawteIntermediate, verisignRoot},
200 },
201 expectedChains: [][]string{
202 {"Google", "Thawte"},
203 {"Google", "VeriSign"},
204 {"Leaf", "Intermediate2"},
205 {"Leaf", "Google", "Thawte", "VeriSign"},
206 },
207 },
208 }
209
210 for i, test := range superChainsTests {
211 var chains [][]*x509.Certificate
212 for _, chain := range test.chains {
213 chains = append(chains, extractTestChain(t, i, chain))
214 }
215 matchTestChainList(t, i, test.expectedChains, removeSuperChains(chains))
216 }
217 }
218
219
220 func TestUpdateCounters(t *testing.T) {
221 counterTests := []struct {
222 errors []errorType
223 reconstructed uint32
224 notReconstructed uint32
225 fixed uint32
226 notFixed uint32
227 }{
228 {[]errorType{}, 1, 0, 0, 0},
229 {[]errorType{VerifyFailed}, 0, 1, 1, 0},
230 {[]errorType{VerifyFailed, FixFailed}, 0, 1, 0, 1},
231
232 {[]errorType{ParseFailure}, 1, 0, 0, 0},
233 {[]errorType{ParseFailure, VerifyFailed}, 0, 1, 1, 0},
234 {[]errorType{ParseFailure, VerifyFailed, FixFailed}, 0, 1, 0, 1},
235 }
236
237 for i, test := range counterTests {
238 f := &Fixer{}
239 var ferrs []*FixError
240 for _, err := range test.errors {
241 ferrs = append(ferrs, &FixError{Type: err})
242 }
243 f.updateCounters(nil, ferrs)
244
245 if f.reconstructed != test.reconstructed {
246 t.Errorf("#%d: Incorrect value for reconstructed, wanted %d, got %d", i, test.reconstructed, f.reconstructed)
247 }
248 if f.notReconstructed != test.notReconstructed {
249 t.Errorf("#%d: Incorrect value for notReconstructed, wanted %d, got %d", i, test.notReconstructed, f.notReconstructed)
250 }
251 if f.fixed != test.fixed {
252 t.Errorf("#%d: Incorrect value for fixed, wanted %d, got %d", i, test.fixed, f.fixed)
253 }
254 if f.notFixed != test.notFixed {
255 t.Errorf("#%d: Incorrect value for notFixed, wanted %d, got %d", i, test.notFixed, f.notFixed)
256 }
257 }
258 }
259
260
261 type fixerQueueTest struct {
262 cert string
263 chain []string
264 roots []string
265
266 dchain []string
267 }
268
269 var fixerQueueTests = []fixerQueueTest{
270 {
271 cert: googleLeaf,
272 chain: []string{verisignRoot, thawteIntermediate},
273 roots: []string{verisignRoot},
274
275 dchain: []string{"VeriSign", "Thawte"},
276 },
277 {
278 cert: googleLeaf,
279 chain: []string{verisignRoot, verisignRoot, thawteIntermediate},
280 roots: []string{verisignRoot},
281
282 dchain: []string{"VeriSign", "Thawte"},
283 },
284 {
285 cert: googleLeaf,
286 roots: []string{verisignRoot},
287
288 dchain: []string{},
289 },
290 }
291
292 func testFixerQueueChain(t *testing.T, i int, qt *fixerQueueTest, f *Fixer) {
293 defer f.wg.Done()
294 fix := <-f.toFix
295
296 matchTestChain(t, i, qt.dchain, fix.chain.certs)
297 }
298
299 func TestFixerQueueChain(t *testing.T) {
300 ch := make(chan *toFix)
301 defer close(ch)
302 f := &Fixer{toFix: ch}
303
304 for i, qt := range fixerQueueTests {
305 f.wg.Add(1)
306 go testFixerQueueChain(t, i, &qt, f)
307 chain := extractTestChain(t, i, qt.chain)
308 roots := extractTestRoots(t, i, qt.roots)
309 f.QueueChain(GetTestCertificateFromPEM(t, qt.cert), chain, roots)
310 f.wg.Wait()
311 }
312 }
313
View as plain text