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 <optional>
8 #include <string_view>
9
10 #include "base/memory/raw_ptr.h"
11 #include "base/memory/scoped_refptr.h"
12 #include "base/numerics/safe_conversions.h"
13 #include "base/ranges/algorithm.h"
14 #include "base/run_loop.h"
15 #include "base/strings/stringprintf.h"
16 #include "base/task/sequenced_task_runner.h"
17 #include "base/task/thread_pool.h"
18 #include "base/test/metrics/histogram_tester.h"
19 #include "base/test/scoped_feature_list.h"
20 #include "base/test/task_environment.h"
21 #include "base/time/time.h"
22 #include "net/base/features.h"
23 #include "net/base/net_errors.h"
24 #include "net/base/test_completion_callback.h"
25 #include "net/cert/cert_verify_proc.h"
26 #include "net/cert/crl_set.h"
27 #include "net/cert/do_nothing_ct_verifier.h"
28 #include "net/cert/ev_root_ca_metadata.h"
29 #include "net/cert/internal/system_trust_store.h"
30 #include "net/cert/sct_status_flags.h"
31 #include "net/cert/time_conversions.h"
32 #include "net/cert/x509_util.h"
33 #include "net/cert_net/cert_net_fetcher_url_request.h"
34 #include "net/http/transport_security_state.h"
35 #include "net/log/net_log_with_source.h"
36 #include "net/log/test_net_log.h"
37 #include "net/test/cert_builder.h"
38 #include "net/test/cert_test_util.h"
39 #include "net/test/embedded_test_server/embedded_test_server.h"
40 #include "net/test/embedded_test_server/http_request.h"
41 #include "net/test/embedded_test_server/http_response.h"
42 #include "net/test/embedded_test_server/request_handler_util.h"
43 #include "net/test/gtest_util.h"
44 #include "net/test/revocation_builder.h"
45 #include "net/url_request/url_request_context.h"
46 #include "net/url_request/url_request_context_builder.h"
47 #include "net/url_request/url_request_test_util.h"
48 #include "testing/gtest/include/gtest/gtest.h"
49 #include "third_party/boringssl/src/pki/trust_store.h"
50 #include "third_party/boringssl/src/pki/trust_store_collection.h"
51 #include "third_party/boringssl/src/pki/trust_store_in_memory.h"
52
53 #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
54 #include "base/version_info/version_info.h" // nogncheck
55 #endif
56
57 using net::test::IsError;
58 using net::test::IsOk;
59
60 using testing::_;
61
62 namespace net {
63
64 namespace {
65
HangRequestAndCallback(base::OnceClosure callback,const test_server::HttpRequest & request)66 std::unique_ptr<test_server::HttpResponse> HangRequestAndCallback(
67 base::OnceClosure callback,
68 const test_server::HttpRequest& request) {
69 std::move(callback).Run();
70 return std::make_unique<test_server::HungResponse>();
71 }
72
FailTest(const std::string & message)73 void FailTest(const std::string& message) {
74 ADD_FAILURE() << message;
75 }
76
FailRequestAndFailTest(const std::string & message,scoped_refptr<base::TaskRunner> main_task_runner,const test_server::HttpRequest & request)77 std::unique_ptr<test_server::HttpResponse> FailRequestAndFailTest(
78 const std::string& message,
79 scoped_refptr<base::TaskRunner> main_task_runner,
80 const test_server::HttpRequest& request) {
81 main_task_runner->PostTask(FROM_HERE, base::BindOnce(FailTest, message));
82 auto response = std::make_unique<test_server::BasicHttpResponse>();
83 response->set_code(HTTP_NOT_ACCEPTABLE);
84 return response;
85 }
86
ServeResponse(HttpStatusCode status_code,const std::string & content_type,const std::string & content,const test_server::HttpRequest & request)87 std::unique_ptr<test_server::HttpResponse> ServeResponse(
88 HttpStatusCode status_code,
89 const std::string& content_type,
90 const std::string& content,
91 const test_server::HttpRequest& request) {
92 auto http_response = std::make_unique<test_server::BasicHttpResponse>();
93
94 http_response->set_code(status_code);
95 http_response->set_content_type(content_type);
96 http_response->set_content(content);
97 return http_response;
98 }
99
MakeRandomHexString(size_t num_bytes)100 std::string MakeRandomHexString(size_t num_bytes) {
101 std::vector<uint8_t> rand_bytes(num_bytes);
102 base::RandBytes(rand_bytes);
103 return base::HexEncode(rand_bytes);
104 }
105
MakeRandomPath(std::string_view suffix)106 static std::string MakeRandomPath(std::string_view suffix) {
107 return "/" + MakeRandomHexString(12) + std::string(suffix);
108 }
109
VerifyOnWorkerThread(const scoped_refptr<CertVerifyProc> & verify_proc,scoped_refptr<X509Certificate> cert,const std::string & hostname,const std::string & ocsp_response,const std::string & sct_list,int flags,CertVerifyResult * verify_result,NetLogSource * out_source,std::optional<base::Time> time_now)110 int VerifyOnWorkerThread(const scoped_refptr<CertVerifyProc>& verify_proc,
111 scoped_refptr<X509Certificate> cert,
112 const std::string& hostname,
113 const std::string& ocsp_response,
114 const std::string& sct_list,
115 int flags,
116 CertVerifyResult* verify_result,
117 NetLogSource* out_source,
118 std::optional<base::Time> time_now) {
119 base::ScopedAllowBaseSyncPrimitivesForTesting scoped_allow_blocking;
120 NetLogWithSource net_log(NetLogWithSource::Make(
121 net::NetLog::Get(), net::NetLogSourceType::CERT_VERIFIER_TASK));
122 int error = verify_proc->Verify(cert.get(), hostname, ocsp_response, sct_list,
123 flags, verify_result, net_log, time_now);
124 *out_source = net_log.source();
125 return error;
126 }
127
128 class MockSystemTrustStore : public SystemTrustStore {
129 public:
GetTrustStore()130 bssl::TrustStore* GetTrustStore() override { return &trust_store_; }
131
IsKnownRoot(const bssl::ParsedCertificate * trust_anchor) const132 bool IsKnownRoot(const bssl::ParsedCertificate* trust_anchor) const override {
133 return mock_is_known_root_;
134 }
135
AddTrustStore(bssl::TrustStore * store)136 void AddTrustStore(bssl::TrustStore* store) {
137 trust_store_.AddTrustStore(store);
138 }
139
SetMockIsKnownRoot(bool is_known_root)140 void SetMockIsKnownRoot(bool is_known_root) {
141 mock_is_known_root_ = is_known_root;
142 }
143
144 #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
chrome_root_store_version() const145 int64_t chrome_root_store_version() const override { return 0; }
146
GetChromeRootConstraints(const bssl::ParsedCertificate * cert) const147 base::span<const ChromeRootCertConstraints> GetChromeRootConstraints(
148 const bssl::ParsedCertificate* cert) const override {
149 return mock_chrome_root_constraints_;
150 }
151
SetMockChromeRootConstraints(std::vector<StaticChromeRootCertConstraints> chrome_root_constraints)152 void SetMockChromeRootConstraints(
153 std::vector<StaticChromeRootCertConstraints> chrome_root_constraints) {
154 mock_chrome_root_constraints_.clear();
155 for (const auto& constraint : chrome_root_constraints) {
156 mock_chrome_root_constraints_.emplace_back(constraint);
157 }
158 }
159 #endif
160
161 private:
162 bssl::TrustStoreCollection trust_store_;
163 bool mock_is_known_root_ = false;
164 #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
165 std::vector<ChromeRootCertConstraints> mock_chrome_root_constraints_;
166 #endif
167 };
168
169 class BlockingTrustStore : public bssl::TrustStore {
170 public:
GetTrust(const bssl::ParsedCertificate * cert)171 bssl::CertificateTrust GetTrust(
172 const bssl::ParsedCertificate* cert) override {
173 return backing_trust_store_.GetTrust(cert);
174 }
175
SyncGetIssuersOf(const bssl::ParsedCertificate * cert,bssl::ParsedCertificateList * issuers)176 void SyncGetIssuersOf(const bssl::ParsedCertificate* cert,
177 bssl::ParsedCertificateList* issuers) override {
178 sync_get_issuer_started_event_.Signal();
179 sync_get_issuer_ok_to_finish_event_.Wait();
180
181 backing_trust_store_.SyncGetIssuersOf(cert, issuers);
182 }
183
184 base::WaitableEvent sync_get_issuer_started_event_;
185 base::WaitableEvent sync_get_issuer_ok_to_finish_event_;
186 bssl::TrustStoreInMemory backing_trust_store_;
187 };
188
189 class MockCTVerifier : public CTVerifier {
190 public:
191 MOCK_CONST_METHOD5(Verify,
192 void(X509Certificate*,
193 std::string_view,
194 std::string_view,
195 SignedCertificateTimestampAndStatusList*,
196 const NetLogWithSource&));
197 };
198
199 class MockCTPolicyEnforcer : public CTPolicyEnforcer {
200 public:
201 MOCK_CONST_METHOD3(CheckCompliance,
202 ct::CTPolicyCompliance(X509Certificate* cert,
203 const ct::SCTList&,
204 const NetLogWithSource&));
205 MOCK_CONST_METHOD1(GetLogDisqualificationTime,
206 std::optional<base::Time>(std::string_view log_id));
207 MOCK_CONST_METHOD0(IsCtEnabled, bool());
208
209 protected:
210 ~MockCTPolicyEnforcer() override = default;
211 };
212
213 } // namespace
214
215 class CertVerifyProcBuiltinTest : public ::testing::Test {
216 public:
SetUp()217 void SetUp() override {
218 cert_net_fetcher_ = base::MakeRefCounted<CertNetFetcherURLRequest>();
219
220 InitializeVerifyProc(CreateParams({}));
221
222 context_ = CreateTestURLRequestContextBuilder()->Build();
223
224 cert_net_fetcher_->SetURLRequestContext(context_.get());
225 }
226
TearDown()227 void TearDown() override { cert_net_fetcher_->Shutdown(); }
228
CreateParams(const CertificateList & additional_trust_anchors,const CertificateList & additional_trust_anchors_with_enforced_constraints={},const CertificateList & additional_distrusted_certificates={})229 CertVerifyProc::InstanceParams CreateParams(
230 const CertificateList& additional_trust_anchors,
231 const CertificateList&
232 additional_trust_anchors_with_enforced_constraints = {},
233 const CertificateList& additional_distrusted_certificates = {}) {
234 CertVerifyProc::InstanceParams instance_params;
235 instance_params.additional_trust_anchors =
236 net::x509_util::ParseAllValidCerts(additional_trust_anchors);
237 instance_params.additional_trust_anchors_with_enforced_constraints =
238 net::x509_util::ParseAllValidCerts(
239 additional_trust_anchors_with_enforced_constraints);
240 std::vector<std::vector<uint8_t>> distrusted_spkis;
241 for (const auto& x509_cert : additional_distrusted_certificates) {
242 std::shared_ptr<const bssl::ParsedCertificate> cert =
243 bssl::ParsedCertificate::Create(
244 bssl::UpRef(x509_cert->cert_buffer()),
245 net::x509_util::DefaultParseCertificateOptions(),
246 /*errors=*/nullptr);
247 EXPECT_TRUE(cert);
248 std::string spki_string = cert->tbs().spki_tlv.AsString();
249 distrusted_spkis.push_back(
250 std::vector<uint8_t>(spki_string.begin(), spki_string.end()));
251 }
252 instance_params.additional_distrusted_spkis = distrusted_spkis;
253 return instance_params;
254 }
255
InitializeVerifyProc(const CertVerifyProc::InstanceParams & instance_params)256 void InitializeVerifyProc(
257 const CertVerifyProc::InstanceParams& instance_params) {
258 auto mock_system_trust_store = std::make_unique<MockSystemTrustStore>();
259 mock_system_trust_store_ = mock_system_trust_store.get();
260 auto mock_ct_verifier = std::make_unique<MockCTVerifier>();
261 mock_ct_verifier_ = mock_ct_verifier.get();
262 mock_ct_policy_enforcer_ = base::MakeRefCounted<MockCTPolicyEnforcer>();
263 verify_proc_ = CreateCertVerifyProcBuiltin(
264 cert_net_fetcher_, CRLSet::EmptyCRLSetForTesting(),
265 std::move(mock_ct_verifier), mock_ct_policy_enforcer_,
266 std::move(mock_system_trust_store), instance_params);
267 }
268
Verify(scoped_refptr<X509Certificate> cert,const std::string & hostname,int flags,CertVerifyResult * verify_result,NetLogSource * out_source,CompletionOnceCallback callback,std::optional<base::Time> time_now=std::nullopt)269 void Verify(scoped_refptr<X509Certificate> cert,
270 const std::string& hostname,
271 int flags,
272 CertVerifyResult* verify_result,
273 NetLogSource* out_source,
274 CompletionOnceCallback callback,
275 std::optional<base::Time> time_now = std::nullopt) {
276 base::ThreadPool::PostTaskAndReplyWithResult(
277 FROM_HERE,
278 {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
279 base::BindOnce(&VerifyOnWorkerThread, verify_proc_, std::move(cert),
280 hostname,
281 /*ocsp_response=*/std::string(),
282 /*sct_list=*/std::string(), flags, verify_result,
283 out_source, time_now),
284 std::move(callback));
285 }
286
Verify(scoped_refptr<X509Certificate> cert,const std::string & hostname,const std::string & ocsp_response,const std::string & sct_list,int flags,CertVerifyResult * verify_result,NetLogSource * out_source,CompletionOnceCallback callback)287 void Verify(scoped_refptr<X509Certificate> cert,
288 const std::string& hostname,
289 const std::string& ocsp_response,
290 const std::string& sct_list,
291 int flags,
292 CertVerifyResult* verify_result,
293 NetLogSource* out_source,
294 CompletionOnceCallback callback) {
295 base::ThreadPool::PostTaskAndReplyWithResult(
296 FROM_HERE,
297 {base::MayBlock(), base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN},
298 base::BindOnce(&VerifyOnWorkerThread, verify_proc_, std::move(cert),
299 hostname, ocsp_response, sct_list, flags, verify_result,
300 out_source, std::nullopt),
301 std::move(callback));
302 }
303
task_environment()304 base::test::TaskEnvironment& task_environment() { return task_environment_; }
305
306 // Creates a CRL issued and signed by |crl_issuer|, marking |revoked_serials|
307 // as revoked, and registers it to be served by the test server.
308 // 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,std::optional<bssl::SignatureAlgorithm> signature_algorithm=std::nullopt)309 GURL CreateAndServeCrl(EmbeddedTestServer* test_server,
310 CertBuilder* crl_issuer,
311 const std::vector<uint64_t>& revoked_serials,
312 std::optional<bssl::SignatureAlgorithm>
313 signature_algorithm = std::nullopt) {
314 std::string crl = BuildCrl(crl_issuer->GetSubject(), crl_issuer->GetKey(),
315 revoked_serials, signature_algorithm);
316 std::string crl_path = MakeRandomPath(".crl");
317 test_server->RegisterRequestHandler(
318 base::BindRepeating(&test_server::HandlePrefixedRequest, crl_path,
319 base::BindRepeating(ServeResponse, HTTP_OK,
320 "application/pkix-crl", crl)));
321 return test_server->GetURL(crl_path);
322 }
323
AddTrustStore(bssl::TrustStore * store)324 void AddTrustStore(bssl::TrustStore* store) {
325 mock_system_trust_store_->AddTrustStore(store);
326 }
327
SetMockIsKnownRoot(bool is_known_root)328 void SetMockIsKnownRoot(bool is_known_root) {
329 mock_system_trust_store_->SetMockIsKnownRoot(is_known_root);
330 }
331
332 #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
SetMockChromeRootConstraints(std::vector<StaticChromeRootCertConstraints> chrome_root_constraints)333 void SetMockChromeRootConstraints(
334 std::vector<StaticChromeRootCertConstraints> chrome_root_constraints) {
335 mock_system_trust_store_->SetMockChromeRootConstraints(
336 std::move(chrome_root_constraints));
337 }
338 #endif
339
context()340 net::URLRequestContext* context() { return context_.get(); }
341
mock_ct_verifier()342 MockCTVerifier* mock_ct_verifier() { return mock_ct_verifier_; }
mock_ct_policy_enforcer()343 MockCTPolicyEnforcer* mock_ct_policy_enforcer() {
344 return mock_ct_policy_enforcer_.get();
345 }
346
347 private:
348 base::test::TaskEnvironment task_environment_{
349 base::test::TaskEnvironment::TimeSource::MOCK_TIME,
350 base::test::TaskEnvironment::MainThreadType::IO,
351 };
352
353 CertVerifier::Config config_;
354 std::unique_ptr<net::URLRequestContext> context_;
355
356 // Must outlive `mock_ct_verifier_` and `mock_system_trust_store_`.
357 scoped_refptr<CertVerifyProc> verify_proc_;
358
359 raw_ptr<MockCTVerifier> mock_ct_verifier_ = nullptr;
360 scoped_refptr<MockCTPolicyEnforcer> mock_ct_policy_enforcer_;
361 raw_ptr<MockSystemTrustStore> mock_system_trust_store_ = nullptr;
362 scoped_refptr<CertNetFetcherURLRequest> cert_net_fetcher_;
363 };
364
TEST_F(CertVerifyProcBuiltinTest,ShouldBypassHSTS)365 TEST_F(CertVerifyProcBuiltinTest, ShouldBypassHSTS) {
366 auto [leaf, root] = CertBuilder::CreateSimpleChain2();
367 InitializeVerifyProc(CreateParams(
368 /*additional_trust_anchors=*/{root->GetX509Certificate()}));
369
370 EmbeddedTestServer test_server(EmbeddedTestServer::TYPE_HTTP);
371 ASSERT_TRUE(test_server.InitializeAndListen());
372
373 // CRL that marks leaf as revoked.
374 leaf->SetCrlDistributionPointUrl(
375 CreateAndServeCrl(&test_server, root.get(), {leaf->GetSerialNumber()}));
376
377 test_server.StartAcceptingConnections();
378
379 {
380 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
381 ASSERT_TRUE(chain.get());
382
383 NetLogSource verify_net_log_source;
384 CertVerifyResult verify_result;
385 TestCompletionCallback verify_callback;
386 // Ensure HSTS upgrades for the domain which hosts the CRLs.
387 context()->transport_security_state()->AddHSTS(
388 test_server.base_url().host(), base::Time::Now() + base::Seconds(30),
389 /*include_subdomains=*/true);
390 ASSERT_TRUE(context()->transport_security_state()->ShouldUpgradeToSSL(
391 test_server.base_url().host()));
392 Verify(chain.get(), "www.example.com",
393 CertVerifyProc::VERIFY_REV_CHECKING_ENABLED,
394 &verify_result, &verify_net_log_source, verify_callback.callback());
395
396 int error = verify_callback.WaitForResult();
397 EXPECT_THAT(error, IsError(ERR_CERT_REVOKED));
398 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
399 }
400 }
401
TEST_F(CertVerifyProcBuiltinTest,SimpleSuccess)402 TEST_F(CertVerifyProcBuiltinTest, SimpleSuccess) {
403 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
404 InitializeVerifyProc(CreateParams(
405 /*additional_trust_anchors=*/{root->GetX509Certificate()}));
406
407 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
408 ASSERT_TRUE(chain.get());
409
410 base::HistogramTester histogram_tester;
411 CertVerifyResult verify_result;
412 NetLogSource verify_net_log_source;
413 TestCompletionCallback callback;
414 Verify(chain.get(), "www.example.com", /*flags=*/0, &verify_result,
415 &verify_net_log_source, callback.callback());
416
417 int error = callback.WaitForResult();
418 EXPECT_THAT(error, IsOk());
419 EXPECT_THAT(histogram_tester.GetAllSamples(
420 "Net.CertVerifier.PathBuilderIterationCount"),
421 testing::ElementsAre(base::Bucket(/*min=*/2, /*count=*/1)));
422 }
423
TEST_F(CertVerifyProcBuiltinTest,CallsCtVerifierAndReturnsSctStatus)424 TEST_F(CertVerifyProcBuiltinTest, CallsCtVerifierAndReturnsSctStatus) {
425 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
426 InitializeVerifyProc(CreateParams(
427 /*additional_trust_anchors=*/{root->GetX509Certificate()}));
428
429 const std::string kOcspResponse = "OCSP response";
430 const std::string kSctList = "SCT list";
431 const std::string kLogId = "CT log id";
432 const ct::SCTVerifyStatus kSctVerifyStatus = ct::SCT_STATUS_LOG_UNKNOWN;
433
434 SignedCertificateTimestampAndStatus sct_and_status;
435 sct_and_status.sct = base::MakeRefCounted<ct::SignedCertificateTimestamp>();
436 sct_and_status.sct->log_id = kLogId;
437 sct_and_status.status = kSctVerifyStatus;
438 SignedCertificateTimestampAndStatusList sct_and_status_list;
439 sct_and_status_list.push_back(sct_and_status);
440 EXPECT_CALL(*mock_ct_verifier(), Verify(_, kOcspResponse, kSctList, _, _))
441 .WillOnce(testing::SetArgPointee<3>(sct_and_status_list));
442 EXPECT_CALL(*mock_ct_policy_enforcer(), CheckCompliance(_, _, _))
443 .WillRepeatedly(
444 testing::Return(ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS));
445
446 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
447 ASSERT_TRUE(chain.get());
448
449 base::HistogramTester histogram_tester;
450 CertVerifyResult verify_result;
451 NetLogSource verify_net_log_source;
452 TestCompletionCallback callback;
453 Verify(chain.get(), "www.example.com", kOcspResponse, kSctList, /*flags=*/0,
454 &verify_result, &verify_net_log_source, callback.callback());
455
456 int error = callback.WaitForResult();
457 EXPECT_THAT(error, IsOk());
458 ASSERT_EQ(verify_result.scts.size(), 1u);
459 EXPECT_EQ(verify_result.scts.front().status, kSctVerifyStatus);
460 EXPECT_EQ(verify_result.scts.front().sct->log_id, kLogId);
461 EXPECT_EQ(verify_result.policy_compliance,
462 ct::CTPolicyCompliance::CT_POLICY_NOT_DIVERSE_SCTS);
463 }
464
465 #if defined(PLATFORM_USES_CHROMIUM_EV_METADATA)
TEST_F(CertVerifyProcBuiltinTest,EVCertStatusMaintainedForCompliantCert)466 TEST_F(CertVerifyProcBuiltinTest, EVCertStatusMaintainedForCompliantCert) {
467 auto [leaf, root] = CertBuilder::CreateSimpleChain2();
468
469 static const char kEVTestCertPolicy[] = "1.2.3.4";
470 leaf->SetCertificatePolicies({kEVTestCertPolicy});
471 ScopedTestEVPolicy scoped_test_ev_policy(
472 EVRootCAMetadata::GetInstance(),
473 X509Certificate::CalculateFingerprint256(root->GetCertBuffer()),
474 kEVTestCertPolicy);
475 InitializeVerifyProc(CreateParams(
476 /*additional_trust_anchors=*/{root->GetX509Certificate()}));
477
478 EXPECT_CALL(*mock_ct_verifier(), Verify(_, _, _, _, _));
479 EXPECT_CALL(*mock_ct_policy_enforcer(), CheckCompliance(_, _, _))
480 .WillRepeatedly(
481 testing::Return(ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));
482
483 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
484 ASSERT_TRUE(chain.get());
485
486 base::HistogramTester histogram_tester;
487 CertVerifyResult verify_result;
488 NetLogSource verify_net_log_source;
489 TestCompletionCallback callback;
490 Verify(chain.get(), "www.example.com", /*flags=*/0, &verify_result,
491 &verify_net_log_source, callback.callback());
492
493 int error = callback.WaitForResult();
494 EXPECT_THAT(error, IsOk());
495 EXPECT_EQ(verify_result.policy_compliance,
496 ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS);
497 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_IS_EV);
498 }
499 #endif
500
TEST_F(CertVerifyProcBuiltinTest,DistrustedIntermediate)501 TEST_F(CertVerifyProcBuiltinTest, DistrustedIntermediate) {
502 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
503 InitializeVerifyProc(CreateParams(
504 /*additional_trust_anchors=*/{root->GetX509Certificate()},
505 /*additional_trust_anchors_with_enforced_constraints=*/{},
506 /*additional_distrusted_certificates=*/
507 {intermediate->GetX509Certificate()}));
508
509 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
510 ASSERT_TRUE(chain.get());
511
512 base::HistogramTester histogram_tester;
513 CertVerifyResult verify_result;
514 NetLogSource verify_net_log_source;
515 TestCompletionCallback callback;
516 Verify(chain.get(), "www.example.com", /*flags=*/0, &verify_result,
517 &verify_net_log_source, callback.callback());
518
519 int error = callback.WaitForResult();
520 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
521 EXPECT_EQ(1u, verify_result.verified_cert->intermediate_buffers().size());
522 EXPECT_THAT(histogram_tester.GetAllSamples(
523 "Net.CertVerifier.PathBuilderIterationCount"),
524 testing::ElementsAre(base::Bucket(/*min=*/2, /*count=*/1)));
525 }
526
TEST_F(CertVerifyProcBuiltinTest,AddedRootWithConstraints)527 TEST_F(CertVerifyProcBuiltinTest, AddedRootWithConstraints) {
528 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
529 root->SetNameConstraintsDnsNames(/*permitted_dns_names=*/{"example.org"},
530 /*excluded_dns_names=*/{});
531 InitializeVerifyProc(CreateParams(
532 /*additional_trust_anchors=*/{},
533 /*additional_trust_anchors_with_enforced_constraints=*/
534 {root->GetX509Certificate()},
535 /*additional_distrusted_certificates=*/{}));
536
537 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
538 ASSERT_TRUE(chain.get());
539
540 base::HistogramTester histogram_tester;
541 CertVerifyResult verify_result;
542 NetLogSource verify_net_log_source;
543 TestCompletionCallback callback;
544 Verify(chain.get(), "www.example.com", /*flags=*/0, &verify_result,
545 &verify_net_log_source, callback.callback());
546
547 int error = callback.WaitForResult();
548 // Doesn't chain back to any valid root.
549 EXPECT_THAT(error, IsError(ERR_CERT_INVALID));
550 }
551
TEST_F(CertVerifyProcBuiltinTest,AddedRootWithConstraintsNotEnforced)552 TEST_F(CertVerifyProcBuiltinTest, AddedRootWithConstraintsNotEnforced) {
553 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
554 root->SetNameConstraintsDnsNames(/*permitted_dns_names=*/{"example.org"},
555 /*excluded_dns_names=*/{});
556 InitializeVerifyProc(CreateParams(
557 /*additional_trust_anchors=*/{root->GetX509Certificate()},
558 /*additional_trust_anchors_with_enforced_constraints=*/{},
559 /*additional_distrusted_certificates=*/{}));
560
561 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
562 ASSERT_TRUE(chain.get());
563
564 base::HistogramTester histogram_tester;
565 CertVerifyResult verify_result;
566 NetLogSource verify_net_log_source;
567 TestCompletionCallback callback;
568 Verify(chain.get(), "www.example.com", /*flags=*/0, &verify_result,
569 &verify_net_log_source, callback.callback());
570
571 int error = callback.WaitForResult();
572 // Constraint isn't enforced.
573 EXPECT_THAT(error, IsOk());
574 }
575
TEST_F(CertVerifyProcBuiltinTest,AddedRootWithOutsideDNSConstraints)576 TEST_F(CertVerifyProcBuiltinTest, AddedRootWithOutsideDNSConstraints) {
577 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
578 CertVerifyProc::InstanceParams instance_params;
579
580 std::shared_ptr<const bssl::ParsedCertificate> root_cert =
581 bssl::ParsedCertificate::Create(
582 bssl::UpRef(root->GetX509Certificate()->cert_buffer()),
583 net::x509_util::DefaultParseCertificateOptions(), nullptr);
584 ASSERT_TRUE(root_cert);
585 CertVerifyProc::CertificateWithConstraints cert_with_constraints;
586 cert_with_constraints.certificate = std::move(root_cert);
587 cert_with_constraints.permitted_dns_names.push_back("example.com");
588
589 instance_params.additional_trust_anchors_with_constraints.push_back(
590 cert_with_constraints);
591
592 InitializeVerifyProc(instance_params);
593
594 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
595 ASSERT_TRUE(chain.get());
596
597 base::HistogramTester histogram_tester;
598 CertVerifyResult verify_result;
599 NetLogSource verify_net_log_source;
600 TestCompletionCallback callback;
601 Verify(chain.get(), "www.example.com", /*flags=*/0, &verify_result,
602 &verify_net_log_source, callback.callback());
603
604 int error = callback.WaitForResult();
605 EXPECT_THAT(error, IsOk());
606 EXPECT_THAT(histogram_tester.GetAllSamples(
607 "Net.CertVerifier.PathBuilderIterationCount"),
608 testing::ElementsAre(base::Bucket(/*min=*/2, /*count=*/1)));
609 }
610
TEST_F(CertVerifyProcBuiltinTest,AddedRootWithOutsideDNSConstraintsNotMatched)611 TEST_F(CertVerifyProcBuiltinTest,
612 AddedRootWithOutsideDNSConstraintsNotMatched) {
613 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
614 CertVerifyProc::InstanceParams instance_params;
615
616 std::shared_ptr<const bssl::ParsedCertificate> root_cert =
617 bssl::ParsedCertificate::Create(
618 bssl::UpRef(root->GetX509Certificate()->cert_buffer()),
619 net::x509_util::DefaultParseCertificateOptions(), nullptr);
620 ASSERT_TRUE(root_cert);
621 CertVerifyProc::CertificateWithConstraints cert_with_constraints;
622 cert_with_constraints.certificate = std::move(root_cert);
623 cert_with_constraints.permitted_dns_names.push_back("foobar.com");
624
625 instance_params.additional_trust_anchors_with_constraints.push_back(
626 cert_with_constraints);
627
628 InitializeVerifyProc(instance_params);
629
630 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
631 ASSERT_TRUE(chain.get());
632 CertVerifyResult verify_result;
633 NetLogSource verify_net_log_source;
634 TestCompletionCallback callback;
635 Verify(chain.get(), "www.example.com", /*flags=*/0, &verify_result,
636 &verify_net_log_source, callback.callback());
637
638 int error = callback.WaitForResult();
639 EXPECT_THAT(error, IsError(ERR_CERT_INVALID));
640 }
641
TEST_F(CertVerifyProcBuiltinTest,AddedRootWithOutsideCIDRConstraints)642 TEST_F(CertVerifyProcBuiltinTest, AddedRootWithOutsideCIDRConstraints) {
643 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
644 CertVerifyProc::InstanceParams instance_params;
645
646 std::shared_ptr<const bssl::ParsedCertificate> root_cert =
647 bssl::ParsedCertificate::Create(
648 bssl::UpRef(root->GetX509Certificate()->cert_buffer()),
649 net::x509_util::DefaultParseCertificateOptions(), nullptr);
650 ASSERT_TRUE(root_cert);
651 CertVerifyProc::CertificateWithConstraints cert_with_constraints;
652 cert_with_constraints.certificate = std::move(root_cert);
653 cert_with_constraints.permitted_cidrs.push_back(
654 {net::IPAddress(192, 168, 1, 104), net::IPAddress(255, 255, 255, 0)});
655
656 instance_params.additional_trust_anchors_with_constraints.push_back(
657 cert_with_constraints);
658
659 InitializeVerifyProc(instance_params);
660
661 leaf->SetSubjectAltNames(/*dns_names=*/{"www.example.com"},
662 /*ip_addresses=*/{net::IPAddress(192, 168, 1, 254)});
663 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
664 ASSERT_TRUE(chain.get());
665
666 base::HistogramTester histogram_tester;
667 CertVerifyResult verify_result;
668 NetLogSource verify_net_log_source;
669 TestCompletionCallback callback;
670 Verify(chain.get(), "www.example.com", /*flags=*/0, &verify_result,
671 &verify_net_log_source, callback.callback());
672
673 int error = callback.WaitForResult();
674 EXPECT_THAT(error, IsOk());
675 EXPECT_THAT(histogram_tester.GetAllSamples(
676 "Net.CertVerifier.PathBuilderIterationCount"),
677 testing::ElementsAre(base::Bucket(/*min=*/2, /*count=*/1)));
678 }
679
TEST_F(CertVerifyProcBuiltinTest,AddedRootWithOutsideCIDRConstraintsNotMatched)680 TEST_F(CertVerifyProcBuiltinTest,
681 AddedRootWithOutsideCIDRConstraintsNotMatched) {
682 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
683 CertVerifyProc::InstanceParams instance_params = CreateParams({});
684
685 std::shared_ptr<const bssl::ParsedCertificate> root_cert =
686 bssl::ParsedCertificate::Create(
687 bssl::UpRef(root->GetX509Certificate()->cert_buffer()),
688 net::x509_util::DefaultParseCertificateOptions(), nullptr);
689 ASSERT_TRUE(root_cert);
690 CertVerifyProc::CertificateWithConstraints cert_with_constraints;
691 cert_with_constraints.certificate = std::move(root_cert);
692 cert_with_constraints.permitted_cidrs.push_back(
693 {net::IPAddress(192, 168, 1, 1), net::IPAddress(255, 255, 255, 0)});
694
695 instance_params.additional_trust_anchors_with_constraints.push_back(
696 cert_with_constraints);
697
698 InitializeVerifyProc(instance_params);
699
700 leaf->SetSubjectAltNames(/*dns_names=*/{"www.example.com"},
701 /*ip_addresses=*/{net::IPAddress(10, 2, 2, 2)});
702 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
703 ASSERT_TRUE(chain.get());
704
705 CertVerifyResult verify_result;
706 NetLogSource verify_net_log_source;
707 TestCompletionCallback callback;
708 Verify(chain.get(), "www.example.com", /*flags=*/0, &verify_result,
709 &verify_net_log_source, callback.callback());
710
711 int error = callback.WaitForResult();
712 EXPECT_THAT(error, IsError(ERR_CERT_INVALID));
713 }
714
TEST_F(CertVerifyProcBuiltinTest,AddedRootWithBadTime)715 TEST_F(CertVerifyProcBuiltinTest, AddedRootWithBadTime) {
716 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
717 root->SetValidity(/*not_before=*/base::Time::Now() - base::Days(10),
718 /*not_after=*/base::Time::Now() - base::Days(5));
719 InitializeVerifyProc(CreateParams(
720 /*additional_trust_anchors=*/{},
721 /*additional_trust_anchors_with_enforced_constraints=*/
722 {root->GetX509Certificate()},
723 /*additional_distrusted_certificates=*/{}));
724
725 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
726 ASSERT_TRUE(chain.get());
727
728 base::HistogramTester histogram_tester;
729 CertVerifyResult verify_result;
730 NetLogSource verify_net_log_source;
731 TestCompletionCallback callback;
732 Verify(chain.get(), "www.example.com", /*flags=*/0, &verify_result,
733 &verify_net_log_source, callback.callback());
734
735 int error = callback.WaitForResult();
736 // Root is valid but expired and we check it.
737 EXPECT_THAT(error, IsError(ERR_CERT_DATE_INVALID));
738 }
739
TEST_F(CertVerifyProcBuiltinTest,AddedRootWithBadTimeButNotEnforced)740 TEST_F(CertVerifyProcBuiltinTest, AddedRootWithBadTimeButNotEnforced) {
741 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
742 root->SetValidity(/*not_before=*/base::Time::Now() - base::Days(10),
743 /*not_after=*/base::Time::Now() - base::Days(5));
744 InitializeVerifyProc(CreateParams(
745 /*additional_trust_anchors=*/{root->GetX509Certificate()},
746 /*additional_trust_anchors_with_enforced_constraints=*/{},
747 /*additional_distrusted_certificates=*/{}));
748
749 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
750 ASSERT_TRUE(chain.get());
751
752 base::HistogramTester histogram_tester;
753 CertVerifyResult verify_result;
754 NetLogSource verify_net_log_source;
755 TestCompletionCallback callback;
756 Verify(chain.get(), "www.example.com", /*flags=*/0, &verify_result,
757 &verify_net_log_source, callback.callback());
758
759 int error = callback.WaitForResult();
760 // Root is valid but expired, but we don't check it.
761 EXPECT_THAT(error, IsOk());
762 }
763
TEST_F(CertVerifyProcBuiltinTest,CustomTime)764 TEST_F(CertVerifyProcBuiltinTest, CustomTime) {
765 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
766 root->SetValidity(/*not_before=*/base::Time::Now() - base::Days(10),
767 /*not_after=*/base::Time::Now() - base::Days(5));
768 InitializeVerifyProc(CreateParams(
769 /*additional_trust_anchors=*/{},
770 /*additional_trust_anchors_with_enforced_constraints=*/
771 {root->GetX509Certificate()},
772 /*additional_distrusted_certificates=*/{}));
773
774 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
775 ASSERT_TRUE(chain.get());
776
777 base::HistogramTester histogram_tester;
778 CertVerifyResult verify_result;
779 NetLogSource verify_net_log_source;
780 TestCompletionCallback callback;
781 Verify(chain.get(), "www.example.com", /*flags=*/0, &verify_result,
782 &verify_net_log_source, callback.callback(),
783 base::Time::Now() - base::Days(7));
784
785 int error = callback.WaitForResult();
786 // Root is expired when compared to base::Time::Now, but is valid in the
787 // custom time passed to Verify.
788 EXPECT_THAT(error, IsOk());
789 }
790
TEST_F(CertVerifyProcBuiltinTest,CustomTimeFailureIsRetriedWithSystemTime)791 TEST_F(CertVerifyProcBuiltinTest, CustomTimeFailureIsRetriedWithSystemTime) {
792 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
793 root->SetValidity(/*not_before=*/base::Time::Now() - base::Days(10),
794 /*not_after=*/base::Time::Now() + base::Days(10));
795 InitializeVerifyProc(CreateParams(
796 /*additional_trust_anchors=*/{},
797 /*additional_trust_anchors_with_enforced_constraints=*/
798 {root->GetX509Certificate()},
799 /*additional_distrusted_certificates=*/{}));
800
801 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
802 ASSERT_TRUE(chain.get());
803
804 base::HistogramTester histogram_tester;
805 CertVerifyResult verify_result;
806 NetLogSource verify_net_log_source;
807 TestCompletionCallback callback;
808 Verify(chain.get(), "www.example.com", /*flags=*/0, &verify_result,
809 &verify_net_log_source, callback.callback(),
810 base::Time::Now() + base::Days(20));
811
812 int error = callback.WaitForResult();
813 // Root is expired when compared to the custom time, but valid when compared
814 // to base::Time::Now.
815 EXPECT_THAT(error, IsOk());
816 }
817
TEST_F(CertVerifyProcBuiltinTest,CRLNotCheckedForKnownRoots)818 TEST_F(CertVerifyProcBuiltinTest, CRLNotCheckedForKnownRoots) {
819 auto [leaf, root] = CertBuilder::CreateSimpleChain2();
820 InitializeVerifyProc(CreateParams(
821 /*additional_trust_anchors=*/{root->GetX509Certificate()}));
822
823 EmbeddedTestServer test_server(EmbeddedTestServer::TYPE_HTTP);
824 ASSERT_TRUE(test_server.InitializeAndListen());
825
826 // CRL that marks leaf as revoked.
827 leaf->SetCrlDistributionPointUrl(
828 CreateAndServeCrl(&test_server, root.get(), {leaf->GetSerialNumber()}));
829
830 test_server.StartAcceptingConnections();
831
832 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
833 ASSERT_TRUE(chain.get());
834
835 NetLogSource verify_net_log_source;
836
837 {
838 CertVerifyResult verify_result;
839 TestCompletionCallback verify_callback;
840 Verify(chain.get(), "www.example.com",
841 CertVerifyProc::VERIFY_REV_CHECKING_ENABLED,
842 &verify_result, &verify_net_log_source, verify_callback.callback());
843
844 int error = verify_callback.WaitForResult();
845 EXPECT_THAT(error, IsError(ERR_CERT_REVOKED));
846 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
847 }
848
849 {
850 // Pretend the root is a known root.
851 SetMockIsKnownRoot(true);
852 base::HistogramTester histogram_tester;
853 CertVerifyResult verify_result;
854 TestCompletionCallback verify_callback;
855 Verify(chain.get(), "www.example.com",
856 CertVerifyProc::VERIFY_REV_CHECKING_ENABLED,
857 &verify_result, &verify_net_log_source, verify_callback.callback());
858
859 int error = verify_callback.WaitForResult();
860 // CRLs are not checked for chains issued by known roots, so verification
861 // should be successful.
862 EXPECT_THAT(error, IsOk());
863 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
864 EXPECT_THAT(histogram_tester.GetAllSamples(
865 "Net.CertVerifier.PathBuilderIterationCount"),
866 testing::ElementsAre(base::Bucket(/*min=*/1, /*count=*/1)));
867 }
868 }
869
870 // Tests that if the verification deadline is exceeded during revocation
871 // checking, additional CRL fetches will not be attempted.
TEST_F(CertVerifyProcBuiltinTest,RevocationCheckDeadlineCRL)872 TEST_F(CertVerifyProcBuiltinTest, RevocationCheckDeadlineCRL) {
873 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
874 InitializeVerifyProc(CreateParams(
875 /*additional_trust_anchors=*/{root->GetX509Certificate()}));
876
877 const base::TimeDelta timeout_increment =
878 CertNetFetcherURLRequest::GetDefaultTimeoutForTesting() +
879 base::Milliseconds(1);
880 const int expected_request_count =
881 base::ClampFloor(GetCertVerifyProcBuiltinTimeLimitForTesting() /
882 timeout_increment) +
883 1;
884
885 EmbeddedTestServer test_server(EmbeddedTestServer::TYPE_HTTP);
886 ASSERT_TRUE(test_server.InitializeAndListen());
887
888 // Set up the test cert to have enough crlDistributionPoint urls that if the
889 // first N-1 requests hang the deadline will be exceeded before the Nth
890 // request is made.
891 std::vector<GURL> crl_urls;
892 std::vector<base::RunLoop> runloops(expected_request_count);
893 for (int i = 0; i < expected_request_count; ++i) {
894 std::string path = base::StringPrintf("/hung/%i", i);
895 crl_urls.emplace_back(test_server.GetURL(path));
896 test_server.RegisterRequestHandler(
897 base::BindRepeating(&test_server::HandlePrefixedRequest, path,
898 base::BindRepeating(&HangRequestAndCallback,
899 runloops[i].QuitClosure())));
900 }
901 // Add CRL URLs and handlers that will add test failures if requested.
902 for (int i = expected_request_count; i < expected_request_count + 1; ++i) {
903 std::string path = base::StringPrintf("/failtest/%i", i);
904 crl_urls.emplace_back(test_server.GetURL(path));
905 test_server.RegisterRequestHandler(base::BindRepeating(
906 &test_server::HandlePrefixedRequest, path,
907 base::BindRepeating(FailRequestAndFailTest,
908 "additional request made after deadline exceeded",
909 base::SequencedTaskRunner::GetCurrentDefault())));
910 }
911 leaf->SetCrlDistributionPointUrls(crl_urls);
912
913 test_server.StartAcceptingConnections();
914
915 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
916 ASSERT_TRUE(chain.get());
917
918 base::HistogramTester histogram_tester;
919 CertVerifyResult verify_result;
920 NetLogSource verify_net_log_source;
921 TestCompletionCallback verify_callback;
922 Verify(chain.get(), "www.example.com",
923 CertVerifyProc::VERIFY_REV_CHECKING_ENABLED,
924 &verify_result, &verify_net_log_source, verify_callback.callback());
925
926 for (int i = 0; i < expected_request_count; i++) {
927 // Wait for request #|i| to be made.
928 runloops[i].Run();
929 // Advance virtual time to cause the timeout task to become runnable.
930 task_environment().AdvanceClock(timeout_increment);
931 }
932
933 // Once |expected_request_count| requests have been made and timed out, the
934 // overall deadline should be reached, and no more requests should have been
935 // made. (If they were, the test will fail due to the ADD_FAILURE callback in
936 // the request handlers.)
937 int error = verify_callback.WaitForResult();
938 // Soft-fail revocation checking was used, therefore verification result
939 // should be OK even though none of the CRLs could be retrieved.
940 EXPECT_THAT(error, IsOk());
941 EXPECT_THAT(histogram_tester.GetAllSamples(
942 "Net.CertVerifier.PathBuilderIterationCount"),
943 testing::ElementsAre(base::Bucket(/*min=*/2, /*count=*/1)));
944 }
945
946 // Tests that if the verification deadline is exceeded during revocation
947 // checking, additional OCSP fetches will not be attempted.
TEST_F(CertVerifyProcBuiltinTest,RevocationCheckDeadlineOCSP)948 TEST_F(CertVerifyProcBuiltinTest, RevocationCheckDeadlineOCSP) {
949 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
950 InitializeVerifyProc(CreateParams(
951 /*additional_trust_anchors=*/{root->GetX509Certificate()}));
952
953 const base::TimeDelta timeout_increment =
954 CertNetFetcherURLRequest::GetDefaultTimeoutForTesting() +
955 base::Milliseconds(1);
956 const int expected_request_count =
957 base::ClampFloor(GetCertVerifyProcBuiltinTimeLimitForTesting() /
958 timeout_increment) +
959 1;
960
961 EmbeddedTestServer test_server(EmbeddedTestServer::TYPE_HTTP);
962 ASSERT_TRUE(test_server.InitializeAndListen());
963
964 // Set up the test cert to have enough OCSP urls that if the
965 // first N-1 requests hang the deadline will be exceeded before the Nth
966 // request is made.
967 std::vector<GURL> ocsp_urls;
968 std::vector<base::RunLoop> runloops(expected_request_count);
969 for (int i = 0; i < expected_request_count; ++i) {
970 std::string path = base::StringPrintf("/hung/%i", i);
971 ocsp_urls.emplace_back(test_server.GetURL(path));
972 test_server.RegisterRequestHandler(
973 base::BindRepeating(&test_server::HandlePrefixedRequest, path,
974 base::BindRepeating(&HangRequestAndCallback,
975 runloops[i].QuitClosure())));
976 }
977 // Add OCSP URLs and handlers that will add test failures if requested.
978 for (int i = expected_request_count; i < expected_request_count + 1; ++i) {
979 std::string path = base::StringPrintf("/failtest/%i", i);
980 ocsp_urls.emplace_back(test_server.GetURL(path));
981 test_server.RegisterRequestHandler(base::BindRepeating(
982 &test_server::HandlePrefixedRequest, path,
983 base::BindRepeating(FailRequestAndFailTest,
984 "additional request made after deadline exceeded",
985 base::SequencedTaskRunner::GetCurrentDefault())));
986 }
987 leaf->SetCaIssuersAndOCSPUrls({}, ocsp_urls);
988
989 test_server.StartAcceptingConnections();
990
991 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
992 ASSERT_TRUE(chain.get());
993
994 CertVerifyResult verify_result;
995 NetLogSource verify_net_log_source;
996 TestCompletionCallback verify_callback;
997 Verify(chain.get(), "www.example.com",
998 CertVerifyProc::VERIFY_REV_CHECKING_ENABLED,
999 &verify_result, &verify_net_log_source, verify_callback.callback());
1000
1001 for (int i = 0; i < expected_request_count; i++) {
1002 // Wait for request #|i| to be made.
1003 runloops[i].Run();
1004 // Advance virtual time to cause the timeout task to become runnable.
1005 task_environment().AdvanceClock(timeout_increment);
1006 }
1007
1008 // Once |expected_request_count| requests have been made and timed out, the
1009 // overall deadline should be reached, and no more requests should have been
1010 // made. (If they were, the test will fail due to the ADD_FAILURE callback in
1011 // the request handlers.)
1012 int error = verify_callback.WaitForResult();
1013 // Soft-fail revocation checking was used, therefore verification result
1014 // should be OK even though none of the OCSP responses could be retrieved.
1015 EXPECT_THAT(error, IsOk());
1016 }
1017
1018 #if defined(PLATFORM_USES_CHROMIUM_EV_METADATA)
1019 // Tests that if we're doing EV verification, that no OCSP revocation checking
1020 // is done.
TEST_F(CertVerifyProcBuiltinTest,EVNoOCSPRevocationChecks)1021 TEST_F(CertVerifyProcBuiltinTest, EVNoOCSPRevocationChecks) {
1022 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
1023 InitializeVerifyProc(CreateParams(
1024 /*additional_trust_anchors=*/{root->GetX509Certificate()}));
1025
1026 // Add test EV policy to leaf and intermediate.
1027 static const char kEVTestCertPolicy[] = "1.2.3.4";
1028 leaf->SetCertificatePolicies({kEVTestCertPolicy});
1029 intermediate->SetCertificatePolicies({kEVTestCertPolicy});
1030
1031 EmbeddedTestServer test_server(EmbeddedTestServer::TYPE_HTTP);
1032 ASSERT_TRUE(test_server.InitializeAndListen());
1033
1034 // Set up the test intermediate to have an OCSP url that fails the test if
1035 // called.
1036 std::vector<GURL> ocsp_urls;
1037 std::string path = "/failtest";
1038 ocsp_urls.emplace_back(test_server.GetURL(path));
1039 test_server.RegisterRequestHandler(base::BindRepeating(
1040 &test_server::HandlePrefixedRequest, path,
1041 base::BindRepeating(FailRequestAndFailTest,
1042 "no OCSP requests should be sent",
1043 base::SequencedTaskRunner::GetCurrentDefault())));
1044 intermediate->SetCaIssuersAndOCSPUrls({}, ocsp_urls);
1045 test_server.StartAcceptingConnections();
1046
1047 // Consider the root of the test chain a valid EV root for the test policy.
1048 ScopedTestEVPolicy scoped_test_ev_policy(
1049 EVRootCAMetadata::GetInstance(),
1050 X509Certificate::CalculateFingerprint256(root->GetCertBuffer()),
1051 kEVTestCertPolicy);
1052
1053 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
1054 ASSERT_TRUE(chain.get());
1055
1056 RecordingNetLogObserver net_log_observer(NetLogCaptureMode::kDefault);
1057 CertVerifyResult verify_result;
1058 NetLogSource verify_net_log_source;
1059 TestCompletionCallback verify_callback;
1060 Verify(chain.get(), "www.example.com",
1061 /*flags=*/0,
1062 &verify_result, &verify_net_log_source, verify_callback.callback());
1063
1064 // EV doesn't do revocation checking, therefore verification result
1065 // should be OK and EV.
1066 int error = verify_callback.WaitForResult();
1067 EXPECT_THAT(error, IsOk());
1068 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_IS_EV);
1069 EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_REV_CHECKING_ENABLED);
1070
1071 auto events = net_log_observer.GetEntriesForSource(verify_net_log_source);
1072
1073 auto event = base::ranges::find(
1074 events, NetLogEventType::CERT_VERIFY_PROC_PATH_BUILD_ATTEMPT,
1075 &NetLogEntry::type);
1076 ASSERT_NE(event, events.end());
1077 EXPECT_EQ(net::NetLogEventPhase::BEGIN, event->phase);
1078 EXPECT_EQ(true, event->params.FindBool("is_ev_attempt"));
1079
1080 event = base::ranges::find(++event, events.end(),
1081 NetLogEventType::CERT_VERIFY_PROC_PATH_BUILT,
1082 &NetLogEntry::type);
1083 ASSERT_NE(event, events.end());
1084 EXPECT_EQ(net::NetLogEventPhase::BEGIN, event->phase);
1085
1086 event = base::ranges::find(++event, events.end(),
1087 NetLogEventType::CERT_VERIFY_PROC_PATH_BUILT,
1088 &NetLogEntry::type);
1089 ASSERT_NE(event, events.end());
1090 EXPECT_EQ(net::NetLogEventPhase::END, event->phase);
1091 EXPECT_FALSE(event->params.FindString("errors"));
1092
1093 event = base::ranges::find(
1094 ++event, events.end(),
1095 NetLogEventType::CERT_VERIFY_PROC_PATH_BUILD_ATTEMPT, &NetLogEntry::type);
1096 ASSERT_NE(event, events.end());
1097 EXPECT_EQ(net::NetLogEventPhase::END, event->phase);
1098 EXPECT_EQ(true, event->params.FindBool("has_valid_path"));
1099 }
1100 #endif // defined(PLATFORM_USES_CHROMIUM_EV_METADATA)
1101
1102 #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
1103
MakeSct(base::Time t,std::string_view log_id)1104 scoped_refptr<ct::SignedCertificateTimestamp> MakeSct(base::Time t,
1105 std::string_view log_id) {
1106 auto sct = base::MakeRefCounted<ct::SignedCertificateTimestamp>();
1107 sct->timestamp = t;
1108 sct->log_id = log_id;
1109 return sct;
1110 }
1111
1112 // Test SCT constraints fail-open if CT is disabled.
TEST_F(CertVerifyProcBuiltinTest,ChromeRootStoreConstraintSctConstraintsWithCtDisabled)1113 TEST_F(CertVerifyProcBuiltinTest,
1114 ChromeRootStoreConstraintSctConstraintsWithCtDisabled) {
1115 auto [leaf, root] = CertBuilder::CreateSimpleChain2();
1116 InitializeVerifyProc(CreateParams(
1117 /*additional_trust_anchors=*/{root->GetX509Certificate()}));
1118
1119 EXPECT_CALL(*mock_ct_policy_enforcer(), IsCtEnabled())
1120 .WillRepeatedly(testing::Return(false));
1121 EXPECT_CALL(*mock_ct_verifier(), Verify(_, _, _, _, _)).Times(2);
1122
1123 scoped_refptr<X509Certificate> chain = leaf->GetX509Certificate();
1124 ASSERT_TRUE(chain.get());
1125
1126 SetMockChromeRootConstraints(
1127 {{.sct_not_after = base::Time::Now() - base::Days(365)}});
1128
1129 {
1130 CertVerifyResult verify_result;
1131 NetLogSource verify_net_log_source;
1132 TestCompletionCallback callback;
1133 Verify(chain.get(), "www.example.com", /*ocsp_response=*/std::string(),
1134 /*sct_list=*/std::string(), /*flags=*/0, &verify_result,
1135 &verify_net_log_source, callback.callback());
1136
1137 int error = callback.WaitForResult();
1138 EXPECT_THAT(error, IsOk());
1139 ASSERT_EQ(verify_result.scts.size(), 0u);
1140 }
1141
1142 SetMockChromeRootConstraints(
1143 {{.sct_all_after = base::Time::Now() + base::Days(365)}});
1144
1145 {
1146 CertVerifyResult verify_result;
1147 NetLogSource verify_net_log_source;
1148 TestCompletionCallback callback;
1149 Verify(chain.get(), "www.example.com", /*ocsp_response=*/std::string(),
1150 /*sct_list=*/std::string(), /*flags=*/0, &verify_result,
1151 &verify_net_log_source, callback.callback());
1152
1153 int error = callback.WaitForResult();
1154 EXPECT_THAT(error, IsOk());
1155 ASSERT_EQ(verify_result.scts.size(), 0u);
1156 }
1157 }
1158
1159 // Test SctNotAfter constraint only requires 1 valid SCT that satisfies the
1160 // constraint.
1161 // Set a SctNotAfter constraint at time t1.
1162 // Mock that there are two SCTs, one of which is at t1 and thus satisfies the
1163 // constraint. The second is at t2 and does not satisfy the constraint, but
1164 // this is ok as only one valid SCT that meets the constraint is needed.
TEST_F(CertVerifyProcBuiltinTest,ChromeRootStoreConstraintSctNotAfter)1165 TEST_F(CertVerifyProcBuiltinTest, ChromeRootStoreConstraintSctNotAfter) {
1166 auto [leaf, root] = CertBuilder::CreateSimpleChain2();
1167 InitializeVerifyProc(CreateParams(
1168 /*additional_trust_anchors=*/{root->GetX509Certificate()}));
1169
1170 const std::string kSctList = "SCT list";
1171 const std::string kLog1 = "log1";
1172 const std::string kLog2 = "log2";
1173 base::Time now = base::Time::Now();
1174 base::Time t1 = now - base::Days(2);
1175 base::Time t2 = now - base::Days(1);
1176 SignedCertificateTimestampAndStatusList sct_and_status_list;
1177 sct_and_status_list.emplace_back(MakeSct(t1, kLog1), ct::SCT_STATUS_OK);
1178 sct_and_status_list.emplace_back(MakeSct(t2, kLog2), ct::SCT_STATUS_OK);
1179
1180 EXPECT_CALL(*mock_ct_verifier(), Verify(_, _, kSctList, _, _))
1181 .WillRepeatedly(testing::SetArgPointee<3>(sct_and_status_list));
1182
1183 SetMockChromeRootConstraints({{.sct_not_after = t1}});
1184
1185 EXPECT_CALL(*mock_ct_policy_enforcer(), IsCtEnabled())
1186 .WillRepeatedly(testing::Return(true));
1187 EXPECT_CALL(*mock_ct_policy_enforcer(), GetLogDisqualificationTime(kLog1))
1188 .WillRepeatedly(testing::Return(std::nullopt));
1189 EXPECT_CALL(*mock_ct_policy_enforcer(), GetLogDisqualificationTime(kLog2))
1190 .WillRepeatedly(testing::Return(std::nullopt));
1191 EXPECT_CALL(*mock_ct_policy_enforcer(), CheckCompliance(_, _, _))
1192 .WillRepeatedly(
1193 testing::Return(ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));
1194
1195 scoped_refptr<X509Certificate> chain = leaf->GetX509Certificate();
1196 ASSERT_TRUE(chain.get());
1197
1198 {
1199 CertVerifyResult verify_result;
1200 NetLogSource verify_net_log_source;
1201 TestCompletionCallback callback;
1202 Verify(chain.get(), "www.example.com", /*ocsp_response=*/std::string(),
1203 kSctList, /*flags=*/0, &verify_result, &verify_net_log_source,
1204 callback.callback());
1205
1206 int error = callback.WaitForResult();
1207 EXPECT_THAT(error, IsOk());
1208 ASSERT_EQ(verify_result.scts.size(), 2u);
1209 }
1210
1211 // Try again with the SctNotAfter set to before both SCTs. Verification should
1212 // fail.
1213 SetMockChromeRootConstraints({{.sct_not_after = t1 - base::Seconds(1)}});
1214 {
1215 CertVerifyResult verify_result;
1216 NetLogSource verify_net_log_source;
1217 TestCompletionCallback callback;
1218 Verify(chain.get(), "www.example.com", /*ocsp_response=*/std::string(),
1219 kSctList, /*flags=*/0, &verify_result, &verify_net_log_source,
1220 callback.callback());
1221
1222 int error = callback.WaitForResult();
1223 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
1224 ASSERT_EQ(verify_result.scts.size(), 2u);
1225 }
1226 }
1227
1228 // Test SctNotAfter constraint is only satisfied by successfully verified SCTs.
1229 // Set a SctNotAfter constraint at time t1.
1230 // Mock that there are two SCTs. One SCT for time t1 but from an unknown log,
1231 // thus should not be usable for the SctNotAfter constraint. The second CT is
1232 // from a known log but is at time t2 which is after t1, so does not satisfy
1233 // the constraint. Therefore the certificate should fail verification.
TEST_F(CertVerifyProcBuiltinTest,ChromeRootStoreConstraintSctNotAfterLogUnknown)1234 TEST_F(CertVerifyProcBuiltinTest,
1235 ChromeRootStoreConstraintSctNotAfterLogUnknown) {
1236 auto [leaf, root] = CertBuilder::CreateSimpleChain2();
1237 InitializeVerifyProc(CreateParams(
1238 /*additional_trust_anchors=*/{root->GetX509Certificate()}));
1239
1240 const std::string kSctList = "SCT list";
1241 const std::string kLog1 = "log1";
1242 const std::string kLog2 = "log2";
1243 base::Time now = base::Time::Now();
1244 base::Time t1 = now - base::Days(2);
1245 base::Time t2 = now - base::Days(1);
1246 SignedCertificateTimestampAndStatusList sct_and_status_list;
1247 sct_and_status_list.emplace_back(MakeSct(t1, kLog1),
1248 ct::SCT_STATUS_LOG_UNKNOWN);
1249 sct_and_status_list.emplace_back(MakeSct(t2, kLog2), ct::SCT_STATUS_OK);
1250
1251 EXPECT_CALL(*mock_ct_policy_enforcer(), IsCtEnabled())
1252 .WillRepeatedly(testing::Return(true));
1253 EXPECT_CALL(*mock_ct_verifier(), Verify(_, _, kSctList, _, _))
1254 .WillOnce(testing::SetArgPointee<3>(sct_and_status_list));
1255
1256 SetMockChromeRootConstraints({{.sct_not_after = t1}});
1257
1258 scoped_refptr<X509Certificate> chain = leaf->GetX509Certificate();
1259 ASSERT_TRUE(chain.get());
1260
1261 CertVerifyResult verify_result;
1262 NetLogSource verify_net_log_source;
1263 TestCompletionCallback callback;
1264 Verify(chain.get(), "www.example.com", /*ocsp_response=*/std::string(),
1265 kSctList, /*flags=*/0, &verify_result, &verify_net_log_source,
1266 callback.callback());
1267
1268 int error = callback.WaitForResult();
1269 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
1270 ASSERT_EQ(verify_result.scts.size(), 2u);
1271 }
1272
1273 // Test SctNotAfter constraint is not satisfied by a SCT from a disqualified
1274 // log even if the SCT timestamp is before the log was disqualified. Once a log
1275 // is disqualified we assume it can not be trusted and could sign SCTs for any
1276 // timestamp.
1277 // SCT #1 is from a disqualified log and the timestamp is before the log was
1278 // disqualified.
1279 // SCT #2 is from a valid log but is after the SctNotAfter constraint, so does
1280 // not satisfy the constraint.
TEST_F(CertVerifyProcBuiltinTest,ChromeRootStoreConstraintSctNotAfterFromDisqualifiedLogBeforeDisqualification)1281 TEST_F(
1282 CertVerifyProcBuiltinTest,
1283 ChromeRootStoreConstraintSctNotAfterFromDisqualifiedLogBeforeDisqualification) {
1284 auto [leaf, root] = CertBuilder::CreateSimpleChain2();
1285 InitializeVerifyProc(CreateParams(
1286 /*additional_trust_anchors=*/{root->GetX509Certificate()}));
1287
1288 const std::string kSctList = "SCT list";
1289 const std::string kLog1 = "log1";
1290 const std::string kLog2 = "log2";
1291 base::Time now = base::Time::Now();
1292 base::Time t1 = now - base::Days(2);
1293 base::Time t2 = now - base::Days(1);
1294 SignedCertificateTimestampAndStatusList sct_and_status_list;
1295 sct_and_status_list.emplace_back(MakeSct(t1, kLog1), ct::SCT_STATUS_OK);
1296 sct_and_status_list.emplace_back(MakeSct(t2, kLog2), ct::SCT_STATUS_OK);
1297
1298 EXPECT_CALL(*mock_ct_verifier(), Verify(_, _, kSctList, _, _))
1299 .WillOnce(testing::SetArgPointee<3>(sct_and_status_list));
1300
1301 SetMockChromeRootConstraints({{.sct_not_after = t1}});
1302
1303 EXPECT_CALL(*mock_ct_policy_enforcer(), IsCtEnabled())
1304 .WillRepeatedly(testing::Return(true));
1305 EXPECT_CALL(*mock_ct_policy_enforcer(), GetLogDisqualificationTime(kLog1))
1306 .WillRepeatedly(testing::Return(t2));
1307 EXPECT_CALL(*mock_ct_policy_enforcer(), GetLogDisqualificationTime(kLog2))
1308 .WillRepeatedly(testing::Return(std::nullopt));
1309
1310 EXPECT_CALL(*mock_ct_policy_enforcer(), CheckCompliance(_, _, _))
1311 .WillRepeatedly(
1312 testing::Return(ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));
1313
1314 scoped_refptr<X509Certificate> chain = leaf->GetX509Certificate();
1315 ASSERT_TRUE(chain.get());
1316
1317 CertVerifyResult verify_result;
1318 NetLogSource verify_net_log_source;
1319 TestCompletionCallback callback;
1320 Verify(chain.get(), "www.example.com", /*ocsp_response=*/std::string(),
1321 kSctList, /*flags=*/0, &verify_result, &verify_net_log_source,
1322 callback.callback());
1323
1324 int error = callback.WaitForResult();
1325 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
1326 }
1327
1328 // Test SctNotAfter constraint is not satisfied by a SCT from a disqualified
1329 // log if the SCT timestamp is after the log was disqualified.
1330 // SCT #1 is from a disqualified log and the timestamp is after the log was
1331 // disqualified.
1332 // SCT #2 is from a valid log but is after the SctNotAfter constraint, so does
1333 // not satisfy the constraint.
TEST_F(CertVerifyProcBuiltinTest,ChromeRootStoreConstraintSctNotAfterFromDisqualifiedLogAfterDisqualification)1334 TEST_F(
1335 CertVerifyProcBuiltinTest,
1336 ChromeRootStoreConstraintSctNotAfterFromDisqualifiedLogAfterDisqualification) {
1337 auto [leaf, root] = CertBuilder::CreateSimpleChain2();
1338 InitializeVerifyProc(CreateParams(
1339 /*additional_trust_anchors=*/{root->GetX509Certificate()}));
1340
1341 const std::string kSctList = "SCT list";
1342 const std::string kLog1 = "log1";
1343 const std::string kLog2 = "log2";
1344 base::Time now = base::Time::Now();
1345 base::Time t1 = now - base::Days(2);
1346 base::Time t2 = now - base::Days(1);
1347 SignedCertificateTimestampAndStatusList sct_and_status_list;
1348 sct_and_status_list.emplace_back(MakeSct(t1, kLog1), ct::SCT_STATUS_OK);
1349 sct_and_status_list.emplace_back(MakeSct(t2, kLog2), ct::SCT_STATUS_OK);
1350
1351 EXPECT_CALL(*mock_ct_verifier(), Verify(_, _, kSctList, _, _))
1352 .WillOnce(testing::SetArgPointee<3>(sct_and_status_list));
1353
1354 SetMockChromeRootConstraints({{.sct_not_after = t1}});
1355
1356 EXPECT_CALL(*mock_ct_policy_enforcer(), IsCtEnabled())
1357 .WillRepeatedly(testing::Return(true));
1358 EXPECT_CALL(*mock_ct_policy_enforcer(), GetLogDisqualificationTime(kLog1))
1359 .WillRepeatedly(testing::Return(t1));
1360 EXPECT_CALL(*mock_ct_policy_enforcer(), GetLogDisqualificationTime(kLog2))
1361 .WillRepeatedly(testing::Return(std::nullopt));
1362
1363 EXPECT_CALL(*mock_ct_policy_enforcer(), CheckCompliance(_, _, _))
1364 .WillRepeatedly(
1365 testing::Return(ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));
1366
1367 scoped_refptr<X509Certificate> chain = leaf->GetX509Certificate();
1368 ASSERT_TRUE(chain.get());
1369
1370 CertVerifyResult verify_result;
1371 NetLogSource verify_net_log_source;
1372 TestCompletionCallback callback;
1373 Verify(chain.get(), "www.example.com", /*ocsp_response=*/std::string(),
1374 kSctList, /*flags=*/0, &verify_result, &verify_net_log_source,
1375 callback.callback());
1376
1377 int error = callback.WaitForResult();
1378 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
1379 }
1380
1381 // Test SctNotAfter constraint is satisfied by a SCT from a disqualified
1382 // log if the log disqualification time is in the future.
TEST_F(CertVerifyProcBuiltinTest,ChromeRootStoreConstraintSctNotAfterFromFutureDisqualifiedLog)1383 TEST_F(CertVerifyProcBuiltinTest,
1384 ChromeRootStoreConstraintSctNotAfterFromFutureDisqualifiedLog) {
1385 auto [leaf, root] = CertBuilder::CreateSimpleChain2();
1386 InitializeVerifyProc(CreateParams(
1387 /*additional_trust_anchors=*/{root->GetX509Certificate()}));
1388
1389 const std::string kSctList = "SCT list";
1390 const std::string kLog1 = "log1";
1391 const std::string kLog2 = "log2";
1392 base::Time now = base::Time::Now();
1393 base::Time t1 = now - base::Days(2);
1394 base::Time future_t = now + base::Days(1);
1395 SignedCertificateTimestampAndStatusList sct_and_status_list;
1396 sct_and_status_list.emplace_back(MakeSct(t1, kLog1), ct::SCT_STATUS_OK);
1397
1398 EXPECT_CALL(*mock_ct_verifier(), Verify(_, _, kSctList, _, _))
1399 .WillOnce(testing::SetArgPointee<3>(sct_and_status_list));
1400
1401 SetMockChromeRootConstraints({{.sct_not_after = t1}});
1402
1403 EXPECT_CALL(*mock_ct_policy_enforcer(), IsCtEnabled())
1404 .WillRepeatedly(testing::Return(true));
1405 EXPECT_CALL(*mock_ct_policy_enforcer(), GetLogDisqualificationTime(kLog1))
1406 .WillRepeatedly(testing::Return(future_t));
1407
1408 EXPECT_CALL(*mock_ct_policy_enforcer(), CheckCompliance(_, _, _))
1409 .WillRepeatedly(
1410 testing::Return(ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));
1411
1412 scoped_refptr<X509Certificate> chain = leaf->GetX509Certificate();
1413 ASSERT_TRUE(chain.get());
1414
1415 CertVerifyResult verify_result;
1416 NetLogSource verify_net_log_source;
1417 TestCompletionCallback callback;
1418 Verify(chain.get(), "www.example.com", /*ocsp_response=*/std::string(),
1419 kSctList, /*flags=*/0, &verify_result, &verify_net_log_source,
1420 callback.callback());
1421
1422 int error = callback.WaitForResult();
1423 EXPECT_THAT(error, IsOk());
1424 }
1425
1426 // Test SctAllAfter constraint requires all valid SCTs to satisfy the
1427 // constraint.
TEST_F(CertVerifyProcBuiltinTest,ChromeRootStoreConstraintSctAllAfter)1428 TEST_F(CertVerifyProcBuiltinTest, ChromeRootStoreConstraintSctAllAfter) {
1429 auto [leaf, root] = CertBuilder::CreateSimpleChain2();
1430 InitializeVerifyProc(CreateParams(
1431 /*additional_trust_anchors=*/{root->GetX509Certificate()}));
1432
1433 const std::string kSctList = "SCT list";
1434 const std::string kLog1 = "log1";
1435 const std::string kLog2 = "log2";
1436 base::Time now = base::Time::Now();
1437 base::Time t0 = now - base::Days(3);
1438 base::Time t1 = now - base::Days(2);
1439 base::Time t2 = now - base::Days(1);
1440 SignedCertificateTimestampAndStatusList sct_and_status_list;
1441 sct_and_status_list.emplace_back(MakeSct(t1, kLog1), ct::SCT_STATUS_OK);
1442 sct_and_status_list.emplace_back(MakeSct(t2, kLog2), ct::SCT_STATUS_OK);
1443
1444 EXPECT_CALL(*mock_ct_verifier(), Verify(_, _, kSctList, _, _))
1445 .WillRepeatedly(testing::SetArgPointee<3>(sct_and_status_list));
1446
1447 // Set a SctAllAfter constraint before the timestamp of either SCT.
1448 SetMockChromeRootConstraints({{.sct_all_after = t0}});
1449
1450 EXPECT_CALL(*mock_ct_policy_enforcer(), IsCtEnabled())
1451 .WillRepeatedly(testing::Return(true));
1452 EXPECT_CALL(*mock_ct_policy_enforcer(), GetLogDisqualificationTime(kLog1))
1453 .WillRepeatedly(testing::Return(std::nullopt));
1454 EXPECT_CALL(*mock_ct_policy_enforcer(), GetLogDisqualificationTime(kLog2))
1455 .WillRepeatedly(testing::Return(std::nullopt));
1456 EXPECT_CALL(*mock_ct_policy_enforcer(), CheckCompliance(_, _, _))
1457 .WillRepeatedly(
1458 testing::Return(ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));
1459
1460 scoped_refptr<X509Certificate> chain = leaf->GetX509Certificate();
1461 ASSERT_TRUE(chain.get());
1462
1463 {
1464 CertVerifyResult verify_result;
1465 NetLogSource verify_net_log_source;
1466 TestCompletionCallback callback;
1467 Verify(chain.get(), "www.example.com", /*ocsp_response=*/std::string(),
1468 kSctList, /*flags=*/0, &verify_result, &verify_net_log_source,
1469 callback.callback());
1470
1471 int error = callback.WaitForResult();
1472 EXPECT_THAT(error, IsOk());
1473 ASSERT_EQ(verify_result.scts.size(), 2u);
1474 }
1475
1476 // Try again with the SctAllAfter set to the same time as one of the SCTs.
1477 // Verification should now fail.
1478 SetMockChromeRootConstraints({{.sct_all_after = t1}});
1479 {
1480 CertVerifyResult verify_result;
1481 NetLogSource verify_net_log_source;
1482 TestCompletionCallback callback;
1483 Verify(chain.get(), "www.example.com", /*ocsp_response=*/std::string(),
1484 kSctList, /*flags=*/0, &verify_result, &verify_net_log_source,
1485 callback.callback());
1486
1487 int error = callback.WaitForResult();
1488 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
1489 ASSERT_EQ(verify_result.scts.size(), 2u);
1490 }
1491 }
1492
CurVersionString()1493 std::string CurVersionString() {
1494 return version_info::GetVersion().GetString();
1495 }
NextVersionString()1496 std::string NextVersionString() {
1497 const std::vector<uint32_t>& components =
1498 version_info::GetVersion().components();
1499 return base::Version(
1500 {components[0], components[1], components[2], components[3] + 1})
1501 .GetString();
1502 }
PrevVersionString()1503 std::string PrevVersionString() {
1504 const std::vector<uint32_t>& components =
1505 version_info::GetVersion().components();
1506 if (components[3] > 0) {
1507 return base::Version(
1508 {components[0], components[1], components[2], components[3] - 1})
1509 .GetString();
1510 } else {
1511 return base::Version(
1512 {components[0], components[1], components[2] - 1, UINT32_MAX})
1513 .GetString();
1514 }
1515 }
1516
TEST_F(CertVerifyProcBuiltinTest,ChromeRootStoreConstraintMinVersion)1517 TEST_F(CertVerifyProcBuiltinTest, ChromeRootStoreConstraintMinVersion) {
1518 auto [leaf, root] = CertBuilder::CreateSimpleChain2();
1519 InitializeVerifyProc(CreateParams(
1520 /*additional_trust_anchors=*/{root->GetX509Certificate()}));
1521 scoped_refptr<X509Certificate> chain = leaf->GetX509Certificate();
1522 ASSERT_TRUE(chain.get());
1523
1524 SetMockChromeRootConstraints({{.min_version = NextVersionString()}});
1525 {
1526 CertVerifyResult verify_result;
1527 NetLogSource verify_net_log_source;
1528 TestCompletionCallback callback;
1529 Verify(chain.get(), "www.example.com",
1530 /*flags=*/0, &verify_result, &verify_net_log_source,
1531 callback.callback());
1532
1533 int error = callback.WaitForResult();
1534 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
1535 }
1536
1537 SetMockChromeRootConstraints({{.min_version = CurVersionString()}});
1538 {
1539 CertVerifyResult verify_result;
1540 NetLogSource verify_net_log_source;
1541 TestCompletionCallback callback;
1542 Verify(chain.get(), "www.example.com",
1543 /*flags=*/0, &verify_result, &verify_net_log_source,
1544 callback.callback());
1545
1546 int error = callback.WaitForResult();
1547 EXPECT_THAT(error, IsOk());
1548 }
1549 }
1550
TEST_F(CertVerifyProcBuiltinTest,ChromeRootStoreConstraintMaxVersion)1551 TEST_F(CertVerifyProcBuiltinTest, ChromeRootStoreConstraintMaxVersion) {
1552 auto [leaf, root] = CertBuilder::CreateSimpleChain2();
1553 InitializeVerifyProc(CreateParams(
1554 /*additional_trust_anchors=*/{root->GetX509Certificate()}));
1555 scoped_refptr<X509Certificate> chain = leaf->GetX509Certificate();
1556 ASSERT_TRUE(chain.get());
1557
1558 SetMockChromeRootConstraints({{.max_version_exclusive = CurVersionString()}});
1559 {
1560 CertVerifyResult verify_result;
1561 NetLogSource verify_net_log_source;
1562 TestCompletionCallback callback;
1563 Verify(chain.get(), "www.example.com",
1564 /*flags=*/0, &verify_result, &verify_net_log_source,
1565 callback.callback());
1566
1567 int error = callback.WaitForResult();
1568 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
1569 }
1570
1571 SetMockChromeRootConstraints(
1572 {{.max_version_exclusive = NextVersionString()}});
1573 {
1574 CertVerifyResult verify_result;
1575 NetLogSource verify_net_log_source;
1576 TestCompletionCallback callback;
1577 Verify(chain.get(), "www.example.com",
1578 /*flags=*/0, &verify_result, &verify_net_log_source,
1579 callback.callback());
1580
1581 int error = callback.WaitForResult();
1582 EXPECT_THAT(error, IsOk());
1583 }
1584 }
1585
TEST_F(CertVerifyProcBuiltinTest,ChromeRootStoreConstraintMinAndMaxVersion)1586 TEST_F(CertVerifyProcBuiltinTest, ChromeRootStoreConstraintMinAndMaxVersion) {
1587 auto [leaf, root] = CertBuilder::CreateSimpleChain2();
1588 InitializeVerifyProc(CreateParams(
1589 /*additional_trust_anchors=*/{root->GetX509Certificate()}));
1590 scoped_refptr<X509Certificate> chain = leaf->GetX509Certificate();
1591 ASSERT_TRUE(chain.get());
1592
1593 // min_version satisfied, max_version_exclusive not satisfied = not trusted.
1594 SetMockChromeRootConstraints({{.min_version = PrevVersionString(),
1595 .max_version_exclusive = CurVersionString()}});
1596 {
1597 CertVerifyResult verify_result;
1598 NetLogSource verify_net_log_source;
1599 TestCompletionCallback callback;
1600 Verify(chain.get(), "www.example.com",
1601 /*flags=*/0, &verify_result, &verify_net_log_source,
1602 callback.callback());
1603
1604 int error = callback.WaitForResult();
1605 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
1606 }
1607
1608 // min_version not satisfied, max_version_exclusive satisfied = not trusted.
1609 SetMockChromeRootConstraints(
1610 {{.min_version = NextVersionString(),
1611 .max_version_exclusive = NextVersionString()}});
1612 {
1613 CertVerifyResult verify_result;
1614 NetLogSource verify_net_log_source;
1615 TestCompletionCallback callback;
1616 Verify(chain.get(), "www.example.com",
1617 /*flags=*/0, &verify_result, &verify_net_log_source,
1618 callback.callback());
1619
1620 int error = callback.WaitForResult();
1621 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
1622 }
1623
1624 // min_version satisfied, max_version_exclusive satisfied = trusted.
1625 SetMockChromeRootConstraints(
1626 {{.min_version = CurVersionString(),
1627 .max_version_exclusive = NextVersionString()}});
1628 {
1629 CertVerifyResult verify_result;
1630 NetLogSource verify_net_log_source;
1631 TestCompletionCallback callback;
1632 Verify(chain.get(), "www.example.com",
1633 /*flags=*/0, &verify_result, &verify_net_log_source,
1634 callback.callback());
1635
1636 int error = callback.WaitForResult();
1637 EXPECT_THAT(error, IsOk());
1638 }
1639 }
1640
1641 // Tests multiple constraint objects in the constraints vector. The CRS
1642 // constraints are satisfied if at least one of the constraint objects is
1643 // satisfied.
1644 //
1645 // The first constraint has a SctNotAfter that is before the SCT and thus is
1646 // not satisfied.
1647 // The second constraint has a SctAllAfter set to the same time, which is
1648 // before the certificate SCT, and thus the certificate verification succeeds.
1649 //
1650 // TODO(https://crbug.com/40941039): This test isn't very interesting right
1651 // now. Once more constraint types are added change the test to be more
1652 // realistic of how multiple constraint sets is expected to be used.
TEST_F(CertVerifyProcBuiltinTest,ChromeRootStoreConstraintMultipleConstraints)1653 TEST_F(CertVerifyProcBuiltinTest,
1654 ChromeRootStoreConstraintMultipleConstraints) {
1655 auto [leaf, root] = CertBuilder::CreateSimpleChain2();
1656 InitializeVerifyProc(CreateParams(
1657 /*additional_trust_anchors=*/{root->GetX509Certificate()}));
1658
1659 const std::string kSctList = "SCT list";
1660 const std::string kLog1 = "log1";
1661 base::Time now = base::Time::Now();
1662 base::Time t1 = now - base::Days(2);
1663 base::Time t2 = now - base::Days(1);
1664 SignedCertificateTimestampAndStatusList sct_and_status_list;
1665 sct_and_status_list.emplace_back(MakeSct(t2, kLog1), ct::SCT_STATUS_OK);
1666
1667 EXPECT_CALL(*mock_ct_policy_enforcer(), IsCtEnabled())
1668 .WillRepeatedly(testing::Return(true));
1669 EXPECT_CALL(*mock_ct_verifier(), Verify(_, _, kSctList, _, _))
1670 .WillOnce(testing::SetArgPointee<3>(sct_and_status_list));
1671 EXPECT_CALL(*mock_ct_policy_enforcer(), GetLogDisqualificationTime(kLog1))
1672 .WillRepeatedly(testing::Return(std::nullopt));
1673 EXPECT_CALL(*mock_ct_policy_enforcer(), CheckCompliance(_, _, _))
1674 .WillRepeatedly(
1675 testing::Return(ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));
1676
1677 SetMockChromeRootConstraints({{.sct_not_after = t1}, {.sct_all_after = t1}});
1678
1679 scoped_refptr<X509Certificate> chain = leaf->GetX509Certificate();
1680 ASSERT_TRUE(chain.get());
1681
1682 CertVerifyResult verify_result;
1683 NetLogSource verify_net_log_source;
1684 TestCompletionCallback callback;
1685 Verify(chain.get(), "www.example.com", /*ocsp_response=*/std::string(),
1686 kSctList, /*flags=*/0, &verify_result, &verify_net_log_source,
1687 callback.callback());
1688
1689 int error = callback.WaitForResult();
1690 EXPECT_THAT(error, IsOk());
1691 }
1692 #endif // BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
1693
TEST_F(CertVerifyProcBuiltinTest,DeadlineExceededDuringSyncGetIssuers)1694 TEST_F(CertVerifyProcBuiltinTest, DeadlineExceededDuringSyncGetIssuers) {
1695 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
1696 InitializeVerifyProc(CreateParams(
1697 /*additional_trust_anchors=*/{root->GetX509Certificate()}));
1698
1699 BlockingTrustStore trust_store;
1700 AddTrustStore(&trust_store);
1701
1702 auto intermediate_parsed_cert = bssl::ParsedCertificate::Create(
1703 intermediate->DupCertBuffer(), {}, nullptr);
1704 ASSERT_TRUE(intermediate_parsed_cert);
1705 trust_store.backing_trust_store_.AddCertificateWithUnspecifiedTrust(
1706 intermediate_parsed_cert);
1707
1708 scoped_refptr<X509Certificate> chain = leaf->GetX509Certificate();
1709 ASSERT_TRUE(chain.get());
1710
1711 CertVerifyResult verify_result;
1712 NetLogSource verify_net_log_source;
1713 TestCompletionCallback verify_callback;
1714 Verify(chain.get(), "www.example.com",
1715 /*flags=*/0,
1716 &verify_result, &verify_net_log_source, verify_callback.callback());
1717
1718 // Wait for trust_store.SyncGetIssuersOf to be called.
1719 trust_store.sync_get_issuer_started_event_.Wait();
1720
1721 // Advance the clock past the verifier deadline.
1722 const base::TimeDelta timeout_increment =
1723 GetCertVerifyProcBuiltinTimeLimitForTesting() + base::Milliseconds(1);
1724 task_environment().AdvanceClock(timeout_increment);
1725
1726 // Signal trust_store.SyncGetIssuersOf to finish.
1727 trust_store.sync_get_issuer_ok_to_finish_event_.Signal();
1728
1729 int error = verify_callback.WaitForResult();
1730 // Because the deadline was reached while retrieving the intermediate, path
1731 // building should have stopped there and not found the root. The partial
1732 // path built up to that point should be returned, and the error should be
1733 // CERT_AUTHORITY_INVALID.
1734 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
1735 ASSERT_EQ(1u, verify_result.verified_cert->intermediate_buffers().size());
1736 EXPECT_EQ(intermediate->GetCertBuffer(),
1737 verify_result.verified_cert->intermediate_buffers()[0].get());
1738 }
1739
1740 namespace {
1741
1742 // Returns a TLV to use as an unknown signature algorithm when building a cert.
1743 // The specific contents are as follows (the OID is from
1744 // https://davidben.net/oid):
1745 //
1746 // SEQUENCE {
1747 // OBJECT_IDENTIFIER { 1.2.840.113554.4.1.72585.0 }
1748 // NULL {}
1749 // }
UnknownSignatureAlgorithmTLV()1750 std::string UnknownSignatureAlgorithmTLV() {
1751 const uint8_t kInvalidSignatureAlgorithmTLV[] = {
1752 0x30, 0x10, 0x06, 0x0c, 0x2a, 0x86, 0x48, 0x86, 0xf7,
1753 0x12, 0x04, 0x01, 0x84, 0xb7, 0x09, 0x00, 0x05, 0x00};
1754 return std::string(std::begin(kInvalidSignatureAlgorithmTLV),
1755 std::end(kInvalidSignatureAlgorithmTLV));
1756 }
1757
1758 // Returns a TLV to use as an invalid signature algorithm when building a cert.
1759 // This is a SEQUENCE so that it will pass the bssl::ParseCertificate code
1760 // and fail inside bssl::ParseSignatureAlgorithm.
1761 // SEQUENCE {
1762 // INTEGER { 42 }
1763 // }
InvalidSignatureAlgorithmTLV()1764 std::string InvalidSignatureAlgorithmTLV() {
1765 const uint8_t kInvalidSignatureAlgorithmTLV[] = {0x30, 0x03, 0x02, 0x01,
1766 0x2a};
1767 return std::string(std::begin(kInvalidSignatureAlgorithmTLV),
1768 std::end(kInvalidSignatureAlgorithmTLV));
1769 }
1770
1771 } // namespace
1772
TEST_F(CertVerifyProcBuiltinTest,UnknownSignatureAlgorithmTarget)1773 TEST_F(CertVerifyProcBuiltinTest, UnknownSignatureAlgorithmTarget) {
1774 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
1775 leaf->SetSignatureAlgorithmTLV(UnknownSignatureAlgorithmTLV());
1776
1777 // Trust the root and build a chain to verify that includes the intermediate.
1778 ScopedTestRoot scoped_root(root->GetX509Certificate());
1779 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
1780 ASSERT_TRUE(chain.get());
1781
1782 int flags = 0;
1783 CertVerifyResult verify_result;
1784 NetLogSource verify_net_log_source;
1785 TestCompletionCallback callback;
1786 Verify(chain.get(), "www.example.com", flags, &verify_result,
1787 &verify_net_log_source, callback.callback());
1788 int error = callback.WaitForResult();
1789 // Unknown signature algorithm in the leaf cert should result in the cert
1790 // being invalid.
1791 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_INVALID);
1792 EXPECT_THAT(error, IsError(ERR_CERT_INVALID));
1793 }
1794
TEST_F(CertVerifyProcBuiltinTest,UnparsableMismatchedTBSSignatureAlgorithmTarget)1795 TEST_F(CertVerifyProcBuiltinTest,
1796 UnparsableMismatchedTBSSignatureAlgorithmTarget) {
1797 auto [leaf, root] = CertBuilder::CreateSimpleChain2();
1798 // Set only the tbsCertificate signature to an invalid value.
1799 leaf->SetTBSSignatureAlgorithmTLV(InvalidSignatureAlgorithmTLV());
1800
1801 // Trust the root and build a chain to verify.
1802 ScopedTestRoot scoped_root(root->GetX509Certificate());
1803 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
1804 ASSERT_TRUE(chain.get());
1805
1806 int flags = 0;
1807 CertVerifyResult verify_result;
1808 NetLogSource verify_net_log_source;
1809 TestCompletionCallback callback;
1810 Verify(chain.get(), "www.example.com", flags, &verify_result,
1811 &verify_net_log_source, callback.callback());
1812 int error = callback.WaitForResult();
1813 // Invalid signature algorithm in the leaf cert should result in the
1814 // cert being invalid.
1815 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_INVALID);
1816 EXPECT_THAT(error, IsError(ERR_CERT_INVALID));
1817 }
1818
TEST_F(CertVerifyProcBuiltinTest,UnknownSignatureAlgorithmIntermediate)1819 TEST_F(CertVerifyProcBuiltinTest, UnknownSignatureAlgorithmIntermediate) {
1820 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
1821 intermediate->SetSignatureAlgorithmTLV(UnknownSignatureAlgorithmTLV());
1822
1823 // Trust the root and build a chain to verify that includes the intermediate.
1824 ScopedTestRoot scoped_root(root->GetX509Certificate());
1825 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
1826 ASSERT_TRUE(chain.get());
1827
1828 int flags = 0;
1829 CertVerifyResult verify_result;
1830 NetLogSource verify_net_log_source;
1831 TestCompletionCallback callback;
1832 Verify(chain.get(), "www.example.com", flags, &verify_result,
1833 &verify_net_log_source, callback.callback());
1834 int error = callback.WaitForResult();
1835 // Unknown signature algorithm in the intermediate cert should result in the
1836 // cert being invalid.
1837 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_INVALID);
1838 EXPECT_THAT(error, IsError(ERR_CERT_INVALID));
1839 }
1840
TEST_F(CertVerifyProcBuiltinTest,UnparsableMismatchedTBSSignatureAlgorithmIntermediate)1841 TEST_F(CertVerifyProcBuiltinTest,
1842 UnparsableMismatchedTBSSignatureAlgorithmIntermediate) {
1843 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
1844 // Set only the tbsCertificate signature to an invalid value.
1845 intermediate->SetTBSSignatureAlgorithmTLV(InvalidSignatureAlgorithmTLV());
1846
1847 // Trust the root and build a chain to verify that includes the intermediate.
1848 ScopedTestRoot scoped_root(root->GetX509Certificate());
1849 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
1850 ASSERT_TRUE(chain.get());
1851 ASSERT_EQ(chain->intermediate_buffers().size(), 1U);
1852
1853 int flags = 0;
1854 CertVerifyResult verify_result;
1855 NetLogSource verify_net_log_source;
1856 TestCompletionCallback callback;
1857 Verify(chain.get(), "www.example.com", flags, &verify_result,
1858 &verify_net_log_source, callback.callback());
1859 int error = callback.WaitForResult();
1860 // Invalid signature algorithm in the intermediate cert should result in the
1861 // cert being invalid.
1862 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_INVALID);
1863 EXPECT_THAT(error, IsError(ERR_CERT_INVALID));
1864 }
1865
TEST_F(CertVerifyProcBuiltinTest,UnknownSignatureAlgorithmRoot)1866 TEST_F(CertVerifyProcBuiltinTest, UnknownSignatureAlgorithmRoot) {
1867 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
1868 root->SetSignatureAlgorithmTLV(UnknownSignatureAlgorithmTLV());
1869
1870 // Trust the root and build a chain to verify that includes the intermediate.
1871 ScopedTestRoot scoped_root(root->GetX509Certificate());
1872 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
1873 ASSERT_TRUE(chain.get());
1874
1875 int flags = 0;
1876 CertVerifyResult verify_result;
1877 NetLogSource verify_net_log_source;
1878 TestCompletionCallback callback;
1879 Verify(chain.get(), "www.example.com", flags, &verify_result,
1880 &verify_net_log_source, callback.callback());
1881 int error = callback.WaitForResult();
1882 // Unknown signature algorithm in the root cert should have no effect on
1883 // verification.
1884 EXPECT_THAT(error, IsOk());
1885 }
1886
1887 // This test is disabled on Android as adding the invalid root through
1888 // ScopedTestRoot causes it to be parsed by the Java X509 code which barfs. We
1889 // could re-enable if Chrome on Android has fully switched to the
1890 // builtin-verifier and ScopedTestRoot no longer has Android-specific code.
1891 #if BUILDFLAG(IS_ANDROID)
1892 #define MAYBE_UnparsableMismatchedTBSSignatureAlgorithmRoot \
1893 DISABLED_UnparsableMismatchedTBSSignatureAlgorithmRoot
1894 #else
1895 #define MAYBE_UnparsableMismatchedTBSSignatureAlgorithmRoot \
1896 UnparsableMismatchedTBSSignatureAlgorithmRoot
1897 #endif
TEST_F(CertVerifyProcBuiltinTest,MAYBE_UnparsableMismatchedTBSSignatureAlgorithmRoot)1898 TEST_F(CertVerifyProcBuiltinTest,
1899 MAYBE_UnparsableMismatchedTBSSignatureAlgorithmRoot) {
1900 auto [leaf, intermediate, root] = CertBuilder::CreateSimpleChain3();
1901 // Set only the tbsCertificate signature to an invalid value.
1902 root->SetTBSSignatureAlgorithmTLV(InvalidSignatureAlgorithmTLV());
1903
1904 // Trust the root and build a chain to verify that includes the intermediate.
1905 ScopedTestRoot scoped_root(root->GetX509Certificate());
1906 scoped_refptr<X509Certificate> chain = leaf->GetX509CertificateChain();
1907 ASSERT_TRUE(chain.get());
1908
1909 int flags = 0;
1910 CertVerifyResult verify_result;
1911 NetLogSource verify_net_log_source;
1912 TestCompletionCallback callback;
1913 Verify(chain.get(), "www.example.com", flags, &verify_result,
1914 &verify_net_log_source, callback.callback());
1915 int error = callback.WaitForResult();
1916 // Invalid signature algorithm in the root cert should have no effect on
1917 // verification.
1918 EXPECT_THAT(error, IsOk());
1919 }
1920
TEST_F(CertVerifyProcBuiltinTest,IterationLimit)1921 TEST_F(CertVerifyProcBuiltinTest, IterationLimit) {
1922 // Create a chain which will require many iterations in the path builder.
1923 std::vector<std::unique_ptr<CertBuilder>> builders =
1924 CertBuilder::CreateSimpleChain(6);
1925
1926 base::Time not_before = base::Time::Now() - base::Days(1);
1927 base::Time not_after = base::Time::Now() + base::Days(1);
1928 for (auto& builder : builders) {
1929 builder->SetValidity(not_before, not_after);
1930 }
1931
1932 // Generate certificates, making two versions of each intermediate.
1933 std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
1934 for (size_t i = 1; i < builders.size(); i++) {
1935 intermediates.push_back(builders[i]->DupCertBuffer());
1936 builders[i]->SetValidity(not_before, not_after + base::Seconds(1));
1937 intermediates.push_back(builders[i]->DupCertBuffer());
1938 }
1939
1940 // The above alone is enough to make the path builder explore many paths, but
1941 // it will always return the best path it has found, so the error will be the
1942 // same. Instead, arrange for all those paths to be invalid (untrusted root),
1943 // and add a separate chain that is valid.
1944 CertBuilder root_ok(/*orig_cert=*/builders[2]->GetCertBuffer(),
1945 /*issuer=*/nullptr);
1946 CertBuilder intermediate_ok(/*orig_cert=*/builders[1]->GetCertBuffer(),
1947 /*issuer=*/&root_ok);
1948 // Using the old intermediate as a template does not preserve the subject,
1949 // SKID, or key.
1950 intermediate_ok.SetSubjectTLV(base::as_byte_span(builders[1]->GetSubject()));
1951 intermediate_ok.SetKey(bssl::UpRef(builders[1]->GetKey()));
1952 intermediate_ok.SetSubjectKeyIdentifier(
1953 builders[1]->GetSubjectKeyIdentifier());
1954 // Make the valid intermediate older than the invalid ones, so that it is
1955 // explored last.
1956 intermediate_ok.SetValidity(not_before - base::Seconds(10),
1957 not_after - base::Seconds(10));
1958 intermediates.push_back(intermediate_ok.DupCertBuffer());
1959
1960 // Verify the chain.
1961 ScopedTestRoot scoped_root(root_ok.GetX509Certificate().get());
1962 scoped_refptr<X509Certificate> chain = X509Certificate::CreateFromBuffer(
1963 builders[0]->DupCertBuffer(), std::move(intermediates));
1964 ASSERT_TRUE(chain.get());
1965
1966 RecordingNetLogObserver net_log_observer(NetLogCaptureMode::kDefault);
1967 int flags = 0;
1968 CertVerifyResult verify_result;
1969 NetLogSource verify_net_log_source;
1970 TestCompletionCallback callback;
1971 Verify(chain.get(), "www.example.com", flags, &verify_result,
1972 &verify_net_log_source, callback.callback());
1973 int error = callback.WaitForResult();
1974
1975 auto events = net_log_observer.GetEntriesForSource(verify_net_log_source);
1976 auto event = base::ranges::find_if(events, [](const NetLogEntry& e) {
1977 return e.type == NetLogEventType::CERT_VERIFY_PROC_PATH_BUILD_ATTEMPT &&
1978 e.phase == NetLogEventPhase::END;
1979 });
1980 ASSERT_NE(event, events.end());
1981
1982 // The path builder gives up before it finishes all the invalid paths.
1983 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_AUTHORITY_INVALID);
1984 EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID));
1985 EXPECT_EQ(true, event->params.FindBool("exceeded_iteration_limit"));
1986 }
1987
1988 } // namespace net
1989