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