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

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

Powered by Google App Engine
This is Rietveld 408576698