• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 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 "net/cert/cert_verify_proc_builtin.h"
6 
7 #include "base/memory/raw_ptr.h"
8 #include "base/numerics/safe_conversions.h"
9 #include "base/ranges/algorithm.h"
10 #include "base/run_loop.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/task/sequenced_task_runner.h"
13 #include "base/task/thread_pool.h"
14 #include "base/test/metrics/histogram_tester.h"
15 #include "base/test/scoped_feature_list.h"
16 #include "base/test/task_environment.h"
17 #include "base/time/time.h"
18 #include "net/base/features.h"
19 #include "net/base/test_completion_callback.h"
20 #include "net/cert/cert_verify_proc.h"
21 #include "net/cert/crl_set.h"
22 #include "net/cert/ev_root_ca_metadata.h"
23 #include "net/cert/internal/system_trust_store.h"
24 #include "net/cert/time_conversions.h"
25 #include "net/cert_net/cert_net_fetcher_url_request.h"
26 #include "net/http/transport_security_state.h"
27 #include "net/log/net_log_with_source.h"
28 #include "net/log/test_net_log.h"
29 #include "net/test/cert_builder.h"
30 #include "net/test/cert_test_util.h"
31 #include "net/test/embedded_test_server/embedded_test_server.h"
32 #include "net/test/embedded_test_server/http_request.h"
33 #include "net/test/embedded_test_server/http_response.h"
34 #include "net/test/embedded_test_server/request_handler_util.h"
35 #include "net/test/gtest_util.h"
36 #include "net/test/revocation_builder.h"
37 #include "net/url_request/url_request_context.h"
38 #include "net/url_request/url_request_context_builder.h"
39 #include "net/url_request/url_request_test_util.h"
40 #include "testing/gtest/include/gtest/gtest.h"
41 #include "third_party/boringssl/src/pki/trust_store.h"
42 #include "third_party/boringssl/src/pki/trust_store_collection.h"
43 #include "third_party/boringssl/src/pki/trust_store_in_memory.h"
44 
45 using net::test::IsError;
46 using net::test::IsOk;
47 
48 namespace net {
49 
50 namespace {
51 
HangRequestAndCallback(base::OnceClosure callback,const test_server::HttpRequest & request)52 std::unique_ptr<test_server::HttpResponse> HangRequestAndCallback(
53     base::OnceClosure callback,
54     const test_server::HttpRequest& request) {
55   std::move(callback).Run();
56   return std::make_unique<test_server::HungResponse>();
57 }
58 
FailTest(const std::string & message)59 void FailTest(const std::string& message) {
60   ADD_FAILURE() << message;
61 }
62 
FailRequestAndFailTest(const std::string & message,scoped_refptr<base::TaskRunner> main_task_runner,const test_server::HttpRequest & request)63 std::unique_ptr<test_server::HttpResponse> FailRequestAndFailTest(
64     const std::string& message,
65     scoped_refptr<base::TaskRunner> main_task_runner,
66     const test_server::HttpRequest& request) {
67   main_task_runner->PostTask(FROM_HERE, base::BindOnce(FailTest, message));
68   auto response = std::make_unique<test_server::BasicHttpResponse>();
69   response->set_code(HTTP_NOT_ACCEPTABLE);
70   return response;
71 }
72 
ServeResponse(HttpStatusCode status_code,const std::string & content_type,const std::string & content,const test_server::HttpRequest & request)73 std::unique_ptr<test_server::HttpResponse> ServeResponse(
74     HttpStatusCode status_code,
75     const std::string& content_type,
76     const std::string& content,
77     const test_server::HttpRequest& request) {
78   auto http_response = std::make_unique<test_server::BasicHttpResponse>();
79 
80   http_response->set_code(status_code);
81   http_response->set_content_type(content_type);
82   http_response->set_content(content);
83   return http_response;
84 }
85 
MakeRandomHexString(size_t num_bytes)86 std::string MakeRandomHexString(size_t num_bytes) {
87   std::vector<char> rand_bytes;
88   rand_bytes.resize(num_bytes);
89 
90   base::RandBytes(rand_bytes.data(), rand_bytes.size());
91   return base::HexEncode(rand_bytes.data(), rand_bytes.size());
92 }
93 
MakeRandomPath(base::StringPiece suffix)94 static std::string MakeRandomPath(base::StringPiece suffix) {
95   return "/" + MakeRandomHexString(12) + std::string(suffix);
96 }
97 
VerifyOnWorkerThread(const scoped_refptr<CertVerifyProc> & verify_proc,scoped_refptr<X509Certificate> cert,const std::string & hostname,int flags,CertVerifyResult * verify_result,NetLogSource * out_source)98 int VerifyOnWorkerThread(const scoped_refptr<CertVerifyProc>& verify_proc,
99                          scoped_refptr<X509Certificate> cert,
100                          const std::string& hostname,
101                          int flags,
102                          CertVerifyResult* verify_result,
103                          NetLogSource* out_source) {
104   base::ScopedAllowBaseSyncPrimitivesForTesting scoped_allow_blocking;
105   NetLogWithSource net_log(NetLogWithSource::Make(
106       net::NetLog::Get(), net::NetLogSourceType::CERT_VERIFIER_TASK));
107   int error = verify_proc->Verify(cert.get(), hostname,
108                                   /*ocsp_response=*/std::string(),
109                                   /*sct_list=*/std::string(), flags,
110                                   verify_result, net_log);
111   *out_source = net_log.source();
112   return error;
113 }
114 
115 class MockSystemTrustStore : public SystemTrustStore {
116  public:
GetTrustStore()117   bssl::TrustStore* GetTrustStore() override { return &trust_store_; }
118 
IsKnownRoot(const bssl::ParsedCertificate * trust_anchor) const119   bool IsKnownRoot(const bssl::ParsedCertificate* trust_anchor) const override {
120     return mock_is_known_root_;
121   }
122 
AddTrustStore(bssl::TrustStore * store)123   void AddTrustStore(bssl::TrustStore* store) {
124     trust_store_.AddTrustStore(store);
125   }
126 
SetMockIsKnownRoot(bool is_known_root)127   void SetMockIsKnownRoot(bool is_known_root) {
128     mock_is_known_root_ = is_known_root;
129   }
130 
131 #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
chrome_root_store_version() const132   int64_t chrome_root_store_version() const override { return 0; }
133 #endif
134 
135  private:
136   bssl::TrustStoreCollection trust_store_;
137   bool mock_is_known_root_ = false;
138 };
139 
140 class BlockingTrustStore : public bssl::TrustStore {
141  public:
GetTrust(const bssl::ParsedCertificate * cert)142   bssl::CertificateTrust GetTrust(
143       const bssl::ParsedCertificate* cert) override {
144     return backing_trust_store_.GetTrust(cert);
145   }
146 
SyncGetIssuersOf(const bssl::ParsedCertificate * cert,bssl::ParsedCertificateList * issuers)147   void SyncGetIssuersOf(const bssl::ParsedCertificate* cert,
148                         bssl::ParsedCertificateList* issuers) override {
149     sync_get_issuer_started_event_.Signal();
150     sync_get_issuer_ok_to_finish_event_.Wait();
151 
152     backing_trust_store_.SyncGetIssuersOf(cert, issuers);
153   }
154 
155   base::WaitableEvent sync_get_issuer_started_event_;
156   base::WaitableEvent sync_get_issuer_ok_to_finish_event_;
157   bssl::TrustStoreInMemory backing_trust_store_;
158 };
159 
160 }  // namespace
161 
162 class CertVerifyProcBuiltinTest : public ::testing::Test {
163  public:
SetUp()164   void SetUp() override {
165     cert_net_fetcher_ = base::MakeRefCounted<CertNetFetcherURLRequest>();
166 
167     InitializeVerifyProc({});
168 
169     context_ = CreateTestURLRequestContextBuilder()->Build();
170 
171     cert_net_fetcher_->SetURLRequestContext(context_.get());
172   }
173 
TearDown()174   void TearDown() override { cert_net_fetcher_->Shutdown(); }
175 
InitializeVerifyProc(const CertificateList & additional_trust_anchors)176   void InitializeVerifyProc(const CertificateList& additional_trust_anchors) {
177     auto mock_system_trust_store = std::make_unique<MockSystemTrustStore>();
178     mock_system_trust_store_ = mock_system_trust_store.get();
179     CertVerifyProc::InstanceParams instance_params;
180     instance_params.additional_trust_anchors = additional_trust_anchors;
181     verify_proc_ = CreateCertVerifyProcBuiltin(
182         cert_net_fetcher_, CRLSet::EmptyCRLSetForTesting(),
183         std::move(mock_system_trust_store), instance_params);
184   }
185 
Verify(scoped_refptr<X509Certificate> cert,const std::string & hostname,int flags,CertVerifyResult * verify_result,NetLogSource * out_source,CompletionOnceCallback callback)186   void Verify(scoped_refptr<X509Certificate> cert,
187               const std::string& hostname,
188               int flags,
189               CertVerifyResult* verify_result,
190               NetLogSource* out_source,
191               CompletionOnceCallback callback) {
192     base::ThreadPool::PostTaskAndReplyWithResult(
193         FROM_HERE,
194         {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
195         base::BindOnce(&VerifyOnWorkerThread, verify_proc_, std::move(cert),
196                        hostname, flags, verify_result, out_source),
197         std::move(callback));
198   }
199 
task_environment()200   base::test::TaskEnvironment& task_environment() { return task_environment_; }
201 
202   // Creates a CRL issued and signed by |crl_issuer|, marking |revoked_serials|
203   // as revoked, and registers it to be served by the test server.
204   // Returns the full URL to retrieve the CRL from the test server.
CreateAndServeCrl(EmbeddedTestServer * test_server,CertBuilder * crl_issuer,const std::vector<uint64_t> & revoked_serials,absl::optional<bssl::SignatureAlgorithm> signature_algorithm=absl::nullopt)205   GURL CreateAndServeCrl(EmbeddedTestServer* test_server,
206                          CertBuilder* crl_issuer,
207                          const std::vector<uint64_t>& revoked_serials,
208                          absl::optional<bssl::SignatureAlgorithm>
209                              signature_algorithm = absl::nullopt) {
210     std::string crl = BuildCrl(crl_issuer->GetSubject(), crl_issuer->GetKey(),
211                                revoked_serials, signature_algorithm);
212     std::string crl_path = MakeRandomPath(".crl");
213     test_server->RegisterRequestHandler(
214         base::BindRepeating(&test_server::HandlePrefixedRequest, crl_path,
215                             base::BindRepeating(ServeResponse, HTTP_OK,
216                                                 "application/pkix-crl", crl)));
217     return test_server->GetURL(crl_path);
218   }
219 
AddTrustStore(bssl::TrustStore * store)220   void AddTrustStore(bssl::TrustStore* store) {
221     mock_system_trust_store_->AddTrustStore(store);
222   }
223 
SetMockIsKnownRoot(bool is_known_root)224   void SetMockIsKnownRoot(bool is_known_root) {
225     mock_system_trust_store_->SetMockIsKnownRoot(is_known_root);
226   }
227 
context()228   net::URLRequestContext* context() { return context_.get(); }
229 
230  private:
231   base::test::TaskEnvironment task_environment_{
232       base::test::TaskEnvironment::TimeSource::MOCK_TIME,
233       base::test::TaskEnvironment::MainThreadType::IO,
234   };
235 
236   CertVerifier::Config config_;
237   std::unique_ptr<net::URLRequestContext> context_;
238 
239   // Must outlive `mock_system_trust_store_`.
240   scoped_refptr<CertVerifyProc> verify_proc_;
241 
242   raw_ptr<MockSystemTrustStore> mock_system_trust_store_ = nullptr;
243   scoped_refptr<CertNetFetcherURLRequest> cert_net_fetcher_;
244 };
245 
TEST_F(CertVerifyProcBuiltinTest,ShouldBypassHSTS)246 TEST_F(CertVerifyProcBuiltinTest, ShouldBypassHSTS) {
247   auto [leaf, root] = CertBuilder::CreateSimpleChain2();
248   InitializeVerifyProc(
249       /*additional_trust_anchors=*/{root->GetX509Certificate()});
250 
251   EmbeddedTestServer test_server(EmbeddedTestServer::TYPE_HTTP);
252   ASSERT_TRUE(test_server.InitializeAndListen());
253 
254   // CRL that marks leaf as revoked.
255   leaf->SetCrlDistributionPointUrl(
256       CreateAndServeCrl(&test_server, root.get(), {leaf->GetSerialNumber()}));
257 
258   test_server.StartAcceptingConnections();
259 
260   {
261     scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
262     ASSERT_TRUE(chain.get());
263 
264     NetLogSource verify_net_log_source;
265     CertVerifyResult verify_result;
266     TestCompletionCallback verify_callback;
267     // Ensure HSTS upgrades for the domain which hosts the CRLs.
268     context()->transport_security_state()->AddHSTS(
269         test_server.base_url().host(), base::Time::Now() + base::Seconds(30),
270         /*include_subdomains=*/true);
271     ASSERT_TRUE(context()->transport_security_state()->ShouldUpgradeToSSL(
272         test_server.base_url().host()));
273     Verify(chain.get(), "www.example.com",
274            CertVerifyProc::VERIFY_REV_CHECKING_ENABLED,
275            &verify_result, &verify_net_log_source, verify_callback.callback());
276 
277     int error = verify_callback.WaitForResult();
278     EXPECT_THAT(error, IsError(ERR_CERT_REVOKED));
279     EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
280   }
281 }
282 
TEST_F(CertVerifyProcBuiltinTest,SimpleSuccess)283 TEST_F(CertVerifyProcBuiltinTest, SimpleSuccess) {
284   auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
285   InitializeVerifyProc(
286       /*additional_trust_anchors=*/{root->GetX509Certificate()});
287 
288   scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
289   ASSERT_TRUE(chain.get());
290 
291   base::HistogramTester histogram_tester;
292   CertVerifyResult verify_result;
293   NetLogSource verify_net_log_source;
294   TestCompletionCallback callback;
295   Verify(chain.get(), "www.example.com", /*flags=*/0, &verify_result,
296          &verify_net_log_source, callback.callback());
297 
298   int error = callback.WaitForResult();
299   EXPECT_THAT(error, IsOk());
300   EXPECT_THAT(histogram_tester.GetAllSamples(
301                   "Net.CertVerifier.PathBuilderIterationCount"),
302               testing::ElementsAre(base::Bucket(/*min=*/2, /*count=*/1)));
303 }
304 
TEST_F(CertVerifyProcBuiltinTest,CRLNotCheckedForKnownRoots)305 TEST_F(CertVerifyProcBuiltinTest, CRLNotCheckedForKnownRoots) {
306   auto [leaf, root] = CertBuilder::CreateSimpleChain2();
307   InitializeVerifyProc(
308       /*additional_trust_anchors=*/{root->GetX509Certificate()});
309 
310   EmbeddedTestServer test_server(EmbeddedTestServer::TYPE_HTTP);
311   ASSERT_TRUE(test_server.InitializeAndListen());
312 
313   // CRL that marks leaf as revoked.
314   leaf->SetCrlDistributionPointUrl(
315       CreateAndServeCrl(&test_server, root.get(), {leaf->GetSerialNumber()}));
316 
317   test_server.StartAcceptingConnections();
318 
319   scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
320   ASSERT_TRUE(chain.get());
321 
322   NetLogSource verify_net_log_source;
323 
324   {
325     CertVerifyResult verify_result;
326     TestCompletionCallback verify_callback;
327     Verify(chain.get(), "www.example.com",
328            CertVerifyProc::VERIFY_REV_CHECKING_ENABLED,
329            &verify_result, &verify_net_log_source, verify_callback.callback());
330 
331     int error = verify_callback.WaitForResult();
332     EXPECT_THAT(error, IsError(ERR_CERT_REVOKED));
333     EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
334   }
335 
336   {
337     // Pretend the root is a known root.
338     SetMockIsKnownRoot(true);
339     base::HistogramTester histogram_tester;
340     CertVerifyResult verify_result;
341     TestCompletionCallback verify_callback;
342     Verify(chain.get(), "www.example.com",
343            CertVerifyProc::VERIFY_REV_CHECKING_ENABLED,
344            &verify_result, &verify_net_log_source, verify_callback.callback());
345 
346     int error = verify_callback.WaitForResult();
347     // CRLs are not checked for chains issued by known roots, so verification
348     // should be successful.
349     EXPECT_THAT(error, IsOk());
350     EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
351     EXPECT_THAT(histogram_tester.GetAllSamples(
352                     "Net.CertVerifier.PathBuilderIterationCount"),
353                 testing::ElementsAre(base::Bucket(/*min=*/1, /*count=*/1)));
354   }
355 }
356 
357 // Tests that if the verification deadline is exceeded during revocation
358 // checking, additional CRL fetches will not be attempted.
TEST_F(CertVerifyProcBuiltinTest,RevocationCheckDeadlineCRL)359 TEST_F(CertVerifyProcBuiltinTest, RevocationCheckDeadlineCRL) {
360   auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
361   InitializeVerifyProc(
362       /*additional_trust_anchors=*/{root->GetX509Certificate()});
363 
364   const base::TimeDelta timeout_increment =
365       CertNetFetcherURLRequest::GetDefaultTimeoutForTesting() +
366       base::Milliseconds(1);
367   const int expected_request_count =
368       base::ClampFloor(GetCertVerifyProcBuiltinTimeLimitForTesting() /
369                        timeout_increment) +
370       1;
371 
372   EmbeddedTestServer test_server(EmbeddedTestServer::TYPE_HTTP);
373   ASSERT_TRUE(test_server.InitializeAndListen());
374 
375   // Set up the test cert to have enough crlDistributionPoint urls that if the
376   // first N-1 requests hang the deadline will be exceeded before the Nth
377   // request is made.
378   std::vector<GURL> crl_urls;
379   std::vector<base::RunLoop> runloops(expected_request_count);
380   for (int i = 0; i < expected_request_count; ++i) {
381     std::string path = base::StringPrintf("/hung/%i", i);
382     crl_urls.emplace_back(test_server.GetURL(path));
383     test_server.RegisterRequestHandler(
384         base::BindRepeating(&test_server::HandlePrefixedRequest, path,
385                             base::BindRepeating(&HangRequestAndCallback,
386                                                 runloops[i].QuitClosure())));
387   }
388   // Add CRL URLs and handlers that will add test failures if requested.
389   for (int i = expected_request_count; i < expected_request_count + 1; ++i) {
390     std::string path = base::StringPrintf("/failtest/%i", i);
391     crl_urls.emplace_back(test_server.GetURL(path));
392     test_server.RegisterRequestHandler(base::BindRepeating(
393         &test_server::HandlePrefixedRequest, path,
394         base::BindRepeating(FailRequestAndFailTest,
395                             "additional request made after deadline exceeded",
396                             base::SequencedTaskRunner::GetCurrentDefault())));
397   }
398   leaf->SetCrlDistributionPointUrls(crl_urls);
399 
400   test_server.StartAcceptingConnections();
401 
402   scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
403   ASSERT_TRUE(chain.get());
404 
405   base::HistogramTester histogram_tester;
406   CertVerifyResult verify_result;
407   NetLogSource verify_net_log_source;
408   TestCompletionCallback verify_callback;
409   Verify(chain.get(), "www.example.com",
410          CertVerifyProc::VERIFY_REV_CHECKING_ENABLED,
411          &verify_result, &verify_net_log_source, verify_callback.callback());
412 
413   for (int i = 0; i < expected_request_count; i++) {
414     // Wait for request #|i| to be made.
415     runloops[i].Run();
416     // Advance virtual time to cause the timeout task to become runnable.
417     task_environment().AdvanceClock(timeout_increment);
418   }
419 
420   // Once |expected_request_count| requests have been made and timed out, the
421   // overall deadline should be reached, and no more requests should have been
422   // made. (If they were, the test will fail due to the ADD_FAILURE callback in
423   // the request handlers.)
424   int error = verify_callback.WaitForResult();
425   // Soft-fail revocation checking was used, therefore verification result
426   // should be OK even though none of the CRLs could be retrieved.
427   EXPECT_THAT(error, IsOk());
428   EXPECT_THAT(histogram_tester.GetAllSamples(
429                   "Net.CertVerifier.PathBuilderIterationCount"),
430               testing::ElementsAre(base::Bucket(/*min=*/2, /*count=*/1)));
431 }
432 
433 // Tests that if the verification deadline is exceeded during revocation
434 // checking, additional OCSP fetches will not be attempted.
TEST_F(CertVerifyProcBuiltinTest,RevocationCheckDeadlineOCSP)435 TEST_F(CertVerifyProcBuiltinTest, RevocationCheckDeadlineOCSP) {
436   auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
437   InitializeVerifyProc(
438       /*additional_trust_anchors=*/{root->GetX509Certificate()});
439 
440   const base::TimeDelta timeout_increment =
441       CertNetFetcherURLRequest::GetDefaultTimeoutForTesting() +
442       base::Milliseconds(1);
443   const int expected_request_count =
444       base::ClampFloor(GetCertVerifyProcBuiltinTimeLimitForTesting() /
445                        timeout_increment) +
446       1;
447 
448   EmbeddedTestServer test_server(EmbeddedTestServer::TYPE_HTTP);
449   ASSERT_TRUE(test_server.InitializeAndListen());
450 
451   // Set up the test cert to have enough OCSP urls that if the
452   // first N-1 requests hang the deadline will be exceeded before the Nth
453   // request is made.
454   std::vector<GURL> ocsp_urls;
455   std::vector<base::RunLoop> runloops(expected_request_count);
456   for (int i = 0; i < expected_request_count; ++i) {
457     std::string path = base::StringPrintf("/hung/%i", i);
458     ocsp_urls.emplace_back(test_server.GetURL(path));
459     test_server.RegisterRequestHandler(
460         base::BindRepeating(&test_server::HandlePrefixedRequest, path,
461                             base::BindRepeating(&HangRequestAndCallback,
462                                                 runloops[i].QuitClosure())));
463   }
464   // Add OCSP URLs and handlers that will add test failures if requested.
465   for (int i = expected_request_count; i < expected_request_count + 1; ++i) {
466     std::string path = base::StringPrintf("/failtest/%i", i);
467     ocsp_urls.emplace_back(test_server.GetURL(path));
468     test_server.RegisterRequestHandler(base::BindRepeating(
469         &test_server::HandlePrefixedRequest, path,
470         base::BindRepeating(FailRequestAndFailTest,
471                             "additional request made after deadline exceeded",
472                             base::SequencedTaskRunner::GetCurrentDefault())));
473   }
474   leaf->SetCaIssuersAndOCSPUrls({}, ocsp_urls);
475 
476   test_server.StartAcceptingConnections();
477 
478   scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
479   ASSERT_TRUE(chain.get());
480 
481   CertVerifyResult verify_result;
482   NetLogSource verify_net_log_source;
483   TestCompletionCallback verify_callback;
484   Verify(chain.get(), "www.example.com",
485          CertVerifyProc::VERIFY_REV_CHECKING_ENABLED,
486          &verify_result, &verify_net_log_source, verify_callback.callback());
487 
488   for (int i = 0; i < expected_request_count; i++) {
489     // Wait for request #|i| to be made.
490     runloops[i].Run();
491     // Advance virtual time to cause the timeout task to become runnable.
492     task_environment().AdvanceClock(timeout_increment);
493   }
494 
495   // Once |expected_request_count| requests have been made and timed out, the
496   // overall deadline should be reached, and no more requests should have been
497   // made. (If they were, the test will fail due to the ADD_FAILURE callback in
498   // the request handlers.)
499   int error = verify_callback.WaitForResult();
500   // Soft-fail revocation checking was used, therefore verification result
501   // should be OK even though none of the OCSP responses could be retrieved.
502   EXPECT_THAT(error, IsOk());
503 }
504 
505 #if defined(PLATFORM_USES_CHROMIUM_EV_METADATA)
506 // Tests that if we're doing EV verification, that no OCSP revocation checking
507 // is done.
TEST_F(CertVerifyProcBuiltinTest,EVNoOCSPRevocationChecks)508 TEST_F(CertVerifyProcBuiltinTest, EVNoOCSPRevocationChecks) {
509   auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
510   InitializeVerifyProc(
511       /*additional_trust_anchors=*/{root->GetX509Certificate()});
512 
513   // Add test EV policy to leaf and intermediate.
514   static const char kEVTestCertPolicy[] = "1.2.3.4";
515   leaf->SetCertificatePolicies({kEVTestCertPolicy});
516   intermediate->SetCertificatePolicies({kEVTestCertPolicy});
517 
518   EmbeddedTestServer test_server(EmbeddedTestServer::TYPE_HTTP);
519   ASSERT_TRUE(test_server.InitializeAndListen());
520 
521   // Set up the test intermediate to have an OCSP url that fails the test if
522   // called.
523   std::vector<GURL> ocsp_urls;
524   std::string path = "/failtest";
525   ocsp_urls.emplace_back(test_server.GetURL(path));
526   test_server.RegisterRequestHandler(base::BindRepeating(
527       &test_server::HandlePrefixedRequest, path,
528       base::BindRepeating(FailRequestAndFailTest,
529                           "no OCSP requests should be sent",
530                           base::SequencedTaskRunner::GetCurrentDefault())));
531   intermediate->SetCaIssuersAndOCSPUrls({}, ocsp_urls);
532   test_server.StartAcceptingConnections();
533 
534   // Consider the root of the test chain a valid EV root for the test policy.
535   ScopedTestEVPolicy scoped_test_ev_policy(
536       EVRootCAMetadata::GetInstance(),
537       X509Certificate::CalculateFingerprint256(root->GetCertBuffer()),
538       kEVTestCertPolicy);
539 
540   scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
541   ASSERT_TRUE(chain.get());
542 
543   RecordingNetLogObserver net_log_observer(NetLogCaptureMode::kDefault);
544   CertVerifyResult verify_result;
545   NetLogSource verify_net_log_source;
546   TestCompletionCallback verify_callback;
547   Verify(chain.get(), "www.example.com",
548          /*flags=*/0,
549          &verify_result, &verify_net_log_source, verify_callback.callback());
550 
551   // EV doesn't do revocation checking, therefore verification result
552   // should be OK and EV.
553   int error = verify_callback.WaitForResult();
554   EXPECT_THAT(error, IsOk());
555   EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_IS_EV);
556   EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
557 
558   auto events = net_log_observer.GetEntriesForSource(verify_net_log_source);
559 
560   auto event = base::ranges::find(
561       events, NetLogEventType::CERT_VERIFY_PROC_PATH_BUILD_ATTEMPT,
562       &NetLogEntry::type);
563   ASSERT_NE(event, events.end());
564   EXPECT_EQ(net::NetLogEventPhase::BEGIN, event->phase);
565   EXPECT_EQ(true, event->params.FindBool("is_ev_attempt"));
566 
567   event = base::ranges::find(++event, events.end(),
568                              NetLogEventType::CERT_VERIFY_PROC_PATH_BUILT,
569                              &NetLogEntry::type);
570   ASSERT_NE(event, events.end());
571   EXPECT_EQ(net::NetLogEventPhase::NONE, event->phase);
572   EXPECT_FALSE(event->params.FindString("errors"));
573 
574   event = base::ranges::find(
575       ++event, events.end(),
576       NetLogEventType::CERT_VERIFY_PROC_PATH_BUILD_ATTEMPT, &NetLogEntry::type);
577   ASSERT_NE(event, events.end());
578   EXPECT_EQ(net::NetLogEventPhase::END, event->phase);
579   EXPECT_EQ(true, event->params.FindBool("has_valid_path"));
580 }
581 #endif  // defined(PLATFORM_USES_CHROMIUM_EV_METADATA)
582 
TEST_F(CertVerifyProcBuiltinTest,DeadlineExceededDuringSyncGetIssuers)583 TEST_F(CertVerifyProcBuiltinTest, DeadlineExceededDuringSyncGetIssuers) {
584   auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
585   InitializeVerifyProc(
586       /*additional_trust_anchors=*/{root->GetX509Certificate()});
587 
588   BlockingTrustStore trust_store;
589   AddTrustStore(&trust_store);
590 
591   auto intermediate_parsed_cert = bssl::ParsedCertificate::Create(
592       intermediate->DupCertBuffer(), {}, nullptr);
593   ASSERT_TRUE(intermediate_parsed_cert);
594   trust_store.backing_trust_store_.AddCertificateWithUnspecifiedTrust(
595       intermediate_parsed_cert);
596 
597   scoped_refptr<X509Certificate> chain = leaf->GetX509Certificate();
598   ASSERT_TRUE(chain.get());
599 
600   CertVerifyResult verify_result;
601   NetLogSource verify_net_log_source;
602   TestCompletionCallback verify_callback;
603   Verify(chain.get(), "www.example.com",
604          /*flags=*/0,
605          &verify_result, &verify_net_log_source, verify_callback.callback());
606 
607   // Wait for trust_store.SyncGetIssuersOf to be called.
608   trust_store.sync_get_issuer_started_event_.Wait();
609 
610   // Advance the clock past the verifier deadline.
611   const base::TimeDelta timeout_increment =
612       GetCertVerifyProcBuiltinTimeLimitForTesting() + base::Milliseconds(1);
613   task_environment().AdvanceClock(timeout_increment);
614 
615   // Signal trust_store.SyncGetIssuersOf to finish.
616   trust_store.sync_get_issuer_ok_to_finish_event_.Signal();
617 
618   int error = verify_callback.WaitForResult();
619   // Because the deadline was reached while retrieving the intermediate, path
620   // building should have stopped there and not found the root. The partial
621   // path built up to that point should be returned, and the error should be
622   // CERT_AUTHORITY_INVALID.
623   EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
624   ASSERT_EQ(1u, verify_result.verified_cert->intermediate_buffers().size());
625   EXPECT_EQ(intermediate->GetCertBuffer(),
626             verify_result.verified_cert->intermediate_buffers()[0].get());
627 }
628 
629 namespace {
630 
631 // Returns a TLV to use as an unknown signature algorithm when building a cert.
632 // The specific contents are as follows (the OID is from
633 // https://davidben.net/oid):
634 //
635 // SEQUENCE {
636 //   OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.0 }
637 //   NULL {}
638 // }
UnknownSignatureAlgorithmTLV()639 std::string UnknownSignatureAlgorithmTLV() {
640   const uint8_t kInvalidSignatureAlgorithmTLV[] = {
641       0x30, 0x10, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7,
642       0x12, 0x04, 0x01, 0x84, 0xb7, 0x09, 0x00, 0x05, 0x00};
643   return std::string(std::begin(kInvalidSignatureAlgorithmTLV),
644                      std::end(kInvalidSignatureAlgorithmTLV));
645 }
646 
647 // Returns a TLV to use as an invalid signature algorithm when building a cert.
648 // This is a SEQUENCE so that it will pass the bssl::ParseCertificate code
649 // and fail inside bssl::ParseSignatureAlgorithm.
650 // SEQUENCE {
651 //   INTEGER { 42 }
652 // }
InvalidSignatureAlgorithmTLV()653 std::string InvalidSignatureAlgorithmTLV() {
654   const uint8_t kInvalidSignatureAlgorithmTLV[] = {0x30, 0x03, 0x02, 0x01,
655                                                    0x2a};
656   return std::string(std::begin(kInvalidSignatureAlgorithmTLV),
657                      std::end(kInvalidSignatureAlgorithmTLV));
658 }
659 
660 }  // namespace
661 
TEST_F(CertVerifyProcBuiltinTest,UnknownSignatureAlgorithmTarget)662 TEST_F(CertVerifyProcBuiltinTest, UnknownSignatureAlgorithmTarget) {
663   auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
664   leaf->SetSignatureAlgorithmTLV(UnknownSignatureAlgorithmTLV());
665 
666   // Trust the root and build a chain to verify that includes the intermediate.
667   ScopedTestRoot scoped_root(root->GetX509Certificate());
668   scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
669   ASSERT_TRUE(chain.get());
670 
671   int flags = 0;
672   CertVerifyResult verify_result;
673   NetLogSource verify_net_log_source;
674   TestCompletionCallback callback;
675   Verify(chain.get(), "www.example.com", flags, &verify_result,
676          &verify_net_log_source, callback.callback());
677   int error = callback.WaitForResult();
678   // Unknown signature algorithm in the leaf cert should result in the cert
679   // being invalid.
680   EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_INVALID);
681   EXPECT_THAT(error, IsError(ERR_CERT_INVALID));
682 }
683 
TEST_F(CertVerifyProcBuiltinTest,UnparsableMismatchedTBSSignatureAlgorithmTarget)684 TEST_F(CertVerifyProcBuiltinTest,
685        UnparsableMismatchedTBSSignatureAlgorithmTarget) {
686   auto [leaf, root] = CertBuilder::CreateSimpleChain2();
687   // Set only the tbsCertificate signature to an invalid value.
688   leaf->SetTBSSignatureAlgorithmTLV(InvalidSignatureAlgorithmTLV());
689 
690   // Trust the root and build a chain to verify.
691   ScopedTestRoot scoped_root(root->GetX509Certificate());
692   scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
693   ASSERT_TRUE(chain.get());
694 
695   int flags = 0;
696   CertVerifyResult verify_result;
697   NetLogSource verify_net_log_source;
698   TestCompletionCallback callback;
699   Verify(chain.get(), "www.example.com", flags, &verify_result,
700          &verify_net_log_source, callback.callback());
701   int error = callback.WaitForResult();
702   // Invalid signature algorithm in the leaf cert should result in the
703   // cert being invalid.
704   EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_INVALID);
705   EXPECT_THAT(error, IsError(ERR_CERT_INVALID));
706 }
707 
TEST_F(CertVerifyProcBuiltinTest,UnknownSignatureAlgorithmIntermediate)708 TEST_F(CertVerifyProcBuiltinTest, UnknownSignatureAlgorithmIntermediate) {
709   auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
710   intermediate->SetSignatureAlgorithmTLV(UnknownSignatureAlgorithmTLV());
711 
712   // Trust the root and build a chain to verify that includes the intermediate.
713   ScopedTestRoot scoped_root(root->GetX509Certificate());
714   scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
715   ASSERT_TRUE(chain.get());
716 
717   int flags = 0;
718   CertVerifyResult verify_result;
719   NetLogSource verify_net_log_source;
720   TestCompletionCallback callback;
721   Verify(chain.get(), "www.example.com", flags, &verify_result,
722          &verify_net_log_source, callback.callback());
723   int error = callback.WaitForResult();
724   // Unknown signature algorithm in the intermediate cert should result in the
725   // cert being invalid.
726   EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_INVALID);
727   EXPECT_THAT(error, IsError(ERR_CERT_INVALID));
728 }
729 
TEST_F(CertVerifyProcBuiltinTest,UnparsableMismatchedTBSSignatureAlgorithmIntermediate)730 TEST_F(CertVerifyProcBuiltinTest,
731        UnparsableMismatchedTBSSignatureAlgorithmIntermediate) {
732   auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
733   // Set only the tbsCertificate signature to an invalid value.
734   intermediate->SetTBSSignatureAlgorithmTLV(InvalidSignatureAlgorithmTLV());
735 
736   // Trust the root and build a chain to verify that includes the intermediate.
737   ScopedTestRoot scoped_root(root->GetX509Certificate());
738   scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
739   ASSERT_TRUE(chain.get());
740   ASSERT_EQ(chain->intermediate_buffers().size(), 1U);
741 
742   int flags = 0;
743   CertVerifyResult verify_result;
744   NetLogSource verify_net_log_source;
745   TestCompletionCallback callback;
746   Verify(chain.get(), "www.example.com", flags, &verify_result,
747          &verify_net_log_source, callback.callback());
748   int error = callback.WaitForResult();
749   // Invalid signature algorithm in the intermediate cert should result in the
750   // cert being invalid.
751   EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_INVALID);
752   EXPECT_THAT(error, IsError(ERR_CERT_INVALID));
753 }
754 
TEST_F(CertVerifyProcBuiltinTest,UnknownSignatureAlgorithmRoot)755 TEST_F(CertVerifyProcBuiltinTest, UnknownSignatureAlgorithmRoot) {
756   auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
757   root->SetSignatureAlgorithmTLV(UnknownSignatureAlgorithmTLV());
758 
759   // Trust the root and build a chain to verify that includes the intermediate.
760   ScopedTestRoot scoped_root(root->GetX509Certificate());
761   scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
762   ASSERT_TRUE(chain.get());
763 
764   int flags = 0;
765   CertVerifyResult verify_result;
766   NetLogSource verify_net_log_source;
767   TestCompletionCallback callback;
768   Verify(chain.get(), "www.example.com", flags, &verify_result,
769          &verify_net_log_source, callback.callback());
770   int error = callback.WaitForResult();
771   // Unknown signature algorithm in the root cert should have no effect on
772   // verification.
773   EXPECT_THAT(error, IsOk());
774 }
775 
776 // This test is disabled on Android as adding the invalid root through
777 // ScopedTestRoot causes it to be parsed by the Java X509 code which barfs. We
778 // could re-enable if Chrome on Android has fully switched to the
779 // builtin-verifier and ScopedTestRoot no longer has Android-specific code.
780 #if BUILDFLAG(IS_ANDROID)
781 #define MAYBE_UnparsableMismatchedTBSSignatureAlgorithmRoot \
782   DISABLED_UnparsableMismatchedTBSSignatureAlgorithmRoot
783 #else
784 #define MAYBE_UnparsableMismatchedTBSSignatureAlgorithmRoot \
785   UnparsableMismatchedTBSSignatureAlgorithmRoot
786 #endif
TEST_F(CertVerifyProcBuiltinTest,MAYBE_UnparsableMismatchedTBSSignatureAlgorithmRoot)787 TEST_F(CertVerifyProcBuiltinTest,
788        MAYBE_UnparsableMismatchedTBSSignatureAlgorithmRoot) {
789   auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
790   // Set only the tbsCertificate signature to an invalid value.
791   root->SetTBSSignatureAlgorithmTLV(InvalidSignatureAlgorithmTLV());
792 
793   // Trust the root and build a chain to verify that includes the intermediate.
794   ScopedTestRoot scoped_root(root->GetX509Certificate());
795   scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
796   ASSERT_TRUE(chain.get());
797 
798   int flags = 0;
799   CertVerifyResult verify_result;
800   NetLogSource verify_net_log_source;
801   TestCompletionCallback callback;
802   Verify(chain.get(), "www.example.com", flags, &verify_result,
803          &verify_net_log_source, callback.callback());
804   int error = callback.WaitForResult();
805   // Invalid signature algorithm in the root cert should have no effect on
806   // verification.
807   EXPECT_THAT(error, IsOk());
808 }
809 
810 class CertVerifyProcBuiltinIterationTest
811     : public CertVerifyProcBuiltinTest,
812       public testing::WithParamInterface<bool> {
813  public:
CertVerifyProcBuiltinIterationTest()814   CertVerifyProcBuiltinIterationTest() {
815     if (new_iteration_limit()) {
816       feature_list_.InitAndEnableFeature(
817           features::kNewCertPathBuilderIterationLimit);
818     } else {
819       feature_list_.InitAndDisableFeature(
820           features::kNewCertPathBuilderIterationLimit);
821     }
822   }
823 
new_iteration_limit() const824   bool new_iteration_limit() const { return GetParam(); }
825 
826  private:
827   base::test::ScopedFeatureList feature_list_;
828 };
829 
TEST_P(CertVerifyProcBuiltinIterationTest,IterationLimit)830 TEST_P(CertVerifyProcBuiltinIterationTest, IterationLimit) {
831   // Create a chain which will require many iterations in the path builder.
832   std::vector<std::unique_ptr<CertBuilder>> builders =
833       CertBuilder::CreateSimpleChain(6);
834 
835   base::Time not_before = base::Time::Now() - base::Days(1);
836   base::Time not_after = base::Time::Now() + base::Days(1);
837   for (auto& builder : builders) {
838     builder->SetValidity(not_before, not_after);
839   }
840 
841   // Generate certificates, making two versions of each intermediate.
842   std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
843   for (size_t i = 1; i < builders.size(); i++) {
844     intermediates.push_back(builders[i]->DupCertBuffer());
845     builders[i]->SetValidity(not_before, not_after + base::Seconds(1));
846     intermediates.push_back(builders[i]->DupCertBuffer());
847   }
848 
849   // The above alone is enough to make the path builder explore many paths, but
850   // it will always return the best path it has found, so the error will be the
851   // same. Instead, arrange for all those paths to be invalid (untrusted root),
852   // and add a separate chain that is valid.
853   CertBuilder root_ok(/*orig_cert=*/builders[2]->GetCertBuffer(),
854                       /*issuer=*/nullptr);
855   CertBuilder intermediate_ok(/*orig_cert=*/builders[1]->GetCertBuffer(),
856                               /*issuer=*/&root_ok);
857   // Using the old intermediate as a template does not preserve the subject,
858   // SKID, or key.
859   intermediate_ok.SetSubjectTLV(
860       base::as_bytes(base::make_span(builders[1]->GetSubject())));
861   intermediate_ok.SetKey(bssl::UpRef(builders[1]->GetKey()));
862   intermediate_ok.SetSubjectKeyIdentifier(
863       builders[1]->GetSubjectKeyIdentifier());
864   // Make the valid intermediate older than the invalid ones, so that it is
865   // explored last.
866   intermediate_ok.SetValidity(not_before - base::Seconds(10),
867                               not_after - base::Seconds(10));
868   intermediates.push_back(intermediate_ok.DupCertBuffer());
869 
870   // Verify the chain.
871   ScopedTestRoot scoped_root(root_ok.GetX509Certificate().get());
872   scoped_refptr<X509Certificate> chain = X509Certificate::CreateFromBuffer(
873       builders[0]->DupCertBuffer(), std::move(intermediates));
874   ASSERT_TRUE(chain.get());
875 
876   RecordingNetLogObserver net_log_observer(NetLogCaptureMode::kDefault);
877   int flags = 0;
878   CertVerifyResult verify_result;
879   NetLogSource verify_net_log_source;
880   TestCompletionCallback callback;
881   Verify(chain.get(), "www.example.com", flags, &verify_result,
882          &verify_net_log_source, callback.callback());
883   int error = callback.WaitForResult();
884 
885   auto events = net_log_observer.GetEntriesForSource(verify_net_log_source);
886   auto event = base::ranges::find_if(events, [](const NetLogEntry& e) {
887     return e.type == NetLogEventType::CERT_VERIFY_PROC_PATH_BUILD_ATTEMPT &&
888            e.phase == NetLogEventPhase::END;
889   });
890   ASSERT_NE(event, events.end());
891 
892   if (new_iteration_limit()) {
893     // The path builder gives up before it finishes all the invalid paths.
894     EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_AUTHORITY_INVALID);
895     EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
896     EXPECT_EQ(true, event->params.FindBool("exceeded_iteration_limit"));
897   } else {
898     // After exploring many dead ends, the path builder finds the valid path.
899     EXPECT_THAT(error, IsOk());
900     EXPECT_FALSE(event->params.Find("exceeded_iteration_limit"));
901   }
902 }
903 
904 INSTANTIATE_TEST_SUITE_P(NewLimit,
905                          CertVerifyProcBuiltinIterationTest,
906                          testing::Bool());
907 
908 }  // namespace net
909