• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The Chromium Authors
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 "path_builder.h"
6 
7 #include <algorithm>
8 
9 #include "fillins/path_service.h"
10 #include "fillins/file_util.h"
11 
12 #include "cert_error_params.h"
13 #include "cert_issuer_source_static.h"
14 #include "common_cert_errors.h"
15 #include "mock_signature_verify_cache.h"
16 #include "parsed_certificate.h"
17 #include "simple_path_builder_delegate.h"
18 #include "test_helpers.h"
19 #include "trust_store_collection.h"
20 #include "trust_store_in_memory.h"
21 #include "verify_certificate_chain.h"
22 #include "input.h"
23 
24 #include "testdata/test_certificate_data.h"
25 #include <gmock/gmock.h>
26 #include <gtest/gtest.h>
27 #include <openssl/pool.h>
28 
29 namespace bssl {
30 
31 // TODO(crbug.com/634443): Assert the errors for each ResultPath.
32 
33 namespace {
34 
35 using ::testing::_;
36 using ::testing::ElementsAre;
37 using ::testing::Exactly;
38 using ::testing::Invoke;
39 using ::testing::NiceMock;
40 using ::testing::Return;
41 using ::testing::SaveArg;
42 using ::testing::SetArgPointee;
43 using ::testing::StrictMock;
44 
45 class TestPathBuilderDelegate : public SimplePathBuilderDelegate {
46  public:
TestPathBuilderDelegate(size_t min_rsa_modulus_length_bits,DigestPolicy digest_policy)47   TestPathBuilderDelegate(size_t min_rsa_modulus_length_bits,
48                           DigestPolicy digest_policy)
49       : SimplePathBuilderDelegate(min_rsa_modulus_length_bits, digest_policy) {}
50 
IsDeadlineExpired()51   bool IsDeadlineExpired() override { return deadline_is_expired_; }
52 
SetDeadlineExpiredForTesting(bool deadline_is_expired)53   void SetDeadlineExpiredForTesting(bool deadline_is_expired) {
54     deadline_is_expired_ = deadline_is_expired;
55   }
56 
GetVerifyCache()57   SignatureVerifyCache* GetVerifyCache() override {
58     return use_signature_cache_ ? &cache_ : nullptr;
59   }
60 
ActivateCache()61   void ActivateCache() { use_signature_cache_ = true; }
62 
DeActivateCache()63   void DeActivateCache() { use_signature_cache_ = false; }
64 
GetMockVerifyCache()65   MockSignatureVerifyCache* GetMockVerifyCache() { return &cache_; }
66 
67  private:
68   bool deadline_is_expired_ = false;
69   bool use_signature_cache_ = false;
70   MockSignatureVerifyCache cache_;
71 };
72 
73 // AsyncCertIssuerSourceStatic always returns its certs asynchronously.
74 class AsyncCertIssuerSourceStatic : public CertIssuerSource {
75  public:
76   class StaticAsyncRequest : public Request {
77    public:
StaticAsyncRequest(ParsedCertificateList && issuers)78     explicit StaticAsyncRequest(ParsedCertificateList&& issuers) {
79       issuers_.swap(issuers);
80       issuers_iter_ = issuers_.begin();
81     }
82 
83     StaticAsyncRequest(const StaticAsyncRequest&) = delete;
84     StaticAsyncRequest& operator=(const StaticAsyncRequest&) = delete;
85 
86     ~StaticAsyncRequest() override = default;
87 
GetNext(ParsedCertificateList * out_certs)88     void GetNext(ParsedCertificateList* out_certs) override {
89       if (issuers_iter_ != issuers_.end())
90         out_certs->push_back(std::move(*issuers_iter_++));
91     }
92 
93     ParsedCertificateList issuers_;
94     ParsedCertificateList::iterator issuers_iter_;
95   };
96 
97   ~AsyncCertIssuerSourceStatic() override = default;
98 
SetAsyncGetCallback(std::function<void ()> closure)99   void SetAsyncGetCallback(std::function<void()> closure) {
100     async_get_callback_ = std::move(closure);
101   }
102 
AddCert(std::shared_ptr<const ParsedCertificate> cert)103   void AddCert(std::shared_ptr<const ParsedCertificate> cert) {
104     static_cert_issuer_source_.AddCert(std::move(cert));
105   }
106 
SyncGetIssuersOf(const ParsedCertificate * cert,ParsedCertificateList * issuers)107   void SyncGetIssuersOf(const ParsedCertificate* cert,
108                         ParsedCertificateList* issuers) override {}
AsyncGetIssuersOf(const ParsedCertificate * cert,std::unique_ptr<Request> * out_req)109   void AsyncGetIssuersOf(const ParsedCertificate* cert,
110                          std::unique_ptr<Request>* out_req) override {
111     num_async_gets_++;
112     ParsedCertificateList issuers;
113     static_cert_issuer_source_.SyncGetIssuersOf(cert, &issuers);
114     auto req = std::make_unique<StaticAsyncRequest>(std::move(issuers));
115     *out_req = std::move(req);
116     if (async_get_callback_) {
117       async_get_callback_();
118     }
119   }
num_async_gets() const120   int num_async_gets() const { return num_async_gets_; }
121 
122  private:
123   CertIssuerSourceStatic static_cert_issuer_source_;
124 
125   int num_async_gets_ = 0;
126   std::function<void()> async_get_callback_ = nullptr;
127 };
128 
ReadTestPem(const std::string & file_name,const std::string & block_name,std::string * result)129 ::testing::AssertionResult ReadTestPem(const std::string& file_name,
130                                        const std::string& block_name,
131                                        std::string* result) {
132   const PemBlockMapping mappings[] = {
133       {block_name.c_str(), result},
134   };
135 
136   return ReadTestDataFromPemFile(file_name, mappings);
137 }
138 
ReadTestCert(const std::string & file_name,std::shared_ptr<const ParsedCertificate> * result)139 ::testing::AssertionResult ReadTestCert(
140     const std::string& file_name,
141     std::shared_ptr<const ParsedCertificate>* result) {
142   std::string der;
143   ::testing::AssertionResult r = ReadTestPem(
144       "testdata/ssl/certificates/" + file_name, "CERTIFICATE", &der);
145   if (!r)
146     return r;
147   CertErrors errors;
148   *result = ParsedCertificate::Create(
149       bssl::UniquePtr<CRYPTO_BUFFER>(CRYPTO_BUFFER_new(
150           reinterpret_cast<const uint8_t*>(der.data()), der.size(), nullptr)),
151       {}, &errors);
152   if (!*result) {
153     return ::testing::AssertionFailure()
154            << "ParseCertificate::Create() failed:\n"
155            << errors.ToDebugString();
156   }
157   return ::testing::AssertionSuccess();
158 }
159 
160 class PathBuilderMultiRootTest : public ::testing::Test {
161  public:
PathBuilderMultiRootTest()162   PathBuilderMultiRootTest()
163       : delegate_(1024, TestPathBuilderDelegate::DigestPolicy::kWeakAllowSha1) {
164   }
165 
SetUp()166   void SetUp() override {
167     ASSERT_TRUE(ReadTestCert("multi-root-A-by-B.pem", &a_by_b_));
168     ASSERT_TRUE(ReadTestCert("multi-root-B-by-C.pem", &b_by_c_));
169     ASSERT_TRUE(ReadTestCert("multi-root-B-by-F.pem", &b_by_f_));
170     ASSERT_TRUE(ReadTestCert("multi-root-C-by-D.pem", &c_by_d_));
171     ASSERT_TRUE(ReadTestCert("multi-root-C-by-E.pem", &c_by_e_));
172     ASSERT_TRUE(ReadTestCert("multi-root-D-by-D.pem", &d_by_d_));
173     ASSERT_TRUE(ReadTestCert("multi-root-E-by-E.pem", &e_by_e_));
174     ASSERT_TRUE(ReadTestCert("multi-root-F-by-E.pem", &f_by_e_));
175   }
176 
177  protected:
178   std::shared_ptr<const ParsedCertificate> a_by_b_, b_by_c_, b_by_f_, c_by_d_,
179       c_by_e_, d_by_d_, e_by_e_, f_by_e_;
180 
181   TestPathBuilderDelegate delegate_;
182   der::GeneralizedTime time_ = {2017, 3, 1, 0, 0, 0};
183 
184   const InitialExplicitPolicy initial_explicit_policy_ =
185       InitialExplicitPolicy::kFalse;
186   const std::set<der::Input> user_initial_policy_set_ = {
187       der::Input(kAnyPolicyOid)};
188   const InitialPolicyMappingInhibit initial_policy_mapping_inhibit_ =
189       InitialPolicyMappingInhibit::kFalse;
190   const InitialAnyPolicyInhibit initial_any_policy_inhibit_ =
191       InitialAnyPolicyInhibit::kFalse;
192 };
193 
194 // Tests when the target cert has the same name and key as a trust anchor,
195 // however is signed by a different trust anchor. This should successfully build
196 // a path, however the trust anchor will be the signer of this cert.
197 //
198 // (This test is very similar to TestEndEntityHasSameNameAndSpkiAsTrustAnchor
199 // but with different data; also in this test the target cert itself is in the
200 // trust store).
TEST_F(PathBuilderMultiRootTest,TargetHasNameAndSpkiOfTrustAnchor)201 TEST_F(PathBuilderMultiRootTest, TargetHasNameAndSpkiOfTrustAnchor) {
202   TrustStoreInMemory trust_store;
203   trust_store.AddTrustAnchor(a_by_b_);
204   trust_store.AddTrustAnchor(b_by_f_);
205 
206   CertPathBuilder path_builder(
207       a_by_b_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU,
208       initial_explicit_policy_, user_initial_policy_set_,
209       initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
210 
211   auto result = path_builder.Run();
212 
213   ASSERT_TRUE(result.HasValidPath());
214   const auto& path = *result.GetBestValidPath();
215   ASSERT_EQ(2U, path.certs.size());
216   EXPECT_EQ(a_by_b_, path.certs[0]);
217   EXPECT_EQ(b_by_f_, path.certs[1]);
218 }
219 
220 // If the target cert is has the same name and key as a trust anchor, however
221 // is NOT itself signed by a trust anchor, it fails. Although the provided SPKI
222 // is trusted, the certificate contents cannot be verified.
TEST_F(PathBuilderMultiRootTest,TargetWithSameNameAsTrustAnchorFails)223 TEST_F(PathBuilderMultiRootTest, TargetWithSameNameAsTrustAnchorFails) {
224   TrustStoreInMemory trust_store;
225   trust_store.AddTrustAnchor(a_by_b_);
226 
227   CertPathBuilder path_builder(
228       a_by_b_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU,
229       initial_explicit_policy_, user_initial_policy_set_,
230       initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
231 
232   auto result = path_builder.Run();
233 
234   EXPECT_FALSE(result.HasValidPath());
235   EXPECT_EQ(1U, result.max_depth_seen);
236 }
237 
238 // Test a failed path building when the trust anchor is provided as a
239 // supplemental certificate. Conceptually the following paths could be built:
240 //
241 //   B(C) <- C(D) <- [Trust anchor D]
242 //   B(C) <- C(D) <- D(D) <- [Trust anchor D]
243 //
244 // However the second one is extraneous given the shorter path.
TEST_F(PathBuilderMultiRootTest,SelfSignedTrustAnchorSupplementalCert)245 TEST_F(PathBuilderMultiRootTest, SelfSignedTrustAnchorSupplementalCert) {
246   TrustStoreInMemory trust_store;
247   trust_store.AddTrustAnchor(d_by_d_);
248 
249   // The (extraneous) trust anchor D(D) is supplied as a certificate, as is the
250   // intermediate needed for path building C(D).
251   CertIssuerSourceStatic sync_certs;
252   sync_certs.AddCert(d_by_d_);
253   sync_certs.AddCert(c_by_d_);
254 
255   // C(D) is not valid at this time, so path building will fail.
256   der::GeneralizedTime expired_time = {2016, 1, 1, 0, 0, 0};
257 
258   CertPathBuilder path_builder(
259       b_by_c_, &trust_store, &delegate_, expired_time, KeyPurpose::ANY_EKU,
260       initial_explicit_policy_, user_initial_policy_set_,
261       initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
262   path_builder.AddCertIssuerSource(&sync_certs);
263 
264   auto result = path_builder.Run();
265 
266   EXPECT_FALSE(result.HasValidPath());
267   ASSERT_EQ(1U, result.paths.size());
268 
269   EXPECT_FALSE(result.paths[0]->IsValid());
270   const auto& path0 = *result.paths[0];
271   ASSERT_EQ(3U, path0.certs.size());
272   EXPECT_EQ(b_by_c_, path0.certs[0]);
273   EXPECT_EQ(c_by_d_, path0.certs[1]);
274   EXPECT_EQ(d_by_d_, path0.certs[2]);
275 }
276 
277 // Test verifying a certificate that is a trust anchor.
TEST_F(PathBuilderMultiRootTest,TargetIsSelfSignedTrustAnchor)278 TEST_F(PathBuilderMultiRootTest, TargetIsSelfSignedTrustAnchor) {
279   TrustStoreInMemory trust_store;
280   trust_store.AddTrustAnchor(e_by_e_);
281   // This is not necessary for the test, just an extra...
282   trust_store.AddTrustAnchor(f_by_e_);
283 
284   CertPathBuilder path_builder(
285       e_by_e_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU,
286       initial_explicit_policy_, user_initial_policy_set_,
287       initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
288 
289   auto result = path_builder.Run();
290 
291   ASSERT_TRUE(result.HasValidPath());
292 
293   // Verifying a trusted leaf certificate is not permitted, however this
294   // certificate is self-signed, and can chain to itself.
295   const auto& path = *result.GetBestValidPath();
296   ASSERT_EQ(2U, path.certs.size());
297   EXPECT_EQ(e_by_e_, path.certs[0]);
298   EXPECT_EQ(e_by_e_, path.certs[1]);
299 }
300 
301 // If the target cert is directly issued by a trust anchor, it should verify
302 // without any intermediate certs being provided.
TEST_F(PathBuilderMultiRootTest,TargetDirectlySignedByTrustAnchor)303 TEST_F(PathBuilderMultiRootTest, TargetDirectlySignedByTrustAnchor) {
304   TrustStoreInMemory trust_store;
305   trust_store.AddTrustAnchor(b_by_f_);
306 
307   CertPathBuilder path_builder(
308       a_by_b_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU,
309       initial_explicit_policy_, user_initial_policy_set_,
310       initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
311 
312   auto result = path_builder.Run();
313 
314   ASSERT_TRUE(result.HasValidPath());
315   const auto& path = *result.GetBestValidPath();
316   ASSERT_EQ(2U, path.certs.size());
317   EXPECT_EQ(a_by_b_, path.certs[0]);
318   EXPECT_EQ(b_by_f_, path.certs[1]);
319 }
320 
321 // Test that async cert queries are not made if the path can be successfully
322 // built with synchronously available certs.
TEST_F(PathBuilderMultiRootTest,TriesSyncFirst)323 TEST_F(PathBuilderMultiRootTest, TriesSyncFirst) {
324   TrustStoreInMemory trust_store;
325   trust_store.AddTrustAnchor(e_by_e_);
326 
327   CertIssuerSourceStatic sync_certs;
328   sync_certs.AddCert(b_by_f_);
329   sync_certs.AddCert(f_by_e_);
330 
331   AsyncCertIssuerSourceStatic async_certs;
332   async_certs.AddCert(b_by_c_);
333   async_certs.AddCert(c_by_e_);
334 
335   CertPathBuilder path_builder(
336       a_by_b_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU,
337       initial_explicit_policy_, user_initial_policy_set_,
338       initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
339   path_builder.AddCertIssuerSource(&async_certs);
340   path_builder.AddCertIssuerSource(&sync_certs);
341 
342   auto result = path_builder.Run();
343 
344   EXPECT_TRUE(result.HasValidPath());
345   EXPECT_EQ(0, async_certs.num_async_gets());
346 }
347 
348 // If async queries are needed, all async sources will be queried
349 // simultaneously.
TEST_F(PathBuilderMultiRootTest,TestAsyncSimultaneous)350 TEST_F(PathBuilderMultiRootTest, TestAsyncSimultaneous) {
351   TrustStoreInMemory trust_store;
352   trust_store.AddTrustAnchor(e_by_e_);
353 
354   CertIssuerSourceStatic sync_certs;
355   sync_certs.AddCert(b_by_c_);
356   sync_certs.AddCert(b_by_f_);
357 
358   AsyncCertIssuerSourceStatic async_certs1;
359   async_certs1.AddCert(c_by_e_);
360 
361   AsyncCertIssuerSourceStatic async_certs2;
362   async_certs2.AddCert(f_by_e_);
363 
364   CertPathBuilder path_builder(
365       a_by_b_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU,
366       initial_explicit_policy_, user_initial_policy_set_,
367       initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
368   path_builder.AddCertIssuerSource(&async_certs1);
369   path_builder.AddCertIssuerSource(&async_certs2);
370   path_builder.AddCertIssuerSource(&sync_certs);
371 
372   auto result = path_builder.Run();
373 
374   EXPECT_TRUE(result.HasValidPath());
375   EXPECT_EQ(1, async_certs1.num_async_gets());
376   EXPECT_EQ(1, async_certs2.num_async_gets());
377 }
378 
379 // Test that PathBuilder does not generate longer paths than necessary if one of
380 // the supplied certs is itself a trust anchor.
TEST_F(PathBuilderMultiRootTest,TestLongChain)381 TEST_F(PathBuilderMultiRootTest, TestLongChain) {
382   // Both D(D) and C(D) are trusted roots.
383   TrustStoreInMemory trust_store;
384   trust_store.AddTrustAnchor(d_by_d_);
385   trust_store.AddTrustAnchor(c_by_d_);
386 
387   // Certs B(C), and C(D) are all supplied.
388   CertIssuerSourceStatic sync_certs;
389   sync_certs.AddCert(b_by_c_);
390   sync_certs.AddCert(c_by_d_);
391 
392   CertPathBuilder path_builder(
393       a_by_b_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU,
394       initial_explicit_policy_, user_initial_policy_set_,
395       initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
396   path_builder.AddCertIssuerSource(&sync_certs);
397 
398   auto result = path_builder.Run();
399 
400   ASSERT_TRUE(result.HasValidPath());
401 
402   // The result path should be A(B) <- B(C) <- C(D)
403   // not the longer but also valid A(B) <- B(C) <- C(D) <- D(D)
404   EXPECT_EQ(3U, result.GetBestValidPath()->certs.size());
405 }
406 
407 // Test that PathBuilder will backtrack and try a different path if the first
408 // one doesn't work out.
TEST_F(PathBuilderMultiRootTest,TestBacktracking)409 TEST_F(PathBuilderMultiRootTest, TestBacktracking) {
410   // Only D(D) is a trusted root.
411   TrustStoreInMemory trust_store;
412   trust_store.AddTrustAnchor(d_by_d_);
413 
414   // Certs B(F) and F(E) are supplied synchronously, thus the path
415   // A(B) <- B(F) <- F(E) should be built first, though it won't verify.
416   CertIssuerSourceStatic sync_certs;
417   sync_certs.AddCert(b_by_f_);
418   sync_certs.AddCert(f_by_e_);
419 
420   // Certs B(C), and C(D) are supplied asynchronously, so the path
421   // A(B) <- B(C) <- C(D) <- D(D) should be tried second.
422   AsyncCertIssuerSourceStatic async_certs;
423   async_certs.AddCert(b_by_c_);
424   async_certs.AddCert(c_by_d_);
425 
426   CertPathBuilder path_builder(
427       a_by_b_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU,
428       initial_explicit_policy_, user_initial_policy_set_,
429       initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
430   path_builder.AddCertIssuerSource(&sync_certs);
431   path_builder.AddCertIssuerSource(&async_certs);
432 
433   auto result = path_builder.Run();
434 
435   ASSERT_TRUE(result.HasValidPath());
436 
437   // The partial path should be returned even though it didn't reach a trust
438   // anchor.
439   ASSERT_EQ(2U, result.paths.size());
440   EXPECT_FALSE(result.paths[0]->IsValid());
441   ASSERT_EQ(3U, result.paths[0]->certs.size());
442   EXPECT_EQ(a_by_b_, result.paths[0]->certs[0]);
443   EXPECT_EQ(b_by_f_, result.paths[0]->certs[1]);
444   EXPECT_EQ(f_by_e_, result.paths[0]->certs[2]);
445 
446   // The result path should be A(B) <- B(C) <- C(D) <- D(D)
447   EXPECT_EQ(1U, result.best_result_index);
448   EXPECT_TRUE(result.paths[1]->IsValid());
449   const auto& path = *result.GetBestValidPath();
450   ASSERT_EQ(4U, path.certs.size());
451   EXPECT_EQ(a_by_b_, path.certs[0]);
452   EXPECT_EQ(b_by_c_, path.certs[1]);
453   EXPECT_EQ(c_by_d_, path.certs[2]);
454   EXPECT_EQ(d_by_d_, path.certs[3]);
455 }
456 
457 // Test that if no path to a trust anchor was found, the partial path is
458 // returned.
TEST_F(PathBuilderMultiRootTest,TestOnlyPartialPathResult)459 TEST_F(PathBuilderMultiRootTest, TestOnlyPartialPathResult) {
460   TrustStoreInMemory trust_store;
461 
462   // Certs B(F) and F(E) are supplied synchronously, thus the path
463   // A(B) <- B(F) <- F(E) should be built first, though it won't verify.
464   CertIssuerSourceStatic sync_certs;
465   sync_certs.AddCert(b_by_f_);
466   sync_certs.AddCert(f_by_e_);
467 
468   CertPathBuilder path_builder(
469       a_by_b_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU,
470       initial_explicit_policy_, user_initial_policy_set_,
471       initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
472   path_builder.AddCertIssuerSource(&sync_certs);
473 
474   auto result = path_builder.Run();
475 
476   EXPECT_FALSE(result.HasValidPath());
477 
478   // The partial path should be returned even though it didn't reach a trust
479   // anchor.
480   ASSERT_EQ(1U, result.paths.size());
481   EXPECT_FALSE(result.paths[0]->IsValid());
482   ASSERT_EQ(3U, result.paths[0]->certs.size());
483   EXPECT_EQ(a_by_b_, result.paths[0]->certs[0]);
484   EXPECT_EQ(b_by_f_, result.paths[0]->certs[1]);
485   EXPECT_EQ(f_by_e_, result.paths[0]->certs[2]);
486 }
487 
488 // Test that if two partial paths are returned, the first is marked as the best
489 // path.
TEST_F(PathBuilderMultiRootTest,TestTwoPartialPathResults)490 TEST_F(PathBuilderMultiRootTest, TestTwoPartialPathResults) {
491   TrustStoreInMemory trust_store;
492 
493   // Certs B(F) and F(E) are supplied synchronously, thus the path
494   // A(B) <- B(F) <- F(E) should be built first, though it won't verify.
495   CertIssuerSourceStatic sync_certs;
496   sync_certs.AddCert(b_by_f_);
497   sync_certs.AddCert(f_by_e_);
498 
499   // Certs B(C), and C(D) are supplied asynchronously, so the path
500   // A(B) <- B(C) <- C(D) <- D(D) should be tried second.
501   AsyncCertIssuerSourceStatic async_certs;
502   async_certs.AddCert(b_by_c_);
503   async_certs.AddCert(c_by_d_);
504 
505   CertPathBuilder path_builder(
506       a_by_b_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU,
507       initial_explicit_policy_, user_initial_policy_set_,
508       initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
509   path_builder.AddCertIssuerSource(&sync_certs);
510   path_builder.AddCertIssuerSource(&async_certs);
511 
512   auto result = path_builder.Run();
513 
514   EXPECT_FALSE(result.HasValidPath());
515 
516   // First partial path found should be marked as the best one.
517   EXPECT_EQ(0U, result.best_result_index);
518 
519   ASSERT_EQ(2U, result.paths.size());
520   EXPECT_FALSE(result.paths[0]->IsValid());
521   ASSERT_EQ(3U, result.paths[0]->certs.size());
522   EXPECT_EQ(a_by_b_, result.paths[0]->certs[0]);
523   EXPECT_EQ(b_by_f_, result.paths[0]->certs[1]);
524   EXPECT_EQ(f_by_e_, result.paths[0]->certs[2]);
525 
526   EXPECT_FALSE(result.paths[1]->IsValid());
527   ASSERT_EQ(3U, result.paths[1]->certs.size());
528   EXPECT_EQ(a_by_b_, result.paths[1]->certs[0]);
529   EXPECT_EQ(b_by_c_, result.paths[1]->certs[1]);
530   EXPECT_EQ(c_by_d_, result.paths[1]->certs[2]);
531 }
532 
533 // Test that if no valid path is found, and the first invalid path is a partial
534 // path, but the 2nd invalid path ends with a cert with a trust record, the 2nd
535 // path should be preferred.
TEST_F(PathBuilderMultiRootTest,TestDistrustedPathPreferredOverPartialPath)536 TEST_F(PathBuilderMultiRootTest, TestDistrustedPathPreferredOverPartialPath) {
537   // Only D(D) has a trust record, but it is distrusted.
538   TrustStoreInMemory trust_store;
539   trust_store.AddDistrustedCertificateForTest(d_by_d_);
540 
541   // Certs B(F) and F(E) are supplied synchronously, thus the path
542   // A(B) <- B(F) <- F(E) should be built first, though it won't verify.
543   CertIssuerSourceStatic sync_certs;
544   sync_certs.AddCert(b_by_f_);
545   sync_certs.AddCert(f_by_e_);
546 
547   // Certs B(C), and C(D) are supplied asynchronously, so the path
548   // A(B) <- B(C) <- C(D) <- D(D) should be tried second.
549   AsyncCertIssuerSourceStatic async_certs;
550   async_certs.AddCert(b_by_c_);
551   async_certs.AddCert(c_by_d_);
552 
553   CertPathBuilder path_builder(
554       a_by_b_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU,
555       initial_explicit_policy_, user_initial_policy_set_,
556       initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
557   path_builder.AddCertIssuerSource(&sync_certs);
558   path_builder.AddCertIssuerSource(&async_certs);
559 
560   auto result = path_builder.Run();
561 
562   EXPECT_FALSE(result.HasValidPath());
563 
564   // The partial path should be returned even though it didn't reach a trust
565   // anchor.
566   ASSERT_EQ(2U, result.paths.size());
567   EXPECT_FALSE(result.paths[0]->IsValid());
568   ASSERT_EQ(3U, result.paths[0]->certs.size());
569   EXPECT_EQ(a_by_b_, result.paths[0]->certs[0]);
570   EXPECT_EQ(b_by_f_, result.paths[0]->certs[1]);
571   EXPECT_EQ(f_by_e_, result.paths[0]->certs[2]);
572 
573   // The result path should be A(B) <- B(C) <- C(D) <- D(D)
574   EXPECT_EQ(1U, result.best_result_index);
575   EXPECT_FALSE(result.paths[1]->IsValid());
576   const auto& path = *result.GetBestPathPossiblyInvalid();
577   ASSERT_EQ(4U, path.certs.size());
578   EXPECT_EQ(a_by_b_, path.certs[0]);
579   EXPECT_EQ(b_by_c_, path.certs[1]);
580   EXPECT_EQ(c_by_d_, path.certs[2]);
581   EXPECT_EQ(d_by_d_, path.certs[3]);
582 }
583 
584 // Test that whichever order CertIssuerSource returns the issuers, the path
585 // building still succeeds.
TEST_F(PathBuilderMultiRootTest,TestCertIssuerOrdering)586 TEST_F(PathBuilderMultiRootTest, TestCertIssuerOrdering) {
587   // Only D(D) is a trusted root.
588   TrustStoreInMemory trust_store;
589   trust_store.AddTrustAnchor(d_by_d_);
590 
591   for (bool reverse_order : {false, true}) {
592     SCOPED_TRACE(reverse_order);
593     std::vector<std::shared_ptr<const ParsedCertificate>> certs = {
594         b_by_c_, b_by_f_, f_by_e_, c_by_d_, c_by_e_};
595     CertIssuerSourceStatic sync_certs;
596     if (reverse_order) {
597       for (auto it = certs.rbegin(); it != certs.rend(); ++it)
598         sync_certs.AddCert(*it);
599     } else {
600       for (const auto& cert : certs)
601         sync_certs.AddCert(cert);
602     }
603 
604     CertPathBuilder path_builder(
605         a_by_b_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU,
606         initial_explicit_policy_, user_initial_policy_set_,
607         initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
608     path_builder.AddCertIssuerSource(&sync_certs);
609 
610     auto result = path_builder.Run();
611 
612     ASSERT_TRUE(result.HasValidPath());
613 
614     // The result path should be A(B) <- B(C) <- C(D) <- D(D)
615     const auto& path = *result.GetBestValidPath();
616     ASSERT_EQ(4U, path.certs.size());
617     EXPECT_EQ(a_by_b_, path.certs[0]);
618     EXPECT_EQ(b_by_c_, path.certs[1]);
619     EXPECT_EQ(c_by_d_, path.certs[2]);
620     EXPECT_EQ(d_by_d_, path.certs[3]);
621   }
622 }
623 
TEST_F(PathBuilderMultiRootTest,TestIterationLimit)624 TEST_F(PathBuilderMultiRootTest, TestIterationLimit) {
625   // D(D) is the trust root.
626   TrustStoreInMemory trust_store;
627   trust_store.AddTrustAnchor(d_by_d_);
628 
629   // Certs B(C) and C(D) are supplied.
630   CertIssuerSourceStatic sync_certs;
631   sync_certs.AddCert(b_by_c_);
632   sync_certs.AddCert(c_by_d_);
633 
634   for (const bool insufficient_limit : {true, false}) {
635     SCOPED_TRACE(insufficient_limit);
636 
637     CertPathBuilder path_builder(
638         a_by_b_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU,
639         initial_explicit_policy_, user_initial_policy_set_,
640         initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
641     path_builder.AddCertIssuerSource(&sync_certs);
642 
643     if (insufficient_limit) {
644       // A limit of one is insufficient to build a path in this case. Therefore
645       // building is expected to fail in this case.
646       path_builder.SetIterationLimit(1);
647     } else {
648       // The other tests in this file exercise the case that |SetIterationLimit|
649       // isn't called. Therefore set a sufficient limit for the path to be
650       // found.
651       path_builder.SetIterationLimit(5);
652     }
653 
654     auto result = path_builder.Run();
655 
656     EXPECT_EQ(!insufficient_limit, result.HasValidPath());
657     EXPECT_EQ(insufficient_limit, result.exceeded_iteration_limit);
658 
659     if (insufficient_limit) {
660       EXPECT_EQ(2U, result.iteration_count);
661     } else {
662       EXPECT_EQ(3U, result.iteration_count);
663     }
664   }
665 }
666 
TEST_F(PathBuilderMultiRootTest,TestTrivialDeadline)667 TEST_F(PathBuilderMultiRootTest, TestTrivialDeadline) {
668   // C(D) is the trust root.
669   TrustStoreInMemory trust_store;
670   trust_store.AddTrustAnchor(c_by_d_);
671 
672   // Cert B(C) is supplied.
673   CertIssuerSourceStatic sync_certs;
674   sync_certs.AddCert(b_by_c_);
675 
676   for (const bool insufficient_limit : {true, false}) {
677     SCOPED_TRACE(insufficient_limit);
678 
679     CertPathBuilder path_builder(
680         a_by_b_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU,
681         initial_explicit_policy_, user_initial_policy_set_,
682         initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
683     path_builder.AddCertIssuerSource(&sync_certs);
684 
685     // Make the deadline either expired or not.
686     delegate_.SetDeadlineExpiredForTesting(insufficient_limit);
687 
688     auto result = path_builder.Run();
689 
690     EXPECT_EQ(!insufficient_limit, result.HasValidPath());
691     EXPECT_EQ(insufficient_limit, result.exceeded_deadline);
692     EXPECT_EQ(delegate_.IsDeadlineExpired(), insufficient_limit);
693 
694     if (insufficient_limit) {
695       ASSERT_EQ(1U, result.paths.size());
696       EXPECT_FALSE(result.paths[0]->IsValid());
697       ASSERT_EQ(1U, result.paths[0]->certs.size());
698       EXPECT_EQ(a_by_b_, result.paths[0]->certs[0]);
699       EXPECT_TRUE(result.paths[0]->errors.ContainsError(
700           cert_errors::kDeadlineExceeded));
701     } else {
702       ASSERT_EQ(1U, result.paths.size());
703       EXPECT_TRUE(result.paths[0]->IsValid());
704       ASSERT_EQ(3U, result.paths[0]->certs.size());
705       EXPECT_EQ(a_by_b_, result.paths[0]->certs[0]);
706       EXPECT_EQ(b_by_c_, result.paths[0]->certs[1]);
707       EXPECT_EQ(c_by_d_, result.paths[0]->certs[2]);
708     }
709   }
710 }
711 
TEST_F(PathBuilderMultiRootTest,TestVerifyCache)712 TEST_F(PathBuilderMultiRootTest, TestVerifyCache) {
713   // C(D) is the trust root.
714   TrustStoreInMemory trust_store;
715   trust_store.AddTrustAnchor(c_by_d_);
716 
717   // Cert B(C) is supplied.
718   CertIssuerSourceStatic sync_certs;
719   sync_certs.AddCert(b_by_c_);
720 
721   // Test Activation / DeActivation of the cache.
722   EXPECT_FALSE(delegate_.GetVerifyCache());
723   delegate_.ActivateCache();
724   EXPECT_TRUE(delegate_.GetVerifyCache());
725   delegate_.DeActivateCache();
726   EXPECT_FALSE(delegate_.GetVerifyCache());
727   delegate_.ActivateCache();
728   EXPECT_TRUE(delegate_.GetVerifyCache());
729   for (size_t i = 0; i < 3; i++) {
730     SCOPED_TRACE(i);
731 
732     CertPathBuilder path_builder(
733         a_by_b_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU,
734         initial_explicit_policy_, user_initial_policy_set_,
735         initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
736     path_builder.AddCertIssuerSource(&sync_certs);
737 
738     auto result = path_builder.Run();
739 
740     ASSERT_EQ(1U, result.paths.size());
741     EXPECT_TRUE(result.paths[0]->IsValid());
742     ASSERT_EQ(3U, result.paths[0]->certs.size());
743     EXPECT_EQ(a_by_b_, result.paths[0]->certs[0]);
744     EXPECT_EQ(b_by_c_, result.paths[0]->certs[1]);
745     EXPECT_EQ(c_by_d_, result.paths[0]->certs[2]);
746 
747     // The path is 3 certificates long, so requires 2 distinct signature
748     // verifications. The first time through the loop will cause 2 cache misses
749     // and stores, subsequent iterations will repeat the same verifications,
750     // causing 2 cache hits.
751     EXPECT_EQ(delegate_.GetMockVerifyCache()->CacheHits(), i * 2);
752     EXPECT_EQ(delegate_.GetMockVerifyCache()->CacheMisses(), 2U);
753     EXPECT_EQ(delegate_.GetMockVerifyCache()->CacheStores(), 2U);
754   }
755 }
756 
TEST_F(PathBuilderMultiRootTest,TestDeadline)757 TEST_F(PathBuilderMultiRootTest, TestDeadline) {
758   TrustStoreInMemory trust_store;
759   trust_store.AddTrustAnchor(d_by_d_);
760 
761   // Cert B(C) is supplied statically.
762   CertIssuerSourceStatic sync_certs;
763   sync_certs.AddCert(b_by_c_);
764 
765   // Cert C(D) is supplied asynchronously and will expire the deadline before
766   // returning the async result.
767   AsyncCertIssuerSourceStatic async_certs;
768   async_certs.AddCert(c_by_d_);
769   async_certs.SetAsyncGetCallback(
770       [&] { delegate_.SetDeadlineExpiredForTesting(true); });
771 
772   CertPathBuilder path_builder(
773       a_by_b_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU,
774       initial_explicit_policy_, user_initial_policy_set_,
775       initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
776   path_builder.AddCertIssuerSource(&sync_certs);
777   path_builder.AddCertIssuerSource(&async_certs);
778 
779   auto result = path_builder.Run();
780 
781   EXPECT_FALSE(result.HasValidPath());
782   EXPECT_TRUE(result.exceeded_deadline);
783   EXPECT_TRUE(delegate_.IsDeadlineExpired());
784 
785   // The chain returned should end in c_by_d_, since the deadline would only be
786   // checked again after the async results had been checked (since
787   // AsyncCertIssuerSourceStatic makes the async results available immediately.)
788   ASSERT_EQ(1U, result.paths.size());
789   EXPECT_FALSE(result.paths[0]->IsValid());
790   ASSERT_EQ(3U, result.paths[0]->certs.size());
791   EXPECT_EQ(a_by_b_, result.paths[0]->certs[0]);
792   EXPECT_EQ(b_by_c_, result.paths[0]->certs[1]);
793   EXPECT_EQ(c_by_d_, result.paths[0]->certs[2]);
794   EXPECT_TRUE(
795       result.paths[0]->errors.ContainsError(cert_errors::kDeadlineExceeded));
796 }
797 
TEST_F(PathBuilderMultiRootTest,TestDepthLimit)798 TEST_F(PathBuilderMultiRootTest, TestDepthLimit) {
799   // D(D) is the trust root.
800   TrustStoreInMemory trust_store;
801   trust_store.AddTrustAnchor(d_by_d_);
802 
803   // Certs B(C) and C(D) are supplied.
804   CertIssuerSourceStatic sync_certs;
805   sync_certs.AddCert(b_by_c_);
806   sync_certs.AddCert(c_by_d_);
807 
808   for (const bool insufficient_limit : {true, false}) {
809     CertPathBuilder path_builder(
810         a_by_b_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU,
811         initial_explicit_policy_, user_initial_policy_set_,
812         initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
813     path_builder.AddCertIssuerSource(&sync_certs);
814 
815     if (insufficient_limit) {
816       // A limit of depth equal to 2 is insufficient to build the path.
817       // Therefore, building is expected to fail.
818       path_builder.SetDepthLimit(2);
819     } else {
820       // The other tests in this file exercise the case that |SetDepthLimit|
821       // isn't called. Therefore, set a sufficient limit for the path to be
822       // found.
823       path_builder.SetDepthLimit(5);
824     }
825 
826     auto result = path_builder.Run();
827 
828     EXPECT_EQ(!insufficient_limit, result.HasValidPath());
829     EXPECT_EQ(insufficient_limit,
830               result.AnyPathContainsError(cert_errors::kDepthLimitExceeded));
831     if (insufficient_limit) {
832       EXPECT_EQ(2U, result.max_depth_seen);
833     } else {
834       EXPECT_EQ(4U, result.max_depth_seen);
835     }
836   }
837 }
838 
TEST_F(PathBuilderMultiRootTest,TestDepthLimitMultiplePaths)839 TEST_F(PathBuilderMultiRootTest, TestDepthLimitMultiplePaths) {
840   // This case tests path building backracking due to reaching the path depth
841   // limit. Given the root and issuer certificates below, there can be two paths
842   // from between the leaf to a trusted root, one has length of 3 and the other
843   // has length of 4. These certificates are specifically chosen because path
844   // building will first explore the 4-certificate long path then the
845   // 3-certificate long path. So with a depth limit of 3, we can test the
846   // backtracking code path.
847 
848   // E(E) and C(D) are the trust roots.
849   TrustStoreInMemory trust_store;
850   trust_store.AddTrustAnchor(e_by_e_);
851   trust_store.AddTrustAnchor(c_by_d_);
852 
853   // Certs B(C). B(F) and F(E) are supplied.
854   CertIssuerSourceStatic sync_certs;
855   sync_certs.AddCert(b_by_c_);
856   sync_certs.AddCert(b_by_f_);
857   sync_certs.AddCert(f_by_e_);
858 
859   CertPathBuilder path_builder(
860       a_by_b_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU,
861       initial_explicit_policy_, user_initial_policy_set_,
862       initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
863   path_builder.AddCertIssuerSource(&sync_certs);
864 
865   path_builder.SetDepthLimit(3);
866 
867   auto result = path_builder.Run();
868 
869   EXPECT_TRUE(result.HasValidPath());
870   EXPECT_TRUE(result.AnyPathContainsError(cert_errors::kDepthLimitExceeded));
871 
872   ASSERT_EQ(result.paths.size(), 2u);
873 
874   const CertPathBuilderResultPath* truncated_path = result.paths[0].get();
875   EXPECT_FALSE(truncated_path->IsValid());
876   EXPECT_TRUE(
877       truncated_path->errors.ContainsError(cert_errors::kDepthLimitExceeded));
878   ASSERT_EQ(truncated_path->certs.size(), 3u);
879   EXPECT_EQ(a_by_b_, truncated_path->certs[0]);
880   EXPECT_EQ(b_by_f_, truncated_path->certs[1]);
881   EXPECT_EQ(f_by_e_, truncated_path->certs[2]);
882 
883   const CertPathBuilderResultPath* valid_path = result.paths[1].get();
884   EXPECT_TRUE(valid_path->IsValid());
885   EXPECT_FALSE(
886       valid_path->errors.ContainsError(cert_errors::kDepthLimitExceeded));
887   ASSERT_EQ(valid_path->certs.size(), 3u);
888   EXPECT_EQ(a_by_b_, valid_path->certs[0]);
889   EXPECT_EQ(b_by_c_, valid_path->certs[1]);
890   EXPECT_EQ(c_by_d_, valid_path->certs[2]);
891 }
892 
893 class PathBuilderKeyRolloverTest : public ::testing::Test {
894  public:
PathBuilderKeyRolloverTest()895   PathBuilderKeyRolloverTest()
896       : delegate_(1024,
897                   SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1) {}
898 
SetUp()899   void SetUp() override {
900     ParsedCertificateList path;
901 
902     VerifyCertChainTest test;
903     ASSERT_TRUE(ReadVerifyCertChainTestFromFile(
904         "testdata/verify_certificate_chain_unittest/key-rollover/oldchain.test",
905         &test));
906     path = test.chain;
907     ASSERT_EQ(3U, path.size());
908     target_ = path[0];
909     oldintermediate_ = path[1];
910     oldroot_ = path[2];
911     time_ = test.time;
912 
913     ASSERT_TRUE(target_);
914     ASSERT_TRUE(oldintermediate_);
915 
916     ASSERT_TRUE(ReadVerifyCertChainTestFromFile(
917         "testdata/verify_certificate_chain_unittest/"
918         "key-rollover/longrolloverchain.test",
919         &test));
920     path = test.chain;
921 
922     ASSERT_EQ(5U, path.size());
923     newintermediate_ = path[1];
924     newroot_ = path[2];
925     newrootrollover_ = path[3];
926     ASSERT_TRUE(newintermediate_);
927     ASSERT_TRUE(newroot_);
928     ASSERT_TRUE(newrootrollover_);
929   }
930 
931  protected:
932   //    oldroot-------->newrootrollover  newroot
933   //       |                      |        |
934   //       v                      v        v
935   // oldintermediate           newintermediate
936   //       |                          |
937   //       +------------+-------------+
938   //                    |
939   //                    v
940   //                  target
941   std::shared_ptr<const ParsedCertificate> target_;
942   std::shared_ptr<const ParsedCertificate> oldintermediate_;
943   std::shared_ptr<const ParsedCertificate> newintermediate_;
944   std::shared_ptr<const ParsedCertificate> oldroot_;
945   std::shared_ptr<const ParsedCertificate> newroot_;
946   std::shared_ptr<const ParsedCertificate> newrootrollover_;
947 
948   SimplePathBuilderDelegate delegate_;
949   der::GeneralizedTime time_;
950 
951   const InitialExplicitPolicy initial_explicit_policy_ =
952       InitialExplicitPolicy::kFalse;
953   const std::set<der::Input> user_initial_policy_set_ = {
954       der::Input(kAnyPolicyOid)};
955   const InitialPolicyMappingInhibit initial_policy_mapping_inhibit_ =
956       InitialPolicyMappingInhibit::kFalse;
957   const InitialAnyPolicyInhibit initial_any_policy_inhibit_ =
958       InitialAnyPolicyInhibit::kFalse;
959 };
960 
961 // Tests that if only the old root cert is trusted, the path builder can build a
962 // path through the new intermediate and rollover cert to the old root.
TEST_F(PathBuilderKeyRolloverTest,TestRolloverOnlyOldRootTrusted)963 TEST_F(PathBuilderKeyRolloverTest, TestRolloverOnlyOldRootTrusted) {
964   // Only oldroot is trusted.
965   TrustStoreInMemory trust_store;
966   trust_store.AddTrustAnchor(oldroot_);
967 
968   // Old intermediate cert is not provided, so the pathbuilder will need to go
969   // through the rollover cert.
970   CertIssuerSourceStatic sync_certs;
971   sync_certs.AddCert(newintermediate_);
972   sync_certs.AddCert(newrootrollover_);
973 
974   CertPathBuilder path_builder(
975       target_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU,
976       initial_explicit_policy_, user_initial_policy_set_,
977       initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
978   path_builder.AddCertIssuerSource(&sync_certs);
979 
980   auto result = path_builder.Run();
981 
982   EXPECT_TRUE(result.HasValidPath());
983 
984   // Due to authorityKeyIdentifier prioritization, path builder will first
985   // attempt: target <- newintermediate <- newrootrollover <- oldroot
986   // which will succeed.
987   ASSERT_EQ(1U, result.paths.size());
988   const auto& path0 = *result.paths[0];
989   EXPECT_EQ(0U, result.best_result_index);
990   EXPECT_TRUE(path0.IsValid());
991   ASSERT_EQ(4U, path0.certs.size());
992   EXPECT_EQ(target_, path0.certs[0]);
993   EXPECT_EQ(newintermediate_, path0.certs[1]);
994   EXPECT_EQ(newrootrollover_, path0.certs[2]);
995   EXPECT_EQ(oldroot_, path0.certs[3]);
996 }
997 
998 // Tests that if both old and new roots are trusted it builds a path through
999 // the new intermediate.
TEST_F(PathBuilderKeyRolloverTest,TestRolloverBothRootsTrusted)1000 TEST_F(PathBuilderKeyRolloverTest, TestRolloverBothRootsTrusted) {
1001   // Both oldroot and newroot are trusted.
1002   TrustStoreInMemory trust_store;
1003   trust_store.AddTrustAnchor(oldroot_);
1004   trust_store.AddTrustAnchor(newroot_);
1005 
1006   // Both old and new intermediates + rollover cert are provided.
1007   CertIssuerSourceStatic sync_certs;
1008   sync_certs.AddCert(oldintermediate_);
1009   sync_certs.AddCert(newintermediate_);
1010   sync_certs.AddCert(newrootrollover_);
1011 
1012   CertPathBuilder path_builder(
1013       target_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU,
1014       initial_explicit_policy_, user_initial_policy_set_,
1015       initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
1016   path_builder.AddCertIssuerSource(&sync_certs);
1017 
1018   auto result = path_builder.Run();
1019 
1020   EXPECT_TRUE(result.HasValidPath());
1021 
1022   ASSERT_EQ(1U, result.paths.size());
1023   const auto& path = *result.paths[0];
1024   EXPECT_TRUE(result.paths[0]->IsValid());
1025   ASSERT_EQ(3U, path.certs.size());
1026   EXPECT_EQ(target_, path.certs[0]);
1027   // The newer intermediate should be used as newer certs are prioritized in
1028   // path building.
1029   EXPECT_EQ(newintermediate_, path.certs[1]);
1030   EXPECT_EQ(newroot_, path.certs[2]);
1031 }
1032 
1033 // If trust anchor query returned no results, and there are no issuer
1034 // sources, path building should fail at that point.
TEST_F(PathBuilderKeyRolloverTest,TestAnchorsNoMatchAndNoIssuerSources)1035 TEST_F(PathBuilderKeyRolloverTest, TestAnchorsNoMatchAndNoIssuerSources) {
1036   TrustStoreInMemory trust_store;
1037   trust_store.AddTrustAnchor(newroot_);
1038 
1039   CertPathBuilder path_builder(
1040       target_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU,
1041       initial_explicit_policy_, user_initial_policy_set_,
1042       initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
1043 
1044   auto result = path_builder.Run();
1045 
1046   EXPECT_FALSE(result.HasValidPath());
1047 
1048   ASSERT_EQ(1U, result.paths.size());
1049   const auto& path = *result.paths[0];
1050   EXPECT_FALSE(result.paths[0]->IsValid());
1051   ASSERT_EQ(1U, path.certs.size());
1052   EXPECT_EQ(target_, path.certs[0]);
1053 }
1054 
1055 // If a path to a trust anchor could not be found, and the last issuer(s) in
1056 // the chain were culled by the loop checker, the partial path up to that point
1057 // should be returned.
TEST_F(PathBuilderKeyRolloverTest,TestReturnsPartialPathEndedByLoopChecker)1058 TEST_F(PathBuilderKeyRolloverTest, TestReturnsPartialPathEndedByLoopChecker) {
1059   TrustStoreInMemory trust_store;
1060 
1061   CertIssuerSourceStatic sync_certs;
1062   sync_certs.AddCert(newintermediate_);
1063   sync_certs.AddCert(newroot_);
1064 
1065   CertIssuerSourceStatic rollover_certs;
1066   rollover_certs.AddCert(newrootrollover_);
1067 
1068   CertPathBuilder path_builder(
1069       target_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU,
1070       initial_explicit_policy_, user_initial_policy_set_,
1071       initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
1072   path_builder.AddCertIssuerSource(&sync_certs);
1073   // The rollover root is added as a second issuer source to ensure we get paths
1074   // back in a deterministic order, otherwise newroot and newrootrollover do not
1075   // differ in any way that the path builder would use for prioritizing which
1076   // path comes back first.
1077   path_builder.AddCertIssuerSource(&rollover_certs);
1078 
1079   auto result = path_builder.Run();
1080 
1081   EXPECT_FALSE(result.HasValidPath());
1082   ASSERT_EQ(2U, result.paths.size());
1083 
1084   // Since none of the certs are trusted, the path builder should build 4
1085   // candidate paths, all of which are disallowed due to the loop checker:
1086   //   target->newintermediate->newroot->newroot
1087   //   target->newintermediate->newroot->newrootrollover
1088   //   target->newintermediate->newrootrollover->newroot
1089   //   target->newintermediate->newrootrollover->newrootrollover
1090   // This should end up returning the 2 partial paths which are the longest
1091   // paths for which no acceptable issuers could be found:
1092   //   target->newintermediate->newroot
1093   //   target->newintermediate->newrootrollover
1094 
1095   {
1096     const auto& path = *result.paths[0];
1097     EXPECT_FALSE(path.IsValid());
1098     ASSERT_EQ(3U, path.certs.size());
1099     EXPECT_EQ(target_, path.certs[0]);
1100     EXPECT_EQ(newintermediate_, path.certs[1]);
1101     EXPECT_EQ(newroot_, path.certs[2]);
1102     EXPECT_TRUE(path.errors.ContainsError(cert_errors::kNoIssuersFound));
1103   }
1104 
1105   {
1106     const auto& path = *result.paths[1];
1107     EXPECT_FALSE(path.IsValid());
1108     ASSERT_EQ(3U, path.certs.size());
1109     EXPECT_EQ(target_, path.certs[0]);
1110     EXPECT_EQ(newintermediate_, path.certs[1]);
1111     EXPECT_EQ(newrootrollover_, path.certs[2]);
1112     EXPECT_TRUE(path.errors.ContainsError(cert_errors::kNoIssuersFound));
1113   }
1114 }
1115 
1116 // Tests that multiple trust root matches on a single path will be considered.
1117 // Both roots have the same subject but different keys. Only one of them will
1118 // verify.
TEST_F(PathBuilderKeyRolloverTest,TestMultipleRootMatchesOnlyOneWorks)1119 TEST_F(PathBuilderKeyRolloverTest, TestMultipleRootMatchesOnlyOneWorks) {
1120   TrustStoreCollection trust_store_collection;
1121   TrustStoreInMemory trust_store1;
1122   TrustStoreInMemory trust_store2;
1123   trust_store_collection.AddTrustStore(&trust_store1);
1124   trust_store_collection.AddTrustStore(&trust_store2);
1125   // Add two trust anchors (newroot_ and oldroot_). Path building will attempt
1126   // them in this same order, as trust_store1 was added to
1127   // trust_store_collection first.
1128   trust_store1.AddTrustAnchor(newroot_);
1129   trust_store2.AddTrustAnchor(oldroot_);
1130 
1131   // Only oldintermediate is supplied, so the path with newroot should fail,
1132   // oldroot should succeed.
1133   CertIssuerSourceStatic sync_certs;
1134   sync_certs.AddCert(oldintermediate_);
1135 
1136   CertPathBuilder path_builder(
1137       target_, &trust_store_collection, &delegate_, time_, KeyPurpose::ANY_EKU,
1138       initial_explicit_policy_, user_initial_policy_set_,
1139       initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
1140   path_builder.AddCertIssuerSource(&sync_certs);
1141 
1142   auto result = path_builder.Run();
1143 
1144   EXPECT_TRUE(result.HasValidPath());
1145   ASSERT_EQ(1U, result.paths.size());
1146 
1147   // Due to authorityKeyIdentifier prioritization, path builder will first
1148   // attempt: target <- old intermediate <- oldroot
1149   // which should succeed.
1150   EXPECT_TRUE(result.paths[result.best_result_index]->IsValid());
1151   const auto& path = *result.paths[result.best_result_index];
1152   ASSERT_EQ(3U, path.certs.size());
1153   EXPECT_EQ(target_, path.certs[0]);
1154   EXPECT_EQ(oldintermediate_, path.certs[1]);
1155   EXPECT_EQ(oldroot_, path.certs[2]);
1156 }
1157 
1158 // Tests that the path builder doesn't build longer than necessary paths,
1159 // by skipping certs where the same Name+SAN+SPKI is already in the current
1160 // path.
TEST_F(PathBuilderKeyRolloverTest,TestRolloverLongChain)1161 TEST_F(PathBuilderKeyRolloverTest, TestRolloverLongChain) {
1162   // Only oldroot is trusted.
1163   TrustStoreInMemory trust_store;
1164   trust_store.AddTrustAnchor(oldroot_);
1165 
1166   // New intermediate and new root are provided synchronously.
1167   CertIssuerSourceStatic sync_certs;
1168   sync_certs.AddCert(newintermediate_);
1169   sync_certs.AddCert(newroot_);
1170 
1171   // Rollover cert is only provided asynchronously. This will force the
1172   // pathbuilder to first try building a longer than necessary path.
1173   AsyncCertIssuerSourceStatic async_certs;
1174   async_certs.AddCert(newrootrollover_);
1175 
1176   CertPathBuilder path_builder(
1177       target_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU,
1178       initial_explicit_policy_, user_initial_policy_set_,
1179       initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
1180   path_builder.AddCertIssuerSource(&sync_certs);
1181   path_builder.AddCertIssuerSource(&async_certs);
1182 
1183   auto result = path_builder.Run();
1184 
1185   EXPECT_TRUE(result.HasValidPath());
1186   ASSERT_EQ(3U, result.paths.size());
1187 
1188   // Path builder will first attempt:
1189   // target <- newintermediate <- newroot <- oldroot
1190   // but it will fail since newroot is self-signed.
1191   EXPECT_FALSE(result.paths[0]->IsValid());
1192   const auto& path0 = *result.paths[0];
1193   ASSERT_EQ(4U, path0.certs.size());
1194   EXPECT_EQ(target_, path0.certs[0]);
1195   EXPECT_EQ(newintermediate_, path0.certs[1]);
1196   EXPECT_EQ(newroot_, path0.certs[2]);
1197   EXPECT_EQ(oldroot_, path0.certs[3]);
1198 
1199   // Path builder will next attempt: target <- newintermediate <- oldroot
1200   // but it will fail since newintermediate is signed by newroot.
1201   EXPECT_FALSE(result.paths[1]->IsValid());
1202   const auto& path1 = *result.paths[1];
1203   ASSERT_EQ(3U, path1.certs.size());
1204   EXPECT_EQ(target_, path1.certs[0]);
1205   EXPECT_EQ(newintermediate_, path1.certs[1]);
1206   EXPECT_EQ(oldroot_, path1.certs[2]);
1207 
1208   // Path builder will skip:
1209   // target <- newintermediate <- newroot <- newrootrollover <- ...
1210   // Since newroot and newrootrollover have the same Name+SAN+SPKI.
1211 
1212   // Finally path builder will use:
1213   // target <- newintermediate <- newrootrollover <- oldroot
1214   EXPECT_EQ(2U, result.best_result_index);
1215   EXPECT_TRUE(result.paths[2]->IsValid());
1216   const auto& path2 = *result.paths[2];
1217   ASSERT_EQ(4U, path2.certs.size());
1218   EXPECT_EQ(target_, path2.certs[0]);
1219   EXPECT_EQ(newintermediate_, path2.certs[1]);
1220   EXPECT_EQ(newrootrollover_, path2.certs[2]);
1221   EXPECT_EQ(oldroot_, path2.certs[3]);
1222 }
1223 
1224 // Tests that when SetExploreAllPaths is combined with SetIterationLimit the
1225 // path builder will return all the paths that were able to be built before the
1226 // iteration limit was reached.
TEST_F(PathBuilderKeyRolloverTest,ExploreAllPathsWithIterationLimit)1227 TEST_F(PathBuilderKeyRolloverTest, ExploreAllPathsWithIterationLimit) {
1228   struct Expectation {
1229     int iteration_limit;
1230     size_t expected_num_paths;
1231     std::vector<std::shared_ptr<const ParsedCertificate>> partial_path;
1232   } kExpectations[] = {
1233       // No iteration limit. All possible paths should be built.
1234       {0, 4, {}},
1235       // Limit 1 is only enough to reach the intermediate, no complete path
1236       // should be built.
1237       {1, 0, {target_, newintermediate_}},
1238       // Limit 2 allows reaching the root on the first path.
1239       {2, 1, {target_, newintermediate_}},
1240       // Next iteration uses oldroot instead of newroot.
1241       {3, 2, {target_, newintermediate_}},
1242       // Backtracking to the target cert.
1243       {4, 2, {target_}},
1244       // Adding oldintermediate.
1245       {5, 2, {target_, oldintermediate_}},
1246       // Trying oldroot.
1247       {6, 3, {target_, oldintermediate_}},
1248       // Trying newroot.
1249       {7, 4, {target_, oldintermediate_}},
1250   };
1251 
1252   // Trust both old and new roots.
1253   TrustStoreInMemory trust_store;
1254   trust_store.AddTrustAnchor(oldroot_);
1255   trust_store.AddTrustAnchor(newroot_);
1256 
1257   // Intermediates and root rollover are all provided synchronously.
1258   CertIssuerSourceStatic sync_certs;
1259   sync_certs.AddCert(oldintermediate_);
1260   sync_certs.AddCert(newintermediate_);
1261 
1262   for (const auto& expectation : kExpectations) {
1263     SCOPED_TRACE(expectation.iteration_limit);
1264 
1265     CertPathBuilder path_builder(
1266         target_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU,
1267         initial_explicit_policy_, user_initial_policy_set_,
1268         initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
1269     path_builder.AddCertIssuerSource(&sync_certs);
1270 
1271     // Explore all paths, rather than stopping at the first valid path.
1272     path_builder.SetExploreAllPaths(true);
1273 
1274     // Limit the number of iterations.
1275     path_builder.SetIterationLimit(expectation.iteration_limit);
1276 
1277     auto result = path_builder.Run();
1278 
1279     EXPECT_EQ(expectation.expected_num_paths > 0, result.HasValidPath());
1280     if (expectation.partial_path.empty()) {
1281       ASSERT_EQ(expectation.expected_num_paths, result.paths.size());
1282     } else {
1283       ASSERT_EQ(1 + expectation.expected_num_paths, result.paths.size());
1284       const auto& path = *result.paths[result.paths.size() - 1];
1285       EXPECT_FALSE(path.IsValid());
1286       EXPECT_EQ(expectation.partial_path, path.certs);
1287       EXPECT_TRUE(
1288           path.errors.ContainsError(cert_errors::kIterationLimitExceeded));
1289     }
1290 
1291     if (expectation.expected_num_paths > 0) {
1292       // Path builder will first build path: target <- newintermediate <-
1293       // newroot
1294       const auto& path0 = *result.paths[0];
1295       EXPECT_TRUE(path0.IsValid());
1296       ASSERT_EQ(3U, path0.certs.size());
1297       EXPECT_EQ(target_, path0.certs[0]);
1298       EXPECT_EQ(newintermediate_, path0.certs[1]);
1299       EXPECT_EQ(newroot_, path0.certs[2]);
1300       EXPECT_EQ(3U, result.max_depth_seen);
1301     }
1302 
1303     if (expectation.expected_num_paths > 1) {
1304       // Next path:  target <- newintermediate <- oldroot
1305       const auto& path1 = *result.paths[1];
1306       EXPECT_FALSE(path1.IsValid());
1307       ASSERT_EQ(3U, path1.certs.size());
1308       EXPECT_EQ(target_, path1.certs[0]);
1309       EXPECT_EQ(newintermediate_, path1.certs[1]);
1310       EXPECT_EQ(oldroot_, path1.certs[2]);
1311       EXPECT_EQ(3U, result.max_depth_seen);
1312     }
1313 
1314     if (expectation.expected_num_paths > 2) {
1315       // Next path:  target <- oldintermediate <- oldroot
1316       const auto& path2 = *result.paths[2];
1317       EXPECT_TRUE(path2.IsValid());
1318       ASSERT_EQ(3U, path2.certs.size());
1319       EXPECT_EQ(target_, path2.certs[0]);
1320       EXPECT_EQ(oldintermediate_, path2.certs[1]);
1321       EXPECT_EQ(oldroot_, path2.certs[2]);
1322       EXPECT_EQ(3U, result.max_depth_seen);
1323     }
1324 
1325     if (expectation.expected_num_paths > 3) {
1326       // Final path:  target <- oldintermediate <- newroot
1327       const auto& path3 = *result.paths[3];
1328       EXPECT_FALSE(path3.IsValid());
1329       ASSERT_EQ(3U, path3.certs.size());
1330       EXPECT_EQ(target_, path3.certs[0]);
1331       EXPECT_EQ(oldintermediate_, path3.certs[1]);
1332       EXPECT_EQ(newroot_, path3.certs[2]);
1333       EXPECT_EQ(3U, result.max_depth_seen);
1334     }
1335   }
1336 }
1337 
1338 // If the target cert is a trust anchor, however is not itself *signed* by a
1339 // trust anchor, then it is not considered valid (the SPKI and name of the
1340 // trust anchor matches the SPKI and subject of the targe certificate, but the
1341 // rest of the certificate cannot be verified).
TEST_F(PathBuilderKeyRolloverTest,TestEndEntityIsTrustRoot)1342 TEST_F(PathBuilderKeyRolloverTest, TestEndEntityIsTrustRoot) {
1343   // Trust newintermediate.
1344   TrustStoreInMemory trust_store;
1345   trust_store.AddTrustAnchor(newintermediate_);
1346 
1347   // Newintermediate is also the target cert.
1348   CertPathBuilder path_builder(
1349       newintermediate_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU,
1350       initial_explicit_policy_, user_initial_policy_set_,
1351       initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
1352 
1353   auto result = path_builder.Run();
1354 
1355   EXPECT_FALSE(result.HasValidPath());
1356 }
1357 
1358 // If target has same Name+SAN+SPKI as a necessary intermediate, test if a path
1359 // can still be built.
1360 // Since LoopChecker will prevent the intermediate from being included, this
1361 // currently does NOT verify. This case shouldn't occur in the web PKI.
TEST_F(PathBuilderKeyRolloverTest,TestEndEntityHasSameNameAndSpkiAsIntermediate)1362 TEST_F(PathBuilderKeyRolloverTest,
1363        TestEndEntityHasSameNameAndSpkiAsIntermediate) {
1364   // Trust oldroot.
1365   TrustStoreInMemory trust_store;
1366   trust_store.AddTrustAnchor(oldroot_);
1367 
1368   // New root rollover is provided synchronously.
1369   CertIssuerSourceStatic sync_certs;
1370   sync_certs.AddCert(newrootrollover_);
1371 
1372   // Newroot is the target cert.
1373   CertPathBuilder path_builder(
1374       newroot_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU,
1375       initial_explicit_policy_, user_initial_policy_set_,
1376       initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
1377   path_builder.AddCertIssuerSource(&sync_certs);
1378 
1379   auto result = path_builder.Run();
1380 
1381   // This could actually be OK, but CertPathBuilder does not build the
1382   // newroot <- newrootrollover <- oldroot path.
1383   EXPECT_FALSE(result.HasValidPath());
1384 }
1385 
1386 // If target has same Name+SAN+SPKI as the trust root, test that a (trivial)
1387 // path can still be built.
TEST_F(PathBuilderKeyRolloverTest,TestEndEntityHasSameNameAndSpkiAsTrustAnchor)1388 TEST_F(PathBuilderKeyRolloverTest,
1389        TestEndEntityHasSameNameAndSpkiAsTrustAnchor) {
1390   // Trust newrootrollover.
1391   TrustStoreInMemory trust_store;
1392   trust_store.AddTrustAnchor(newrootrollover_);
1393 
1394   // Newroot is the target cert.
1395   CertPathBuilder path_builder(
1396       newroot_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU,
1397       initial_explicit_policy_, user_initial_policy_set_,
1398       initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
1399 
1400   auto result = path_builder.Run();
1401 
1402   ASSERT_TRUE(result.HasValidPath());
1403 
1404   const CertPathBuilderResultPath* best_result = result.GetBestValidPath();
1405 
1406   // Newroot has same name+SPKI as newrootrollover, thus the path is valid and
1407   // only contains newroot.
1408   EXPECT_TRUE(best_result->IsValid());
1409   ASSERT_EQ(2U, best_result->certs.size());
1410   EXPECT_EQ(newroot_, best_result->certs[0]);
1411   EXPECT_EQ(newrootrollover_, best_result->certs[1]);
1412 }
1413 
1414 // Test that PathBuilder will not try the same path twice if multiple
1415 // CertIssuerSources provide the same certificate.
TEST_F(PathBuilderKeyRolloverTest,TestDuplicateIntermediates)1416 TEST_F(PathBuilderKeyRolloverTest, TestDuplicateIntermediates) {
1417   // Create a separate copy of oldintermediate.
1418   std::shared_ptr<const ParsedCertificate> oldintermediate_dupe(
1419       ParsedCertificate::Create(
1420           bssl::UniquePtr<CRYPTO_BUFFER>(CRYPTO_BUFFER_new(
1421               oldintermediate_->der_cert().UnsafeData(),
1422               oldintermediate_->der_cert().Length(), nullptr)),
1423           {}, nullptr));
1424 
1425   // Only newroot is a trusted root.
1426   TrustStoreInMemory trust_store;
1427   trust_store.AddTrustAnchor(newroot_);
1428 
1429   // The oldintermediate is supplied synchronously by |sync_certs1| and
1430   // another copy of oldintermediate is supplied synchronously by |sync_certs2|.
1431   // The path target <- oldintermediate <- newroot  should be built first,
1432   // though it won't verify. It should not be attempted again even though
1433   // oldintermediate was supplied twice.
1434   CertIssuerSourceStatic sync_certs1;
1435   sync_certs1.AddCert(oldintermediate_);
1436   CertIssuerSourceStatic sync_certs2;
1437   sync_certs2.AddCert(oldintermediate_dupe);
1438 
1439   // The newintermediate is supplied asynchronously, so the path
1440   // target <- newintermediate <- newroot should be tried second.
1441   AsyncCertIssuerSourceStatic async_certs;
1442   async_certs.AddCert(newintermediate_);
1443 
1444   CertPathBuilder path_builder(
1445       target_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU,
1446       initial_explicit_policy_, user_initial_policy_set_,
1447       initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
1448   path_builder.AddCertIssuerSource(&sync_certs1);
1449   path_builder.AddCertIssuerSource(&sync_certs2);
1450   path_builder.AddCertIssuerSource(&async_certs);
1451 
1452   auto result = path_builder.Run();
1453 
1454   EXPECT_TRUE(result.HasValidPath());
1455   ASSERT_EQ(2U, result.paths.size());
1456 
1457   // Path builder will first attempt: target <- oldintermediate <- newroot
1458   // but it will fail since oldintermediate is signed by oldroot.
1459   EXPECT_FALSE(result.paths[0]->IsValid());
1460   const auto& path0 = *result.paths[0];
1461 
1462   ASSERT_EQ(3U, path0.certs.size());
1463   EXPECT_EQ(target_, path0.certs[0]);
1464   // Compare the DER instead of ParsedCertificate pointer, don't care which copy
1465   // of oldintermediate was used in the path.
1466   EXPECT_EQ(oldintermediate_->der_cert(), path0.certs[1]->der_cert());
1467   EXPECT_EQ(newroot_, path0.certs[2]);
1468 
1469   // Path builder will next attempt: target <- newintermediate <- newroot
1470   // which will succeed.
1471   EXPECT_EQ(1U, result.best_result_index);
1472   EXPECT_TRUE(result.paths[1]->IsValid());
1473   const auto& path1 = *result.paths[1];
1474   ASSERT_EQ(3U, path1.certs.size());
1475   EXPECT_EQ(target_, path1.certs[0]);
1476   EXPECT_EQ(newintermediate_, path1.certs[1]);
1477   EXPECT_EQ(newroot_, path1.certs[2]);
1478 }
1479 
1480 // Test when PathBuilder is given a cert via CertIssuerSources that has the same
1481 // SPKI as a trust anchor.
TEST_F(PathBuilderKeyRolloverTest,TestDuplicateIntermediateAndRoot)1482 TEST_F(PathBuilderKeyRolloverTest, TestDuplicateIntermediateAndRoot) {
1483   // Create a separate copy of newroot.
1484   std::shared_ptr<const ParsedCertificate> newroot_dupe(
1485       ParsedCertificate::Create(
1486           bssl::UniquePtr<CRYPTO_BUFFER>(
1487               CRYPTO_BUFFER_new(newroot_->der_cert().UnsafeData(),
1488                                 newroot_->der_cert().Length(), nullptr)),
1489           {}, nullptr));
1490 
1491   // Only newroot is a trusted root.
1492   TrustStoreInMemory trust_store;
1493   trust_store.AddTrustAnchor(newroot_);
1494 
1495   // The oldintermediate and newroot are supplied synchronously by |sync_certs|.
1496   CertIssuerSourceStatic sync_certs;
1497   sync_certs.AddCert(oldintermediate_);
1498   sync_certs.AddCert(newroot_dupe);
1499 
1500   CertPathBuilder path_builder(
1501       target_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU,
1502       initial_explicit_policy_, user_initial_policy_set_,
1503       initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
1504   path_builder.AddCertIssuerSource(&sync_certs);
1505 
1506   auto result = path_builder.Run();
1507 
1508   EXPECT_FALSE(result.HasValidPath());
1509   ASSERT_EQ(1U, result.paths.size());
1510 
1511   // Path builder attempt: target <- oldintermediate <- newroot
1512   // but it will fail since oldintermediate is signed by oldroot.
1513   EXPECT_FALSE(result.paths[0]->IsValid());
1514   const auto& path = *result.paths[0];
1515   ASSERT_EQ(3U, path.certs.size());
1516   EXPECT_EQ(target_, path.certs[0]);
1517   EXPECT_EQ(oldintermediate_, path.certs[1]);
1518   // Compare the DER instead of ParsedCertificate pointer, don't care which copy
1519   // of newroot was used in the path.
1520   EXPECT_EQ(newroot_->der_cert(), path.certs[2]->der_cert());
1521 }
1522 
1523 class MockCertIssuerSourceRequest : public CertIssuerSource::Request {
1524  public:
1525   MOCK_METHOD1(GetNext, void(ParsedCertificateList*));
1526 };
1527 
1528 class MockCertIssuerSource : public CertIssuerSource {
1529  public:
1530   MOCK_METHOD2(SyncGetIssuersOf,
1531                void(const ParsedCertificate*, ParsedCertificateList*));
1532   MOCK_METHOD2(AsyncGetIssuersOf,
1533                void(const ParsedCertificate*, std::unique_ptr<Request>*));
1534 };
1535 
1536 // Helper class to pass the Request to the PathBuilder when it calls
1537 // AsyncGetIssuersOf. (GoogleMock has a ByMove helper, but it apparently can
1538 // only be used with Return, not SetArgPointee.)
1539 class CertIssuerSourceRequestMover {
1540  public:
CertIssuerSourceRequestMover(std::unique_ptr<CertIssuerSource::Request> req)1541   explicit CertIssuerSourceRequestMover(
1542       std::unique_ptr<CertIssuerSource::Request> req)
1543       : request_(std::move(req)) {}
MoveIt(const ParsedCertificate * cert,std::unique_ptr<CertIssuerSource::Request> * out_req)1544   void MoveIt(const ParsedCertificate* cert,
1545               std::unique_ptr<CertIssuerSource::Request>* out_req) {
1546     *out_req = std::move(request_);
1547   }
1548 
1549  private:
1550   std::unique_ptr<CertIssuerSource::Request> request_;
1551 };
1552 
1553 // Functor that when called with a ParsedCertificateList* will append the
1554 // specified certificate.
1555 class AppendCertToList {
1556  public:
AppendCertToList(const std::shared_ptr<const ParsedCertificate> & cert)1557   explicit AppendCertToList(
1558       const std::shared_ptr<const ParsedCertificate>& cert)
1559       : cert_(cert) {}
1560 
operator ()(ParsedCertificateList * out)1561   void operator()(ParsedCertificateList* out) { out->push_back(cert_); }
1562 
1563  private:
1564   std::shared_ptr<const ParsedCertificate> cert_;
1565 };
1566 
1567 // Test that a single CertIssuerSource returning multiple async batches of
1568 // issuers is handled correctly. Due to the StrictMocks, it also tests that path
1569 // builder does not request issuers of certs that it shouldn't.
TEST_F(PathBuilderKeyRolloverTest,TestMultipleAsyncIssuersFromSingleSource)1570 TEST_F(PathBuilderKeyRolloverTest, TestMultipleAsyncIssuersFromSingleSource) {
1571   StrictMock<MockCertIssuerSource> cert_issuer_source;
1572 
1573   // Only newroot is a trusted root.
1574   TrustStoreInMemory trust_store;
1575   trust_store.AddTrustAnchor(newroot_);
1576 
1577   CertPathBuilder path_builder(
1578       target_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU,
1579       initial_explicit_policy_, user_initial_policy_set_,
1580       initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
1581   path_builder.AddCertIssuerSource(&cert_issuer_source);
1582 
1583   // Create the mock CertIssuerSource::Request...
1584   auto target_issuers_req_owner =
1585       std::make_unique<StrictMock<MockCertIssuerSourceRequest>>();
1586   // Keep a raw pointer to the Request...
1587   StrictMock<MockCertIssuerSourceRequest>* target_issuers_req =
1588       target_issuers_req_owner.get();
1589   // Setup helper class to pass ownership of the Request to the PathBuilder when
1590   // it calls AsyncGetIssuersOf.
1591   CertIssuerSourceRequestMover req_mover(std::move(target_issuers_req_owner));
1592   {
1593     ::testing::InSequence s;
1594     EXPECT_CALL(cert_issuer_source, SyncGetIssuersOf(target_.get(), _));
1595     EXPECT_CALL(cert_issuer_source, AsyncGetIssuersOf(target_.get(), _))
1596         .WillOnce(Invoke(&req_mover, &CertIssuerSourceRequestMover::MoveIt));
1597   }
1598 
1599   EXPECT_CALL(*target_issuers_req, GetNext(_))
1600       // First async batch: return oldintermediate_.
1601       .WillOnce(Invoke(AppendCertToList(oldintermediate_)))
1602       // Second async batch: return newintermediate_.
1603       .WillOnce(Invoke(AppendCertToList(newintermediate_)));
1604   {
1605     ::testing::InSequence s;
1606     // oldintermediate_ does not create a valid path, so both sync and async
1607     // lookups are expected.
1608     EXPECT_CALL(cert_issuer_source,
1609                 SyncGetIssuersOf(oldintermediate_.get(), _));
1610     EXPECT_CALL(cert_issuer_source,
1611                 AsyncGetIssuersOf(oldintermediate_.get(), _));
1612   }
1613 
1614   // newroot_ is in the trust store, so this path will be completed
1615   // synchronously. AsyncGetIssuersOf will not be called on newintermediate_.
1616   EXPECT_CALL(cert_issuer_source, SyncGetIssuersOf(newintermediate_.get(), _));
1617 
1618   // Ensure pathbuilder finished and filled result.
1619   auto result = path_builder.Run();
1620 
1621   // Note that VerifyAndClearExpectations(target_issuers_req) is not called
1622   // here. PathBuilder could have destroyed it already, so just let the
1623   // expectations get checked by the destructor.
1624   ::testing::Mock::VerifyAndClearExpectations(&cert_issuer_source);
1625 
1626   EXPECT_TRUE(result.HasValidPath());
1627   ASSERT_EQ(2U, result.paths.size());
1628 
1629   // Path builder first attempts: target <- oldintermediate <- newroot
1630   // but it will fail since oldintermediate is signed by oldroot.
1631   EXPECT_FALSE(result.paths[0]->IsValid());
1632   const auto& path0 = *result.paths[0];
1633   ASSERT_EQ(3U, path0.certs.size());
1634   EXPECT_EQ(target_, path0.certs[0]);
1635   EXPECT_EQ(oldintermediate_, path0.certs[1]);
1636   EXPECT_EQ(newroot_, path0.certs[2]);
1637 
1638   // After the second batch of async results, path builder will attempt:
1639   // target <- newintermediate <- newroot which will succeed.
1640   EXPECT_TRUE(result.paths[1]->IsValid());
1641   const auto& path1 = *result.paths[1];
1642   ASSERT_EQ(3U, path1.certs.size());
1643   EXPECT_EQ(target_, path1.certs[0]);
1644   EXPECT_EQ(newintermediate_, path1.certs[1]);
1645   EXPECT_EQ(newroot_, path1.certs[2]);
1646 }
1647 
1648 // Test that PathBuilder will not try the same path twice if CertIssuerSources
1649 // asynchronously provide the same certificate multiple times.
TEST_F(PathBuilderKeyRolloverTest,TestDuplicateAsyncIntermediates)1650 TEST_F(PathBuilderKeyRolloverTest, TestDuplicateAsyncIntermediates) {
1651   StrictMock<MockCertIssuerSource> cert_issuer_source;
1652 
1653   // Only newroot is a trusted root.
1654   TrustStoreInMemory trust_store;
1655   trust_store.AddTrustAnchor(newroot_);
1656 
1657   CertPathBuilder path_builder(
1658       target_, &trust_store, &delegate_, time_, KeyPurpose::ANY_EKU,
1659       initial_explicit_policy_, user_initial_policy_set_,
1660       initial_policy_mapping_inhibit_, initial_any_policy_inhibit_);
1661   path_builder.AddCertIssuerSource(&cert_issuer_source);
1662 
1663   // Create the mock CertIssuerSource::Request...
1664   auto target_issuers_req_owner =
1665       std::make_unique<StrictMock<MockCertIssuerSourceRequest>>();
1666   // Keep a raw pointer to the Request...
1667   StrictMock<MockCertIssuerSourceRequest>* target_issuers_req =
1668       target_issuers_req_owner.get();
1669   // Setup helper class to pass ownership of the Request to the PathBuilder when
1670   // it calls AsyncGetIssuersOf.
1671   CertIssuerSourceRequestMover req_mover(std::move(target_issuers_req_owner));
1672   {
1673     ::testing::InSequence s;
1674     EXPECT_CALL(cert_issuer_source, SyncGetIssuersOf(target_.get(), _));
1675     EXPECT_CALL(cert_issuer_source, AsyncGetIssuersOf(target_.get(), _))
1676         .WillOnce(Invoke(&req_mover, &CertIssuerSourceRequestMover::MoveIt));
1677   }
1678 
1679   std::shared_ptr<const ParsedCertificate> oldintermediate_dupe(
1680       ParsedCertificate::Create(
1681           bssl::UniquePtr<CRYPTO_BUFFER>(CRYPTO_BUFFER_new(
1682               oldintermediate_->der_cert().UnsafeData(),
1683               oldintermediate_->der_cert().Length(), nullptr)),
1684           {}, nullptr));
1685 
1686   EXPECT_CALL(*target_issuers_req, GetNext(_))
1687       // First async batch: return oldintermediate_.
1688       .WillOnce(Invoke(AppendCertToList(oldintermediate_)))
1689       // Second async batch: return a different copy of oldintermediate_ again.
1690       .WillOnce(Invoke(AppendCertToList(oldintermediate_dupe)))
1691       // Third async batch: return newintermediate_.
1692       .WillOnce(Invoke(AppendCertToList(newintermediate_)));
1693 
1694   {
1695     ::testing::InSequence s;
1696     // oldintermediate_ does not create a valid path, so both sync and async
1697     // lookups are expected.
1698     EXPECT_CALL(cert_issuer_source,
1699                 SyncGetIssuersOf(oldintermediate_.get(), _));
1700     EXPECT_CALL(cert_issuer_source,
1701                 AsyncGetIssuersOf(oldintermediate_.get(), _));
1702   }
1703 
1704   // newroot_ is in the trust store, so this path will be completed
1705   // synchronously. AsyncGetIssuersOf will not be called on newintermediate_.
1706   EXPECT_CALL(cert_issuer_source, SyncGetIssuersOf(newintermediate_.get(), _));
1707 
1708   // Ensure pathbuilder finished and filled result.
1709   auto result = path_builder.Run();
1710 
1711   ::testing::Mock::VerifyAndClearExpectations(&cert_issuer_source);
1712 
1713   EXPECT_TRUE(result.HasValidPath());
1714   ASSERT_EQ(2U, result.paths.size());
1715 
1716   // Path builder first attempts: target <- oldintermediate <- newroot
1717   // but it will fail since oldintermediate is signed by oldroot.
1718   EXPECT_FALSE(result.paths[0]->IsValid());
1719   const auto& path0 = *result.paths[0];
1720   ASSERT_EQ(3U, path0.certs.size());
1721   EXPECT_EQ(target_, path0.certs[0]);
1722   EXPECT_EQ(oldintermediate_, path0.certs[1]);
1723   EXPECT_EQ(newroot_, path0.certs[2]);
1724 
1725   // The second async result does not generate any path.
1726 
1727   // After the third batch of async results, path builder will attempt:
1728   // target <- newintermediate <- newroot which will succeed.
1729   EXPECT_TRUE(result.paths[1]->IsValid());
1730   const auto& path1 = *result.paths[1];
1731   ASSERT_EQ(3U, path1.certs.size());
1732   EXPECT_EQ(target_, path1.certs[0]);
1733   EXPECT_EQ(newintermediate_, path1.certs[1]);
1734   EXPECT_EQ(newroot_, path1.certs[2]);
1735 }
1736 
1737 class PathBuilderSimpleChainTest : public ::testing::Test {
1738  public:
1739   PathBuilderSimpleChainTest() = default;
1740 
1741  protected:
SetUp()1742   void SetUp() override {
1743     // Read a simple test chain comprised of a target, intermediate, and root.
1744     ASSERT_TRUE(ReadVerifyCertChainTestFromFile(
1745         "testdata/verify_certificate_chain_unittest/target-and-intermediate/"
1746         "main.test",
1747         &test_));
1748     ASSERT_EQ(3u, test_.chain.size());
1749   }
1750 
1751   // Runs the path builder for the target certificate while |distrusted_cert| is
1752   // blocked, and |delegate| if non-null.
RunPathBuilder(const std::shared_ptr<const ParsedCertificate> & distrusted_cert,CertPathBuilderDelegate * optional_delegate)1753   CertPathBuilder::Result RunPathBuilder(
1754       const std::shared_ptr<const ParsedCertificate>& distrusted_cert,
1755       CertPathBuilderDelegate* optional_delegate) {
1756     // Set up the trust store such that |distrusted_cert| is blocked, and
1757     // the root is trusted (except if it was |distrusted_cert|).
1758     TrustStoreInMemory trust_store;
1759     if (distrusted_cert != test_.chain.back())
1760       trust_store.AddTrustAnchor(test_.chain.back());
1761     if (distrusted_cert)
1762       trust_store.AddDistrustedCertificateForTest(distrusted_cert);
1763 
1764     // Add the single intermediate.
1765     CertIssuerSourceStatic intermediates;
1766     intermediates.AddCert(test_.chain[1]);
1767 
1768     SimplePathBuilderDelegate default_delegate(
1769         1024, SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1);
1770     CertPathBuilderDelegate* delegate =
1771         optional_delegate ? optional_delegate : &default_delegate;
1772 
1773     const InitialExplicitPolicy initial_explicit_policy =
1774         InitialExplicitPolicy::kFalse;
1775     const std::set<der::Input> user_initial_policy_set = {
1776         der::Input(kAnyPolicyOid)};
1777     const InitialPolicyMappingInhibit initial_policy_mapping_inhibit =
1778         InitialPolicyMappingInhibit::kFalse;
1779     const InitialAnyPolicyInhibit initial_any_policy_inhibit =
1780         InitialAnyPolicyInhibit::kFalse;
1781 
1782     CertPathBuilder path_builder(
1783         test_.chain.front(), &trust_store, delegate, test_.time,
1784         KeyPurpose::ANY_EKU, initial_explicit_policy, user_initial_policy_set,
1785         initial_policy_mapping_inhibit, initial_any_policy_inhibit);
1786     path_builder.AddCertIssuerSource(&intermediates);
1787     return path_builder.Run();
1788   }
1789 
1790  protected:
1791   VerifyCertChainTest test_;
1792 };
1793 
1794 // Test fixture for running the path builder over a simple chain, while varying
1795 // the trustedness of certain certificates.
1796 class PathBuilderDistrustTest : public PathBuilderSimpleChainTest {
1797  public:
1798   PathBuilderDistrustTest() = default;
1799 
1800  protected:
1801   // Runs the path builder for the target certificate while |distrusted_cert| is
1802   // blocked.
RunPathBuilderWithDistrustedCert(const std::shared_ptr<const ParsedCertificate> & distrusted_cert)1803   CertPathBuilder::Result RunPathBuilderWithDistrustedCert(
1804       const std::shared_ptr<const ParsedCertificate>& distrusted_cert) {
1805     return RunPathBuilder(distrusted_cert, nullptr);
1806   }
1807 };
1808 
1809 // Tests that path building fails when the target, intermediate, or root are
1810 // distrusted (but the path is otherwise valid).
TEST_F(PathBuilderDistrustTest,TargetIntermediateRoot)1811 TEST_F(PathBuilderDistrustTest, TargetIntermediateRoot) {
1812   // First do a control test -- path building without any blocked
1813   // certificates should work.
1814   CertPathBuilder::Result result = RunPathBuilderWithDistrustedCert(nullptr);
1815   {
1816     ASSERT_TRUE(result.HasValidPath());
1817     // The built path should be identical the the one read from disk.
1818     const auto& path = *result.GetBestValidPath();
1819     ASSERT_EQ(test_.chain.size(), path.certs.size());
1820     for (size_t i = 0; i < test_.chain.size(); ++i)
1821       EXPECT_EQ(test_.chain[i], path.certs[i]);
1822   }
1823 
1824   // Try path building when only the target is blocked - should fail.
1825   result = RunPathBuilderWithDistrustedCert(test_.chain[0]);
1826   {
1827     EXPECT_FALSE(result.HasValidPath());
1828     ASSERT_LT(result.best_result_index, result.paths.size());
1829     const auto& best_path = result.paths[result.best_result_index];
1830 
1831     // The built chain has length 1 since path building stopped once
1832     // it encountered the blocked certificate (target).
1833     ASSERT_EQ(1u, best_path->certs.size());
1834     EXPECT_EQ(best_path->certs[0], test_.chain[0]);
1835     EXPECT_TRUE(best_path->errors.ContainsHighSeverityErrors());
1836     best_path->errors.ContainsError(cert_errors::kDistrustedByTrustStore);
1837   }
1838 
1839   // Try path building when only the intermediate is blocked - should fail.
1840   result = RunPathBuilderWithDistrustedCert(test_.chain[1]);
1841   {
1842     EXPECT_FALSE(result.HasValidPath());
1843     ASSERT_LT(result.best_result_index, result.paths.size());
1844     const auto& best_path = result.paths[result.best_result_index];
1845 
1846     // The built chain has length 2 since path building stopped once
1847     // it encountered the blocked certificate (intermediate).
1848     ASSERT_EQ(2u, best_path->certs.size());
1849     EXPECT_EQ(best_path->certs[0], test_.chain[0]);
1850     EXPECT_EQ(best_path->certs[1], test_.chain[1]);
1851     EXPECT_TRUE(best_path->errors.ContainsHighSeverityErrors());
1852     best_path->errors.ContainsError(cert_errors::kDistrustedByTrustStore);
1853   }
1854 
1855   // Try path building when only the root is blocked - should fail.
1856   result = RunPathBuilderWithDistrustedCert(test_.chain[2]);
1857   {
1858     EXPECT_FALSE(result.HasValidPath());
1859     ASSERT_LT(result.best_result_index, result.paths.size());
1860     const auto& best_path = result.paths[result.best_result_index];
1861 
1862     // The built chain has length 3 since path building stopped once
1863     // it encountered the blocked certificate (root).
1864     ASSERT_EQ(3u, best_path->certs.size());
1865     EXPECT_EQ(best_path->certs[0], test_.chain[0]);
1866     EXPECT_EQ(best_path->certs[1], test_.chain[1]);
1867     EXPECT_EQ(best_path->certs[2], test_.chain[2]);
1868     EXPECT_TRUE(best_path->errors.ContainsHighSeverityErrors());
1869     best_path->errors.ContainsError(cert_errors::kDistrustedByTrustStore);
1870   }
1871 }
1872 
1873 // Test fixture for running the path builder over a simple chain, while varying
1874 // what CheckPathAfterVerification() does.
1875 class PathBuilderCheckPathAfterVerificationTest
1876     : public PathBuilderSimpleChainTest {};
1877 
1878 class CertPathBuilderDelegateBase : public SimplePathBuilderDelegate {
1879  public:
CertPathBuilderDelegateBase()1880   CertPathBuilderDelegateBase()
1881       : SimplePathBuilderDelegate(
1882             1024,
1883             SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1) {}
CheckPathAfterVerification(const CertPathBuilder & path_builder,CertPathBuilderResultPath * path)1884   void CheckPathAfterVerification(const CertPathBuilder& path_builder,
1885                                   CertPathBuilderResultPath* path) override {
1886     ADD_FAILURE() << "Tests must override this";
1887   }
1888 };
1889 
1890 class MockPathBuilderDelegate : public CertPathBuilderDelegateBase {
1891  public:
1892   MOCK_METHOD2(CheckPathAfterVerification,
1893                void(const CertPathBuilder& path_builder,
1894                     CertPathBuilderResultPath* path));
1895 };
1896 
TEST_F(PathBuilderCheckPathAfterVerificationTest,NoOpToValidPath)1897 TEST_F(PathBuilderCheckPathAfterVerificationTest, NoOpToValidPath) {
1898   StrictMock<MockPathBuilderDelegate> delegate;
1899   // Just verify that the hook is called.
1900   EXPECT_CALL(delegate, CheckPathAfterVerification(_, _));
1901 
1902   CertPathBuilder::Result result = RunPathBuilder(nullptr, &delegate);
1903   EXPECT_TRUE(result.HasValidPath());
1904 }
1905 
1906 DEFINE_CERT_ERROR_ID(kWarningFromDelegate, "Warning from delegate");
1907 
1908 class AddWarningPathBuilderDelegate : public CertPathBuilderDelegateBase {
1909  public:
CheckPathAfterVerification(const CertPathBuilder & path_builder,CertPathBuilderResultPath * path)1910   void CheckPathAfterVerification(const CertPathBuilder& path_builder,
1911                                   CertPathBuilderResultPath* path) override {
1912     path->errors.GetErrorsForCert(1)->AddWarning(kWarningFromDelegate, nullptr);
1913   }
1914 };
1915 
TEST_F(PathBuilderCheckPathAfterVerificationTest,AddsWarningToValidPath)1916 TEST_F(PathBuilderCheckPathAfterVerificationTest, AddsWarningToValidPath) {
1917   AddWarningPathBuilderDelegate delegate;
1918   CertPathBuilder::Result result = RunPathBuilder(nullptr, &delegate);
1919   ASSERT_TRUE(result.HasValidPath());
1920 
1921   // A warning should have been added to certificate at index 1 in the path.
1922   const CertErrors* cert1_errors =
1923       result.GetBestValidPath()->errors.GetErrorsForCert(1);
1924   ASSERT_TRUE(cert1_errors);
1925   EXPECT_TRUE(cert1_errors->ContainsError(kWarningFromDelegate));
1926 }
1927 
1928 DEFINE_CERT_ERROR_ID(kErrorFromDelegate, "Error from delegate");
1929 
1930 class AddErrorPathBuilderDelegate : public CertPathBuilderDelegateBase {
1931  public:
CheckPathAfterVerification(const CertPathBuilder & path_builder,CertPathBuilderResultPath * path)1932   void CheckPathAfterVerification(const CertPathBuilder& path_builder,
1933                                   CertPathBuilderResultPath* path) override {
1934     path->errors.GetErrorsForCert(2)->AddError(kErrorFromDelegate, nullptr);
1935   }
1936 };
1937 
TEST_F(PathBuilderCheckPathAfterVerificationTest,AddsErrorToValidPath)1938 TEST_F(PathBuilderCheckPathAfterVerificationTest, AddsErrorToValidPath) {
1939   AddErrorPathBuilderDelegate delegate;
1940   CertPathBuilder::Result result = RunPathBuilder(nullptr, &delegate);
1941 
1942   // Verification failed.
1943   ASSERT_FALSE(result.HasValidPath());
1944 
1945   ASSERT_LT(result.best_result_index, result.paths.size());
1946   const CertPathBuilderResultPath* failed_path =
1947       result.paths[result.best_result_index].get();
1948   ASSERT_TRUE(failed_path);
1949 
1950   // An error should have been added to certificate at index 2 in the path.
1951   const CertErrors* cert2_errors = failed_path->errors.GetErrorsForCert(2);
1952   ASSERT_TRUE(cert2_errors);
1953   EXPECT_TRUE(cert2_errors->ContainsError(kErrorFromDelegate));
1954 }
1955 
TEST_F(PathBuilderCheckPathAfterVerificationTest,NoopToAlreadyInvalidPath)1956 TEST_F(PathBuilderCheckPathAfterVerificationTest, NoopToAlreadyInvalidPath) {
1957   StrictMock<MockPathBuilderDelegate> delegate;
1958   // Just verify that the hook is called (on an invalid path).
1959   EXPECT_CALL(delegate, CheckPathAfterVerification(_, _));
1960 
1961   // Run the pathbuilder with certificate at index 1 actively distrusted.
1962   CertPathBuilder::Result result = RunPathBuilder(test_.chain[1], &delegate);
1963   EXPECT_FALSE(result.HasValidPath());
1964 }
1965 
1966 struct DelegateData : public CertPathBuilderDelegateData {
1967   int value = 0xB33F;
1968 };
1969 
1970 class SetsDelegateDataPathBuilderDelegate : public CertPathBuilderDelegateBase {
1971  public:
CheckPathAfterVerification(const CertPathBuilder & path_builder,CertPathBuilderResultPath * path)1972   void CheckPathAfterVerification(const CertPathBuilder& path_builder,
1973                                   CertPathBuilderResultPath* path) override {
1974     path->delegate_data = std::make_unique<DelegateData>();
1975   }
1976 };
1977 
TEST_F(PathBuilderCheckPathAfterVerificationTest,SetsDelegateData)1978 TEST_F(PathBuilderCheckPathAfterVerificationTest, SetsDelegateData) {
1979   SetsDelegateDataPathBuilderDelegate delegate;
1980   CertPathBuilder::Result result = RunPathBuilder(nullptr, &delegate);
1981   ASSERT_TRUE(result.HasValidPath());
1982 
1983   DelegateData* data = reinterpret_cast<DelegateData*>(
1984       result.GetBestValidPath()->delegate_data.get());
1985 
1986   EXPECT_EQ(0xB33F, data->value);
1987 }
1988 
TEST(PathBuilderPrioritizationTest,DatePrioritization)1989 TEST(PathBuilderPrioritizationTest, DatePrioritization) {
1990   std::string test_dir =
1991       "testdata/path_builder_unittest/validity_date_prioritization/";
1992   std::shared_ptr<const ParsedCertificate> root =
1993       ReadCertFromFile(test_dir + "root.pem");
1994   ASSERT_TRUE(root);
1995   std::shared_ptr<const ParsedCertificate> int_ac =
1996       ReadCertFromFile(test_dir + "int_ac.pem");
1997   ASSERT_TRUE(int_ac);
1998   std::shared_ptr<const ParsedCertificate> int_ad =
1999       ReadCertFromFile(test_dir + "int_ad.pem");
2000   ASSERT_TRUE(int_ad);
2001   std::shared_ptr<const ParsedCertificate> int_bc =
2002       ReadCertFromFile(test_dir + "int_bc.pem");
2003   ASSERT_TRUE(int_bc);
2004   std::shared_ptr<const ParsedCertificate> int_bd =
2005       ReadCertFromFile(test_dir + "int_bd.pem");
2006   ASSERT_TRUE(int_bd);
2007   std::shared_ptr<const ParsedCertificate> target =
2008       ReadCertFromFile(test_dir + "target.pem");
2009   ASSERT_TRUE(target);
2010 
2011   SimplePathBuilderDelegate delegate(
2012       1024, SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1);
2013   der::GeneralizedTime verify_time = {2017, 3, 1, 0, 0, 0};
2014 
2015   // Distrust the root certificate. This will force the path builder to attempt
2016   // all possible paths.
2017   TrustStoreInMemory trust_store;
2018   trust_store.AddDistrustedCertificateForTest(root);
2019 
2020   for (bool reverse_input_order : {false, true}) {
2021     SCOPED_TRACE(reverse_input_order);
2022 
2023     CertIssuerSourceStatic intermediates;
2024     // Test with the intermediates supplied in two different orders to ensure
2025     // the results don't depend on input ordering.
2026     if (reverse_input_order) {
2027       intermediates.AddCert(int_bd);
2028       intermediates.AddCert(int_bc);
2029       intermediates.AddCert(int_ad);
2030       intermediates.AddCert(int_ac);
2031     } else {
2032       intermediates.AddCert(int_ac);
2033       intermediates.AddCert(int_ad);
2034       intermediates.AddCert(int_bc);
2035       intermediates.AddCert(int_bd);
2036     }
2037 
2038     CertPathBuilder path_builder(
2039         target, &trust_store, &delegate, verify_time, KeyPurpose::ANY_EKU,
2040         InitialExplicitPolicy::kFalse, {der::Input(kAnyPolicyOid)},
2041         InitialPolicyMappingInhibit::kFalse, InitialAnyPolicyInhibit::kFalse);
2042     path_builder.AddCertIssuerSource(&intermediates);
2043 
2044     CertPathBuilder::Result result = path_builder.Run();
2045     EXPECT_FALSE(result.HasValidPath());
2046     ASSERT_EQ(4U, result.paths.size());
2047 
2048     // Path builder should have attempted paths using the intermediates in
2049     // order: bd, bc, ad, ac
2050 
2051     EXPECT_FALSE(result.paths[0]->IsValid());
2052     ASSERT_EQ(3U, result.paths[0]->certs.size());
2053     EXPECT_EQ(target, result.paths[0]->certs[0]);
2054     EXPECT_EQ(int_bd, result.paths[0]->certs[1]);
2055     EXPECT_EQ(root, result.paths[0]->certs[2]);
2056 
2057     EXPECT_FALSE(result.paths[1]->IsValid());
2058     ASSERT_EQ(3U, result.paths[1]->certs.size());
2059     EXPECT_EQ(target, result.paths[1]->certs[0]);
2060     EXPECT_EQ(int_bc, result.paths[1]->certs[1]);
2061     EXPECT_EQ(root, result.paths[1]->certs[2]);
2062 
2063     EXPECT_FALSE(result.paths[2]->IsValid());
2064     ASSERT_EQ(3U, result.paths[2]->certs.size());
2065     EXPECT_EQ(target, result.paths[2]->certs[0]);
2066     EXPECT_EQ(int_ad, result.paths[2]->certs[1]);
2067     EXPECT_EQ(root, result.paths[2]->certs[2]);
2068 
2069     EXPECT_FALSE(result.paths[3]->IsValid());
2070     ASSERT_EQ(3U, result.paths[3]->certs.size());
2071     EXPECT_EQ(target, result.paths[3]->certs[0]);
2072     EXPECT_EQ(int_ac, result.paths[3]->certs[1]);
2073     EXPECT_EQ(root, result.paths[3]->certs[2]);
2074   }
2075 }
2076 
TEST(PathBuilderPrioritizationTest,KeyIdPrioritization)2077 TEST(PathBuilderPrioritizationTest, KeyIdPrioritization) {
2078   std::string test_dir =
2079       "testdata/path_builder_unittest/key_id_prioritization/";
2080   std::shared_ptr<const ParsedCertificate> root =
2081       ReadCertFromFile(test_dir + "root.pem");
2082   ASSERT_TRUE(root);
2083   std::shared_ptr<const ParsedCertificate> int_matching_ski_a =
2084       ReadCertFromFile(test_dir + "int_matching_ski_a.pem");
2085   ASSERT_TRUE(int_matching_ski_a);
2086   std::shared_ptr<const ParsedCertificate> int_matching_ski_b =
2087       ReadCertFromFile(test_dir + "int_matching_ski_b.pem");
2088   ASSERT_TRUE(int_matching_ski_b);
2089   std::shared_ptr<const ParsedCertificate> int_no_ski_a =
2090       ReadCertFromFile(test_dir + "int_no_ski_a.pem");
2091   ASSERT_TRUE(int_no_ski_a);
2092   std::shared_ptr<const ParsedCertificate> int_no_ski_b =
2093       ReadCertFromFile(test_dir + "int_no_ski_b.pem");
2094   ASSERT_TRUE(int_no_ski_b);
2095   std::shared_ptr<const ParsedCertificate> int_different_ski_a =
2096       ReadCertFromFile(test_dir + "int_different_ski_a.pem");
2097   ASSERT_TRUE(int_different_ski_a);
2098   std::shared_ptr<const ParsedCertificate> int_different_ski_b =
2099       ReadCertFromFile(test_dir + "int_different_ski_b.pem");
2100   ASSERT_TRUE(int_different_ski_b);
2101   std::shared_ptr<const ParsedCertificate> target =
2102       ReadCertFromFile(test_dir + "target.pem");
2103   ASSERT_TRUE(target);
2104 
2105   SimplePathBuilderDelegate delegate(
2106       1024, SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1);
2107   der::GeneralizedTime verify_time = {2017, 3, 1, 0, 0, 0};
2108 
2109   // Distrust the root certificate. This will force the path builder to attempt
2110   // all possible paths.
2111   TrustStoreInMemory trust_store;
2112   trust_store.AddDistrustedCertificateForTest(root);
2113 
2114   for (bool reverse_input_order : {false, true}) {
2115     SCOPED_TRACE(reverse_input_order);
2116 
2117     CertIssuerSourceStatic intermediates;
2118     // Test with the intermediates supplied in two different orders to ensure
2119     // the results don't depend on input ordering.
2120     if (reverse_input_order) {
2121       intermediates.AddCert(int_different_ski_b);
2122       intermediates.AddCert(int_different_ski_a);
2123       intermediates.AddCert(int_no_ski_b);
2124       intermediates.AddCert(int_no_ski_a);
2125       intermediates.AddCert(int_matching_ski_b);
2126       intermediates.AddCert(int_matching_ski_a);
2127     } else {
2128       intermediates.AddCert(int_matching_ski_a);
2129       intermediates.AddCert(int_matching_ski_b);
2130       intermediates.AddCert(int_no_ski_a);
2131       intermediates.AddCert(int_no_ski_b);
2132       intermediates.AddCert(int_different_ski_a);
2133       intermediates.AddCert(int_different_ski_b);
2134     }
2135 
2136     CertPathBuilder path_builder(
2137         target, &trust_store, &delegate, verify_time, KeyPurpose::ANY_EKU,
2138         InitialExplicitPolicy::kFalse, {der::Input(kAnyPolicyOid)},
2139         InitialPolicyMappingInhibit::kFalse, InitialAnyPolicyInhibit::kFalse);
2140     path_builder.AddCertIssuerSource(&intermediates);
2141 
2142     CertPathBuilder::Result result = path_builder.Run();
2143     EXPECT_FALSE(result.HasValidPath());
2144     ASSERT_EQ(6U, result.paths.size());
2145 
2146     // Path builder should have attempted paths using the intermediates in
2147     // order: matching_ski_b, matching_ski_a, no_ski_b, no_ski_a,
2148     // different_ski_b, different_ski_a
2149 
2150     EXPECT_FALSE(result.paths[0]->IsValid());
2151     ASSERT_EQ(3U, result.paths[0]->certs.size());
2152     EXPECT_EQ(target, result.paths[0]->certs[0]);
2153     EXPECT_EQ(int_matching_ski_b, result.paths[0]->certs[1]);
2154     EXPECT_EQ(root, result.paths[0]->certs[2]);
2155 
2156     EXPECT_FALSE(result.paths[1]->IsValid());
2157     ASSERT_EQ(3U, result.paths[1]->certs.size());
2158     EXPECT_EQ(target, result.paths[1]->certs[0]);
2159     EXPECT_EQ(int_matching_ski_a, result.paths[1]->certs[1]);
2160     EXPECT_EQ(root, result.paths[1]->certs[2]);
2161 
2162     EXPECT_FALSE(result.paths[2]->IsValid());
2163     ASSERT_EQ(3U, result.paths[2]->certs.size());
2164     EXPECT_EQ(target, result.paths[2]->certs[0]);
2165     EXPECT_EQ(int_no_ski_b, result.paths[2]->certs[1]);
2166     EXPECT_EQ(root, result.paths[2]->certs[2]);
2167 
2168     EXPECT_FALSE(result.paths[3]->IsValid());
2169     ASSERT_EQ(3U, result.paths[3]->certs.size());
2170     EXPECT_EQ(target, result.paths[3]->certs[0]);
2171     EXPECT_EQ(int_no_ski_a, result.paths[3]->certs[1]);
2172     EXPECT_EQ(root, result.paths[3]->certs[2]);
2173 
2174     EXPECT_FALSE(result.paths[4]->IsValid());
2175     ASSERT_EQ(3U, result.paths[4]->certs.size());
2176     EXPECT_EQ(target, result.paths[4]->certs[0]);
2177     EXPECT_EQ(int_different_ski_b, result.paths[4]->certs[1]);
2178     EXPECT_EQ(root, result.paths[4]->certs[2]);
2179 
2180     EXPECT_FALSE(result.paths[5]->IsValid());
2181     ASSERT_EQ(3U, result.paths[5]->certs.size());
2182     EXPECT_EQ(target, result.paths[5]->certs[0]);
2183     EXPECT_EQ(int_different_ski_a, result.paths[5]->certs[1]);
2184     EXPECT_EQ(root, result.paths[5]->certs[2]);
2185   }
2186 }
2187 
TEST(PathBuilderPrioritizationTest,TrustAndKeyIdPrioritization)2188 TEST(PathBuilderPrioritizationTest, TrustAndKeyIdPrioritization) {
2189   std::string test_dir =
2190       "testdata/path_builder_unittest/key_id_prioritization/";
2191   std::shared_ptr<const ParsedCertificate> root =
2192       ReadCertFromFile(test_dir + "root.pem");
2193   ASSERT_TRUE(root);
2194   std::shared_ptr<const ParsedCertificate> trusted_and_matching =
2195       ReadCertFromFile(test_dir + "int_matching_ski_a.pem");
2196   ASSERT_TRUE(trusted_and_matching);
2197   std::shared_ptr<const ParsedCertificate> matching =
2198       ReadCertFromFile(test_dir + "int_matching_ski_b.pem");
2199   ASSERT_TRUE(matching);
2200   std::shared_ptr<const ParsedCertificate> distrusted_and_matching =
2201       ReadCertFromFile(test_dir + "int_matching_ski_c.pem");
2202   ASSERT_TRUE(distrusted_and_matching);
2203   std::shared_ptr<const ParsedCertificate> trusted_and_no_match_data =
2204       ReadCertFromFile(test_dir + "int_no_ski_a.pem");
2205   ASSERT_TRUE(trusted_and_no_match_data);
2206   std::shared_ptr<const ParsedCertificate> no_match_data =
2207       ReadCertFromFile(test_dir + "int_no_ski_b.pem");
2208   ASSERT_TRUE(no_match_data);
2209   std::shared_ptr<const ParsedCertificate> distrusted_and_no_match_data =
2210       ReadCertFromFile(test_dir + "int_no_ski_c.pem");
2211   ASSERT_TRUE(distrusted_and_no_match_data);
2212   std::shared_ptr<const ParsedCertificate> trusted_and_mismatch =
2213       ReadCertFromFile(test_dir + "int_different_ski_a.pem");
2214   ASSERT_TRUE(trusted_and_mismatch);
2215   std::shared_ptr<const ParsedCertificate> mismatch =
2216       ReadCertFromFile(test_dir + "int_different_ski_b.pem");
2217   ASSERT_TRUE(mismatch);
2218   std::shared_ptr<const ParsedCertificate> distrusted_and_mismatch =
2219       ReadCertFromFile(test_dir + "int_different_ski_c.pem");
2220   ASSERT_TRUE(distrusted_and_mismatch);
2221   std::shared_ptr<const ParsedCertificate> target =
2222       ReadCertFromFile(test_dir + "target.pem");
2223   ASSERT_TRUE(target);
2224 
2225   SimplePathBuilderDelegate delegate(
2226       1024, SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1);
2227   der::GeneralizedTime verify_time = {2017, 3, 1, 0, 0, 0};
2228 
2229   for (bool reverse_input_order : {false, true}) {
2230     SCOPED_TRACE(reverse_input_order);
2231 
2232     TrustStoreInMemory trust_store;
2233     // Test with the intermediates supplied in two different orders to ensure
2234     // the results don't depend on input ordering.
2235     if (reverse_input_order) {
2236       trust_store.AddTrustAnchor(trusted_and_matching);
2237       trust_store.AddCertificateWithUnspecifiedTrust(matching);
2238       trust_store.AddDistrustedCertificateForTest(distrusted_and_matching);
2239       trust_store.AddTrustAnchor(trusted_and_no_match_data);
2240       trust_store.AddCertificateWithUnspecifiedTrust(no_match_data);
2241       trust_store.AddDistrustedCertificateForTest(distrusted_and_no_match_data);
2242       trust_store.AddTrustAnchor(trusted_and_mismatch);
2243       trust_store.AddCertificateWithUnspecifiedTrust(mismatch);
2244       trust_store.AddDistrustedCertificateForTest(distrusted_and_mismatch);
2245     } else {
2246       trust_store.AddDistrustedCertificateForTest(distrusted_and_matching);
2247       trust_store.AddCertificateWithUnspecifiedTrust(no_match_data);
2248       trust_store.AddTrustAnchor(trusted_and_no_match_data);
2249       trust_store.AddTrustAnchor(trusted_and_matching);
2250       trust_store.AddCertificateWithUnspecifiedTrust(matching);
2251       trust_store.AddCertificateWithUnspecifiedTrust(mismatch);
2252       trust_store.AddDistrustedCertificateForTest(distrusted_and_no_match_data);
2253       trust_store.AddTrustAnchor(trusted_and_mismatch);
2254       trust_store.AddDistrustedCertificateForTest(distrusted_and_mismatch);
2255     }
2256     // Also distrust the root certificate. This will force the path builder to
2257     // report paths that included an unspecified trust intermediate.
2258     trust_store.AddDistrustedCertificateForTest(root);
2259 
2260     CertPathBuilder path_builder(
2261         target, &trust_store, &delegate, verify_time, KeyPurpose::ANY_EKU,
2262         InitialExplicitPolicy::kFalse, {der::Input(kAnyPolicyOid)},
2263         InitialPolicyMappingInhibit::kFalse, InitialAnyPolicyInhibit::kFalse);
2264     path_builder.SetExploreAllPaths(true);
2265 
2266     CertPathBuilder::Result result = path_builder.Run();
2267     EXPECT_TRUE(result.HasValidPath());
2268     ASSERT_EQ(9U, result.paths.size());
2269 
2270     // Path builder should have attempted paths using the intermediates in
2271     // order: trusted_and_matching, trusted_and_no_match_data, matching,
2272     // no_match_data, trusted_and_mismatch, mismatch, distrusted_and_matching,
2273     // distrusted_and_no_match_data, distrusted_and_mismatch.
2274 
2275     EXPECT_TRUE(result.paths[0]->IsValid());
2276     ASSERT_EQ(2U, result.paths[0]->certs.size());
2277     EXPECT_EQ(target, result.paths[0]->certs[0]);
2278     EXPECT_EQ(trusted_and_matching, result.paths[0]->certs[1]);
2279 
2280     EXPECT_TRUE(result.paths[1]->IsValid());
2281     ASSERT_EQ(2U, result.paths[1]->certs.size());
2282     EXPECT_EQ(target, result.paths[1]->certs[0]);
2283     EXPECT_EQ(trusted_and_no_match_data, result.paths[1]->certs[1]);
2284 
2285     EXPECT_FALSE(result.paths[2]->IsValid());
2286     ASSERT_EQ(3U, result.paths[2]->certs.size());
2287     EXPECT_EQ(target, result.paths[2]->certs[0]);
2288     EXPECT_EQ(matching, result.paths[2]->certs[1]);
2289     EXPECT_EQ(root, result.paths[2]->certs[2]);
2290 
2291     EXPECT_FALSE(result.paths[3]->IsValid());
2292     ASSERT_EQ(3U, result.paths[3]->certs.size());
2293     EXPECT_EQ(target, result.paths[3]->certs[0]);
2294     EXPECT_EQ(no_match_data, result.paths[3]->certs[1]);
2295     EXPECT_EQ(root, result.paths[3]->certs[2]);
2296 
2297     // Although this intermediate is trusted, it has the wrong key, so
2298     // the path should not be valid.
2299     EXPECT_FALSE(result.paths[4]->IsValid());
2300     ASSERT_EQ(2U, result.paths[4]->certs.size());
2301     EXPECT_EQ(target, result.paths[4]->certs[0]);
2302     EXPECT_EQ(trusted_and_mismatch, result.paths[4]->certs[1]);
2303 
2304     EXPECT_FALSE(result.paths[5]->IsValid());
2305     ASSERT_EQ(3U, result.paths[5]->certs.size());
2306     EXPECT_EQ(target, result.paths[5]->certs[0]);
2307     EXPECT_EQ(mismatch, result.paths[5]->certs[1]);
2308     EXPECT_EQ(root, result.paths[5]->certs[2]);
2309 
2310     EXPECT_FALSE(result.paths[6]->IsValid());
2311     ASSERT_EQ(2U, result.paths[6]->certs.size());
2312     EXPECT_EQ(target, result.paths[6]->certs[0]);
2313     EXPECT_EQ(distrusted_and_matching, result.paths[6]->certs[1]);
2314 
2315     EXPECT_FALSE(result.paths[7]->IsValid());
2316     ASSERT_EQ(2U, result.paths[7]->certs.size());
2317     EXPECT_EQ(target, result.paths[7]->certs[0]);
2318     EXPECT_EQ(distrusted_and_no_match_data, result.paths[7]->certs[1]);
2319 
2320     EXPECT_FALSE(result.paths[8]->IsValid());
2321     ASSERT_EQ(2U, result.paths[8]->certs.size());
2322     EXPECT_EQ(target, result.paths[8]->certs[0]);
2323     EXPECT_EQ(distrusted_and_mismatch, result.paths[8]->certs[1]);
2324   }
2325 }
2326 
2327 // PathBuilder does not support prioritization based on the issuer name &
2328 // serial in authorityKeyIdentifier, so this test just ensures that it does not
2329 // affect prioritization order and that it is generally just ignored
2330 // completely.
TEST(PathBuilderPrioritizationTest,KeyIdNameAndSerialPrioritization)2331 TEST(PathBuilderPrioritizationTest, KeyIdNameAndSerialPrioritization) {
2332   std::string test_dir =
2333       "testdata/path_builder_unittest/key_id_name_and_serial_prioritization/";
2334   std::shared_ptr<const ParsedCertificate> root =
2335       ReadCertFromFile(test_dir + "root.pem");
2336   ASSERT_TRUE(root);
2337   std::shared_ptr<const ParsedCertificate> root2 =
2338       ReadCertFromFile(test_dir + "root2.pem");
2339   ASSERT_TRUE(root2);
2340   std::shared_ptr<const ParsedCertificate> int_matching =
2341       ReadCertFromFile(test_dir + "int_matching.pem");
2342   ASSERT_TRUE(int_matching);
2343   std::shared_ptr<const ParsedCertificate> int_match_name_only =
2344       ReadCertFromFile(test_dir + "int_match_name_only.pem");
2345   ASSERT_TRUE(int_match_name_only);
2346   std::shared_ptr<const ParsedCertificate> int_mismatch =
2347       ReadCertFromFile(test_dir + "int_mismatch.pem");
2348   ASSERT_TRUE(int_mismatch);
2349   std::shared_ptr<const ParsedCertificate> target =
2350       ReadCertFromFile(test_dir + "target.pem");
2351   ASSERT_TRUE(target);
2352 
2353   SimplePathBuilderDelegate delegate(
2354       1024, SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1);
2355   der::GeneralizedTime verify_time = {2017, 3, 1, 0, 0, 0};
2356 
2357   // Distrust the root certificates. This will force the path builder to attempt
2358   // all possible paths.
2359   TrustStoreInMemory trust_store;
2360   trust_store.AddDistrustedCertificateForTest(root);
2361   trust_store.AddDistrustedCertificateForTest(root2);
2362 
2363   for (bool reverse_input_order : {false, true}) {
2364     SCOPED_TRACE(reverse_input_order);
2365 
2366     CertIssuerSourceStatic intermediates;
2367     // Test with the intermediates supplied in two different orders to ensure
2368     // the results don't depend on input ordering.
2369     if (reverse_input_order) {
2370       intermediates.AddCert(int_mismatch);
2371       intermediates.AddCert(int_match_name_only);
2372       intermediates.AddCert(int_matching);
2373     } else {
2374       intermediates.AddCert(int_matching);
2375       intermediates.AddCert(int_match_name_only);
2376       intermediates.AddCert(int_mismatch);
2377     }
2378 
2379     CertPathBuilder path_builder(
2380         target, &trust_store, &delegate, verify_time, KeyPurpose::ANY_EKU,
2381         InitialExplicitPolicy::kFalse, {der::Input(kAnyPolicyOid)},
2382         InitialPolicyMappingInhibit::kFalse, InitialAnyPolicyInhibit::kFalse);
2383     path_builder.AddCertIssuerSource(&intermediates);
2384 
2385     CertPathBuilder::Result result = path_builder.Run();
2386     EXPECT_FALSE(result.HasValidPath());
2387     ASSERT_EQ(3U, result.paths.size());
2388 
2389     // The serial & issuer method is not used in prioritization, so the certs
2390     // should have been prioritized based on dates. The test certs have the
2391     // date priority order in the reverse of what authorityKeyIdentifier
2392     // prioritization would have done if it were supported.
2393     // Path builder should have attempted paths using the intermediates in
2394     // order: mismatch, match_name_only, matching
2395 
2396     EXPECT_FALSE(result.paths[0]->IsValid());
2397     ASSERT_EQ(3U, result.paths[0]->certs.size());
2398     EXPECT_EQ(target, result.paths[0]->certs[0]);
2399     EXPECT_EQ(int_mismatch, result.paths[0]->certs[1]);
2400     EXPECT_EQ(root2, result.paths[0]->certs[2]);
2401 
2402     EXPECT_FALSE(result.paths[1]->IsValid());
2403     ASSERT_EQ(3U, result.paths[1]->certs.size());
2404     EXPECT_EQ(target, result.paths[1]->certs[0]);
2405     EXPECT_EQ(int_match_name_only, result.paths[1]->certs[1]);
2406     EXPECT_EQ(root, result.paths[1]->certs[2]);
2407 
2408     EXPECT_FALSE(result.paths[2]->IsValid());
2409     ASSERT_EQ(3U, result.paths[2]->certs.size());
2410     EXPECT_EQ(target, result.paths[2]->certs[0]);
2411     EXPECT_EQ(int_matching, result.paths[2]->certs[1]);
2412     EXPECT_EQ(root, result.paths[2]->certs[2]);
2413   }
2414 }
2415 
TEST(PathBuilderPrioritizationTest,SelfIssuedPrioritization)2416 TEST(PathBuilderPrioritizationTest, SelfIssuedPrioritization) {
2417   std::string test_dir =
2418       "testdata/path_builder_unittest/self_issued_prioritization/";
2419   std::shared_ptr<const ParsedCertificate> root1 =
2420       ReadCertFromFile(test_dir + "root1.pem");
2421   ASSERT_TRUE(root1);
2422   std::shared_ptr<const ParsedCertificate> root1_cross =
2423       ReadCertFromFile(test_dir + "root1_cross.pem");
2424   ASSERT_TRUE(root1_cross);
2425   std::shared_ptr<const ParsedCertificate> target =
2426       ReadCertFromFile(test_dir + "target.pem");
2427   ASSERT_TRUE(target);
2428 
2429   SimplePathBuilderDelegate delegate(
2430       1024, SimplePathBuilderDelegate::DigestPolicy::kWeakAllowSha1);
2431   der::GeneralizedTime verify_time = {2017, 3, 1, 0, 0, 0};
2432 
2433   TrustStoreInMemory trust_store;
2434   trust_store.AddTrustAnchor(root1);
2435   trust_store.AddTrustAnchor(root1_cross);
2436   CertPathBuilder path_builder(
2437       target, &trust_store, &delegate, verify_time, KeyPurpose::ANY_EKU,
2438       InitialExplicitPolicy::kFalse, {der::Input(kAnyPolicyOid)},
2439       InitialPolicyMappingInhibit::kFalse, InitialAnyPolicyInhibit::kFalse);
2440   path_builder.SetExploreAllPaths(true);
2441 
2442   CertPathBuilder::Result result = path_builder.Run();
2443   EXPECT_TRUE(result.HasValidPath());
2444 
2445   // Path builder should have built paths to both trusted roots.
2446   ASSERT_EQ(2U, result.paths.size());
2447 
2448   // |root1| should have been preferred because it is self-issued, even though
2449   // the notBefore date is older than |root1_cross|.
2450   EXPECT_TRUE(result.paths[0]->IsValid());
2451   ASSERT_EQ(2U, result.paths[0]->certs.size());
2452   EXPECT_EQ(target, result.paths[0]->certs[0]);
2453   EXPECT_EQ(root1, result.paths[0]->certs[1]);
2454 
2455   EXPECT_TRUE(result.paths[1]->IsValid());
2456   ASSERT_EQ(2U, result.paths[1]->certs.size());
2457   EXPECT_EQ(target, result.paths[1]->certs[0]);
2458   EXPECT_EQ(root1_cross, result.paths[1]->certs[1]);
2459 }
2460 
2461 }  // namespace
2462 
2463 }  // namespace net
2464