...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package scanner
16
17 import (
18 "container/list"
19 "context"
20 "log"
21 "net/http"
22 "net/http/httptest"
23 "regexp"
24 "testing"
25
26 ct "github.com/google/certificate-transparency-go"
27 "github.com/google/certificate-transparency-go/client"
28 "github.com/google/certificate-transparency-go/jsonclient"
29 "github.com/google/certificate-transparency-go/x509"
30 )
31
32 func TestScannerMatchAll(t *testing.T) {
33 var cert x509.Certificate
34 m := &MatchAll{}
35 if !m.CertificateMatches(&cert) {
36 t.Fatal("MatchAll didn't match!")
37 }
38 }
39 func TestScannerMatchNone(t *testing.T) {
40 var cert x509.Certificate
41 m := &MatchNone{}
42 if m.CertificateMatches(&cert) {
43 t.Fatal("MatchNone matched!")
44 }
45 }
46
47 func TestScannerMatchSubjectRegexMatchesCertificateCommonName(t *testing.T) {
48 const SubjectName = "www.example.com"
49 const SubjectRegEx = ".*example.com"
50 var cert x509.Certificate
51 cert.Subject.CommonName = SubjectName
52
53 m := MatchSubjectRegex{regexp.MustCompile(SubjectRegEx), nil}
54 if !m.CertificateMatches(&cert) {
55 t.Fatal("MatchSubjectRegex failed to match on Cert Subject CommonName")
56 }
57 }
58
59 func TestScannerMatchSubjectRegexIgnoresDifferentCertificateCommonName(t *testing.T) {
60 const SubjectName = "www.google.com"
61 const SubjectRegEx = ".*example.com"
62 var cert x509.Certificate
63 cert.Subject.CommonName = SubjectName
64
65 m := MatchSubjectRegex{regexp.MustCompile(SubjectRegEx), nil}
66 if m.CertificateMatches(&cert) {
67 t.Fatal("MatchSubjectRegex incorrectly matched on Cert Subject CommonName")
68 }
69 }
70
71 func TestScannerMatchSubjectRegexIgnoresDifferentCertificateSAN(t *testing.T) {
72 const SubjectName = "www.google.com"
73 const SubjectRegEx = ".*example.com"
74 var cert x509.Certificate
75 cert.Subject.CommonName = SubjectName
76
77 m := MatchSubjectRegex{regexp.MustCompile(SubjectRegEx), nil}
78 cert.Subject.CommonName = "Wibble"
79 cert.DNSNames = append(cert.DNSNames, "Wibble")
80 cert.DNSNames = append(cert.DNSNames, SubjectName)
81
82 if m.CertificateMatches(&cert) {
83 t.Fatal("MatchSubjectRegex incorrectly matched on Cert SubjectAlternativeName")
84 }
85 }
86
87 func TestScannerMatchSubjectRegexMatchesCertificateSAN(t *testing.T) {
88 const SubjectName = "www.example.com"
89 const SubjectRegEx = ".*example.com"
90 var cert x509.Certificate
91 cert.Subject.CommonName = SubjectName
92
93 m := MatchSubjectRegex{regexp.MustCompile(SubjectRegEx), nil}
94 cert.Subject.CommonName = "Wibble"
95 cert.DNSNames = append(cert.DNSNames, "Wibble")
96 cert.DNSNames = append(cert.DNSNames, SubjectName)
97
98 if !m.CertificateMatches(&cert) {
99 t.Fatal("MatchSubjectRegex failed to match on Cert SubjectAlternativeName")
100 }
101 }
102
103 func TestScannerMatchSubjectRegexMatchesPrecertificateCommonName(t *testing.T) {
104 const SubjectName = "www.example.com"
105 const SubjectRegEx = ".*example.com"
106 var precert ct.Precertificate
107 precert.TBSCertificate = &x509.Certificate{}
108 precert.TBSCertificate.Subject.CommonName = SubjectName
109
110 m := MatchSubjectRegex{nil, regexp.MustCompile(SubjectRegEx)}
111 if !m.PrecertificateMatches(&precert) {
112 t.Fatal("MatchSubjectRegex failed to match on Precert Subject CommonName")
113 }
114 }
115
116 func TestScannerMatchSubjectRegexIgnoresDifferentPrecertificateCommonName(t *testing.T) {
117 const SubjectName = "www.google.com"
118 const SubjectRegEx = ".*example.com"
119 var precert ct.Precertificate
120 precert.TBSCertificate = &x509.Certificate{}
121 precert.TBSCertificate.Subject.CommonName = SubjectName
122
123 m := MatchSubjectRegex{nil, regexp.MustCompile(SubjectRegEx)}
124 if m.PrecertificateMatches(&precert) {
125 t.Fatal("MatchSubjectRegex incorrectly matched on Precert Subject CommonName")
126 }
127 }
128
129 func TestScannerMatchSubjectRegexIgnoresDifferentPrecertificateSAN(t *testing.T) {
130 const SubjectName = "www.google.com"
131 const SubjectRegEx = ".*example.com"
132 var precert ct.Precertificate
133 precert.TBSCertificate = &x509.Certificate{}
134 precert.TBSCertificate.Subject.CommonName = SubjectName
135
136 m := MatchSubjectRegex{nil, regexp.MustCompile(SubjectRegEx)}
137 precert.TBSCertificate.Subject.CommonName = "Wibble"
138 precert.TBSCertificate.DNSNames = append(precert.TBSCertificate.DNSNames, "Wibble")
139 precert.TBSCertificate.DNSNames = append(precert.TBSCertificate.DNSNames, SubjectName)
140
141 if m.PrecertificateMatches(&precert) {
142 t.Fatal("MatchSubjectRegex incorrectly matched on Precert SubjectAlternativeName")
143 }
144 }
145
146 func TestScannerMatchSubjectRegexMatchesPrecertificateSAN(t *testing.T) {
147 const SubjectName = "www.example.com"
148 const SubjectRegEx = ".*example.com"
149 var precert ct.Precertificate
150 precert.TBSCertificate = &x509.Certificate{}
151 precert.TBSCertificate.Subject.CommonName = SubjectName
152
153 m := MatchSubjectRegex{nil, regexp.MustCompile(SubjectRegEx)}
154 precert.TBSCertificate.Subject.CommonName = "Wibble"
155 precert.TBSCertificate.DNSNames = append(precert.TBSCertificate.DNSNames, "Wibble")
156 precert.TBSCertificate.DNSNames = append(precert.TBSCertificate.DNSNames, SubjectName)
157
158 if !m.PrecertificateMatches(&precert) {
159 t.Fatal("MatchSubjectRegex failed to match on Precert SubjectAlternativeName")
160 }
161 }
162
163 func TestScannerEndToEnd(t *testing.T) {
164 ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
165 switch r.URL.Path {
166 case "/ct/v1/get-sth":
167 log.Printf("GetSTH")
168 if _, err := w.Write([]byte(FourEntrySTH)); err != nil {
169 t.Fatal("Failed to write get-sth response")
170 }
171 case "/ct/v1/get-entries":
172 log.Printf("GetEntries %s", r.URL.RawQuery)
173 if _, err := w.Write([]byte(FourEntries)); err != nil {
174 t.Fatal("Failed to write get-sth response")
175 }
176 default:
177 t.Fatal("Unexpected request")
178 }
179 }))
180 defer ts.Close()
181
182 logClient, err := client.New(ts.URL, &http.Client{}, jsonclient.Options{})
183 if err != nil {
184 t.Fatal(err)
185 }
186 opts := ScannerOptions{
187 FetcherOptions: FetcherOptions{
188 BatchSize: 10,
189 ParallelFetch: 1,
190 StartIndex: 0,
191 },
192 Matcher: &MatchSubjectRegex{regexp.MustCompile(`.*\.google\.com`), nil},
193 NumWorkers: 1,
194 }
195 scanner := NewScanner(logClient, opts)
196
197 var matchedCerts list.List
198 var matchedPrecerts list.List
199
200 ctx := context.Background()
201 err = scanner.Scan(ctx, func(re *ct.RawLogEntry) {
202
203
204 e, _ := re.ToLogEntry()
205 if e.X509Cert == nil {
206 return
207 }
208 matchedCerts.PushBack(*e.X509Cert)
209 }, func(re *ct.RawLogEntry) {
210 e, _ := re.ToLogEntry()
211 if e.X509Cert == nil {
212 return
213 }
214 matchedPrecerts.PushBack(*e.Precert)
215 })
216
217 if err != nil {
218 t.Fatal(err)
219 }
220
221 if matchedPrecerts.Len() != 0 {
222 t.Fatal("Found unexpected Precert")
223 }
224
225 switch matchedCerts.Len() {
226 case 0:
227 t.Fatal("Failed to find mail.google.com cert")
228 case 1:
229 if matchedCerts.Front().Value.(x509.Certificate).Subject.CommonName != "mail.google.com" {
230 t.Fatal("Matched unexpected cert")
231 }
232 default:
233 t.Fatal("Found unexpected number of certs")
234 }
235 }
236
237 func TestDefaultScannerOptions(t *testing.T) {
238 opts := DefaultScannerOptions()
239 switch opts.Matcher.(type) {
240 case *MatchAll:
241
242 default:
243 t.Fatalf("Default Matcher is a %T, expected MatchAll.", opts.Matcher)
244 }
245 if opts.PrecertOnly {
246 t.Fatal("Expected PrecertOnly to be false.")
247 }
248 if opts.BatchSize < 1 {
249 t.Fatalf("Insane BatchSize %d", opts.BatchSize)
250 }
251 if opts.NumWorkers < 1 {
252 t.Fatalf("Insane NumWorkers %d", opts.NumWorkers)
253 }
254 if opts.ParallelFetch < 1 {
255 t.Fatalf("Insane ParallelFetch %d", opts.ParallelFetch)
256 }
257 if opts.StartIndex != 0 {
258 t.Fatalf("Expected StartIndex to be 0, but was %d", opts.StartIndex)
259 }
260 }
261
View as plain text