Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(676)

Side by Side Diff: net/cert/internal/cert_issuer_source_aia_unittest.cc

Issue 2036033002: Add CertIssuerSourceAia: authorityInfoAccess fetching for CertPathBuilder. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@cert-parsing-path-building
Patch Set: review changes Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/cert/internal/cert_issuer_source_aia.h"
6
7 #include "base/bind.h"
8 #include "net/cert/internal/parsed_certificate.h"
9 #include "net/cert/internal/test_helpers.h"
10 #include "testing/gmock/include/gmock/gmock.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "url/gurl.h"
13
14 namespace net {
15
16 namespace {
17
18 using ::testing::Mock;
19 using ::testing::StrictMock;
20
21 ::testing::AssertionResult ReadTestPem(const std::string& file_name,
22 const std::string& block_name,
23 std::string* result) {
24 const PemBlockMapping mappings[] = {
25 {block_name.c_str(), result},
26 };
27
28 return ReadTestDataFromPemFile(file_name, mappings);
29 }
30
31 ::testing::AssertionResult ReadTestCert(
32 const std::string& file_name,
33 scoped_refptr<ParsedCertificate>* result) {
34 std::string der;
35 ::testing::AssertionResult r =
36 ReadTestPem("net/data/cert_issuer_source_aia_unittest/" + file_name,
37 "CERTIFICATE", &der);
38 if (!r)
39 return r;
40 *result = ParsedCertificate::CreateFromCertificateCopy(der);
41 if (!*result)
42 return ::testing::AssertionFailure() << "CreateFromCertificateCopy failed";
43 return ::testing::AssertionSuccess();
44 }
45
46 std::vector<uint8_t> CertDataVector(const ParsedCertificate* cert) {
47 std::vector<uint8_t> data(
48 cert->der_cert().UnsafeData(),
49 cert->der_cert().UnsafeData() + cert->der_cert().Length());
50 return data;
51 }
52
53 class RequestManager {
eroman 2016/06/04 01:08:48 Please add a comment for this class.
mattm 2016/06/04 03:24:08 Done.
54 public:
55 class Request : public CertNetFetcher::Request {
56 public:
57 Request(RequestManager* manager,
58 const CertNetFetcher::FetchCallback& callback)
59 : manager_(manager), callback_(callback) {}
60 ~Request() override { manager_->RequestWasDestroyed(); }
61
62 CertNetFetcher::FetchCallback get_callback() const { return callback_; }
63
64 private:
65 RequestManager* manager_;
66 CertNetFetcher::FetchCallback callback_;
67 };
68
69 ~RequestManager() { CHECK_EQ(nullptr, request_); }
eroman 2016/06/04 01:08:48 ASSERT_FALSE ?
mattm 2016/06/04 03:24:08 If the request is still alive it'll try to access
70
71 std::unique_ptr<Request> CreateRequest(
72 const CertNetFetcher::FetchCallback& callback) {
73 CHECK_EQ(nullptr, request_);
eroman 2016/06/04 01:08:47 EXPECT_FALSE() ?
mattm 2016/06/04 03:24:08 Done.
74 std::unique_ptr<Request> request(new Request(this, callback));
75 request_ = request.get();
76 return request;
77 }
78
79 bool is_request_alive() const { return request_; }
80
81 CertNetFetcher::FetchCallback get_callback() const {
82 CHECK(is_request_alive());
83 return request_->get_callback();
84 }
85
86 private:
87 void RequestWasDestroyed() {
88 CHECK_NE(nullptr, request_);
89 request_ = nullptr;
90 }
91
92 Request* request_;
93 };
94
95 // MockCertNetFetcherImpl is an implementation of CertNetFetcher for testing.
96 class MockCertNetFetcherImpl : public CertNetFetcher {
97 public:
98 MockCertNetFetcherImpl() = default;
99 ~MockCertNetFetcherImpl() override = default;
100
101 RequestManager* GetRequestManagerForURL(const GURL& url) {
102 auto it = request_map_.find(url);
103 if (it == request_map_.end())
104 return nullptr;
105 return it->second.get();
106 }
107
108 WARN_UNUSED_RESULT std::unique_ptr<Request> FetchCaIssuers(
109 const GURL& url,
110 int timeout_milliseconds,
111 int max_response_bytes,
112 const FetchCallback& callback) override {
113 CHECK(request_map_.find(url) == request_map_.end());
eroman 2016/06/04 01:08:48 I think the ASSERT_* / EXPECT_* stuff is preferabl
mattm 2016/06/04 03:24:08 Done.
114
115 std::unique_ptr<RequestManager> request_manager(new RequestManager());
116
117 std::unique_ptr<Request> request = request_manager->CreateRequest(callback);
118
119 request_map_[url] = std::move(request_manager);
120
121 return request;
122 }
123
124 WARN_UNUSED_RESULT std::unique_ptr<Request> FetchCrl(
125 const GURL& url,
126 int timeout_milliseconds,
127 int max_response_bytes,
128 const FetchCallback& callback) override {
129 NOTREACHED();
130 return nullptr;
131 }
132
133 WARN_UNUSED_RESULT std::unique_ptr<Request> FetchOcsp(
134 const GURL& url,
135 int timeout_milliseconds,
136 int max_response_bytes,
137 const FetchCallback& callback) override {
138 NOTREACHED();
139 return nullptr;
140 }
141
142 private:
143 // std::map<GURL, RequestImpl*> request_map_;
eroman 2016/06/04 01:08:48 uncomment or delete.
mattm 2016/06/04 03:24:08 Done.
144 std::map<GURL, std::unique_ptr<RequestManager>> request_map_;
145
146 DISALLOW_COPY_AND_ASSIGN(MockCertNetFetcherImpl);
147 };
148
149 class MockIssuerCallback {
150 public:
151 MOCK_METHOD1(Callback, void(CertIssuerSource::Request*));
152 };
153
154 void NotCalled(CertIssuerSource::Request* request) {
155 ADD_FAILURE() << "NotCalled was called";
156 }
157
158 // CertIssuerSourceAia does not return results for SyncGetIssuersOf.
159 TEST(CertIssuerSourceAiaUnittest, NoSyncResults) {
eroman 2016/06/04 01:08:47 nit: Rather than suffix of Unittest --> suffix of
mattm 2016/06/04 03:24:08 Done.
160 scoped_refptr<ParsedCertificate> cert;
161 ASSERT_TRUE(ReadTestCert("target_two_aia.pem", &cert));
162
163 StrictMock<MockCertNetFetcherImpl> mock_fetcher;
164 CertIssuerSourceAia aia_source(&mock_fetcher);
165 std::vector<scoped_refptr<ParsedCertificate>> issuers;
166 aia_source.SyncGetIssuersOf(cert.get(), &issuers);
167 EXPECT_EQ(0U, issuers.size());
168 }
169
170 // If the AuthorityInfoAccess extension is not present, AsyncGetIssuersOf should
171 // synchronously indicate no results.
172 TEST(CertIssuerSourceAiaUnittest, NoAia) {
173 scoped_refptr<ParsedCertificate> cert;
174 ASSERT_TRUE(ReadTestCert("target_no_aia.pem", &cert));
175
176 StrictMock<MockCertNetFetcherImpl> mock_fetcher;
177 CertIssuerSourceAia aia_source(&mock_fetcher);
178 std::unique_ptr<CertIssuerSource::Request> request;
179 aia_source.AsyncGetIssuersOf(cert.get(), base::Bind(&NotCalled), &request);
180 EXPECT_EQ(nullptr, request);
181 }
182
183 // If the AuthorityInfoAccess extension only contains non-http URIs,
184 // AsyncGetIssuersOf should create a Request object. The URL scheme check is
185 // part of the specific CertNetFetcher implementation, this tests that we handle
186 // ERR_DISALLOWED_URL_SCHEME properly. If FetchCaIssuers is modified to fail
187 // synchronously in that case, this test will be more interesting.
188 TEST(CertIssuerSourceAiaUnittest, FileAia) {
189 scoped_refptr<ParsedCertificate> cert;
190 ASSERT_TRUE(ReadTestCert("target_file_aia.pem", &cert));
191
192 StrictMock<MockIssuerCallback> mock_callback;
193 StrictMock<MockCertNetFetcherImpl> mock_fetcher;
194 CertIssuerSourceAia aia_source(&mock_fetcher);
195 std::unique_ptr<CertIssuerSource::Request> cert_source_request;
196 aia_source.AsyncGetIssuersOf(cert.get(),
197 base::Bind(&MockIssuerCallback::Callback,
198 base::Unretained(&mock_callback)),
199 &cert_source_request);
200 ASSERT_NE(nullptr, cert_source_request);
201
202 RequestManager* req_manager =
203 mock_fetcher.GetRequestManagerForURL(GURL("file:///dev/null"));
204 ASSERT_TRUE(req_manager);
205 ASSERT_TRUE(req_manager->is_request_alive());
206
207 EXPECT_CALL(mock_callback, Callback(cert_source_request.get()));
208 // CertNetFetcher rejects the URL scheme.
209 req_manager->get_callback().Run(ERR_DISALLOWED_URL_SCHEME,
210 std::vector<uint8_t>());
211 Mock::VerifyAndClearExpectations(&mock_callback);
212
213 // No results.
214 scoped_refptr<ParsedCertificate> result_cert;
215 CompletionStatus status = cert_source_request->GetNext(&result_cert);
216 EXPECT_EQ(CompletionStatus::SYNC, status);
217 EXPECT_FALSE(result_cert.get());
218 }
219
220 // If the AuthorityInfoAccess extension contains an invalid URL,
221 // AsyncGetIssuersOf should synchronously indicate no results.
222 TEST(CertIssuerSourceAiaUnittest, OneInvalidURL) {
223 scoped_refptr<ParsedCertificate> cert;
224 ASSERT_TRUE(ReadTestCert("target_invalid_url_aia.pem", &cert));
225
226 StrictMock<MockCertNetFetcherImpl> mock_fetcher;
227 CertIssuerSourceAia aia_source(&mock_fetcher);
228 std::unique_ptr<CertIssuerSource::Request> request;
229 aia_source.AsyncGetIssuersOf(cert.get(), base::Bind(&NotCalled), &request);
230 EXPECT_EQ(nullptr, request);
231 }
232
233 // AuthorityInfoAccess with a single HTTP url pointing to a single DER cert.
234 TEST(CertIssuerSourceAiaUnittest, OneAia) {
235 scoped_refptr<ParsedCertificate> cert;
236 ASSERT_TRUE(ReadTestCert("target_one_aia.pem", &cert));
237 scoped_refptr<ParsedCertificate> intermediate_cert;
238 ASSERT_TRUE(ReadTestCert("i.pem", &intermediate_cert));
239
240 StrictMock<MockIssuerCallback> mock_callback;
241 StrictMock<MockCertNetFetcherImpl> mock_fetcher;
242 CertIssuerSourceAia aia_source(&mock_fetcher);
243 std::unique_ptr<CertIssuerSource::Request> cert_source_request;
244 aia_source.AsyncGetIssuersOf(cert.get(),
245 base::Bind(&MockIssuerCallback::Callback,
246 base::Unretained(&mock_callback)),
247 &cert_source_request);
248 ASSERT_NE(nullptr, cert_source_request);
249
250 RequestManager* req_manager =
251 mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia/I.cer"));
252 ASSERT_TRUE(req_manager);
253 ASSERT_TRUE(req_manager->is_request_alive());
254
255 EXPECT_CALL(mock_callback, Callback(cert_source_request.get()));
256 req_manager->get_callback().Run(OK, CertDataVector(intermediate_cert.get()));
257 Mock::VerifyAndClearExpectations(&mock_callback);
258
259 scoped_refptr<ParsedCertificate> result_cert;
260 CompletionStatus status = cert_source_request->GetNext(&result_cert);
261 EXPECT_EQ(CompletionStatus::SYNC, status);
262 ASSERT_TRUE(result_cert.get());
263 ASSERT_EQ(result_cert->der_cert(), intermediate_cert->der_cert());
264
265 status = cert_source_request->GetNext(&result_cert);
266 EXPECT_EQ(CompletionStatus::SYNC, status);
267 EXPECT_FALSE(result_cert.get());
268
269 EXPECT_TRUE(req_manager->is_request_alive());
270 cert_source_request.reset();
271 EXPECT_FALSE(req_manager->is_request_alive());
272 }
273
274 // AuthorityInfoAccess with two URIs, one a FILE, the other a HTTP.
275 // Simulate a ERR_DISALLOWED_URL_SCHEME for the file URL. If FetchCaIssuers is
276 // modified to synchronously reject disallowed schemes, this test will be more
277 // interesting.
278 TEST(CertIssuerSourceAiaUnittest, OneFileOneHttpAia) {
279 scoped_refptr<ParsedCertificate> cert;
280 ASSERT_TRUE(ReadTestCert("target_file_and_http_aia.pem", &cert));
281 scoped_refptr<ParsedCertificate> intermediate_cert;
282 ASSERT_TRUE(ReadTestCert("i2.pem", &intermediate_cert));
283
284 StrictMock<MockIssuerCallback> mock_callback;
285 StrictMock<MockCertNetFetcherImpl> mock_fetcher;
286 CertIssuerSourceAia aia_source(&mock_fetcher);
287 std::unique_ptr<CertIssuerSource::Request> cert_source_request;
288 aia_source.AsyncGetIssuersOf(cert.get(),
289 base::Bind(&MockIssuerCallback::Callback,
290 base::Unretained(&mock_callback)),
291 &cert_source_request);
292 ASSERT_NE(nullptr, cert_source_request);
293
294 RequestManager* req_manager =
295 mock_fetcher.GetRequestManagerForURL(GURL("file:///dev/null"));
296 ASSERT_TRUE(req_manager);
297 ASSERT_TRUE(req_manager->is_request_alive());
298
299 RequestManager* req_manager2 =
300 mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia2/I2.foo"));
301 ASSERT_TRUE(req_manager2);
302 ASSERT_TRUE(req_manager2->is_request_alive());
303
304 // Request for file URL completes with disallowed scheme failure. Callback is
305 // NOT called.
306 req_manager->get_callback().Run(ERR_DISALLOWED_URL_SCHEME,
307 std::vector<uint8_t>());
308 Mock::VerifyAndClearExpectations(&mock_callback);
309
310 // Request for I2.foo completes. Callback should be called now.
311 EXPECT_CALL(mock_callback, Callback(cert_source_request.get()));
312 req_manager2->get_callback().Run(OK, CertDataVector(intermediate_cert.get()));
313 Mock::VerifyAndClearExpectations(&mock_callback);
314
315 scoped_refptr<ParsedCertificate> result_cert;
316 CompletionStatus status = cert_source_request->GetNext(&result_cert);
317 EXPECT_EQ(CompletionStatus::SYNC, status);
318 ASSERT_TRUE(result_cert.get());
319 ASSERT_EQ(result_cert->der_cert(), intermediate_cert->der_cert());
320
321 status = cert_source_request->GetNext(&result_cert);
322 EXPECT_EQ(CompletionStatus::SYNC, status);
323 EXPECT_FALSE(result_cert.get());
324
325 EXPECT_TRUE(req_manager2->is_request_alive());
326 cert_source_request.reset();
327 EXPECT_FALSE(req_manager2->is_request_alive());
328 }
329
330 // AuthorityInfoAccess with two URIs, one is invalid, the other HTTP.
331 TEST(CertIssuerSourceAiaUnittest, OneInvalidOneHttpAia) {
332 scoped_refptr<ParsedCertificate> cert;
333 ASSERT_TRUE(ReadTestCert("target_invalid_and_http_aia.pem", &cert));
334 scoped_refptr<ParsedCertificate> intermediate_cert;
335 ASSERT_TRUE(ReadTestCert("i2.pem", &intermediate_cert));
336
337 StrictMock<MockIssuerCallback> mock_callback;
338 StrictMock<MockCertNetFetcherImpl> mock_fetcher;
339 CertIssuerSourceAia aia_source(&mock_fetcher);
340 std::unique_ptr<CertIssuerSource::Request> cert_source_request;
341 aia_source.AsyncGetIssuersOf(cert.get(),
342 base::Bind(&MockIssuerCallback::Callback,
343 base::Unretained(&mock_callback)),
344 &cert_source_request);
345 ASSERT_NE(nullptr, cert_source_request);
346
347 RequestManager* req_manager =
348 mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia2/I2.foo"));
349 ASSERT_TRUE(req_manager);
350 ASSERT_TRUE(req_manager->is_request_alive());
351
352 EXPECT_CALL(mock_callback, Callback(cert_source_request.get()));
353 req_manager->get_callback().Run(OK, CertDataVector(intermediate_cert.get()));
354 Mock::VerifyAndClearExpectations(&mock_callback);
355
356 scoped_refptr<ParsedCertificate> result_cert;
357 CompletionStatus status = cert_source_request->GetNext(&result_cert);
358 EXPECT_EQ(CompletionStatus::SYNC, status);
359 ASSERT_TRUE(result_cert.get());
360 ASSERT_EQ(result_cert->der_cert(), intermediate_cert->der_cert());
361
362 status = cert_source_request->GetNext(&result_cert);
363 EXPECT_EQ(CompletionStatus::SYNC, status);
364 EXPECT_FALSE(result_cert.get());
365
366 EXPECT_TRUE(req_manager->is_request_alive());
367 cert_source_request.reset();
368 EXPECT_FALSE(req_manager->is_request_alive());
369 }
370
371 // AuthorityInfoAccess with two HTTP urls, each pointing to a single DER cert.
372 // One request completes, results are retrieved, then the next request completes
373 // and the results are retrieved.
374 TEST(CertIssuerSourceAiaUnittest, TwoAiaCompletedInSeries) {
375 scoped_refptr<ParsedCertificate> cert;
376 ASSERT_TRUE(ReadTestCert("target_two_aia.pem", &cert));
377 scoped_refptr<ParsedCertificate> intermediate_cert;
378 ASSERT_TRUE(ReadTestCert("i.pem", &intermediate_cert));
379 scoped_refptr<ParsedCertificate> intermediate_cert2;
380 ASSERT_TRUE(ReadTestCert("i2.pem", &intermediate_cert2));
381
382 StrictMock<MockIssuerCallback> mock_callback;
383 StrictMock<MockCertNetFetcherImpl> mock_fetcher;
384 CertIssuerSourceAia aia_source(&mock_fetcher);
385 std::unique_ptr<CertIssuerSource::Request> cert_source_request;
386 aia_source.AsyncGetIssuersOf(cert.get(),
387 base::Bind(&MockIssuerCallback::Callback,
388 base::Unretained(&mock_callback)),
389 &cert_source_request);
390 ASSERT_NE(nullptr, cert_source_request);
391
392 RequestManager* req_manager =
393 mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia/I.cer"));
394 ASSERT_TRUE(req_manager);
395 ASSERT_TRUE(req_manager->is_request_alive());
396
397 RequestManager* req_manager2 =
398 mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia2/I2.foo"));
399 ASSERT_TRUE(req_manager2);
400 ASSERT_TRUE(req_manager2->is_request_alive());
401
402 // Request for I.cer completes first.
403 EXPECT_CALL(mock_callback, Callback(cert_source_request.get()));
404 req_manager->get_callback().Run(OK, CertDataVector(intermediate_cert.get()));
405 Mock::VerifyAndClearExpectations(&mock_callback);
406
407 // Results are retrieved before the other request completes.
408 scoped_refptr<ParsedCertificate> result_cert;
409 CompletionStatus status = cert_source_request->GetNext(&result_cert);
410 EXPECT_EQ(CompletionStatus::SYNC, status);
411 ASSERT_TRUE(result_cert.get());
412 ASSERT_EQ(result_cert->der_cert(), intermediate_cert->der_cert());
413
414 status = cert_source_request->GetNext(&result_cert);
415 // The other http request is still pending, status should be ASYNC to signify
416 // the need to wait for another callback.
417 ASSERT_EQ(CompletionStatus::ASYNC, status);
418 EXPECT_FALSE(result_cert.get());
419
420 // Request for I2.foo completes.
421 ASSERT_TRUE(req_manager2->is_request_alive());
422 EXPECT_CALL(mock_callback, Callback(cert_source_request.get()));
423 req_manager2->get_callback().Run(OK,
424 CertDataVector(intermediate_cert2.get()));
425 Mock::VerifyAndClearExpectations(&mock_callback);
426
427 // Results from the second http request are retrieved.
428 status = cert_source_request->GetNext(&result_cert);
429 EXPECT_EQ(CompletionStatus::SYNC, status);
430 ASSERT_TRUE(result_cert.get());
431 ASSERT_EQ(result_cert->der_cert(), intermediate_cert2->der_cert());
432
433 // No more results.
434 status = cert_source_request->GetNext(&result_cert);
435 ASSERT_EQ(CompletionStatus::SYNC, status);
436 EXPECT_FALSE(result_cert.get());
437
438 EXPECT_TRUE(req_manager->is_request_alive());
439 EXPECT_TRUE(req_manager2->is_request_alive());
440 cert_source_request.reset();
441 EXPECT_FALSE(req_manager->is_request_alive());
442 EXPECT_FALSE(req_manager2->is_request_alive());
443 }
444
445 // AuthorityInfoAccess with two HTTP urls, each pointing to a single DER cert.
446 // Both HTTP requests complete before the results are retrieved from the
447 // CertIssuerSourceAia. There should only be a single callback since the 2nd
448 // HTTP request completed before GetNext was called, so both requests can be
449 // supplied to the caller in the same batch.
450 TEST(CertIssuerSourceAiaUnittest, TwoAiaCompletedBeforeGetNext) {
451 scoped_refptr<ParsedCertificate> cert;
452 ASSERT_TRUE(ReadTestCert("target_two_aia.pem", &cert));
453 scoped_refptr<ParsedCertificate> intermediate_cert;
454 ASSERT_TRUE(ReadTestCert("i.pem", &intermediate_cert));
455 scoped_refptr<ParsedCertificate> intermediate_cert2;
456 ASSERT_TRUE(ReadTestCert("i2.pem", &intermediate_cert2));
457
458 StrictMock<MockIssuerCallback> mock_callback;
459 StrictMock<MockCertNetFetcherImpl> mock_fetcher;
460 CertIssuerSourceAia aia_source(&mock_fetcher);
461 std::unique_ptr<CertIssuerSource::Request> cert_source_request;
462 aia_source.AsyncGetIssuersOf(cert.get(),
463 base::Bind(&MockIssuerCallback::Callback,
464 base::Unretained(&mock_callback)),
465 &cert_source_request);
466 ASSERT_NE(nullptr, cert_source_request);
467
468 RequestManager* req_manager =
469 mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia/I.cer"));
470 ASSERT_TRUE(req_manager);
471 ASSERT_TRUE(req_manager->is_request_alive());
472
473 RequestManager* req_manager2 =
474 mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia2/I2.foo"));
475 ASSERT_TRUE(req_manager2);
476 ASSERT_TRUE(req_manager2->is_request_alive());
477
478 // First HTTP request completes. Callback is called as soon as the first
479 // request completes.
480 EXPECT_CALL(mock_callback, Callback(cert_source_request.get()));
481 req_manager->get_callback().Run(OK, CertDataVector(intermediate_cert.get()));
482 Mock::VerifyAndClearExpectations(&mock_callback);
483
484 // Second HTTP request completes before any results were retrieved from the
485 // CertIssuerSourceAia. The callback should not be called again.
486 ASSERT_TRUE(req_manager2->is_request_alive());
487 req_manager2->get_callback().Run(OK,
488 CertDataVector(intermediate_cert2.get()));
489
490 // Caller retrieves results. Both certs should be supplied.
491 scoped_refptr<ParsedCertificate> result_cert;
492 CompletionStatus status = cert_source_request->GetNext(&result_cert);
493 EXPECT_EQ(CompletionStatus::SYNC, status);
494 ASSERT_TRUE(result_cert.get());
495 ASSERT_EQ(result_cert->der_cert(), intermediate_cert->der_cert());
496
497 // 2nd cert is retrieved.
498 status = cert_source_request->GetNext(&result_cert);
499 EXPECT_EQ(CompletionStatus::SYNC, status);
500 ASSERT_TRUE(result_cert.get());
501 ASSERT_EQ(result_cert->der_cert(), intermediate_cert2->der_cert());
502
503 // All results are done, SYNC signals completion.
504 status = cert_source_request->GetNext(&result_cert);
505 ASSERT_EQ(CompletionStatus::SYNC, status);
506 EXPECT_FALSE(result_cert.get());
507 }
508
509 // AuthorityInfoAccess with three HTTP urls, each pointing to a single DER cert.
510 //
511 // 1) Two HTTP requests complete before the results are retrieved from the
512 // CertIssuerSourceAia.
513 // 2) A single cert result is retrieved via GetNext.
514 // 3) The third HTTP request completes.
515 // 4) The remaining two certs are retrieved.
516 //
517 // Only one callback should occur (after the first HTTP request completed),
518 // since the pending cert results weren't exhausted before the 3rd request
519 // completed.
520 TEST(CertIssuerSourceAiaUnittest, AiaRequestCompletesDuringGetNextSequence) {
521 scoped_refptr<ParsedCertificate> cert;
522 ASSERT_TRUE(ReadTestCert("target_three_aia.pem", &cert));
523 scoped_refptr<ParsedCertificate> intermediate_cert;
524 ASSERT_TRUE(ReadTestCert("i.pem", &intermediate_cert));
525 scoped_refptr<ParsedCertificate> intermediate_cert2;
526 ASSERT_TRUE(ReadTestCert("i2.pem", &intermediate_cert2));
527 scoped_refptr<ParsedCertificate> intermediate_cert3;
528 ASSERT_TRUE(ReadTestCert("i3.pem", &intermediate_cert3));
529
530 StrictMock<MockIssuerCallback> mock_callback;
531 StrictMock<MockCertNetFetcherImpl> mock_fetcher;
532 CertIssuerSourceAia aia_source(&mock_fetcher);
533 std::unique_ptr<CertIssuerSource::Request> cert_source_request;
534 aia_source.AsyncGetIssuersOf(cert.get(),
535 base::Bind(&MockIssuerCallback::Callback,
536 base::Unretained(&mock_callback)),
537 &cert_source_request);
538 ASSERT_NE(nullptr, cert_source_request);
539
540 RequestManager* req_manager =
541 mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia/I.cer"));
542 ASSERT_TRUE(req_manager);
543 ASSERT_TRUE(req_manager->is_request_alive());
544
545 RequestManager* req_manager2 =
546 mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia2/I2.foo"));
547 ASSERT_TRUE(req_manager2);
548 ASSERT_TRUE(req_manager2->is_request_alive());
549
550 RequestManager* req_manager3 =
551 mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia3/I3.foo"));
552 ASSERT_TRUE(req_manager3);
553 ASSERT_TRUE(req_manager3->is_request_alive());
554
555 // First HTTP request completes. Callback is called as soon as the first
556 // request completes.
557 EXPECT_CALL(mock_callback, Callback(cert_source_request.get()));
558 req_manager->get_callback().Run(OK, CertDataVector(intermediate_cert.get()));
559 Mock::VerifyAndClearExpectations(&mock_callback);
560
561 // Second HTTP request completes before any results were retrieved from the
562 // CertIssuerSourceAia. The callback should not be called again.
563 ASSERT_TRUE(req_manager2->is_request_alive());
564 req_manager2->get_callback().Run(OK,
565 CertDataVector(intermediate_cert2.get()));
566
567 // Caller retrieves a single result.
568 scoped_refptr<ParsedCertificate> result_cert;
569 CompletionStatus status = cert_source_request->GetNext(&result_cert);
570 EXPECT_EQ(CompletionStatus::SYNC, status);
571 ASSERT_TRUE(result_cert.get());
572 ASSERT_EQ(result_cert->der_cert(), intermediate_cert->der_cert());
573
574 // Third HTTP request completes.
575 // The callback should not be called again, since the last GetNext call had
576 // indicated more results were pending still.
577 ASSERT_TRUE(req_manager3->is_request_alive());
578 req_manager3->get_callback().Run(OK,
579 CertDataVector(intermediate_cert3.get()));
580
581 // 2nd cert is retrieved.
582 status = cert_source_request->GetNext(&result_cert);
583 EXPECT_EQ(CompletionStatus::SYNC, status);
584 ASSERT_TRUE(result_cert.get());
585 ASSERT_EQ(result_cert->der_cert(), intermediate_cert2->der_cert());
586
587 // 3rd cert is retrieved.
588 status = cert_source_request->GetNext(&result_cert);
589 EXPECT_EQ(CompletionStatus::SYNC, status);
590 ASSERT_TRUE(result_cert.get());
591 ASSERT_EQ(result_cert->der_cert(), intermediate_cert3->der_cert());
592
593 // All results are done, SYNC signals completion.
594 status = cert_source_request->GetNext(&result_cert);
595 ASSERT_EQ(CompletionStatus::SYNC, status);
596 EXPECT_FALSE(result_cert.get());
597 }
598
599 // AuthorityInfoAccess with a single HTTP url pointing to a single DER cert,
eroman 2016/06/04 01:08:47 nice set of test cases btw!
mattm 2016/06/04 03:24:08 Thanks :)
600 // CertNetFetcher request fails. The callback should be called to indicate the
601 // request is complete, but no results should be provided.
602 TEST(CertIssuerSourceAiaUnittest, OneAiaHttpError) {
603 scoped_refptr<ParsedCertificate> cert;
604 ASSERT_TRUE(ReadTestCert("target_one_aia.pem", &cert));
605
606 StrictMock<MockIssuerCallback> mock_callback;
607 StrictMock<MockCertNetFetcherImpl> mock_fetcher;
608 CertIssuerSourceAia aia_source(&mock_fetcher);
609 std::unique_ptr<CertIssuerSource::Request> cert_source_request;
610 aia_source.AsyncGetIssuersOf(cert.get(),
611 base::Bind(&MockIssuerCallback::Callback,
612 base::Unretained(&mock_callback)),
613 &cert_source_request);
614 ASSERT_NE(nullptr, cert_source_request);
615
616 RequestManager* req_manager =
617 mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia/I.cer"));
618 ASSERT_TRUE(req_manager);
619 ASSERT_TRUE(req_manager->is_request_alive());
620
621 EXPECT_CALL(mock_callback, Callback(cert_source_request.get()));
622 // HTTP request returns with an error.
623 req_manager->get_callback().Run(ERR_FAILED, std::vector<uint8_t>());
624 Mock::VerifyAndClearExpectations(&mock_callback);
625
626 scoped_refptr<ParsedCertificate> result_cert;
627 CompletionStatus status = cert_source_request->GetNext(&result_cert);
628 EXPECT_EQ(CompletionStatus::SYNC, status);
629 EXPECT_FALSE(result_cert.get());
630 }
631
632 // AuthorityInfoAccess with a single HTTP url pointing to a single DER cert,
633 // CertNetFetcher request completes, but the DER cert fails to parse. The
634 // callback should be called to indicate the request is complete, but no results
635 // should be provided.
636 TEST(CertIssuerSourceAiaUnittest, OneAiaParseError) {
637 scoped_refptr<ParsedCertificate> cert;
638 ASSERT_TRUE(ReadTestCert("target_one_aia.pem", &cert));
639
640 StrictMock<MockIssuerCallback> mock_callback;
641 StrictMock<MockCertNetFetcherImpl> mock_fetcher;
642 CertIssuerSourceAia aia_source(&mock_fetcher);
643 std::unique_ptr<CertIssuerSource::Request> cert_source_request;
644 aia_source.AsyncGetIssuersOf(cert.get(),
645 base::Bind(&MockIssuerCallback::Callback,
646 base::Unretained(&mock_callback)),
647 &cert_source_request);
648 ASSERT_NE(nullptr, cert_source_request);
649
650 RequestManager* req_manager =
651 mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia/I.cer"));
652 ASSERT_TRUE(req_manager);
653 ASSERT_TRUE(req_manager->is_request_alive());
654
655 EXPECT_CALL(mock_callback, Callback(cert_source_request.get()));
656 // HTTP request returns with an error.
657 uint8_t data[] = {1, 2, 3, 4, 5};
658 req_manager->get_callback().Run(
659 OK, std::vector<uint8_t>(data, data + arraysize(data)));
eroman 2016/06/04 01:08:47 i believe you can use uniform initialization notat
mattm 2016/06/04 03:24:08 Ah, cool. Done.
660 Mock::VerifyAndClearExpectations(&mock_callback);
661
662 scoped_refptr<ParsedCertificate> result_cert;
663 CompletionStatus status = cert_source_request->GetNext(&result_cert);
664 EXPECT_EQ(CompletionStatus::SYNC, status);
665 EXPECT_FALSE(result_cert.get());
666 }
667
668 // AuthorityInfoAccess with two HTTP urls, each pointing to a single DER cert.
669 // One request fails. No callback should be generated yet. Once the second
670 // request completes, the callback should occur.
671 TEST(CertIssuerSourceAiaUnittest, TwoAiaCompletedInSeriesFirstFails) {
672 scoped_refptr<ParsedCertificate> cert;
673 ASSERT_TRUE(ReadTestCert("target_two_aia.pem", &cert));
674 scoped_refptr<ParsedCertificate> intermediate_cert2;
675 ASSERT_TRUE(ReadTestCert("i2.pem", &intermediate_cert2));
676
677 StrictMock<MockIssuerCallback> mock_callback;
678 StrictMock<MockCertNetFetcherImpl> mock_fetcher;
679 CertIssuerSourceAia aia_source(&mock_fetcher);
680 std::unique_ptr<CertIssuerSource::Request> cert_source_request;
681 aia_source.AsyncGetIssuersOf(cert.get(),
682 base::Bind(&MockIssuerCallback::Callback,
683 base::Unretained(&mock_callback)),
684 &cert_source_request);
685 ASSERT_NE(nullptr, cert_source_request);
686
687 RequestManager* req_manager =
688 mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia/I.cer"));
689 ASSERT_TRUE(req_manager);
690 ASSERT_TRUE(req_manager->is_request_alive());
691
692 RequestManager* req_manager2 =
693 mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia2/I2.foo"));
694 ASSERT_TRUE(req_manager2);
695 ASSERT_TRUE(req_manager2->is_request_alive());
696
697 // Request for I.cer completes first, but fails. Callback is NOT called.
698 req_manager->get_callback().Run(ERR_INVALID_RESPONSE, std::vector<uint8_t>());
699 Mock::VerifyAndClearExpectations(&mock_callback);
700
701 // Request for I2.foo completes. Callback should be called now.
702 ASSERT_TRUE(req_manager2->is_request_alive());
703 EXPECT_CALL(mock_callback, Callback(cert_source_request.get()));
704 req_manager2->get_callback().Run(OK,
705 CertDataVector(intermediate_cert2.get()));
706 Mock::VerifyAndClearExpectations(&mock_callback);
707
708 // Results from the second http request are retrieved.
709 scoped_refptr<ParsedCertificate> result_cert;
710 CompletionStatus status = cert_source_request->GetNext(&result_cert);
711 EXPECT_EQ(CompletionStatus::SYNC, status);
712 ASSERT_TRUE(result_cert.get());
713 ASSERT_EQ(result_cert->der_cert(), intermediate_cert2->der_cert());
714
715 // No more results.
716 status = cert_source_request->GetNext(&result_cert);
717 ASSERT_EQ(CompletionStatus::SYNC, status);
718 EXPECT_FALSE(result_cert.get());
719 }
720
721 // AuthorityInfoAccess with two HTTP urls, each pointing to a single DER cert.
722 // First request completes, result is retrieved, then the second request fails.
723 // The second callback should occur to indicate that the results are exhausted,
724 // even though no more results are available.
725 TEST(CertIssuerSourceAiaUnittest, TwoAiaCompletedInSeriesSecondFails) {
726 scoped_refptr<ParsedCertificate> cert;
727 ASSERT_TRUE(ReadTestCert("target_two_aia.pem", &cert));
728 scoped_refptr<ParsedCertificate> intermediate_cert;
729 ASSERT_TRUE(ReadTestCert("i.pem", &intermediate_cert));
730
731 StrictMock<MockIssuerCallback> mock_callback;
732 StrictMock<MockCertNetFetcherImpl> mock_fetcher;
733 CertIssuerSourceAia aia_source(&mock_fetcher);
734 std::unique_ptr<CertIssuerSource::Request> cert_source_request;
735 aia_source.AsyncGetIssuersOf(cert.get(),
736 base::Bind(&MockIssuerCallback::Callback,
737 base::Unretained(&mock_callback)),
738 &cert_source_request);
739 ASSERT_NE(nullptr, cert_source_request);
740
741 RequestManager* req_manager =
742 mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia/I.cer"));
743 ASSERT_TRUE(req_manager);
744 ASSERT_TRUE(req_manager->is_request_alive());
745
746 RequestManager* req_manager2 =
747 mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia2/I2.foo"));
748 ASSERT_TRUE(req_manager2);
749 ASSERT_TRUE(req_manager2->is_request_alive());
750
751 // Request for I.cer completes first.
752 EXPECT_CALL(mock_callback, Callback(cert_source_request.get()));
753 req_manager->get_callback().Run(OK, CertDataVector(intermediate_cert.get()));
754 Mock::VerifyAndClearExpectations(&mock_callback);
755
756 // Results are retrieved before the other request completes.
757 scoped_refptr<ParsedCertificate> result_cert;
758 CompletionStatus status = cert_source_request->GetNext(&result_cert);
759 EXPECT_EQ(CompletionStatus::SYNC, status);
760 ASSERT_TRUE(result_cert.get());
761 ASSERT_EQ(result_cert->der_cert(), intermediate_cert->der_cert());
762
763 status = cert_source_request->GetNext(&result_cert);
764 // The other http request is still pending, status should be ASYNC to signify
765 // the need to wait for another callback.
766 ASSERT_EQ(CompletionStatus::ASYNC, status);
767 EXPECT_FALSE(result_cert.get());
768
769 // Request for I2.foo fails. Callback should be called to indicate that
770 // results are exhausted.
771 ASSERT_TRUE(req_manager2->is_request_alive());
772 EXPECT_CALL(mock_callback, Callback(cert_source_request.get()));
773 req_manager2->get_callback().Run(ERR_INVALID_RESPONSE,
774 std::vector<uint8_t>());
775 Mock::VerifyAndClearExpectations(&mock_callback);
776
777 // GetNext has no more results.
778 status = cert_source_request->GetNext(&result_cert);
779 ASSERT_EQ(CompletionStatus::SYNC, status);
780 EXPECT_FALSE(result_cert.get());
781 }
782
783 // AuthorityInfoAccess with two HTTP urls. Request is cancelled before any HTTP
784 // requests finish.
785 TEST(CertIssuerSourceAiaUnittest, CertSourceRequestCancelled) {
786 scoped_refptr<ParsedCertificate> cert;
787 ASSERT_TRUE(ReadTestCert("target_two_aia.pem", &cert));
788
789 StrictMock<MockIssuerCallback> mock_callback;
790 StrictMock<MockCertNetFetcherImpl> mock_fetcher;
791 CertIssuerSourceAia aia_source(&mock_fetcher);
792 std::unique_ptr<CertIssuerSource::Request> cert_source_request;
793 aia_source.AsyncGetIssuersOf(cert.get(),
794 base::Bind(&MockIssuerCallback::Callback,
795 base::Unretained(&mock_callback)),
796 &cert_source_request);
797 ASSERT_NE(nullptr, cert_source_request);
798
799 RequestManager* req_manager =
800 mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia/I.cer"));
801 ASSERT_TRUE(req_manager);
802 ASSERT_TRUE(req_manager->is_request_alive());
803
804 RequestManager* req_manager2 =
805 mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia2/I2.foo"));
806 ASSERT_TRUE(req_manager2);
807 ASSERT_TRUE(req_manager2->is_request_alive());
808
809 // Delete The CertIssuerSource::Request, cancelling it.
810 cert_source_request.reset();
811 // Both CertNetFetcher::Requests should be cancelled.
812 EXPECT_FALSE(req_manager->is_request_alive());
813 EXPECT_FALSE(req_manager2->is_request_alive());
814 }
815
816 // AuthorityInfoAccess with two HTTP urls, each pointing to a single DER cert.
817 // One request completes, results are retrieved, then request is cancelled
818 // before the second HTTP request completes.
819 TEST(CertIssuerSourceAiaUnittest, TwoAiaOneCompletedThenRequestCancelled) {
820 scoped_refptr<ParsedCertificate> cert;
821 ASSERT_TRUE(ReadTestCert("target_two_aia.pem", &cert));
822 scoped_refptr<ParsedCertificate> intermediate_cert;
823 ASSERT_TRUE(ReadTestCert("i.pem", &intermediate_cert));
824
825 StrictMock<MockIssuerCallback> mock_callback;
826 StrictMock<MockCertNetFetcherImpl> mock_fetcher;
827 CertIssuerSourceAia aia_source(&mock_fetcher);
828 std::unique_ptr<CertIssuerSource::Request> cert_source_request;
829 aia_source.AsyncGetIssuersOf(cert.get(),
830 base::Bind(&MockIssuerCallback::Callback,
831 base::Unretained(&mock_callback)),
832 &cert_source_request);
833 ASSERT_NE(nullptr, cert_source_request);
834
835 RequestManager* req_manager =
836 mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia/I.cer"));
837 ASSERT_TRUE(req_manager);
838 ASSERT_TRUE(req_manager->is_request_alive());
839
840 RequestManager* req_manager2 =
841 mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia2/I2.foo"));
842 ASSERT_TRUE(req_manager2);
843 ASSERT_TRUE(req_manager2->is_request_alive());
844
845 // Request for I.cer completes first.
846 EXPECT_CALL(mock_callback, Callback(cert_source_request.get()));
847 req_manager->get_callback().Run(OK, CertDataVector(intermediate_cert.get()));
848 Mock::VerifyAndClearExpectations(&mock_callback);
849
850 // Results are retrieved before the other request completes.
851 scoped_refptr<ParsedCertificate> result_cert;
852 CompletionStatus status = cert_source_request->GetNext(&result_cert);
853 EXPECT_EQ(CompletionStatus::SYNC, status);
854 ASSERT_TRUE(result_cert.get());
855 ASSERT_EQ(result_cert->der_cert(), intermediate_cert->der_cert());
856
857 status = cert_source_request->GetNext(&result_cert);
858 // The other http request is still pending, status should be ASYNC to signify
859 // the need to wait for another callback.
860 ASSERT_EQ(CompletionStatus::ASYNC, status);
861 EXPECT_FALSE(result_cert.get());
862
863 // Delete The CertIssuerSource::Request, cancelling it.
864 cert_source_request.reset();
865 // Both CertNetFetcher::Requests should be cancelled.
866 EXPECT_FALSE(req_manager->is_request_alive());
867 EXPECT_FALSE(req_manager2->is_request_alive());
868 }
869
870 // AuthorityInfoAccess with six HTTP URLs. kMaxFetchesPerCert is 5, so the
871 // sixth URL should be ignored.
872 TEST(CertIssuerSourceAiaUnittest, MaxFetchesPerCert) {
873 scoped_refptr<ParsedCertificate> cert;
874 ASSERT_TRUE(ReadTestCert("target_six_aia.pem", &cert));
875
876 StrictMock<MockIssuerCallback> mock_callback;
877 StrictMock<MockCertNetFetcherImpl> mock_fetcher;
878 CertIssuerSourceAia aia_source(&mock_fetcher);
879 std::unique_ptr<CertIssuerSource::Request> cert_source_request;
880 aia_source.AsyncGetIssuersOf(cert.get(),
881 base::Bind(&MockIssuerCallback::Callback,
882 base::Unretained(&mock_callback)),
883 &cert_source_request);
884 ASSERT_NE(nullptr, cert_source_request);
885
886 RequestManager* req_manager =
887 mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia/I.cer"));
888 ASSERT_TRUE(req_manager);
889 EXPECT_TRUE(req_manager->is_request_alive());
890
891 RequestManager* req_manager2 =
892 mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia2/I2.foo"));
893 ASSERT_TRUE(req_manager2);
894 EXPECT_TRUE(req_manager2->is_request_alive());
895
896 RequestManager* req_manager3 =
897 mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia3/I3.foo"));
898 ASSERT_TRUE(req_manager3);
899 EXPECT_TRUE(req_manager3->is_request_alive());
900
901 RequestManager* req_manager4 =
902 mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia4/I4.foo"));
903 ASSERT_TRUE(req_manager4);
904 EXPECT_TRUE(req_manager4->is_request_alive());
905
906 RequestManager* req_manager5 =
907 mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia5/I5.foo"));
908 ASSERT_TRUE(req_manager5);
909 EXPECT_TRUE(req_manager5->is_request_alive());
910
911 // Sixth URL should not have created a request.
912 EXPECT_FALSE(
913 mock_fetcher.GetRequestManagerForURL(GURL("http://url-for-aia6/I6.foo")));
914 }
915
916 } // namespace
917
918 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698