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

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

Issue 1923433002: Certificate path builder for new certificate verification library (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase 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/path_builder.h"
6
7 #include "base/base_paths.h"
8 #include "base/cancelable_callback.h"
9 #include "base/files/file_util.h"
10 #include "base/location.h"
11 #include "base/path_service.h"
12 #include "base/threading/thread_task_runner_handle.h"
13 #include "net/base/net_errors.h"
14 #include "net/base/test_completion_callback.h"
15 #include "net/cert/internal/cert_issuer_source_static.h"
16 #include "net/cert/internal/parsed_certificate.h"
17 #include "net/cert/internal/signature_policy.h"
18 #include "net/cert/internal/test_helpers.h"
19 #include "net/cert/internal/trust_store.h"
20 #include "net/cert/internal/verify_certificate_chain.h"
21 #include "net/cert/pem_tokenizer.h"
22 #include "net/der/input.h"
23 #include "net/test/cert_test_util.h"
24 #include "net/test/test_certificate_data.h"
25 #include "testing/gmock/include/gmock/gmock.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27
28 namespace net {
29
30 namespace {
31
32 using ::testing::_;
33 using ::testing::Invoke;
34 using ::testing::SaveArg;
35 using ::testing::StrictMock;
36 using ::testing::SetArgPointee;
37 using ::testing::Return;
38 using CertVector = std::vector<scoped_refptr<ParsedCertificate>>;
39
40 // AsyncCertIssuerSourceStatic always returns its certs asynchronously.
41 class AsyncCertIssuerSourceStatic : public CertIssuerSource {
42 public:
43 class StaticAsyncRequest : public Request {
44 public:
45 StaticAsyncRequest(const IssuerCallback& issuers_callback,
46 CertVector&& issuers)
47 : cancelable_closure_(base::Bind(&StaticAsyncRequest::RunCallback,
48 base::Unretained(this))),
49 issuers_callback_(issuers_callback) {
50 issuers_.swap(issuers);
51 issuers_iter_ = issuers_.begin();
52 }
53 ~StaticAsyncRequest() override {}
54
55 CompletionStatus GetNext(
56 scoped_refptr<ParsedCertificate>* out_cert) override {
57 if (issuers_iter_ == issuers_.end())
58 *out_cert = nullptr;
59 else
60 *out_cert = std::move(*issuers_iter_++);
61 return CompletionStatus::SYNC;
62 }
63
64 base::Closure callback() { return cancelable_closure_.callback(); }
65
66 private:
67 void RunCallback() { issuers_callback_.Run(this); }
68
69 base::CancelableClosure cancelable_closure_;
70 IssuerCallback issuers_callback_;
71 CertVector issuers_;
72 CertVector::iterator issuers_iter_;
73
74 DISALLOW_COPY_AND_ASSIGN(StaticAsyncRequest);
75 };
76
77 ~AsyncCertIssuerSourceStatic() override {}
78
79 void AddCert(scoped_refptr<ParsedCertificate> cert) {
80 static_cert_issuer_source_.AddCert(std::move(cert));
81 }
82
83 void SyncGetIssuersOf(const ParsedCertificate* cert,
84 CertVector* issuers) override {}
85 void AsyncGetIssuersOf(const ParsedCertificate* cert,
86 const IssuerCallback& issuers_callback,
87 std::unique_ptr<Request>* out_req) override {
88 num_async_gets_++;
89 CertVector issuers;
90 static_cert_issuer_source_.SyncGetIssuersOf(cert, &issuers);
91 std::unique_ptr<StaticAsyncRequest> req(
92 new StaticAsyncRequest(issuers_callback, std::move(issuers)));
93 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, req->callback());
94 *out_req = std::move(req);
95 }
96 int num_async_gets() const { return num_async_gets_; }
97
98 private:
99 CertIssuerSourceStatic static_cert_issuer_source_;
100
101 int num_async_gets_ = 0;
102 };
103
104 // Reads a data file from the unit-test data.
105 std::string ReadTestFileToString(const std::string& file_name) {
106 // Compute the full path, relative to the src/ directory.
107 base::FilePath src_root;
108 PathService::Get(base::DIR_SOURCE_ROOT, &src_root);
109 base::FilePath filepath = src_root.AppendASCII(file_name);
110
111 // Read the full contents of the file.
112 std::string file_data;
113 if (!base::ReadFileToString(filepath, &file_data)) {
114 ADD_FAILURE() << "Couldn't read file: " << filepath.value();
115 return std::string();
116 }
117
118 return file_data;
119 }
120
121 // Reads a verify_certificate_chain_unittest-style test case from |file_name|.
122 // Test cases are comprised of a certificate chain, trust store, a timestamp to
123 // validate at, and the expected result of verification (though the expected
124 // result is ignored here).
125 void ReadVerifyCertChainTestFromFile(const std::string& file_name,
126 std::vector<std::string>* chain,
127 scoped_refptr<ParsedCertificate>* root,
128 der::GeneralizedTime* time) {
129 chain->clear();
130
131 std::string file_data = ReadTestFileToString(file_name);
132
133 std::vector<std::string> pem_headers;
134
135 const char kCertificateHeader[] = "CERTIFICATE";
136 const char kTrustedCertificateHeader[] = "TRUSTED_CERTIFICATE";
137 const char kTimeHeader[] = "TIME";
138
139 pem_headers.push_back(kCertificateHeader);
140 pem_headers.push_back(kTrustedCertificateHeader);
141 pem_headers.push_back(kTimeHeader);
142
143 bool has_time = false;
144
145 PEMTokenizer pem_tokenizer(file_data, pem_headers);
146 while (pem_tokenizer.GetNext()) {
147 const std::string& block_type = pem_tokenizer.block_type();
148 const std::string& block_data = pem_tokenizer.data();
149
150 if (block_type == kCertificateHeader) {
151 chain->push_back(block_data);
152 } else if (block_type == kTrustedCertificateHeader) {
153 *root = ParsedCertificate::CreateFromCertificateCopy(block_data, {});
154 ASSERT_TRUE(*root);
155 } else if (block_type == kTimeHeader) {
156 ASSERT_FALSE(has_time) << "Duplicate " << kTimeHeader;
157 has_time = true;
158 ASSERT_TRUE(der::ParseUTCTime(der::Input(&block_data), time));
159 }
160 }
161
162 ASSERT_TRUE(has_time);
163 }
164
165 ::testing::AssertionResult ReadTestPem(const std::string& file_name,
166 const std::string& block_name,
167 std::string* result) {
168 const PemBlockMapping mappings[] = {
169 {block_name.c_str(), result},
170 };
171
172 return ReadTestDataFromPemFile(file_name, mappings);
173 }
174
175 ::testing::AssertionResult ReadTestCert(
176 const std::string& file_name,
177 scoped_refptr<ParsedCertificate>* result) {
178 std::string der;
179 ::testing::AssertionResult r = ReadTestPem(
180 "net/data/ssl/certificates/" + file_name, "CERTIFICATE", &der);
181 if (!r)
182 return r;
183 *result = ParsedCertificate::CreateFromCertificateCopy(der, {});
184 if (!*result)
185 return ::testing::AssertionFailure() << "CreateFromCertificateCopy failed";
186 return ::testing::AssertionSuccess();
187 }
188
189 // Run the path builder, and wait for async completion if necessary. The return
190 // value signifies whether the path builder completed synchronously or
191 // asynchronously, not that RunPathBuilder itself is asynchronous.
192 CompletionStatus RunPathBuilder(CertPathBuilder* path_builder) {
193 TestClosure callback;
194 CompletionStatus rv = path_builder->Run(callback.closure());
195
196 if (rv == CompletionStatus::ASYNC) {
197 DVLOG(1) << "waiting for async completion...";
198 callback.WaitForResult();
199 DVLOG(1) << "async completed.";
200 }
201 return rv;
202 }
203
204 class PathBuilderMultiRootTest : public ::testing::Test {
205 public:
206 PathBuilderMultiRootTest() : signature_policy_(1024) {}
207
208 void SetUp() override {
209 ASSERT_TRUE(ReadTestCert("multi-root-A-by-B.pem", &a_by_b_));
210 ASSERT_TRUE(ReadTestCert("multi-root-B-by-C.pem", &b_by_c_));
211 ASSERT_TRUE(ReadTestCert("multi-root-B-by-F.pem", &b_by_f_));
212 ASSERT_TRUE(ReadTestCert("multi-root-C-by-D.pem", &c_by_d_));
213 ASSERT_TRUE(ReadTestCert("multi-root-C-by-E.pem", &c_by_e_));
214 ASSERT_TRUE(ReadTestCert("multi-root-D-by-D.pem", &d_by_d_));
215 ASSERT_TRUE(ReadTestCert("multi-root-E-by-E.pem", &e_by_e_));
216 ASSERT_TRUE(ReadTestCert("multi-root-F-by-E.pem", &f_by_e_));
217 }
218
219 protected:
220 scoped_refptr<ParsedCertificate> a_by_b_, b_by_c_, b_by_f_, c_by_d_, c_by_e_,
221 d_by_d_, e_by_e_, f_by_e_;
222
223 SimpleSignaturePolicy signature_policy_;
224 der::GeneralizedTime time_ = {2016, 4, 11, 0, 0, 0};
225 };
226
227 // If the target cert is a trust anchor, it should verify and should not include
228 // anything else in the path.
229 TEST_F(PathBuilderMultiRootTest, TargetIsTrustAnchor) {
230 TrustStore trust_store;
231 trust_store.AddTrustedCertificate(a_by_b_);
232 trust_store.AddTrustedCertificate(b_by_f_);
233
234 CertPathBuilder::Result result;
235 CertPathBuilder path_builder(a_by_b_, &trust_store, &signature_policy_, time_,
236 &result);
237
238 EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
239
240 EXPECT_EQ(OK, result.result());
241 EXPECT_EQ(1U, result.paths[result.best_result_index]->path.size());
242 EXPECT_EQ(a_by_b_, result.paths[result.best_result_index]->path[0]);
243 }
244
245 // If the target cert is directly issued by a trust anchor, it should verify
246 // without any intermediate certs being provided.
247 TEST_F(PathBuilderMultiRootTest, TargetDirectlySignedByTrustAnchor) {
248 TrustStore trust_store;
249 trust_store.AddTrustedCertificate(b_by_f_);
250
251 CertPathBuilder::Result result;
252 CertPathBuilder path_builder(a_by_b_, &trust_store, &signature_policy_, time_,
253 &result);
254
255 EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
256
257 EXPECT_EQ(OK, result.result());
258 EXPECT_EQ(2U, result.paths[result.best_result_index]->path.size());
259 EXPECT_EQ(a_by_b_, result.paths[result.best_result_index]->path[0]);
260 EXPECT_EQ(b_by_f_, result.paths[result.best_result_index]->path[1]);
261 }
262
263 // Test that async cert queries are not made if the path can be successfully
264 // built with synchronously available certs.
265 TEST_F(PathBuilderMultiRootTest, TriesSyncFirst) {
266 TrustStore trust_store;
267 trust_store.AddTrustedCertificate(e_by_e_);
268
269 CertIssuerSourceStatic sync_certs;
270 sync_certs.AddCert(a_by_b_);
271 sync_certs.AddCert(b_by_f_);
272 sync_certs.AddCert(f_by_e_);
273
274 AsyncCertIssuerSourceStatic async_certs;
275 async_certs.AddCert(b_by_c_);
276 async_certs.AddCert(c_by_e_);
277
278 CertPathBuilder::Result result;
279 CertPathBuilder path_builder(a_by_b_, &trust_store, &signature_policy_, time_,
280 &result);
281 path_builder.AddCertIssuerSource(&async_certs);
282 path_builder.AddCertIssuerSource(&sync_certs);
283
284 EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
285
286 EXPECT_EQ(OK, result.result());
287 EXPECT_EQ(0, async_certs.num_async_gets());
288 }
289
290 // Test that async cert queries are not made if no callback is provided.
291 TEST_F(PathBuilderMultiRootTest, SychronousOnlyMode) {
292 TrustStore trust_store;
293 trust_store.AddTrustedCertificate(e_by_e_);
294
295 CertIssuerSourceStatic sync_certs;
296 sync_certs.AddCert(f_by_e_);
297
298 AsyncCertIssuerSourceStatic async_certs;
299 async_certs.AddCert(b_by_f_);
300
301 CertPathBuilder::Result result;
302 CertPathBuilder path_builder(a_by_b_, &trust_store, &signature_policy_, time_,
303 &result);
304 path_builder.AddCertIssuerSource(&async_certs);
305 path_builder.AddCertIssuerSource(&sync_certs);
306
307 EXPECT_EQ(CompletionStatus::SYNC, path_builder.Run(base::Closure()));
308
309 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, result.result());
310 EXPECT_EQ(0, async_certs.num_async_gets());
311 }
312
313 // If async queries are needed, all async sources will be queried
314 // simultaneously.
315 TEST_F(PathBuilderMultiRootTest, TestAsyncSimultaneous) {
316 TrustStore trust_store;
317 trust_store.AddTrustedCertificate(e_by_e_);
318
319 CertIssuerSourceStatic sync_certs;
320 sync_certs.AddCert(a_by_b_);
321 sync_certs.AddCert(b_by_c_);
322 sync_certs.AddCert(b_by_f_);
323
324 AsyncCertIssuerSourceStatic async_certs1;
325 async_certs1.AddCert(c_by_e_);
326
327 AsyncCertIssuerSourceStatic async_certs2;
328 async_certs2.AddCert(f_by_e_);
329
330 CertPathBuilder::Result result;
331 CertPathBuilder path_builder(a_by_b_, &trust_store, &signature_policy_, time_,
332 &result);
333 path_builder.AddCertIssuerSource(&async_certs1);
334 path_builder.AddCertIssuerSource(&async_certs2);
335 path_builder.AddCertIssuerSource(&sync_certs);
336
337 EXPECT_EQ(CompletionStatus::ASYNC, RunPathBuilder(&path_builder));
338
339 EXPECT_EQ(OK, result.result());
340 EXPECT_EQ(1, async_certs1.num_async_gets());
341 EXPECT_EQ(1, async_certs2.num_async_gets());
342 }
343
344 // Test that PathBuilder does not generate longer paths than necessary if one of
345 // the supplied certs is itself a trust anchor.
346 TEST_F(PathBuilderMultiRootTest, TestLongChain) {
347 // Both D(D) and C(D) are trusted roots.
348 TrustStore trust_store;
349 trust_store.AddTrustedCertificate(d_by_d_);
350 trust_store.AddTrustedCertificate(c_by_d_);
351
352 // Certs A(B), B(C), and C(D) are all supplied.
353 CertIssuerSourceStatic sync_certs;
354 sync_certs.AddCert(a_by_b_);
355 sync_certs.AddCert(b_by_c_);
356 sync_certs.AddCert(c_by_d_);
357
358 CertPathBuilder::Result result;
359 CertPathBuilder path_builder(a_by_b_, &trust_store, &signature_policy_, time_,
360 &result);
361 path_builder.AddCertIssuerSource(&sync_certs);
362
363 EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
364
365 EXPECT_EQ(OK, result.result());
366
367 // The result path should be A(B) <- B(C) <- C(D)
368 // not the longer but also valid A(B) <- B(C) <- C(D) <- D(D)
369 EXPECT_EQ(3U, result.paths[result.best_result_index]->path.size());
370 }
371
372 // Test that PathBuilder will backtrack and try a different path if the first
373 // one doesn't work out.
374 TEST_F(PathBuilderMultiRootTest, TestBacktracking) {
375 // Only D(D) is a trusted root.
376 TrustStore trust_store;
377 trust_store.AddTrustedCertificate(d_by_d_);
378
379 // Certs A(B), B(F), and F(E) are supplied synchronously, thus the path
380 // A(B) <- B(F) <- F(E) should be built first, though it won't verify.
381 CertIssuerSourceStatic sync_certs;
382 sync_certs.AddCert(a_by_b_);
383 sync_certs.AddCert(b_by_f_);
384 sync_certs.AddCert(f_by_e_);
385
386 // Certs B(C), and C(D) are supplied asynchronously, so the path
387 // A(B) <- B(C) <- C(D) <- D(D) should be tried second.
388 AsyncCertIssuerSourceStatic async_certs;
389 async_certs.AddCert(b_by_c_);
390 async_certs.AddCert(c_by_d_);
391
392 CertPathBuilder::Result result;
393 CertPathBuilder path_builder(a_by_b_, &trust_store, &signature_policy_, time_,
394 &result);
395 path_builder.AddCertIssuerSource(&sync_certs);
396 path_builder.AddCertIssuerSource(&async_certs);
397
398 EXPECT_EQ(CompletionStatus::ASYNC, RunPathBuilder(&path_builder));
399
400 EXPECT_EQ(OK, result.result());
401
402 // The result path should be A(B) <- B(C) <- C(D) <- D(D)
403 ASSERT_EQ(4U, result.paths[result.best_result_index]->path.size());
404 EXPECT_EQ(a_by_b_, result.paths[result.best_result_index]->path[0]);
405 EXPECT_EQ(b_by_c_, result.paths[result.best_result_index]->path[1]);
406 EXPECT_EQ(c_by_d_, result.paths[result.best_result_index]->path[2]);
407 EXPECT_EQ(d_by_d_, result.paths[result.best_result_index]->path[3]);
408 }
409
410 class PathBuilderKeyRolloverTest : public ::testing::Test {
411 public:
412 PathBuilderKeyRolloverTest() : signature_policy_(1024) {}
413
414 void SetUp() override {
415 std::vector<std::string> path;
416
417 ReadVerifyCertChainTestFromFile(
418 "net/data/verify_certificate_chain_unittest/key-rollover-oldchain.pem",
419 &path, &oldroot_, &time_);
420 ASSERT_EQ(2U, path.size());
421 target_ = ParsedCertificate::CreateFromCertificateCopy(path[0], {});
422 oldintermediary_ =
423 ParsedCertificate::CreateFromCertificateCopy(path[1], {});
424 ASSERT_TRUE(target_);
425 ASSERT_TRUE(oldintermediary_);
426
427 ReadVerifyCertChainTestFromFile(
428 "net/data/verify_certificate_chain_unittest/"
429 "key-rollover-longrolloverchain.pem",
430 &path, &oldroot_, &time_);
431 ASSERT_EQ(4U, path.size());
432 newintermediary_ =
433 ParsedCertificate::CreateFromCertificateCopy(path[1], {});
434 newroot_ = ParsedCertificate::CreateFromCertificateCopy(path[2], {});
435 newrootrollover_ =
436 ParsedCertificate::CreateFromCertificateCopy(path[3], {});
437 ASSERT_TRUE(newintermediary_);
438 ASSERT_TRUE(newroot_);
439 ASSERT_TRUE(newrootrollover_);
440 }
441
442 protected:
443 // oldroot-------->newrootrollover newroot
444 // | | |
445 // v v v
446 // oldintermediary newintermediary
447 // | |
448 // +------------+-------------+
449 // |
450 // v
451 // target
452 scoped_refptr<ParsedCertificate> target_, oldintermediary_, newintermediary_,
453 oldroot_, newroot_, newrootrollover_;
454
455 SimpleSignaturePolicy signature_policy_;
456 der::GeneralizedTime time_;
457 };
458
459 // Tests that if only the old root cert is trusted, the path builder can build a
460 // path through the new intermediate and rollover cert to the old root.
461 TEST_F(PathBuilderKeyRolloverTest, TestRolloverOnlyOldRootTrusted) {
462 // Only oldroot is trusted.
463 TrustStore trust_store;
464 trust_store.AddTrustedCertificate(oldroot_);
465
466 // Old intermediary cert is not provided, so the pathbuilder will need to go
467 // through the rollover cert.
468 CertIssuerSourceStatic sync_certs;
469 sync_certs.AddCert(newintermediary_);
470 sync_certs.AddCert(newrootrollover_);
471
472 CertPathBuilder::Result result;
473 CertPathBuilder path_builder(target_, &trust_store, &signature_policy_, time_,
474 &result);
475 path_builder.AddCertIssuerSource(&sync_certs);
476
477 EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
478
479 EXPECT_EQ(OK, result.result());
480
481 // Path builder will first attempt: target <- newintermediary <- oldroot
482 // but it will fail since newintermediary is signed by newroot.
483 ASSERT_EQ(2U, result.paths.size());
484 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, result.paths[0]->rv);
485 ASSERT_EQ(3U, result.paths[0]->path.size());
486 EXPECT_EQ(target_, result.paths[0]->path[0]);
487 EXPECT_EQ(newintermediary_, result.paths[0]->path[1]);
488 EXPECT_EQ(oldroot_, result.paths[0]->path[2]);
489
490 // Path builder will next attempt:
491 // target <- newintermediary <- newrootrollover <- oldroot
492 // which will succeed.
493 EXPECT_EQ(1U, result.best_result_index);
494 EXPECT_EQ(OK, result.paths[1]->rv);
495 ASSERT_EQ(4U, result.paths[1]->path.size());
496 EXPECT_EQ(target_, result.paths[1]->path[0]);
497 EXPECT_EQ(newintermediary_, result.paths[1]->path[1]);
498 EXPECT_EQ(newrootrollover_, result.paths[1]->path[2]);
499 EXPECT_EQ(oldroot_, result.paths[1]->path[3]);
500 }
501
502 // Tests that if both old and new roots are trusted it can build a path through
503 // either.
504 // TODO(mattm): Once prioritization is implemented, it should test that it
505 // always builds the path through the new intermediary and new root.
506 TEST_F(PathBuilderKeyRolloverTest, TestRolloverBothRootsTrusted) {
507 // Both oldroot and newroot are trusted.
508 TrustStore trust_store;
509 trust_store.AddTrustedCertificate(oldroot_);
510 trust_store.AddTrustedCertificate(newroot_);
511
512 // Both old and new intermediates + rollover cert are provided.
513 CertIssuerSourceStatic sync_certs;
514 sync_certs.AddCert(oldintermediary_);
515 sync_certs.AddCert(newintermediary_);
516 sync_certs.AddCert(newrootrollover_);
517
518 CertPathBuilder::Result result;
519 CertPathBuilder path_builder(target_, &trust_store, &signature_policy_, time_,
520 &result);
521 path_builder.AddCertIssuerSource(&sync_certs);
522
523 EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
524
525 EXPECT_EQ(OK, result.result());
526
527 // Path builder willattempt one of:
528 // target <- oldintermediary <- oldroot
529 // target <- newintermediary <- newroot
530 // either will succeed.
531 ASSERT_EQ(1U, result.paths.size());
532 EXPECT_EQ(OK, result.paths[0]->rv);
533 ASSERT_EQ(3U, result.paths[0]->path.size());
534 EXPECT_EQ(target_, result.paths[0]->path[0]);
535 if (result.paths[0]->path[1] != newintermediary_) {
536 DVLOG(1) << "USED OLD";
537 EXPECT_EQ(oldintermediary_, result.paths[0]->path[1]);
538 EXPECT_EQ(oldroot_, result.paths[0]->path[2]);
539 } else {
540 DVLOG(1) << "USED NEW";
541 EXPECT_EQ(newintermediary_, result.paths[0]->path[1]);
542 EXPECT_EQ(newroot_, result.paths[0]->path[2]);
543 }
544 }
545
546 // Tests that multiple trust root matches on a single path will be considered.
547 // Both roots have the same subject but different keys. Only one of them will
548 // verify.
549 TEST_F(PathBuilderKeyRolloverTest, TestMultipleRootMatchesOnlyOneWorks) {
550 // Both newroot and oldroot are trusted.
551 TrustStore trust_store;
552 // Note: The test assumes newroot will be tried before oldroot.
553 // Currently this depends on the order the roots are added.
554 trust_store.AddTrustedCertificate(newroot_);
555 trust_store.AddTrustedCertificate(oldroot_);
556
557 // Only oldintermediary is supplied, so the path with newroot should fail,
558 // oldroot should succeed.
559 CertIssuerSourceStatic sync_certs;
560 sync_certs.AddCert(oldintermediary_);
561
562 CertPathBuilder::Result result;
563 CertPathBuilder path_builder(target_, &trust_store, &signature_policy_, time_,
564 &result);
565 path_builder.AddCertIssuerSource(&sync_certs);
566
567 EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
568
569 EXPECT_EQ(OK, result.result());
570 ASSERT_EQ(2U, result.paths.size());
571
572 // Path builder will first attempt: target <- oldintermediary <- newroot
573 // but it will fail since oldintermediary is signed by oldroot.
574 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, result.paths[0]->rv);
575 ASSERT_EQ(3U, result.paths[0]->path.size());
576 EXPECT_EQ(target_, result.paths[0]->path[0]);
577 EXPECT_EQ(oldintermediary_, result.paths[0]->path[1]);
578 EXPECT_EQ(newroot_, result.paths[0]->path[2]);
579
580 // Path builder will next attempt:
581 // target <- old intermediary <- oldroot
582 // which should succeed.
583 EXPECT_EQ(OK, result.paths[1]->rv);
584 ASSERT_EQ(3U, result.paths[1]->path.size());
585 EXPECT_EQ(target_, result.paths[1]->path[0]);
586 EXPECT_EQ(oldintermediary_, result.paths[1]->path[1]);
587 EXPECT_EQ(oldroot_, result.paths[1]->path[2]);
588 }
589
590 // Tests that the path builder doesn't build longer than necessary paths.
591 TEST_F(PathBuilderKeyRolloverTest, TestRolloverLongChain) {
592 // Only oldroot is trusted.
593 TrustStore trust_store;
594 trust_store.AddTrustedCertificate(oldroot_);
595
596 // New intermediate and new root are provided synchronously.
597 CertIssuerSourceStatic sync_certs;
598 sync_certs.AddCert(newintermediary_);
599 sync_certs.AddCert(newroot_);
600
601 // Rollover cert is only provided asynchronously. This will force the
602 // pathbuilder to first try building a longer than necessary path.
603 AsyncCertIssuerSourceStatic async_certs;
604 async_certs.AddCert(newrootrollover_);
605
606 CertPathBuilder::Result result;
607 CertPathBuilder path_builder(target_, &trust_store, &signature_policy_, time_,
608 &result);
609 path_builder.AddCertIssuerSource(&sync_certs);
610 path_builder.AddCertIssuerSource(&async_certs);
611
612 EXPECT_EQ(CompletionStatus::ASYNC, RunPathBuilder(&path_builder));
613
614 EXPECT_EQ(OK, result.result());
615 ASSERT_EQ(3U, result.paths.size());
616
617 // Path builder will first attempt: target <- newintermediary <- oldroot
618 // but it will fail since newintermediary is signed by newroot.
619 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, result.paths[0]->rv);
620 ASSERT_EQ(3U, result.paths[0]->path.size());
621 EXPECT_EQ(target_, result.paths[0]->path[0]);
622 EXPECT_EQ(newintermediary_, result.paths[0]->path[1]);
623 EXPECT_EQ(oldroot_, result.paths[0]->path[2]);
624
625 // Path builder will next attempt:
626 // target <- newintermediary <- newroot <- oldroot
627 // but it will fail since newroot is self-signed.
628 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, result.paths[1]->rv);
629 ASSERT_EQ(4U, result.paths[1]->path.size());
630 EXPECT_EQ(target_, result.paths[1]->path[0]);
631 EXPECT_EQ(newintermediary_, result.paths[1]->path[1]);
632 EXPECT_EQ(newroot_, result.paths[1]->path[2]);
633 EXPECT_EQ(oldroot_, result.paths[1]->path[3]);
634
635 // Path builder will skip:
636 // target <- newintermediary <- newroot <- newrootrollover <- ...
637 // Since newroot and newrootrollover have the same Name+SAN+SPKI.
638
639 // Finally path builder will use:
640 // target <- newintermediary <- newrootrollover <- oldroot
641 EXPECT_EQ(2U, result.best_result_index);
642 EXPECT_EQ(OK, result.paths[2]->rv);
643 ASSERT_EQ(4U, result.paths[2]->path.size());
644 EXPECT_EQ(target_, result.paths[2]->path[0]);
645 EXPECT_EQ(newintermediary_, result.paths[2]->path[1]);
646 EXPECT_EQ(newrootrollover_, result.paths[2]->path[2]);
647 EXPECT_EQ(oldroot_, result.paths[2]->path[3]);
648 }
649
650 // If the target cert is a trust root, that alone is a valid path.
651 TEST_F(PathBuilderKeyRolloverTest, TestEndEntityIsTrustRoot) {
652 // Trust newintermediary.
653 TrustStore trust_store;
654 trust_store.AddTrustedCertificate(newintermediary_);
655
656 CertPathBuilder::Result result;
657 // Newintermediary is also the target cert.
658 CertPathBuilder path_builder(newintermediary_, &trust_store,
659 &signature_policy_, time_, &result);
660
661 EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
662
663 EXPECT_EQ(OK, result.result());
664
665 ASSERT_EQ(1U, result.paths.size());
666 EXPECT_EQ(OK, result.paths[0]->rv);
667 ASSERT_EQ(1U, result.paths[0]->path.size());
668 EXPECT_EQ(newintermediary_, result.paths[0]->path[0]);
669 }
670
671 // If target has same Name+SAN+SPKI as a necessary intermediate, test if a path
672 // can still be built.
673 // Since LoopChecker will prevent the intermediate from being included, this
674 // currently does NOT verify. This case shouldn't occur in the web PKI.
675 TEST_F(PathBuilderKeyRolloverTest,
676 TestEndEntityHasSameNameAndSpkiAsIntermediate) {
677 // Trust oldroot.
678 TrustStore trust_store;
679 trust_store.AddTrustedCertificate(oldroot_);
680
681 // New root rollover is provided synchronously.
682 CertIssuerSourceStatic sync_certs;
683 sync_certs.AddCert(newrootrollover_);
684
685 CertPathBuilder::Result result;
686 // Newroot is the target cert.
687 CertPathBuilder path_builder(newroot_, &trust_store, &signature_policy_,
688 time_, &result);
689 path_builder.AddCertIssuerSource(&sync_certs);
690
691 EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
692
693 // This could actually be OK, but CertPathBuilder does not build the
694 // newroot <- newrootrollover <- oldroot path.
695 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, result.result());
696 }
697
698 // If target has same Name+SAN+SPKI as the trust root, test that a (trivial)
699 // path can still be built.
700 TEST_F(PathBuilderKeyRolloverTest,
701 TestEndEntityHasSameNameAndSpkiAsTrustAnchor) {
702 // Trust newrootrollover.
703 TrustStore trust_store;
704 trust_store.AddTrustedCertificate(newrootrollover_);
705
706 CertPathBuilder::Result result;
707 // Newroot is the target cert.
708 CertPathBuilder path_builder(newroot_, &trust_store, &signature_policy_,
709 time_, &result);
710
711 EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
712
713 EXPECT_EQ(OK, result.result());
714
715 ASSERT_FALSE(result.paths.empty());
716 const CertPathBuilder::ResultPath* best_result =
717 result.paths[result.best_result_index].get();
718
719 // Newroot has same name+SPKI as newrootrollover, thus the path is valid and
720 // only contains newroot.
721 EXPECT_EQ(OK, best_result->rv);
722 ASSERT_EQ(1U, best_result->path.size());
723 EXPECT_EQ(newroot_, best_result->path[0]);
724 }
725
726 // Test that PathBuilder will not try the same path twice if multiple
727 // CertIssuerSources provide the same certificate.
728 TEST_F(PathBuilderKeyRolloverTest, TestDuplicateIntermediates) {
729 // Create a separate copy of oldintermediary.
730 scoped_refptr<ParsedCertificate> oldintermediary_dupe(
731 ParsedCertificate::CreateFromCertificateCopy(
732 oldintermediary_->der_cert().AsStringPiece(), {}));
733
734 // Only newroot is a trusted root.
735 TrustStore trust_store;
736 trust_store.AddTrustedCertificate(newroot_);
737
738 // The oldintermediary is supplied synchronously by |sync_certs1| and
739 // another copy of oldintermediary is supplied synchronously by |sync_certs2|.
740 // The path target <- oldintermediary <- newroot should be built first,
741 // though it won't verify. It should not be attempted again even though
742 // oldintermediary was supplied twice.
743 CertIssuerSourceStatic sync_certs1;
744 sync_certs1.AddCert(oldintermediary_);
745 CertIssuerSourceStatic sync_certs2;
746 sync_certs2.AddCert(oldintermediary_dupe);
747
748 // The newintermediary is supplied asynchronously, so the path
749 // target <- newintermediary <- newroot should be tried second.
750 AsyncCertIssuerSourceStatic async_certs;
751 async_certs.AddCert(newintermediary_);
752
753 CertPathBuilder::Result result;
754 CertPathBuilder path_builder(target_, &trust_store, &signature_policy_, time_,
755 &result);
756 path_builder.AddCertIssuerSource(&sync_certs1);
757 path_builder.AddCertIssuerSource(&sync_certs2);
758 path_builder.AddCertIssuerSource(&async_certs);
759
760 EXPECT_EQ(CompletionStatus::ASYNC, RunPathBuilder(&path_builder));
761
762 EXPECT_EQ(OK, result.result());
763 ASSERT_EQ(2U, result.paths.size());
764
765 // Path builder will first attempt: target <- oldintermediary <- newroot
766 // but it will fail since oldintermediary is signed by oldroot.
767 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, result.paths[0]->rv);
768 ASSERT_EQ(3U, result.paths[0]->path.size());
769 EXPECT_EQ(target_, result.paths[0]->path[0]);
770 // Compare the DER instead of ParsedCertificate pointer, don't care which copy
771 // of oldintermediary was used in the path.
772 EXPECT_EQ(oldintermediary_->der_cert(), result.paths[0]->path[1]->der_cert());
773 EXPECT_EQ(newroot_, result.paths[0]->path[2]);
774
775 // Path builder will next attempt: target <- newintermediary <- newroot
776 // which will succeed.
777 EXPECT_EQ(1U, result.best_result_index);
778 EXPECT_EQ(OK, result.paths[1]->rv);
779 ASSERT_EQ(3U, result.paths[1]->path.size());
780 EXPECT_EQ(target_, result.paths[1]->path[0]);
781 EXPECT_EQ(newintermediary_, result.paths[1]->path[1]);
782 EXPECT_EQ(newroot_, result.paths[1]->path[2]);
783 }
784
785 // Test that PathBuilder will not try the same path twice if the same cert is
786 // presented via a CertIssuerSources and a TrustAnchor.
787 TEST_F(PathBuilderKeyRolloverTest, TestDuplicateIntermediateAndRoot) {
788 // Create a separate copy of newroot.
789 scoped_refptr<ParsedCertificate> newroot_dupe(
790 ParsedCertificate::CreateFromCertificateCopy(
791 newroot_->der_cert().AsStringPiece(), {}));
792
793 // Only newroot is a trusted root.
794 TrustStore trust_store;
795 trust_store.AddTrustedCertificate(newroot_);
796
797 // The oldintermediary and newroot are supplied synchronously by |sync_certs|.
798 CertIssuerSourceStatic sync_certs;
799 sync_certs.AddCert(oldintermediary_);
800 sync_certs.AddCert(newroot_dupe);
801
802 CertPathBuilder::Result result;
803 CertPathBuilder path_builder(target_, &trust_store, &signature_policy_, time_,
804 &result);
805 path_builder.AddCertIssuerSource(&sync_certs);
806
807 EXPECT_EQ(CompletionStatus::SYNC, RunPathBuilder(&path_builder));
808
809 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, result.result());
810 ASSERT_EQ(1U, result.paths.size());
811
812 // Path builder attempt: target <- oldintermediary <- newroot
813 // but it will fail since oldintermediary is signed by oldroot.
814 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, result.paths[0]->rv);
815 ASSERT_EQ(3U, result.paths[0]->path.size());
816 EXPECT_EQ(target_, result.paths[0]->path[0]);
817 EXPECT_EQ(oldintermediary_, result.paths[0]->path[1]);
818 // Compare the DER instead of ParsedCertificate pointer, don't care which copy
819 // of newroot was used in the path.
820 EXPECT_EQ(newroot_->der_cert(), result.paths[0]->path[2]->der_cert());
821 }
822
823 class MockCertIssuerSourceRequest : public CertIssuerSource::Request {
824 public:
825 MOCK_METHOD1(GetNext, CompletionStatus(scoped_refptr<ParsedCertificate>*));
826 };
827
828 class MockCertIssuerSource : public CertIssuerSource {
829 public:
830 MOCK_METHOD2(SyncGetIssuersOf,
831 void(const ParsedCertificate*,
832 std::vector<scoped_refptr<ParsedCertificate>>*));
833 MOCK_METHOD3(AsyncGetIssuersOf,
834 void(const ParsedCertificate*,
835 const IssuerCallback&,
836 std::unique_ptr<Request>*));
837 };
838
839 // Helper class to pass the Request to the PathBuilder when it calls
840 // AsyncGetIssuersOf. (GoogleMock has a ByMove helper, but it apparently can
841 // only be used with Return, not SetArgPointee.)
842 class CertIssuerSourceRequestMover {
843 public:
844 CertIssuerSourceRequestMover(std::unique_ptr<CertIssuerSource::Request> req)
845 : request_(std::move(req)) {}
846 void MoveIt(const ParsedCertificate* cert,
847 const CertIssuerSource::IssuerCallback& issuers_callback,
848 std::unique_ptr<CertIssuerSource::Request>* out_req) {
849 *out_req = std::move(request_);
850 }
851
852 private:
853 std::unique_ptr<CertIssuerSource::Request> request_;
854 };
855
856 // Test that a single CertIssuerSource returning multiple async batches of
857 // issuers is handled correctly. Due to the StrictMocks, it also tests that path
858 // builder does not request issuers of certs that it shouldn't.
859 TEST_F(PathBuilderKeyRolloverTest, TestMultipleAsyncCallbacksFromSingleSource) {
860 StrictMock<MockCertIssuerSource> cert_issuer_source;
861
862 // Only newroot is a trusted root.
863 TrustStore trust_store;
864 trust_store.AddTrustedCertificate(newroot_);
865
866 CertPathBuilder::Result result;
867 CertPathBuilder path_builder(target_, &trust_store, &signature_policy_, time_,
868 &result);
869 path_builder.AddCertIssuerSource(&cert_issuer_source);
870
871 CertIssuerSource::IssuerCallback target_issuers_callback;
872 // Create the mock CertIssuerSource::Request...
873 std::unique_ptr<StrictMock<MockCertIssuerSourceRequest>>
874 target_issuers_req_owner(new StrictMock<MockCertIssuerSourceRequest>());
875 // Keep a raw pointer to the Request...
876 StrictMock<MockCertIssuerSourceRequest>* target_issuers_req =
877 target_issuers_req_owner.get();
878 // Setup helper class to pass ownership of the Request to the PathBuilder when
879 // it calls AsyncGetIssuersOf.
880 CertIssuerSourceRequestMover req_mover(std::move(target_issuers_req_owner));
881 {
882 ::testing::InSequence s;
883 EXPECT_CALL(cert_issuer_source, SyncGetIssuersOf(target_.get(), _));
884 EXPECT_CALL(cert_issuer_source, AsyncGetIssuersOf(target_.get(), _, _))
885 .WillOnce(
886 DoAll(SaveArg<1>(&target_issuers_callback),
887 Invoke(&req_mover, &CertIssuerSourceRequestMover::MoveIt)));
888 }
889
890 TestClosure callback;
891 CompletionStatus rv = path_builder.Run(callback.closure());
892 ASSERT_EQ(CompletionStatus::ASYNC, rv);
893
894 ASSERT_FALSE(target_issuers_callback.is_null());
895
896 ::testing::Mock::VerifyAndClearExpectations(&cert_issuer_source);
897
898 // First async batch: return oldintermediary_.
899 EXPECT_CALL(*target_issuers_req, GetNext(_))
900 .WillOnce(DoAll(SetArgPointee<0>(oldintermediary_),
901 Return(CompletionStatus::SYNC)))
902 .WillOnce(
903 DoAll(SetArgPointee<0>(nullptr), Return(CompletionStatus::ASYNC)));
904 {
905 ::testing::InSequence s;
906 // oldintermediary_ does not create a valid path, so both sync and async
907 // lookups are expected.
908 EXPECT_CALL(cert_issuer_source,
909 SyncGetIssuersOf(oldintermediary_.get(), _));
910 EXPECT_CALL(cert_issuer_source,
911 AsyncGetIssuersOf(oldintermediary_.get(), _, _));
912 }
913 target_issuers_callback.Run(target_issuers_req);
914 ::testing::Mock::VerifyAndClearExpectations(target_issuers_req);
915 ::testing::Mock::VerifyAndClearExpectations(&cert_issuer_source);
916
917 // Second async batch: return newintermediary_.
918 EXPECT_CALL(*target_issuers_req, GetNext(_))
919 .WillOnce(DoAll(SetArgPointee<0>(newintermediary_),
920 Return(CompletionStatus::SYNC)))
921 .WillOnce(
922 DoAll(SetArgPointee<0>(nullptr), Return(CompletionStatus::ASYNC)));
923 // newroot_ is in the trust store, so this path will be completed
924 // synchronously. AsyncGetIssuersOf will not be called on newintermediary_.
925 EXPECT_CALL(cert_issuer_source, SyncGetIssuersOf(newintermediary_.get(), _));
926 target_issuers_callback.Run(target_issuers_req);
927 // Note that VerifyAndClearExpectations(target_issuers_req) is not called
928 // here. PathBuilder could have destroyed it already, so just let the
929 // expectations get checked by the destructor.
930 ::testing::Mock::VerifyAndClearExpectations(&cert_issuer_source);
931
932 // Ensure pathbuilder finished and filled result.
933 callback.WaitForResult();
934
935 EXPECT_EQ(OK, result.result());
936 ASSERT_EQ(2U, result.paths.size());
937
938 // Path builder first attempts: target <- oldintermediary <- newroot
939 // but it will fail since oldintermediary is signed by oldroot.
940 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, result.paths[0]->rv);
941 ASSERT_EQ(3U, result.paths[0]->path.size());
942 EXPECT_EQ(target_, result.paths[0]->path[0]);
943 EXPECT_EQ(oldintermediary_, result.paths[0]->path[1]);
944 EXPECT_EQ(newroot_, result.paths[0]->path[2]);
945
946 // After the second batch of async results, path builder will attempt:
947 // target <- newintermediary <- newroot which will succeed.
948 EXPECT_EQ(OK, result.paths[1]->rv);
949 ASSERT_EQ(3U, result.paths[1]->path.size());
950 EXPECT_EQ(target_, result.paths[1]->path[0]);
951 EXPECT_EQ(newintermediary_, result.paths[1]->path[1]);
952 EXPECT_EQ(newroot_, result.paths[1]->path[2]);
953 }
954
955 // Test that PathBuilder will not try the same path twice if CertIssuerSources
956 // asynchronously provide the same certificate multiple times.
957 TEST_F(PathBuilderKeyRolloverTest, TestDuplicateAsyncIntermediates) {
958 StrictMock<MockCertIssuerSource> cert_issuer_source;
959
960 // Only newroot is a trusted root.
961 TrustStore trust_store;
962 trust_store.AddTrustedCertificate(newroot_);
963
964 CertPathBuilder::Result result;
965 CertPathBuilder path_builder(target_, &trust_store, &signature_policy_, time_,
966 &result);
967 path_builder.AddCertIssuerSource(&cert_issuer_source);
968
969 CertIssuerSource::IssuerCallback target_issuers_callback;
970 // Create the mock CertIssuerSource::Request...
971 std::unique_ptr<StrictMock<MockCertIssuerSourceRequest>>
972 target_issuers_req_owner(new StrictMock<MockCertIssuerSourceRequest>());
973 // Keep a raw pointer to the Request...
974 StrictMock<MockCertIssuerSourceRequest>* target_issuers_req =
975 target_issuers_req_owner.get();
976 // Setup helper class to pass ownership of the Request to the PathBuilder when
977 // it calls AsyncGetIssuersOf.
978 CertIssuerSourceRequestMover req_mover(std::move(target_issuers_req_owner));
979 {
980 ::testing::InSequence s;
981 EXPECT_CALL(cert_issuer_source, SyncGetIssuersOf(target_.get(), _));
982 EXPECT_CALL(cert_issuer_source, AsyncGetIssuersOf(target_.get(), _, _))
983 .WillOnce(
984 DoAll(SaveArg<1>(&target_issuers_callback),
985 Invoke(&req_mover, &CertIssuerSourceRequestMover::MoveIt)));
986 }
987
988 TestClosure callback;
989 CompletionStatus rv = path_builder.Run(callback.closure());
990 ASSERT_EQ(CompletionStatus::ASYNC, rv);
991
992 ASSERT_FALSE(target_issuers_callback.is_null());
993
994 ::testing::Mock::VerifyAndClearExpectations(&cert_issuer_source);
995
996 // First async batch: return oldintermediary_.
997 EXPECT_CALL(*target_issuers_req, GetNext(_))
998 .WillOnce(DoAll(SetArgPointee<0>(oldintermediary_),
999 Return(CompletionStatus::SYNC)))
1000 .WillOnce(
1001 DoAll(SetArgPointee<0>(nullptr), Return(CompletionStatus::ASYNC)));
1002 {
1003 ::testing::InSequence s;
1004 // oldintermediary_ does not create a valid path, so both sync and async
1005 // lookups are expected.
1006 EXPECT_CALL(cert_issuer_source,
1007 SyncGetIssuersOf(oldintermediary_.get(), _));
1008 EXPECT_CALL(cert_issuer_source,
1009 AsyncGetIssuersOf(oldintermediary_.get(), _, _));
1010 }
1011 target_issuers_callback.Run(target_issuers_req);
1012 ::testing::Mock::VerifyAndClearExpectations(target_issuers_req);
1013 ::testing::Mock::VerifyAndClearExpectations(&cert_issuer_source);
1014
1015 // Second async batch: return a different copy of oldintermediary_ again.
1016 scoped_refptr<ParsedCertificate> oldintermediary_dupe(
1017 ParsedCertificate::CreateFromCertificateCopy(
1018 oldintermediary_->der_cert().AsStringPiece(), {}));
1019 EXPECT_CALL(*target_issuers_req, GetNext(_))
1020 .WillOnce(DoAll(SetArgPointee<0>(oldintermediary_dupe),
1021 Return(CompletionStatus::SYNC)))
1022 .WillOnce(
1023 DoAll(SetArgPointee<0>(nullptr), Return(CompletionStatus::ASYNC)));
1024 target_issuers_callback.Run(target_issuers_req);
1025 // oldintermediary was already processed above, it should not generate any
1026 // more requests.
1027 ::testing::Mock::VerifyAndClearExpectations(target_issuers_req);
1028 ::testing::Mock::VerifyAndClearExpectations(&cert_issuer_source);
1029
1030 // Third async batch: return newintermediary_.
1031 EXPECT_CALL(*target_issuers_req, GetNext(_))
1032 .WillOnce(DoAll(SetArgPointee<0>(newintermediary_),
1033 Return(CompletionStatus::SYNC)))
1034 .WillOnce(
1035 DoAll(SetArgPointee<0>(nullptr), Return(CompletionStatus::ASYNC)));
1036 // newroot_ is in the trust store, so this path will be completed
1037 // synchronously. AsyncGetIssuersOf will not be called on newintermediary_.
1038 EXPECT_CALL(cert_issuer_source, SyncGetIssuersOf(newintermediary_.get(), _));
1039 target_issuers_callback.Run(target_issuers_req);
1040 // Note that VerifyAndClearExpectations(target_issuers_req) is not called
1041 // here. PathBuilder could have destroyed it already, so just let the
1042 // expectations get checked by the destructor.
1043 ::testing::Mock::VerifyAndClearExpectations(&cert_issuer_source);
1044
1045 // Ensure pathbuilder finished and filled result.
1046 callback.WaitForResult();
1047
1048 EXPECT_EQ(OK, result.result());
1049 ASSERT_EQ(2U, result.paths.size());
1050
1051 // Path builder first attempts: target <- oldintermediary <- newroot
1052 // but it will fail since oldintermediary is signed by oldroot.
1053 EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, result.paths[0]->rv);
1054 ASSERT_EQ(3U, result.paths[0]->path.size());
1055 EXPECT_EQ(target_, result.paths[0]->path[0]);
1056 EXPECT_EQ(oldintermediary_, result.paths[0]->path[1]);
1057 EXPECT_EQ(newroot_, result.paths[0]->path[2]);
1058
1059 // The second async result does not generate any path.
1060
1061 // After the third batch of async results, path builder will attempt:
1062 // target <- newintermediary <- newroot which will succeed.
1063 EXPECT_EQ(OK, result.paths[1]->rv);
1064 ASSERT_EQ(3U, result.paths[1]->path.size());
1065 EXPECT_EQ(target_, result.paths[1]->path[0]);
1066 EXPECT_EQ(newintermediary_, result.paths[1]->path[1]);
1067 EXPECT_EQ(newroot_, result.paths[1]->path[2]);
1068 }
1069
1070 } // namespace
1071
1072 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698