1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/cert/trial_comparison_cert_verifier.h"
6
7 #include <utility>
8 #include <vector>
9
10 #include "base/bind.h"
11 #include "base/test/bind.h"
12 #include "base/test/metrics/histogram_tester.h"
13 #include "base/threading/sequenced_task_runner_handle.h"
14 #include "build/build_config.h"
15 #include "crypto/sha2.h"
16 #include "net/base/test_completion_callback.h"
17 #include "net/cert/cert_verify_proc.h"
18 #include "net/cert/cert_verify_result.h"
19 #include "net/cert/ev_root_ca_metadata.h"
20 #include "net/cert/x509_certificate.h"
21 #include "net/cert/x509_util.h"
22 #include "net/log/net_log_with_source.h"
23 #include "net/test/cert_test_util.h"
24 #include "net/test/gtest_util.h"
25 #include "net/test/test_data_directory.h"
26 #include "net/test/test_with_task_environment.h"
27 #include "testing/gmock/include/gmock/gmock.h"
28 #include "testing/gtest/include/gtest/gtest.h"
29
30 using net::test::IsError;
31 using net::test::IsOk;
32 using testing::_;
33 using testing::DoAll;
34 using testing::Return;
35 using testing::SetArgPointee;
36
37 namespace net {
38
39 namespace {
40
41 MATCHER_P(CertChainMatches, expected_cert, "") {
42 CertificateList actual_certs =
43 X509Certificate::CreateCertificateListFromBytes(
44 arg.data(), arg.size(), X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
45 if (actual_certs.empty()) {
46 *result_listener << "failed to parse arg";
47 return false;
48 }
49 std::vector<std::string> actual_der_certs;
50 for (const auto& cert : actual_certs) {
51 actual_der_certs.emplace_back(
52 x509_util::CryptoBufferAsStringPiece(cert->cert_buffer()));
53 }
54
55 std::vector<std::string> expected_der_certs;
56 expected_der_certs.emplace_back(
57 x509_util::CryptoBufferAsStringPiece(expected_cert->cert_buffer()));
58 for (const auto& buffer : expected_cert->intermediate_buffers()) {
59 expected_der_certs.emplace_back(
60 x509_util::CryptoBufferAsStringPiece(buffer.get()));
61 }
62
63 return actual_der_certs == expected_der_certs;
64 }
65
66 // Like TestClosure, but handles multiple closure.Run()/WaitForResult()
67 // calls correctly regardless of ordering.
68 class RepeatedTestClosure {
69 public:
RepeatedTestClosure()70 RepeatedTestClosure()
71 : closure_(base::BindRepeating(&RepeatedTestClosure::DidSetResult,
72 base::Unretained(this))) {}
73
closure() const74 const base::RepeatingClosure& closure() const { return closure_; }
75
WaitForResult()76 void WaitForResult() {
77 DCHECK(!run_loop_);
78 if (!have_result_) {
79 run_loop_.reset(new base::RunLoop());
80 run_loop_->Run();
81 run_loop_.reset();
82 DCHECK(have_result_);
83 }
84 have_result_--; // Auto-reset for next callback.
85 }
86
87 private:
DidSetResult()88 void DidSetResult() {
89 have_result_++;
90 if (run_loop_)
91 run_loop_->Quit();
92 }
93
94 // RunLoop. Only non-NULL during the call to WaitForResult, so the class is
95 // reusable.
96 std::unique_ptr<base::RunLoop> run_loop_;
97
98 unsigned int have_result_ = 0;
99
100 base::RepeatingClosure closure_;
101 };
102
103 // Fake CertVerifyProc that sets the CertVerifyResult to a given value for
104 // all certificates that are Verify()'d
105 class FakeCertVerifyProc : public CertVerifyProc {
106 public:
FakeCertVerifyProc(const int result_error,const CertVerifyResult & result)107 FakeCertVerifyProc(const int result_error, const CertVerifyResult& result)
108 : result_error_(result_error),
109 result_(result),
110 main_task_runner_(base::SequencedTaskRunnerHandle::Get()) {}
111
WaitForVerifyCall()112 void WaitForVerifyCall() { verify_called_.WaitForResult(); }
num_verifications() const113 int num_verifications() const { return num_verifications_; }
114
115 // CertVerifyProc implementation:
SupportsAdditionalTrustAnchors() const116 bool SupportsAdditionalTrustAnchors() const override { return false; }
117
118 protected:
119 ~FakeCertVerifyProc() override = default;
120
121 private:
122 int VerifyInternal(X509Certificate* cert,
123 const std::string& hostname,
124 const std::string& ocsp_response,
125 const std::string& sct_list,
126 int flags,
127 CRLSet* crl_set,
128 const CertificateList& additional_trust_anchors,
129 CertVerifyResult* verify_result,
130 const NetLogWithSource& net_log) override;
131
132 // Runs on the main thread
133 void VerifyCalled();
134
135 const int result_error_;
136 const CertVerifyResult result_;
137 int num_verifications_ = 0;
138 RepeatedTestClosure verify_called_;
139 scoped_refptr<base::TaskRunner> main_task_runner_;
140
141 DISALLOW_COPY_AND_ASSIGN(FakeCertVerifyProc);
142 };
143
VerifyInternal(X509Certificate * cert,const std::string & hostname,const std::string & ocsp_response,const std::string & sct_list,int flags,CRLSet * crl_set,const CertificateList & additional_trust_anchors,CertVerifyResult * verify_result,const NetLogWithSource & net_log)144 int FakeCertVerifyProc::VerifyInternal(
145 X509Certificate* cert,
146 const std::string& hostname,
147 const std::string& ocsp_response,
148 const std::string& sct_list,
149 int flags,
150 CRLSet* crl_set,
151 const CertificateList& additional_trust_anchors,
152 CertVerifyResult* verify_result,
153 const NetLogWithSource& net_log) {
154 *verify_result = result_;
155 main_task_runner_->PostTask(
156 FROM_HERE, base::BindOnce(&FakeCertVerifyProc::VerifyCalled, this));
157 return result_error_;
158 }
159
VerifyCalled()160 void FakeCertVerifyProc::VerifyCalled() {
161 ++num_verifications_;
162 verify_called_.closure().Run();
163 }
164
165 // Fake CertVerifyProc that causes a failure if it is called.
166 class NotCalledCertVerifyProc : public CertVerifyProc {
167 public:
168 NotCalledCertVerifyProc() = default;
169
170 // CertVerifyProc implementation:
SupportsAdditionalTrustAnchors() const171 bool SupportsAdditionalTrustAnchors() const override { return false; }
172
173 protected:
174 ~NotCalledCertVerifyProc() override = default;
175
176 private:
177 int VerifyInternal(X509Certificate* cert,
178 const std::string& hostname,
179 const std::string& ocsp_response,
180 const std::string& sct_list,
181 int flags,
182 CRLSet* crl_set,
183 const CertificateList& additional_trust_anchors,
184 CertVerifyResult* verify_result,
185 const NetLogWithSource& net_log) override;
186
187 DISALLOW_COPY_AND_ASSIGN(NotCalledCertVerifyProc);
188 };
189
VerifyInternal(X509Certificate * cert,const std::string & hostname,const std::string & ocsp_response,const std::string & sct_list,int flags,CRLSet * crl_set,const CertificateList & additional_trust_anchors,CertVerifyResult * verify_result,const NetLogWithSource & net_log)190 int NotCalledCertVerifyProc::VerifyInternal(
191 X509Certificate* cert,
192 const std::string& hostname,
193 const std::string& ocsp_response,
194 const std::string& sct_list,
195 int flags,
196 CRLSet* crl_set,
197 const CertificateList& additional_trust_anchors,
198 CertVerifyResult* verify_result,
199 const NetLogWithSource& net_log) {
200 ADD_FAILURE() << "NotCalledCertVerifyProc was called!";
201 return ERR_UNEXPECTED;
202 }
203
NotCalledCallback(int error)204 void NotCalledCallback(int error) {
205 ADD_FAILURE() << "NotCalledCallback was called with error code " << error;
206 }
207
208 class MockCertVerifyProc : public CertVerifyProc {
209 public:
210 MockCertVerifyProc() = default;
211 // CertVerifyProc implementation:
SupportsAdditionalTrustAnchors() const212 bool SupportsAdditionalTrustAnchors() const override { return false; }
213 MOCK_METHOD9(VerifyInternal,
214 int(X509Certificate* cert,
215 const std::string& hostname,
216 const std::string& ocsp_response,
217 const std::string& sct_list,
218 int flags,
219 CRLSet* crl_set,
220 const CertificateList& additional_trust_anchors,
221 CertVerifyResult* verify_result,
222 const NetLogWithSource& net_log));
223
224 protected:
225 ~MockCertVerifyProc() override = default;
226
227 DISALLOW_COPY_AND_ASSIGN(MockCertVerifyProc);
228 };
229
230 struct TrialReportInfo {
TrialReportInfonet::__anon7a71c6290111::TrialReportInfo231 TrialReportInfo(const std::string& hostname,
232 const scoped_refptr<X509Certificate>& unverified_cert,
233 bool enable_rev_checking,
234 bool require_rev_checking_local_anchors,
235 bool enable_sha1_local_anchors,
236 bool disable_symantec_enforcement,
237 const std::string& stapled_ocsp,
238 const std::string& sct_list,
239 const CertVerifyResult& primary_result,
240 const CertVerifyResult& trial_result)
241 : hostname(hostname),
242 unverified_cert(unverified_cert),
243 enable_rev_checking(enable_rev_checking),
244 require_rev_checking_local_anchors(require_rev_checking_local_anchors),
245 enable_sha1_local_anchors(enable_sha1_local_anchors),
246 disable_symantec_enforcement(disable_symantec_enforcement),
247 stapled_ocsp(stapled_ocsp),
248 sct_list(sct_list),
249 primary_result(primary_result),
250 trial_result(trial_result) {}
251
252 std::string hostname;
253 scoped_refptr<X509Certificate> unverified_cert;
254 bool enable_rev_checking;
255 bool require_rev_checking_local_anchors;
256 bool enable_sha1_local_anchors;
257 bool disable_symantec_enforcement;
258 std::string stapled_ocsp;
259 std::string sct_list;
260 CertVerifyResult primary_result;
261 CertVerifyResult trial_result;
262 };
263
RecordTrialReport(std::vector<TrialReportInfo> * reports,const std::string & hostname,const scoped_refptr<X509Certificate> & unverified_cert,bool enable_rev_checking,bool require_rev_checking_local_anchors,bool enable_sha1_local_anchors,bool disable_symantec_enforcement,const std::string & stapled_ocsp,const std::string & sct_list,const CertVerifyResult & primary_result,const CertVerifyResult & trial_result)264 void RecordTrialReport(std::vector<TrialReportInfo>* reports,
265 const std::string& hostname,
266 const scoped_refptr<X509Certificate>& unverified_cert,
267 bool enable_rev_checking,
268 bool require_rev_checking_local_anchors,
269 bool enable_sha1_local_anchors,
270 bool disable_symantec_enforcement,
271 const std::string& stapled_ocsp,
272 const std::string& sct_list,
273 const CertVerifyResult& primary_result,
274 const CertVerifyResult& trial_result) {
275 TrialReportInfo report(hostname, unverified_cert, enable_rev_checking,
276 require_rev_checking_local_anchors,
277 enable_sha1_local_anchors,
278 disable_symantec_enforcement, stapled_ocsp, sct_list,
279 primary_result, trial_result);
280 reports->push_back(report);
281 }
282
283 } // namespace
284
285 class TrialComparisonCertVerifierTest : public TestWithTaskEnvironment {
SetUp()286 void SetUp() override {
287 cert_chain_1_ = CreateCertificateChainFromFile(
288 GetTestCertsDirectory(), "multi-root-chain1.pem",
289 X509Certificate::FORMAT_AUTO);
290 ASSERT_TRUE(cert_chain_1_);
291 leaf_cert_1_ = X509Certificate::CreateFromBuffer(
292 bssl::UpRef(cert_chain_1_->cert_buffer()), {});
293 ASSERT_TRUE(leaf_cert_1_);
294 cert_chain_2_ = CreateCertificateChainFromFile(
295 GetTestCertsDirectory(), "multi-root-chain2.pem",
296 X509Certificate::FORMAT_AUTO);
297 ASSERT_TRUE(cert_chain_2_);
298 }
299
300 protected:
301 scoped_refptr<X509Certificate> cert_chain_1_;
302 scoped_refptr<X509Certificate> cert_chain_2_;
303 scoped_refptr<X509Certificate> leaf_cert_1_;
304 base::HistogramTester histograms_;
305 };
306
TEST_F(TrialComparisonCertVerifierTest,InitiallyDisallowed)307 TEST_F(TrialComparisonCertVerifierTest, InitiallyDisallowed) {
308 CertVerifyResult dummy_result;
309 dummy_result.verified_cert = cert_chain_1_;
310
311 auto verify_proc = base::MakeRefCounted<FakeCertVerifyProc>(OK, dummy_result);
312 std::vector<TrialReportInfo> reports;
313 TrialComparisonCertVerifier verifier(
314 verify_proc, base::MakeRefCounted<NotCalledCertVerifyProc>(),
315 base::BindRepeating(&RecordTrialReport, &reports));
316 CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0,
317 /*ocsp_response=*/std::string(),
318 /*sct_list=*/std::string());
319 CertVerifyResult result;
320 TestCompletionCallback callback;
321 std::unique_ptr<CertVerifier::Request> request;
322 int error = verifier.Verify(params, &result, callback.callback(), &request,
323 NetLogWithSource());
324 ASSERT_THAT(error, IsError(ERR_IO_PENDING));
325 EXPECT_TRUE(request);
326
327 error = callback.WaitForResult();
328 EXPECT_THAT(error, IsOk());
329
330 RunUntilIdle();
331
332 // Expect no report.
333 EXPECT_TRUE(reports.empty());
334
335 // Primary verifier should have ran, trial verifier should not have.
336 EXPECT_EQ(1, verify_proc->num_verifications());
337 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 0);
338 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary",
339 0);
340 histograms_.ExpectTotalCount("Net.CertVerifier_TrialComparisonResult", 0);
341 }
342
TEST_F(TrialComparisonCertVerifierTest,InitiallyDisallowedThenAllowed)343 TEST_F(TrialComparisonCertVerifierTest, InitiallyDisallowedThenAllowed) {
344 // Certificate that has multiple subjectAltName entries. This allows easily
345 // confirming which verification attempt the report was generated for without
346 // having to mock different CertVerifyProc results for each.
347 base::FilePath certs_dir =
348 GetTestNetDataDirectory()
349 .AppendASCII("verify_certificate_chain_unittest")
350 .AppendASCII("many-names");
351 scoped_refptr<X509Certificate> cert_chain = CreateCertificateChainFromFile(
352 certs_dir, "ok-all-types.pem", X509Certificate::FORMAT_AUTO);
353 ASSERT_TRUE(cert_chain);
354 ASSERT_EQ(2U, cert_chain->intermediate_buffers().size());
355
356 scoped_refptr<X509Certificate> leaf = X509Certificate::CreateFromBuffer(
357 bssl::UpRef(cert_chain->cert_buffer()), {});
358 ASSERT_TRUE(leaf);
359
360 CertVerifyResult primary_result;
361 primary_result.verified_cert = cert_chain;
362 scoped_refptr<FakeCertVerifyProc> verify_proc1 =
363 base::MakeRefCounted<FakeCertVerifyProc>(OK, primary_result);
364
365 // Trial verifier returns an error status.
366 CertVerifyResult secondary_result;
367 secondary_result.cert_status = CERT_STATUS_DATE_INVALID;
368 secondary_result.verified_cert = cert_chain;
369 scoped_refptr<FakeCertVerifyProc> verify_proc2 =
370 base::MakeRefCounted<FakeCertVerifyProc>(ERR_CERT_DATE_INVALID,
371 secondary_result);
372
373 std::vector<TrialReportInfo> reports;
374 TrialComparisonCertVerifier verifier(
375 verify_proc1, verify_proc2,
376 base::BindRepeating(&RecordTrialReport, &reports));
377
378 CertVerifier::RequestParams params(leaf, "t0.test", /*flags=*/0,
379 /*ocsp_response=*/std::string(),
380 /*sct_list=*/std::string());
381 CertVerifyResult result;
382 TestCompletionCallback callback;
383 std::unique_ptr<CertVerifier::Request> request;
384 int error = verifier.Verify(params, &result, callback.callback(), &request,
385 NetLogWithSource());
386 ASSERT_THAT(error, IsError(ERR_IO_PENDING));
387 EXPECT_TRUE(request);
388 error = callback.WaitForResult();
389 EXPECT_THAT(error, IsOk());
390
391 // Enable the trial and do another verification.
392 verifier.set_trial_allowed(true);
393 CertVerifier::RequestParams params2(leaf, "t1.test", /*flags=*/0,
394 /*ocsp_response=*/std::string(),
395 /*sct_list=*/std::string());
396 CertVerifyResult result2;
397 TestCompletionCallback callback2;
398 std::unique_ptr<CertVerifier::Request> request2;
399 error = verifier.Verify(params2, &result2, callback2.callback(), &request2,
400 NetLogWithSource());
401 ASSERT_THAT(error, IsError(ERR_IO_PENDING));
402 EXPECT_TRUE(request2);
403
404 error = callback2.WaitForResult();
405 EXPECT_THAT(error, IsOk());
406
407 verify_proc2->WaitForVerifyCall();
408 RunUntilIdle();
409
410 // Primary verifier should have run twice, trial verifier should run once.
411 EXPECT_EQ(2, verify_proc1->num_verifications());
412 EXPECT_EQ(1, verify_proc2->num_verifications());
413 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 1);
414 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary",
415 1);
416 histograms_.ExpectUniqueSample(
417 "Net.CertVerifier_TrialComparisonResult",
418 TrialComparisonCertVerifier::kPrimaryValidSecondaryError, 1);
419
420 // Expect a report from the second verification.
421 ASSERT_EQ(1U, reports.size());
422 const TrialReportInfo& report = reports[0];
423 EXPECT_EQ("t1.test", report.hostname);
424 }
425
TEST_F(TrialComparisonCertVerifierTest,InitiallyAllowedThenDisallowed)426 TEST_F(TrialComparisonCertVerifierTest, InitiallyAllowedThenDisallowed) {
427 // Certificate that has multiple subjectAltName entries. This allows easily
428 // confirming which verification attempt the report was generated for without
429 // having to mock different CertVerifyProc results for each.
430 base::FilePath certs_dir =
431 GetTestNetDataDirectory()
432 .AppendASCII("verify_certificate_chain_unittest")
433 .AppendASCII("many-names");
434 scoped_refptr<X509Certificate> cert_chain = CreateCertificateChainFromFile(
435 certs_dir, "ok-all-types.pem", X509Certificate::FORMAT_AUTO);
436 ASSERT_TRUE(cert_chain);
437 ASSERT_EQ(2U, cert_chain->intermediate_buffers().size());
438
439 scoped_refptr<X509Certificate> leaf = X509Certificate::CreateFromBuffer(
440 bssl::UpRef(cert_chain->cert_buffer()), {});
441 ASSERT_TRUE(leaf);
442
443 CertVerifyResult primary_result;
444 primary_result.verified_cert = cert_chain;
445 scoped_refptr<FakeCertVerifyProc> verify_proc1 =
446 base::MakeRefCounted<FakeCertVerifyProc>(OK, primary_result);
447
448 // Trial verifier returns an error status.
449 CertVerifyResult secondary_result;
450 secondary_result.cert_status = CERT_STATUS_DATE_INVALID;
451 secondary_result.verified_cert = cert_chain;
452 scoped_refptr<FakeCertVerifyProc> verify_proc2 =
453 base::MakeRefCounted<FakeCertVerifyProc>(ERR_CERT_DATE_INVALID,
454 secondary_result);
455
456 std::vector<TrialReportInfo> reports;
457 TrialComparisonCertVerifier verifier(
458 verify_proc1, verify_proc2,
459 base::BindRepeating(&RecordTrialReport, &reports));
460 verifier.set_trial_allowed(true);
461
462 CertVerifier::RequestParams params(leaf, "t0.test", /*flags=*/0,
463 /*ocsp_response=*/std::string(),
464 /*sct_list=*/std::string());
465 CertVerifyResult result;
466 TestCompletionCallback callback;
467 std::unique_ptr<CertVerifier::Request> request;
468 int error = verifier.Verify(params, &result, callback.callback(), &request,
469 NetLogWithSource());
470 ASSERT_THAT(error, IsError(ERR_IO_PENDING));
471 EXPECT_TRUE(request);
472 error = callback.WaitForResult();
473 EXPECT_THAT(error, IsOk());
474
475 // Disable the trial and do another verification.
476 verifier.set_trial_allowed(false);
477 CertVerifier::RequestParams params2(leaf, "t1.test", /*flags=*/0,
478 /*ocsp_response=*/std::string(),
479 /*sct_list=*/std::string());
480 CertVerifyResult result2;
481 TestCompletionCallback callback2;
482 std::unique_ptr<CertVerifier::Request> request2;
483 error = verifier.Verify(params2, &result2, callback2.callback(), &request2,
484 NetLogWithSource());
485 ASSERT_THAT(error, IsError(ERR_IO_PENDING));
486 EXPECT_TRUE(request2);
487
488 error = callback2.WaitForResult();
489 EXPECT_THAT(error, IsOk());
490
491 verify_proc2->WaitForVerifyCall();
492 RunUntilIdle();
493
494 // Primary verifier should have run twice, trial verifier should run once.
495 EXPECT_EQ(2, verify_proc1->num_verifications());
496 EXPECT_EQ(1, verify_proc2->num_verifications());
497 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 1);
498 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary",
499 1);
500 histograms_.ExpectUniqueSample(
501 "Net.CertVerifier_TrialComparisonResult",
502 TrialComparisonCertVerifier::kPrimaryValidSecondaryError, 1);
503
504 // Expect a report from the first verification.
505 ASSERT_EQ(1U, reports.size());
506 const TrialReportInfo& report = reports[0];
507 EXPECT_EQ("t0.test", report.hostname);
508 }
509
TEST_F(TrialComparisonCertVerifierTest,ConfigChangedDuringPrimaryVerification)510 TEST_F(TrialComparisonCertVerifierTest,
511 ConfigChangedDuringPrimaryVerification) {
512 CertVerifyResult primary_result;
513 primary_result.verified_cert = cert_chain_1_;
514 scoped_refptr<FakeCertVerifyProc> verify_proc1 =
515 base::MakeRefCounted<FakeCertVerifyProc>(OK, primary_result);
516
517 std::vector<TrialReportInfo> reports;
518 TrialComparisonCertVerifier verifier(
519 verify_proc1, base::MakeRefCounted<NotCalledCertVerifyProc>(),
520 base::BindRepeating(&RecordTrialReport, &reports));
521 verifier.set_trial_allowed(true);
522
523 CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0,
524 /*ocsp_response=*/std::string(),
525 /*sct_list=*/std::string());
526 CertVerifyResult result;
527 TestCompletionCallback callback;
528 std::unique_ptr<CertVerifier::Request> request;
529 int error = verifier.Verify(params, &result, callback.callback(), &request,
530 NetLogWithSource());
531 ASSERT_THAT(error, IsError(ERR_IO_PENDING));
532 EXPECT_TRUE(request);
533
534 // Change the verifier config before the primary verification finishes.
535 CertVerifier::Config config;
536 config.enable_sha1_local_anchors = true;
537 verifier.SetConfig(config);
538
539 error = callback.WaitForResult();
540 EXPECT_THAT(error, IsOk());
541
542 RunUntilIdle();
543
544 // Since the config changed, trial verifier should not run.
545 EXPECT_EQ(1, verify_proc1->num_verifications());
546 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 0);
547 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary",
548 0);
549 histograms_.ExpectTotalCount("Net.CertVerifier_TrialComparisonResult", 0);
550
551 // Expect no report.
552 EXPECT_TRUE(reports.empty());
553 }
554
TEST_F(TrialComparisonCertVerifierTest,ConfigChangedDuringTrialVerification)555 TEST_F(TrialComparisonCertVerifierTest, ConfigChangedDuringTrialVerification) {
556 CertVerifyResult primary_result;
557 primary_result.verified_cert = cert_chain_1_;
558 scoped_refptr<FakeCertVerifyProc> verify_proc1 =
559 base::MakeRefCounted<FakeCertVerifyProc>(OK, primary_result);
560
561 // Trial verifier returns an error status.
562 CertVerifyResult secondary_result;
563 secondary_result.cert_status = CERT_STATUS_DATE_INVALID;
564 secondary_result.verified_cert = cert_chain_1_;
565 scoped_refptr<FakeCertVerifyProc> verify_proc2 =
566 base::MakeRefCounted<FakeCertVerifyProc>(ERR_CERT_DATE_INVALID,
567 secondary_result);
568
569 std::vector<TrialReportInfo> reports;
570 TrialComparisonCertVerifier verifier(
571 verify_proc1, verify_proc2,
572 base::BindRepeating(&RecordTrialReport, &reports));
573 verifier.set_trial_allowed(true);
574
575 CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0,
576 /*ocsp_response=*/std::string(),
577 /*sct_list=*/std::string());
578 CertVerifyResult result;
579 TestCompletionCallback callback;
580 std::unique_ptr<CertVerifier::Request> request;
581 int error = verifier.Verify(params, &result, callback.callback(), &request,
582 NetLogWithSource());
583 ASSERT_THAT(error, IsError(ERR_IO_PENDING));
584 EXPECT_TRUE(request);
585
586 error = callback.WaitForResult();
587 EXPECT_THAT(error, IsOk());
588
589 // Change the verifier config during the trial verification.
590 CertVerifier::Config config;
591 config.enable_sha1_local_anchors = true;
592 verifier.SetConfig(config);
593
594 RunUntilIdle();
595
596 // Since the config was the same when both primary and trial verification
597 // started, the result should still be reported.
598 EXPECT_EQ(1, verify_proc1->num_verifications());
599 EXPECT_EQ(1, verify_proc2->num_verifications());
600 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 1);
601 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary",
602 1);
603 histograms_.ExpectUniqueSample(
604 "Net.CertVerifier_TrialComparisonResult",
605 TrialComparisonCertVerifier::kPrimaryValidSecondaryError, 1);
606
607 // Expect a report.
608 ASSERT_EQ(1U, reports.size());
609 const TrialReportInfo& report = reports[0];
610
611 EXPECT_EQ(0U, report.primary_result.cert_status);
612 EXPECT_EQ(CERT_STATUS_DATE_INVALID, report.trial_result.cert_status);
613 }
614
TEST_F(TrialComparisonCertVerifierTest,SameResult)615 TEST_F(TrialComparisonCertVerifierTest, SameResult) {
616 CertVerifyResult dummy_result;
617 dummy_result.verified_cert = cert_chain_1_;
618 scoped_refptr<FakeCertVerifyProc> verify_proc1 =
619 base::MakeRefCounted<FakeCertVerifyProc>(OK, dummy_result);
620 scoped_refptr<FakeCertVerifyProc> verify_proc2 =
621 base::MakeRefCounted<FakeCertVerifyProc>(OK, dummy_result);
622
623 std::vector<TrialReportInfo> reports;
624 TrialComparisonCertVerifier verifier(
625 verify_proc1, verify_proc2,
626 base::BindRepeating(&RecordTrialReport, &reports));
627 verifier.set_trial_allowed(true);
628
629 CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0,
630 /*ocsp_response=*/std::string(),
631 /*sct_list=*/std::string());
632 CertVerifyResult result;
633 TestCompletionCallback callback;
634 std::unique_ptr<CertVerifier::Request> request;
635 int error = verifier.Verify(params, &result, callback.callback(), &request,
636 NetLogWithSource());
637 ASSERT_THAT(error, IsError(ERR_IO_PENDING));
638 EXPECT_TRUE(request);
639
640 error = callback.WaitForResult();
641 EXPECT_THAT(error, IsOk());
642
643 verify_proc2->WaitForVerifyCall();
644 RunUntilIdle();
645
646 // Expect no report.
647 EXPECT_TRUE(reports.empty());
648
649 EXPECT_EQ(1, verify_proc1->num_verifications());
650 EXPECT_EQ(1, verify_proc2->num_verifications());
651 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 1);
652 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary",
653 1);
654 histograms_.ExpectUniqueSample("Net.CertVerifier_TrialComparisonResult",
655 TrialComparisonCertVerifier::kEqual, 1);
656 }
657
TEST_F(TrialComparisonCertVerifierTest,PrimaryVerifierErrorSecondaryOk)658 TEST_F(TrialComparisonCertVerifierTest, PrimaryVerifierErrorSecondaryOk) {
659 // Primary verifier returns an error status.
660 CertVerifyResult primary_result;
661 primary_result.verified_cert = cert_chain_1_;
662 primary_result.cert_status = CERT_STATUS_DATE_INVALID;
663 scoped_refptr<FakeCertVerifyProc> verify_proc1 =
664 base::MakeRefCounted<FakeCertVerifyProc>(ERR_CERT_DATE_INVALID,
665 primary_result);
666
667 CertVerifyResult secondary_result;
668 secondary_result.verified_cert = cert_chain_1_;
669 scoped_refptr<FakeCertVerifyProc> verify_proc2 =
670 base::MakeRefCounted<FakeCertVerifyProc>(OK, secondary_result);
671
672 std::vector<TrialReportInfo> reports;
673 TrialComparisonCertVerifier verifier(
674 verify_proc1, verify_proc2,
675 base::BindRepeating(&RecordTrialReport, &reports));
676 verifier.set_trial_allowed(true);
677
678 CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0,
679 /*ocsp_response=*/std::string(),
680 /*sct_list=*/std::string());
681 CertVerifyResult result;
682 TestCompletionCallback callback;
683 std::unique_ptr<CertVerifier::Request> request;
684 int error = verifier.Verify(params, &result, callback.callback(), &request,
685 NetLogWithSource());
686 ASSERT_THAT(error, IsError(ERR_IO_PENDING));
687 EXPECT_TRUE(request);
688
689 error = callback.WaitForResult();
690 EXPECT_THAT(error, IsError(ERR_CERT_DATE_INVALID));
691
692 verify_proc2->WaitForVerifyCall();
693 RunUntilIdle();
694
695 // Expect a report.
696 ASSERT_EQ(1U, reports.size());
697 const TrialReportInfo& report = reports[0];
698
699 EXPECT_EQ(CERT_STATUS_DATE_INVALID, report.primary_result.cert_status);
700 EXPECT_EQ(0U, report.trial_result.cert_status);
701
702 EXPECT_TRUE(report.primary_result.verified_cert->EqualsIncludingChain(
703 cert_chain_1_.get()));
704 EXPECT_TRUE(report.trial_result.verified_cert->EqualsIncludingChain(
705 cert_chain_1_.get()));
706 EXPECT_TRUE(report.unverified_cert->EqualsIncludingChain(leaf_cert_1_.get()));
707
708 EXPECT_FALSE(report.enable_rev_checking);
709 EXPECT_FALSE(report.require_rev_checking_local_anchors);
710 EXPECT_FALSE(report.enable_sha1_local_anchors);
711 EXPECT_FALSE(report.disable_symantec_enforcement);
712
713 EXPECT_EQ(1, verify_proc1->num_verifications());
714 EXPECT_EQ(1, verify_proc2->num_verifications());
715 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 1);
716 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary",
717 1);
718 histograms_.ExpectUniqueSample(
719 "Net.CertVerifier_TrialComparisonResult",
720 TrialComparisonCertVerifier::kPrimaryErrorSecondaryValid, 1);
721 }
722
TEST_F(TrialComparisonCertVerifierTest,PrimaryVerifierOkSecondaryError)723 TEST_F(TrialComparisonCertVerifierTest, PrimaryVerifierOkSecondaryError) {
724 CertVerifyResult primary_result;
725 primary_result.verified_cert = cert_chain_1_;
726 scoped_refptr<FakeCertVerifyProc> verify_proc1 =
727 base::MakeRefCounted<FakeCertVerifyProc>(OK, primary_result);
728
729 // Trial verifier returns an error status.
730 CertVerifyResult secondary_result;
731 secondary_result.cert_status = CERT_STATUS_DATE_INVALID;
732 secondary_result.verified_cert = cert_chain_1_;
733 scoped_refptr<FakeCertVerifyProc> verify_proc2 =
734 base::MakeRefCounted<FakeCertVerifyProc>(ERR_CERT_DATE_INVALID,
735 secondary_result);
736
737 std::vector<TrialReportInfo> reports;
738 TrialComparisonCertVerifier verifier(
739 verify_proc1, verify_proc2,
740 base::BindRepeating(&RecordTrialReport, &reports));
741 verifier.set_trial_allowed(true);
742
743 CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0,
744 "ocsp", "sct");
745 CertVerifyResult result;
746 TestCompletionCallback callback;
747 std::unique_ptr<CertVerifier::Request> request;
748 int error = verifier.Verify(params, &result, callback.callback(), &request,
749 NetLogWithSource());
750 ASSERT_THAT(error, IsError(ERR_IO_PENDING));
751 EXPECT_TRUE(request);
752
753 error = callback.WaitForResult();
754 EXPECT_THAT(error, IsOk());
755
756 verify_proc2->WaitForVerifyCall();
757 RunUntilIdle();
758
759 // Expect a report.
760 ASSERT_EQ(1U, reports.size());
761 const TrialReportInfo& report = reports[0];
762
763 EXPECT_EQ(0U, report.primary_result.cert_status);
764 EXPECT_EQ(CERT_STATUS_DATE_INVALID, report.trial_result.cert_status);
765
766 EXPECT_TRUE(report.primary_result.verified_cert->EqualsIncludingChain(
767 cert_chain_1_.get()));
768 EXPECT_TRUE(report.trial_result.verified_cert->EqualsIncludingChain(
769 cert_chain_1_.get()));
770 EXPECT_TRUE(report.unverified_cert->EqualsIncludingChain(leaf_cert_1_.get()));
771 EXPECT_EQ("ocsp", report.stapled_ocsp);
772 EXPECT_EQ("sct", report.sct_list);
773
774 EXPECT_EQ(1, verify_proc1->num_verifications());
775 EXPECT_EQ(1, verify_proc2->num_verifications());
776 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 1);
777 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary",
778 1);
779 histograms_.ExpectUniqueSample(
780 "Net.CertVerifier_TrialComparisonResult",
781 TrialComparisonCertVerifier::kPrimaryValidSecondaryError, 1);
782 }
783
TEST_F(TrialComparisonCertVerifierTest,BothVerifiersDifferentErrors)784 TEST_F(TrialComparisonCertVerifierTest, BothVerifiersDifferentErrors) {
785 // Primary verifier returns an error status.
786 CertVerifyResult primary_result;
787 primary_result.cert_status = CERT_STATUS_VALIDITY_TOO_LONG;
788 primary_result.verified_cert = cert_chain_1_;
789 scoped_refptr<FakeCertVerifyProc> verify_proc1 =
790 base::MakeRefCounted<FakeCertVerifyProc>(ERR_CERT_VALIDITY_TOO_LONG,
791 primary_result);
792
793 // Trial verifier returns a different error status.
794 CertVerifyResult secondary_result;
795 secondary_result.cert_status = CERT_STATUS_DATE_INVALID;
796 secondary_result.verified_cert = cert_chain_1_;
797 scoped_refptr<FakeCertVerifyProc> verify_proc2 =
798 base::MakeRefCounted<FakeCertVerifyProc>(ERR_CERT_DATE_INVALID,
799 secondary_result);
800
801 std::vector<TrialReportInfo> reports;
802 TrialComparisonCertVerifier verifier(
803 verify_proc1, verify_proc2,
804 base::BindRepeating(&RecordTrialReport, &reports));
805 verifier.set_trial_allowed(true);
806
807 CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0,
808 /*ocsp_response=*/std::string(),
809 /*sct_list=*/std::string());
810 CertVerifyResult result;
811 TestCompletionCallback callback;
812 std::unique_ptr<CertVerifier::Request> request;
813 int error = verifier.Verify(params, &result, callback.callback(), &request,
814 NetLogWithSource());
815 ASSERT_THAT(error, IsError(ERR_IO_PENDING));
816 EXPECT_TRUE(request);
817
818 error = callback.WaitForResult();
819 EXPECT_THAT(error, IsError(ERR_CERT_VALIDITY_TOO_LONG));
820
821 verify_proc2->WaitForVerifyCall();
822 RunUntilIdle();
823
824 // Expect a report.
825 ASSERT_EQ(1U, reports.size());
826 const TrialReportInfo& report = reports[0];
827
828 EXPECT_EQ(CERT_STATUS_VALIDITY_TOO_LONG, report.primary_result.cert_status);
829 EXPECT_EQ(CERT_STATUS_DATE_INVALID, report.trial_result.cert_status);
830
831 EXPECT_TRUE(report.primary_result.verified_cert->EqualsIncludingChain(
832 cert_chain_1_.get()));
833 EXPECT_TRUE(report.trial_result.verified_cert->EqualsIncludingChain(
834 cert_chain_1_.get()));
835 EXPECT_TRUE(report.unverified_cert->EqualsIncludingChain(leaf_cert_1_.get()));
836
837 EXPECT_EQ(1, verify_proc1->num_verifications());
838 EXPECT_EQ(1, verify_proc2->num_verifications());
839 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 1);
840 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary",
841 1);
842 histograms_.ExpectUniqueSample(
843 "Net.CertVerifier_TrialComparisonResult",
844 TrialComparisonCertVerifier::kBothErrorDifferentDetails, 1);
845 }
846
TEST_F(TrialComparisonCertVerifierTest,BothVerifiersOkDifferentVerifiedChains)847 TEST_F(TrialComparisonCertVerifierTest,
848 BothVerifiersOkDifferentVerifiedChains) {
849 // Primary verifier returns chain1 regardless of arguments.
850 CertVerifyResult primary_result;
851 primary_result.verified_cert = cert_chain_1_;
852 scoped_refptr<FakeCertVerifyProc> verify_proc1 =
853 base::MakeRefCounted<FakeCertVerifyProc>(OK, primary_result);
854
855 // Trial verifier returns a different verified cert chain.
856 CertVerifyResult secondary_result;
857 secondary_result.verified_cert = cert_chain_2_;
858 scoped_refptr<FakeCertVerifyProc> verify_proc2 =
859 base::MakeRefCounted<FakeCertVerifyProc>(OK, secondary_result);
860
861 std::vector<TrialReportInfo> reports;
862 TrialComparisonCertVerifier verifier(
863 verify_proc1, verify_proc2,
864 base::BindRepeating(&RecordTrialReport, &reports));
865 verifier.set_trial_allowed(true);
866
867 CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0,
868 /*ocsp_response=*/std::string(),
869 /*sct_list=*/std::string());
870 CertVerifyResult result;
871 TestCompletionCallback callback;
872 std::unique_ptr<CertVerifier::Request> request;
873 int error = verifier.Verify(params, &result, callback.callback(), &request,
874 NetLogWithSource());
875 ASSERT_THAT(error, IsError(ERR_IO_PENDING));
876 EXPECT_TRUE(request);
877
878 error = callback.WaitForResult();
879 EXPECT_THAT(error, IsOk());
880
881 verify_proc2->WaitForVerifyCall();
882 RunUntilIdle();
883
884 // Expect a report.
885 ASSERT_EQ(1U, reports.size());
886 const TrialReportInfo& report = reports[0];
887
888 EXPECT_EQ(0U, report.primary_result.cert_status);
889 EXPECT_EQ(0U, report.trial_result.cert_status);
890
891 EXPECT_TRUE(report.primary_result.verified_cert->EqualsIncludingChain(
892 cert_chain_1_.get()));
893 EXPECT_TRUE(report.trial_result.verified_cert->EqualsIncludingChain(
894 cert_chain_2_.get()));
895 EXPECT_TRUE(report.unverified_cert->EqualsIncludingChain(leaf_cert_1_.get()));
896
897 // The primary verifier should be used twice (first with the initial chain,
898 // then with the results of the trial verifier).
899 EXPECT_EQ(2, verify_proc1->num_verifications());
900 EXPECT_EQ(1, verify_proc2->num_verifications());
901 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 1);
902 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary",
903 1);
904 histograms_.ExpectUniqueSample(
905 "Net.CertVerifier_TrialComparisonResult",
906 TrialComparisonCertVerifier::kBothValidDifferentDetails, 1);
907 }
908
TEST_F(TrialComparisonCertVerifierTest,DifferentVerifiedChainsAndConfigHasChanged)909 TEST_F(TrialComparisonCertVerifierTest,
910 DifferentVerifiedChainsAndConfigHasChanged) {
911 // Primary verifier returns chain1 regardless of arguments.
912 CertVerifyResult primary_result;
913 primary_result.verified_cert = cert_chain_1_;
914 scoped_refptr<FakeCertVerifyProc> verify_proc1 =
915 base::MakeRefCounted<FakeCertVerifyProc>(ERR_CERT_REVOKED,
916 primary_result);
917
918 // Trial verifier returns a different verified cert chain.
919 CertVerifyResult secondary_result;
920 secondary_result.verified_cert = cert_chain_2_;
921 scoped_refptr<FakeCertVerifyProc> verify_proc2 =
922 base::MakeRefCounted<FakeCertVerifyProc>(OK, secondary_result);
923
924 std::vector<TrialReportInfo> reports;
925 TrialComparisonCertVerifier verifier(
926 verify_proc1, verify_proc2,
927 base::BindRepeating(&RecordTrialReport, &reports));
928 verifier.set_trial_allowed(true);
929
930 CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0,
931 /*ocsp_response=*/std::string(),
932 /*sct_list=*/std::string());
933 CertVerifyResult result;
934 TestCompletionCallback callback;
935 std::unique_ptr<CertVerifier::Request> request;
936 int error = verifier.Verify(params, &result, callback.callback(), &request,
937 NetLogWithSource());
938 ASSERT_THAT(error, IsError(ERR_IO_PENDING));
939 EXPECT_TRUE(request);
940
941 error = callback.WaitForResult();
942 EXPECT_THAT(error, IsError(ERR_CERT_REVOKED));
943
944 // Change the configuration. The trial verification should complete, but
945 // the difference in verified chains should prevent a trial reverification.
946 CertVerifier::Config config;
947 config.enable_sha1_local_anchors = true;
948 verifier.SetConfig(config);
949
950 verify_proc2->WaitForVerifyCall();
951 RunUntilIdle();
952
953 // Expect no report, since the configuration changed and the primary
954 // verifier could not be used to retry.
955 ASSERT_EQ(0U, reports.size());
956
957 // The primary verifier should only be used once, as the configuration
958 // changes after the trial verification is started.
959 EXPECT_EQ(1, verify_proc1->num_verifications());
960 EXPECT_EQ(1, verify_proc2->num_verifications());
961 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 1);
962 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary",
963 1);
964 histograms_.ExpectUniqueSample(
965 "Net.CertVerifier_TrialComparisonResult",
966 TrialComparisonCertVerifier::kIgnoredConfigurationChanged, 1);
967 }
968
TEST_F(TrialComparisonCertVerifierTest,BothVerifiersOkDifferentVerifiedChainsEqualAfterReverification)969 TEST_F(TrialComparisonCertVerifierTest,
970 BothVerifiersOkDifferentVerifiedChainsEqualAfterReverification) {
971 CertVerifyResult chain1_result;
972 chain1_result.verified_cert = cert_chain_1_;
973 CertVerifyResult chain2_result;
974 chain2_result.verified_cert = cert_chain_2_;
975
976 scoped_refptr<MockCertVerifyProc> verify_proc1 =
977 base::MakeRefCounted<MockCertVerifyProc>();
978 // Primary verifier returns ok status and chain1 if verifying the leaf alone.
979 EXPECT_CALL(*verify_proc1,
980 VerifyInternal(leaf_cert_1_.get(), _, _, _, _, _, _, _, _))
981 .WillOnce(DoAll(SetArgPointee<7>(chain1_result), Return(OK)));
982 // Primary verifier returns ok status and chain2 if verifying chain2.
983 EXPECT_CALL(*verify_proc1,
984 VerifyInternal(cert_chain_2_.get(), _, _, _, _, _, _, _, _))
985 .WillOnce(DoAll(SetArgPointee<7>(chain2_result), Return(OK)));
986
987 // Trial verifier returns ok status and chain2.
988 scoped_refptr<FakeCertVerifyProc> verify_proc2 =
989 base::MakeRefCounted<FakeCertVerifyProc>(OK, chain2_result);
990
991 std::vector<TrialReportInfo> reports;
992 TrialComparisonCertVerifier verifier(
993 verify_proc1, verify_proc2,
994 base::BindRepeating(&RecordTrialReport, &reports));
995 verifier.set_trial_allowed(true);
996
997 CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0,
998 /*ocsp_response=*/std::string(),
999 /*sct_list=*/std::string());
1000 CertVerifyResult result;
1001 TestCompletionCallback callback;
1002 std::unique_ptr<CertVerifier::Request> request;
1003 int error = verifier.Verify(params, &result, callback.callback(), &request,
1004 NetLogWithSource());
1005 ASSERT_THAT(error, IsError(ERR_IO_PENDING));
1006 EXPECT_TRUE(request);
1007
1008 error = callback.WaitForResult();
1009 EXPECT_THAT(error, IsOk());
1010
1011 verify_proc2->WaitForVerifyCall();
1012 RunUntilIdle();
1013
1014 // Expect no report.
1015 EXPECT_TRUE(reports.empty());
1016
1017 testing::Mock::VerifyAndClear(verify_proc1.get());
1018 EXPECT_EQ(1, verify_proc2->num_verifications());
1019 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 1);
1020 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary",
1021 1);
1022 histograms_.ExpectUniqueSample(
1023 "Net.CertVerifier_TrialComparisonResult",
1024 TrialComparisonCertVerifier::kIgnoredDifferentPathReVerifiesEquivalent,
1025 1);
1026 }
1027
TEST_F(TrialComparisonCertVerifierTest,DifferentVerifiedChainsIgnorableDifferenceAfterReverification)1028 TEST_F(TrialComparisonCertVerifierTest,
1029 DifferentVerifiedChainsIgnorableDifferenceAfterReverification) {
1030 base::FilePath certs_dir =
1031 GetTestNetDataDirectory()
1032 .AppendASCII("trial_comparison_cert_verifier_unittest")
1033 .AppendASCII("target-multiple-policies");
1034 scoped_refptr<X509Certificate> cert_chain = CreateCertificateChainFromFile(
1035 certs_dir, "chain.pem", X509Certificate::FORMAT_AUTO);
1036 ASSERT_TRUE(cert_chain);
1037 ASSERT_EQ(2U, cert_chain->intermediate_buffers().size());
1038
1039 scoped_refptr<X509Certificate> leaf = X509Certificate::CreateFromBuffer(
1040 bssl::UpRef(cert_chain->cert_buffer()), {});
1041 ASSERT_TRUE(leaf);
1042
1043 // Chain with the same leaf and different root. This is not a valid chain, but
1044 // doesn't matter for the unittest since this uses mock CertVerifyProcs.
1045 std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
1046 intermediates.push_back(
1047 bssl::UpRef(cert_chain_1_->intermediate_buffers().back().get()));
1048 scoped_refptr<X509Certificate> different_chain =
1049 X509Certificate::CreateFromBuffer(bssl::UpRef(cert_chain->cert_buffer()),
1050 std::move(intermediates));
1051 ASSERT_TRUE(different_chain);
1052
1053 CertVerifyResult different_chain_result;
1054 different_chain_result.verified_cert = different_chain;
1055
1056 CertVerifyResult nonev_chain_result;
1057 nonev_chain_result.verified_cert = cert_chain;
1058
1059 CertVerifyResult ev_chain_result;
1060 ev_chain_result.verified_cert = cert_chain;
1061 ev_chain_result.cert_status =
1062 CERT_STATUS_IS_EV | CERT_STATUS_REV_CHECKING_ENABLED;
1063
1064 SHA256HashValue root_fingerprint;
1065 crypto::SHA256HashString(x509_util::CryptoBufferAsStringPiece(
1066 cert_chain->intermediate_buffers().back().get()),
1067 root_fingerprint.data,
1068 sizeof(root_fingerprint.data));
1069 // Both policies in the target are EV policies, but only 1.2.6.7 is valid for
1070 // the root in cert_chain.
1071 ScopedTestEVPolicy scoped_ev_policy_1(EVRootCAMetadata::GetInstance(),
1072 root_fingerprint, "1.2.6.7");
1073 ScopedTestEVPolicy scoped_ev_policy_2(EVRootCAMetadata::GetInstance(),
1074 SHA256HashValue(), "1.2.3.4");
1075
1076 scoped_refptr<MockCertVerifyProc> verify_proc1 =
1077 base::MakeRefCounted<MockCertVerifyProc>();
1078 // Primary verifier returns ok status and different_chain if verifying leaf
1079 // alone.
1080 EXPECT_CALL(*verify_proc1, VerifyInternal(leaf.get(), _, _, _, _, _, _, _, _))
1081 .WillOnce(DoAll(SetArgPointee<7>(different_chain_result), Return(OK)));
1082 // Primary verifier returns ok status and nonev_chain_result if verifying
1083 // cert_chain.
1084 EXPECT_CALL(*verify_proc1,
1085 VerifyInternal(cert_chain.get(), _, _, _, _, _, _, _, _))
1086 .WillOnce(DoAll(SetArgPointee<7>(nonev_chain_result), Return(OK)));
1087
1088 // Trial verifier returns ok status and ev_chain_result.
1089 scoped_refptr<FakeCertVerifyProc> verify_proc2 =
1090 base::MakeRefCounted<FakeCertVerifyProc>(OK, ev_chain_result);
1091
1092 std::vector<TrialReportInfo> reports;
1093 TrialComparisonCertVerifier verifier(
1094 verify_proc1, verify_proc2,
1095 base::BindRepeating(&RecordTrialReport, &reports));
1096 verifier.set_trial_allowed(true);
1097
1098 CertVerifier::RequestParams params(leaf, "test.example", /*flags=*/0,
1099 /*ocsp_response=*/std::string(),
1100 /*sct_list=*/std::string());
1101 CertVerifyResult result;
1102 TestCompletionCallback callback;
1103 std::unique_ptr<CertVerifier::Request> request;
1104 int error = verifier.Verify(params, &result, callback.callback(), &request,
1105 NetLogWithSource());
1106 ASSERT_THAT(error, IsError(ERR_IO_PENDING));
1107 EXPECT_TRUE(request);
1108
1109 error = callback.WaitForResult();
1110 EXPECT_THAT(error, IsOk());
1111
1112 verify_proc2->WaitForVerifyCall();
1113 RunUntilIdle();
1114
1115 // Expect no report.
1116 EXPECT_TRUE(reports.empty());
1117
1118 // Primary verifier should be used twice, the second time with the chain
1119 // from the trial verifier.
1120 testing::Mock::VerifyAndClear(verify_proc1.get());
1121 EXPECT_EQ(1, verify_proc2->num_verifications());
1122 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 1);
1123 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary",
1124 1);
1125 histograms_.ExpectUniqueSample(
1126 "Net.CertVerifier_TrialComparisonResult",
1127 TrialComparisonCertVerifier::kIgnoredDifferentPathReVerifiesEquivalent,
1128 1);
1129 }
1130
TEST_F(TrialComparisonCertVerifierTest,BothVerifiersOkDifferentCertStatus)1131 TEST_F(TrialComparisonCertVerifierTest, BothVerifiersOkDifferentCertStatus) {
1132 CertVerifyResult primary_result;
1133 primary_result.verified_cert = cert_chain_1_;
1134 primary_result.cert_status =
1135 CERT_STATUS_IS_EV | CERT_STATUS_REV_CHECKING_ENABLED;
1136 scoped_refptr<FakeCertVerifyProc> verify_proc1 =
1137 base::MakeRefCounted<FakeCertVerifyProc>(OK, primary_result);
1138
1139 CertVerifyResult secondary_result;
1140 secondary_result.verified_cert = cert_chain_1_;
1141 secondary_result.cert_status = CERT_STATUS_CT_COMPLIANCE_FAILED;
1142 scoped_refptr<FakeCertVerifyProc> verify_proc2 =
1143 base::MakeRefCounted<FakeCertVerifyProc>(OK, secondary_result);
1144
1145 std::vector<TrialReportInfo> reports;
1146 TrialComparisonCertVerifier verifier(
1147 verify_proc1, verify_proc2,
1148 base::BindRepeating(&RecordTrialReport, &reports));
1149 verifier.set_trial_allowed(true);
1150
1151 CertVerifier::Config config;
1152 config.enable_rev_checking = true;
1153 config.enable_sha1_local_anchors = true;
1154 verifier.SetConfig(config);
1155
1156 CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", 0,
1157 /*ocsp_response=*/std::string(),
1158 /*sct_list=*/std::string());
1159 CertVerifyResult result;
1160 TestCompletionCallback callback;
1161 std::unique_ptr<CertVerifier::Request> request;
1162 int error = verifier.Verify(params, &result, callback.callback(), &request,
1163 NetLogWithSource());
1164 ASSERT_THAT(error, IsError(ERR_IO_PENDING));
1165 EXPECT_TRUE(request);
1166
1167 error = callback.WaitForResult();
1168 EXPECT_THAT(error, IsOk());
1169
1170 verify_proc2->WaitForVerifyCall();
1171 RunUntilIdle();
1172
1173 // Expect a report.
1174 ASSERT_EQ(1U, reports.size());
1175 const TrialReportInfo& report = reports[0];
1176
1177 EXPECT_EQ(CERT_STATUS_IS_EV | CERT_STATUS_REV_CHECKING_ENABLED,
1178 report.primary_result.cert_status);
1179 EXPECT_EQ(CERT_STATUS_CT_COMPLIANCE_FAILED, report.trial_result.cert_status);
1180
1181 EXPECT_TRUE(report.enable_rev_checking);
1182 EXPECT_FALSE(report.require_rev_checking_local_anchors);
1183 EXPECT_TRUE(report.enable_sha1_local_anchors);
1184 EXPECT_FALSE(report.disable_symantec_enforcement);
1185
1186 EXPECT_TRUE(report.primary_result.verified_cert->EqualsIncludingChain(
1187 cert_chain_1_.get()));
1188 EXPECT_TRUE(report.trial_result.verified_cert->EqualsIncludingChain(
1189 cert_chain_1_.get()));
1190 EXPECT_TRUE(report.unverified_cert->EqualsIncludingChain(leaf_cert_1_.get()));
1191
1192 EXPECT_EQ(1, verify_proc1->num_verifications());
1193 EXPECT_EQ(1, verify_proc2->num_verifications());
1194 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 1);
1195 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary",
1196 1);
1197 histograms_.ExpectUniqueSample(
1198 "Net.CertVerifier_TrialComparisonResult",
1199 TrialComparisonCertVerifier::kBothValidDifferentDetails, 1);
1200 }
1201
TEST_F(TrialComparisonCertVerifierTest,CancelledDuringPrimaryVerification)1202 TEST_F(TrialComparisonCertVerifierTest, CancelledDuringPrimaryVerification) {
1203 // Primary verifier returns an error status.
1204 CertVerifyResult primary_result;
1205 primary_result.verified_cert = cert_chain_1_;
1206 primary_result.cert_status = CERT_STATUS_DATE_INVALID;
1207 scoped_refptr<FakeCertVerifyProc> verify_proc1 =
1208 base::MakeRefCounted<FakeCertVerifyProc>(ERR_CERT_DATE_INVALID,
1209 primary_result);
1210
1211 // Trial verifier has ok status.
1212 CertVerifyResult secondary_result;
1213 secondary_result.verified_cert = cert_chain_1_;
1214 scoped_refptr<FakeCertVerifyProc> verify_proc2 =
1215 base::MakeRefCounted<FakeCertVerifyProc>(OK, secondary_result);
1216
1217 std::vector<TrialReportInfo> reports;
1218 TrialComparisonCertVerifier verifier(
1219 verify_proc1, verify_proc2,
1220 base::BindRepeating(&RecordTrialReport, &reports));
1221 verifier.set_trial_allowed(true);
1222
1223 CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0,
1224 /*ocsp_response=*/std::string(),
1225 /*sct_list=*/std::string());
1226 CertVerifyResult result;
1227 std::unique_ptr<CertVerifier::Request> request;
1228 int error =
1229 verifier.Verify(params, &result, base::BindOnce(&NotCalledCallback),
1230 &request, NetLogWithSource());
1231 ASSERT_THAT(error, IsError(ERR_IO_PENDING));
1232 EXPECT_TRUE(request);
1233
1234 // Delete the request, cancelling it.
1235 request.reset();
1236
1237 // The callback to the main verifier does not run. However, the verification
1238 // still completes in the background and triggers the trial verification.
1239
1240 // Trial verifier should still run.
1241 verify_proc2->WaitForVerifyCall();
1242 RunUntilIdle();
1243
1244 // Expect a report.
1245 ASSERT_EQ(1U, reports.size());
1246 const TrialReportInfo& report = reports[0];
1247
1248 EXPECT_EQ(CERT_STATUS_DATE_INVALID, report.primary_result.cert_status);
1249 EXPECT_EQ(0U, report.trial_result.cert_status);
1250
1251 EXPECT_TRUE(report.primary_result.verified_cert->EqualsIncludingChain(
1252 cert_chain_1_.get()));
1253 EXPECT_TRUE(report.trial_result.verified_cert->EqualsIncludingChain(
1254 cert_chain_1_.get()));
1255 EXPECT_TRUE(report.unverified_cert->EqualsIncludingChain(leaf_cert_1_.get()));
1256
1257 EXPECT_EQ(1, verify_proc1->num_verifications());
1258 EXPECT_EQ(1, verify_proc2->num_verifications());
1259 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 1);
1260 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary",
1261 1);
1262 histograms_.ExpectUniqueSample(
1263 "Net.CertVerifier_TrialComparisonResult",
1264 TrialComparisonCertVerifier::kPrimaryErrorSecondaryValid, 1);
1265 }
1266
TEST_F(TrialComparisonCertVerifierTest,DeletedDuringPrimaryVerification)1267 TEST_F(TrialComparisonCertVerifierTest, DeletedDuringPrimaryVerification) {
1268 // Primary verifier returns an error status.
1269 CertVerifyResult primary_result;
1270 primary_result.verified_cert = cert_chain_1_;
1271 primary_result.cert_status = CERT_STATUS_DATE_INVALID;
1272 scoped_refptr<FakeCertVerifyProc> verify_proc1 =
1273 base::MakeRefCounted<FakeCertVerifyProc>(ERR_CERT_DATE_INVALID,
1274 primary_result);
1275
1276 std::vector<TrialReportInfo> reports;
1277 auto verifier = std::make_unique<TrialComparisonCertVerifier>(
1278 verify_proc1, base::MakeRefCounted<NotCalledCertVerifyProc>(),
1279 base::BindRepeating(&RecordTrialReport, &reports));
1280 verifier->set_trial_allowed(true);
1281
1282 CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0,
1283 /*ocsp_response=*/std::string(),
1284 /*sct_list=*/std::string());
1285 CertVerifyResult result;
1286 std::unique_ptr<CertVerifier::Request> request;
1287 int error =
1288 verifier->Verify(params, &result, base::BindOnce(&NotCalledCallback),
1289 &request, NetLogWithSource());
1290 ASSERT_THAT(error, IsError(ERR_IO_PENDING));
1291 EXPECT_TRUE(request);
1292
1293 // Delete the TrialComparisonCertVerifier.
1294 verifier.reset();
1295
1296 // The callback to the main verifier does not run. The verification task
1297 // still completes in the background, but since the CertVerifier has been
1298 // deleted, the result is ignored.
1299
1300 // Wait for any tasks to finish.
1301 RunUntilIdle();
1302
1303 // Expect no report.
1304 EXPECT_TRUE(reports.empty());
1305
1306 // The trial verifier should never be called, nor histograms recorded.
1307 EXPECT_EQ(1, verify_proc1->num_verifications());
1308 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 0);
1309 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary",
1310 0);
1311 histograms_.ExpectTotalCount("Net.CertVerifier_TrialComparisonResult", 0);
1312 }
1313
TEST_F(TrialComparisonCertVerifierTest,DeletedDuringVerificationResult)1314 TEST_F(TrialComparisonCertVerifierTest, DeletedDuringVerificationResult) {
1315 // Primary verifier returns an error status.
1316 CertVerifyResult primary_result;
1317 primary_result.verified_cert = cert_chain_1_;
1318 primary_result.cert_status = CERT_STATUS_DATE_INVALID;
1319 scoped_refptr<FakeCertVerifyProc> verify_proc1 =
1320 base::MakeRefCounted<FakeCertVerifyProc>(ERR_CERT_DATE_INVALID,
1321 primary_result);
1322
1323 std::vector<TrialReportInfo> reports;
1324 auto verifier = std::make_unique<TrialComparisonCertVerifier>(
1325 verify_proc1, base::MakeRefCounted<NotCalledCertVerifyProc>(),
1326 base::BindRepeating(&RecordTrialReport, &reports));
1327 verifier->set_trial_allowed(true);
1328
1329 CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0,
1330 /*ocsp_response=*/std::string(),
1331 /*sct_list=*/std::string());
1332 CertVerifyResult result;
1333 TestCompletionCallback callback;
1334 std::unique_ptr<CertVerifier::Request> request;
1335 int error = verifier->Verify(
1336 params, &result,
1337 base::BindLambdaForTesting([&callback, &verifier](int result) {
1338 // Delete the verifier while processing the result. This should not
1339 // start a trial verification.
1340 verifier.reset();
1341 callback.callback().Run(result);
1342 }),
1343 &request, NetLogWithSource());
1344 ASSERT_THAT(error, IsError(ERR_IO_PENDING));
1345 EXPECT_TRUE(request);
1346
1347 // Wait for primary verifier to finish.
1348 error = callback.WaitForResult();
1349 EXPECT_THAT(error, IsError(ERR_CERT_DATE_INVALID));
1350
1351 // The callback to the trial verifier does not run. No verification task
1352 // should start, as the verifier was deleted before the trial verification
1353 // was started.
1354
1355 // Wait for any tasks to finish.
1356 RunUntilIdle();
1357
1358 // Expect no report.
1359 EXPECT_TRUE(reports.empty());
1360
1361 // Histograms for the primary or trial verification should not be recorded,
1362 // as the trial verification was cancelled by deleting the verifier.
1363 EXPECT_EQ(1, verify_proc1->num_verifications());
1364 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 0);
1365 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary",
1366 0);
1367 histograms_.ExpectTotalCount("Net.CertVerifier_TrialComparisonResult", 0);
1368 }
1369
TEST_F(TrialComparisonCertVerifierTest,DeletedDuringTrialReport)1370 TEST_F(TrialComparisonCertVerifierTest, DeletedDuringTrialReport) {
1371 // Primary verifier returns an error status.
1372 CertVerifyResult primary_result;
1373 primary_result.verified_cert = cert_chain_1_;
1374 primary_result.cert_status = CERT_STATUS_DATE_INVALID;
1375 scoped_refptr<FakeCertVerifyProc> verify_proc1 =
1376 base::MakeRefCounted<FakeCertVerifyProc>(ERR_CERT_DATE_INVALID,
1377 primary_result);
1378
1379 // Trial verifier has ok status.
1380 CertVerifyResult secondary_result;
1381 secondary_result.verified_cert = cert_chain_1_;
1382 scoped_refptr<FakeCertVerifyProc> verify_proc2 =
1383 base::MakeRefCounted<FakeCertVerifyProc>(OK, secondary_result);
1384
1385 bool was_report_callback_called = false;
1386 std::unique_ptr<TrialComparisonCertVerifier> verifier;
1387 verifier = std::make_unique<TrialComparisonCertVerifier>(
1388 verify_proc1, verify_proc2,
1389 base::BindLambdaForTesting(
1390 [&verifier, &was_report_callback_called](
1391 const std::string& hostname,
1392 const scoped_refptr<X509Certificate>& unverified_cert,
1393 bool enable_rev_checking, bool require_rev_checking_local_anchors,
1394 bool enable_sha1_local_anchors, bool disable_symantec_enforcement,
1395 const std::string& stapled_ocsp, const std::string& sct_list,
1396 const net::CertVerifyResult& primary_result,
1397 const net::CertVerifyResult& trial_result) {
1398 // During processing of a report, delete the underlying verifier.
1399 // This should not cause any issues.
1400 was_report_callback_called = true;
1401 verifier.reset();
1402 }));
1403 verifier->set_trial_allowed(true);
1404
1405 CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0,
1406 /*ocsp_response=*/std::string(),
1407 /*sct_list=*/std::string());
1408 CertVerifyResult result;
1409 TestCompletionCallback callback;
1410 std::unique_ptr<CertVerifier::Request> request;
1411 int error = verifier->Verify(params, &result, callback.callback(), &request,
1412 NetLogWithSource());
1413 ASSERT_THAT(error, IsError(ERR_IO_PENDING));
1414 EXPECT_TRUE(request);
1415
1416 // The callback should be notified of the primary result.
1417 ASSERT_THAT(callback.WaitForResult(), IsError(ERR_CERT_DATE_INVALID));
1418
1419 // Wait for the verification task to complete in the background. This
1420 // should ultimately call the ReportCallback that will delete the
1421 // verifier.
1422 RunUntilIdle();
1423
1424 EXPECT_TRUE(was_report_callback_called);
1425
1426 EXPECT_EQ(1, verify_proc1->num_verifications());
1427 EXPECT_EQ(1, verify_proc2->num_verifications());
1428 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 1);
1429 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary",
1430 1);
1431 histograms_.ExpectUniqueSample(
1432 "Net.CertVerifier_TrialComparisonResult",
1433 TrialComparisonCertVerifier::kPrimaryErrorSecondaryValid, 1);
1434 }
1435
TEST_F(TrialComparisonCertVerifierTest,DeletedAfterTrialVerificationStarted)1436 TEST_F(TrialComparisonCertVerifierTest, DeletedAfterTrialVerificationStarted) {
1437 // Primary verifier returns an error status.
1438 CertVerifyResult primary_result;
1439 primary_result.verified_cert = cert_chain_1_;
1440 primary_result.cert_status = CERT_STATUS_DATE_INVALID;
1441 scoped_refptr<FakeCertVerifyProc> verify_proc1 =
1442 base::MakeRefCounted<FakeCertVerifyProc>(ERR_CERT_DATE_INVALID,
1443 primary_result);
1444
1445 // Trial verifier has ok status.
1446 CertVerifyResult secondary_result;
1447 secondary_result.verified_cert = cert_chain_1_;
1448 scoped_refptr<FakeCertVerifyProc> verify_proc2 =
1449 base::MakeRefCounted<FakeCertVerifyProc>(OK, secondary_result);
1450
1451 std::vector<TrialReportInfo> reports;
1452 auto verifier = std::make_unique<TrialComparisonCertVerifier>(
1453 verify_proc1, verify_proc2,
1454 base::BindRepeating(&RecordTrialReport, &reports));
1455 verifier->set_trial_allowed(true);
1456
1457 CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0,
1458 /*ocsp_response=*/std::string(),
1459 /*sct_list=*/std::string());
1460 CertVerifyResult result;
1461 TestCompletionCallback callback;
1462 std::unique_ptr<CertVerifier::Request> request;
1463 int error = verifier->Verify(params, &result, callback.callback(), &request,
1464 NetLogWithSource());
1465 ASSERT_THAT(error, IsError(ERR_IO_PENDING));
1466 EXPECT_TRUE(request);
1467
1468 // Wait for primary verifier to finish.
1469 error = callback.WaitForResult();
1470 EXPECT_THAT(error, IsError(ERR_CERT_DATE_INVALID));
1471
1472 // Delete the TrialComparisonCertVerifier. The trial verification is still
1473 // running on the task scheduler (or, depending on timing, has posted back
1474 // to the IO thread after the Quit event).
1475 verifier.reset();
1476
1477 // The callback to the trial verifier does not run. The verification task
1478 // still completes in the background, but since the CertVerifier has been
1479 // deleted, the result is ignored.
1480
1481 // Wait for any tasks to finish.
1482 RunUntilIdle();
1483
1484 // Expect no report.
1485 EXPECT_TRUE(reports.empty());
1486
1487 EXPECT_EQ(1, verify_proc1->num_verifications());
1488 EXPECT_EQ(1, verify_proc2->num_verifications());
1489 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 1);
1490 // Histograms for trial verifier should not be recorded.
1491 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary",
1492 0);
1493 histograms_.ExpectTotalCount("Net.CertVerifier_TrialComparisonResult", 0);
1494 }
1495
TEST_F(TrialComparisonCertVerifierTest,MacUndesiredRevocationChecking)1496 TEST_F(TrialComparisonCertVerifierTest, MacUndesiredRevocationChecking) {
1497 CertVerifyResult revoked_result;
1498 revoked_result.verified_cert = cert_chain_1_;
1499 revoked_result.cert_status = CERT_STATUS_REVOKED;
1500
1501 CertVerifyResult ok_result;
1502 ok_result.verified_cert = cert_chain_1_;
1503
1504 // Primary verifier returns an error status.
1505 scoped_refptr<FakeCertVerifyProc> verify_proc1 =
1506 base::MakeRefCounted<FakeCertVerifyProc>(ERR_CERT_REVOKED,
1507 revoked_result);
1508
1509 scoped_refptr<MockCertVerifyProc> verify_proc2 =
1510 base::MakeRefCounted<MockCertVerifyProc>();
1511 // Secondary verifier returns ok status...
1512 EXPECT_CALL(*verify_proc2, VerifyInternal(_, _, _, _, _, _, _, _, _))
1513 .WillOnce(DoAll(SetArgPointee<7>(ok_result), Return(OK)));
1514
1515 #if defined(OS_APPLE)
1516 // The secondary should have been called twice on Mac due to attempting
1517 // the kIgnoredMacUndesiredRevocationCheckingWorkaround.
1518 EXPECT_CALL(
1519 *verify_proc2,
1520 VerifyInternal(_, _, _, _, CertVerifyProc::VERIFY_REV_CHECKING_ENABLED, _,
1521 _, _, _))
1522 .WillOnce(
1523 DoAll(SetArgPointee<7>(revoked_result), Return(ERR_CERT_REVOKED)));
1524 #endif
1525
1526 std::vector<TrialReportInfo> reports;
1527 TrialComparisonCertVerifier verifier(
1528 verify_proc1, verify_proc2,
1529 base::BindRepeating(&RecordTrialReport, &reports));
1530 verifier.set_trial_allowed(true);
1531
1532 CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0,
1533 /*ocsp_response=*/std::string(),
1534 /*sct_list=*/std::string());
1535 CertVerifyResult result;
1536 TestCompletionCallback callback;
1537 std::unique_ptr<CertVerifier::Request> request;
1538 int error = verifier.Verify(params, &result, callback.callback(), &request,
1539 NetLogWithSource());
1540 ASSERT_THAT(error, IsError(ERR_IO_PENDING));
1541 EXPECT_TRUE(request);
1542
1543 error = callback.WaitForResult();
1544 EXPECT_THAT(error, IsError(ERR_CERT_REVOKED));
1545
1546 RunUntilIdle();
1547
1548 EXPECT_EQ(1, verify_proc1->num_verifications());
1549 testing::Mock::VerifyAndClear(verify_proc2.get());
1550 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 1);
1551 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary",
1552 1);
1553 #if defined(OS_APPLE)
1554 // Expect no report.
1555 EXPECT_EQ(0U, reports.size());
1556
1557 histograms_.ExpectUniqueSample(
1558 "Net.CertVerifier_TrialComparisonResult",
1559 TrialComparisonCertVerifier::kIgnoredMacUndesiredRevocationChecking, 1);
1560 #else
1561 // Expect a report.
1562 EXPECT_EQ(1U, reports.size());
1563
1564 histograms_.ExpectUniqueSample(
1565 "Net.CertVerifier_TrialComparisonResult",
1566 TrialComparisonCertVerifier::kPrimaryErrorSecondaryValid, 1);
1567 #endif
1568 }
1569
TEST_F(TrialComparisonCertVerifierTest,PrimaryRevokedSecondaryOk)1570 TEST_F(TrialComparisonCertVerifierTest, PrimaryRevokedSecondaryOk) {
1571 CertVerifyResult revoked_result;
1572 revoked_result.verified_cert = cert_chain_1_;
1573 revoked_result.cert_status = CERT_STATUS_REVOKED;
1574
1575 CertVerifyResult ok_result;
1576 ok_result.verified_cert = cert_chain_1_;
1577
1578 // Primary verifier returns an error status.
1579 scoped_refptr<FakeCertVerifyProc> verify_proc1 =
1580 base::MakeRefCounted<FakeCertVerifyProc>(ERR_CERT_REVOKED,
1581 revoked_result);
1582
1583 // Secondary verifier returns ok status regardless of whether
1584 // REV_CHECKING_ENABLED was passed.
1585 scoped_refptr<MockCertVerifyProc> verify_proc2 =
1586 base::MakeRefCounted<MockCertVerifyProc>();
1587 EXPECT_CALL(*verify_proc2, VerifyInternal(_, _, _, _, _, _, _, _, _))
1588 #if defined(OS_APPLE)
1589 // The secondary should have been called twice on Mac due to attempting
1590 // the kIgnoredMacUndesiredRevocationCheckingWorkaround.
1591 .Times(2)
1592 #else
1593 .Times(1)
1594 #endif
1595 .WillRepeatedly(DoAll(SetArgPointee<7>(ok_result), Return(OK)));
1596
1597 std::vector<TrialReportInfo> reports;
1598 TrialComparisonCertVerifier verifier(
1599 verify_proc1, verify_proc2,
1600 base::BindRepeating(&RecordTrialReport, &reports));
1601 verifier.set_trial_allowed(true);
1602
1603 CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0,
1604 /*ocsp_response=*/std::string(),
1605 /*sct_list=*/std::string());
1606 CertVerifyResult result;
1607 TestCompletionCallback callback;
1608 std::unique_ptr<CertVerifier::Request> request;
1609 int error = verifier.Verify(params, &result, callback.callback(), &request,
1610 NetLogWithSource());
1611 ASSERT_THAT(error, IsError(ERR_IO_PENDING));
1612 EXPECT_TRUE(request);
1613
1614 error = callback.WaitForResult();
1615 EXPECT_THAT(error, IsError(ERR_CERT_REVOKED));
1616
1617 RunUntilIdle();
1618
1619 EXPECT_EQ(1, verify_proc1->num_verifications());
1620 testing::Mock::VerifyAndClear(verify_proc2.get());
1621 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 1);
1622 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary",
1623 1);
1624 histograms_.ExpectUniqueSample(
1625 "Net.CertVerifier_TrialComparisonResult",
1626 TrialComparisonCertVerifier::kPrimaryErrorSecondaryValid, 1);
1627
1628 // Expect a report.
1629 EXPECT_EQ(1U, reports.size());
1630 }
1631
TEST_F(TrialComparisonCertVerifierTest,MultipleEVPolicies)1632 TEST_F(TrialComparisonCertVerifierTest, MultipleEVPolicies) {
1633 base::FilePath certs_dir =
1634 GetTestNetDataDirectory()
1635 .AppendASCII("trial_comparison_cert_verifier_unittest")
1636 .AppendASCII("target-multiple-policies");
1637 scoped_refptr<X509Certificate> cert_chain = CreateCertificateChainFromFile(
1638 certs_dir, "chain.pem", X509Certificate::FORMAT_AUTO);
1639 ASSERT_TRUE(cert_chain);
1640 ASSERT_EQ(2U, cert_chain->intermediate_buffers().size());
1641
1642 SHA256HashValue root_fingerprint;
1643 crypto::SHA256HashString(x509_util::CryptoBufferAsStringPiece(
1644 cert_chain->intermediate_buffers().back().get()),
1645 root_fingerprint.data,
1646 sizeof(root_fingerprint.data));
1647
1648 // Both policies in the target are EV policies, but only 1.2.6.7 is valid for
1649 // the root in this chain.
1650 ScopedTestEVPolicy scoped_ev_policy_1(EVRootCAMetadata::GetInstance(),
1651 root_fingerprint, "1.2.6.7");
1652 ScopedTestEVPolicy scoped_ev_policy_2(EVRootCAMetadata::GetInstance(),
1653 SHA256HashValue(), "1.2.3.4");
1654
1655 // Both verifiers return OK, but secondary returns EV status.
1656 CertVerifyResult primary_result;
1657 primary_result.verified_cert = cert_chain;
1658 scoped_refptr<FakeCertVerifyProc> verify_proc1 =
1659 base::MakeRefCounted<FakeCertVerifyProc>(OK, primary_result);
1660
1661 CertVerifyResult secondary_result;
1662 secondary_result.verified_cert = cert_chain;
1663 secondary_result.cert_status =
1664 CERT_STATUS_IS_EV | CERT_STATUS_REV_CHECKING_ENABLED;
1665 scoped_refptr<FakeCertVerifyProc> verify_proc2 =
1666 base::MakeRefCounted<FakeCertVerifyProc>(OK, secondary_result);
1667
1668 std::vector<TrialReportInfo> reports;
1669 TrialComparisonCertVerifier verifier(
1670 verify_proc1, verify_proc2,
1671 base::BindRepeating(&RecordTrialReport, &reports));
1672 verifier.set_trial_allowed(true);
1673
1674 CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0,
1675 /*ocsp_response=*/std::string(),
1676 /*sct_list=*/std::string());
1677 CertVerifyResult result;
1678 TestCompletionCallback callback;
1679 std::unique_ptr<CertVerifier::Request> request;
1680 int error = verifier.Verify(params, &result, callback.callback(), &request,
1681 NetLogWithSource());
1682 ASSERT_THAT(error, IsError(ERR_IO_PENDING));
1683 EXPECT_TRUE(request);
1684
1685 error = callback.WaitForResult();
1686 EXPECT_THAT(error, IsOk());
1687
1688 verify_proc2->WaitForVerifyCall();
1689 RunUntilIdle();
1690
1691 // Expect no report.
1692 EXPECT_TRUE(reports.empty());
1693
1694 EXPECT_EQ(1, verify_proc1->num_verifications());
1695 EXPECT_EQ(1, verify_proc2->num_verifications());
1696 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 1);
1697 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary",
1698 1);
1699 histograms_.ExpectUniqueSample(
1700 "Net.CertVerifier_TrialComparisonResult",
1701 TrialComparisonCertVerifier::kIgnoredMultipleEVPoliciesAndOneMatchesRoot,
1702 1);
1703 }
1704
TEST_F(TrialComparisonCertVerifierTest,MultipleEVPoliciesNoneValidForRoot)1705 TEST_F(TrialComparisonCertVerifierTest, MultipleEVPoliciesNoneValidForRoot) {
1706 base::FilePath certs_dir =
1707 GetTestNetDataDirectory()
1708 .AppendASCII("trial_comparison_cert_verifier_unittest")
1709 .AppendASCII("target-multiple-policies");
1710 scoped_refptr<X509Certificate> cert_chain = CreateCertificateChainFromFile(
1711 certs_dir, "chain.pem", X509Certificate::FORMAT_AUTO);
1712 ASSERT_TRUE(cert_chain);
1713
1714 // Both policies in the target are EV policies, but neither is valid for the
1715 // root in this chain.
1716 ScopedTestEVPolicy scoped_ev_policy_1(EVRootCAMetadata::GetInstance(), {1},
1717 "1.2.6.7");
1718 ScopedTestEVPolicy scoped_ev_policy_2(EVRootCAMetadata::GetInstance(), {2},
1719 "1.2.3.4");
1720
1721 // Both verifiers return OK, but secondary returns EV status.
1722 CertVerifyResult primary_result;
1723 primary_result.verified_cert = cert_chain;
1724 scoped_refptr<FakeCertVerifyProc> verify_proc1 =
1725 base::MakeRefCounted<FakeCertVerifyProc>(OK, primary_result);
1726
1727 CertVerifyResult secondary_result;
1728 secondary_result.verified_cert = cert_chain;
1729 secondary_result.cert_status =
1730 CERT_STATUS_IS_EV | CERT_STATUS_REV_CHECKING_ENABLED;
1731 scoped_refptr<FakeCertVerifyProc> verify_proc2 =
1732 base::MakeRefCounted<FakeCertVerifyProc>(OK, secondary_result);
1733
1734 std::vector<TrialReportInfo> reports;
1735 TrialComparisonCertVerifier verifier(
1736 verify_proc1, verify_proc2,
1737 base::BindRepeating(&RecordTrialReport, &reports));
1738 verifier.set_trial_allowed(true);
1739
1740 CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0,
1741 /*ocsp_response=*/std::string(),
1742 /*sct_list=*/std::string());
1743 CertVerifyResult result;
1744 TestCompletionCallback callback;
1745 std::unique_ptr<CertVerifier::Request> request;
1746 int error = verifier.Verify(params, &result, callback.callback(), &request,
1747 NetLogWithSource());
1748 ASSERT_THAT(error, IsError(ERR_IO_PENDING));
1749 EXPECT_TRUE(request);
1750
1751 error = callback.WaitForResult();
1752 EXPECT_THAT(error, IsOk());
1753
1754 verify_proc2->WaitForVerifyCall();
1755 RunUntilIdle();
1756
1757 // Expect a report.
1758 ASSERT_EQ(1U, reports.size());
1759
1760 EXPECT_EQ(1, verify_proc1->num_verifications());
1761 EXPECT_EQ(1, verify_proc2->num_verifications());
1762 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 1);
1763 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary",
1764 1);
1765 histograms_.ExpectUniqueSample(
1766 "Net.CertVerifier_TrialComparisonResult",
1767 TrialComparisonCertVerifier::kBothValidDifferentDetails, 1);
1768 }
1769
TEST_F(TrialComparisonCertVerifierTest,MultiplePoliciesOnlyOneIsEV)1770 TEST_F(TrialComparisonCertVerifierTest, MultiplePoliciesOnlyOneIsEV) {
1771 base::FilePath certs_dir =
1772 GetTestNetDataDirectory()
1773 .AppendASCII("trial_comparison_cert_verifier_unittest")
1774 .AppendASCII("target-multiple-policies");
1775 scoped_refptr<X509Certificate> cert_chain = CreateCertificateChainFromFile(
1776 certs_dir, "chain.pem", X509Certificate::FORMAT_AUTO);
1777 ASSERT_TRUE(cert_chain);
1778 ASSERT_EQ(2U, cert_chain->intermediate_buffers().size());
1779
1780 SHA256HashValue root_fingerprint;
1781 crypto::SHA256HashString(x509_util::CryptoBufferAsStringPiece(
1782 cert_chain->intermediate_buffers().back().get()),
1783 root_fingerprint.data,
1784 sizeof(root_fingerprint.data));
1785
1786 // One policy in the target is an EV policy and is valid for the root.
1787 ScopedTestEVPolicy scoped_ev_policy_1(EVRootCAMetadata::GetInstance(),
1788 root_fingerprint, "1.2.6.7");
1789
1790 // Both verifiers return OK, but secondary returns EV status.
1791 CertVerifyResult primary_result;
1792 primary_result.verified_cert = cert_chain;
1793 scoped_refptr<FakeCertVerifyProc> verify_proc1 =
1794 base::MakeRefCounted<FakeCertVerifyProc>(OK, primary_result);
1795
1796 CertVerifyResult secondary_result;
1797 secondary_result.verified_cert = cert_chain;
1798 secondary_result.cert_status =
1799 CERT_STATUS_IS_EV | CERT_STATUS_REV_CHECKING_ENABLED;
1800 scoped_refptr<FakeCertVerifyProc> verify_proc2 =
1801 base::MakeRefCounted<FakeCertVerifyProc>(OK, secondary_result);
1802
1803 std::vector<TrialReportInfo> reports;
1804 TrialComparisonCertVerifier verifier(
1805 verify_proc1, verify_proc2,
1806 base::BindRepeating(&RecordTrialReport, &reports));
1807 verifier.set_trial_allowed(true);
1808
1809 CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0,
1810 /*ocsp_response=*/std::string(),
1811 /*sct_list=*/std::string());
1812 CertVerifyResult result;
1813 TestCompletionCallback callback;
1814 std::unique_ptr<CertVerifier::Request> request;
1815 int error = verifier.Verify(params, &result, callback.callback(), &request,
1816 NetLogWithSource());
1817 ASSERT_THAT(error, IsError(ERR_IO_PENDING));
1818 EXPECT_TRUE(request);
1819
1820 error = callback.WaitForResult();
1821 EXPECT_THAT(error, IsOk());
1822
1823 verify_proc2->WaitForVerifyCall();
1824 RunUntilIdle();
1825
1826 // Expect a report.
1827 ASSERT_EQ(1U, reports.size());
1828
1829 EXPECT_EQ(1, verify_proc1->num_verifications());
1830 EXPECT_EQ(1, verify_proc2->num_verifications());
1831 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 1);
1832 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary",
1833 1);
1834 histograms_.ExpectUniqueSample(
1835 "Net.CertVerifier_TrialComparisonResult",
1836 TrialComparisonCertVerifier::kBothValidDifferentDetails, 1);
1837 }
1838
TEST_F(TrialComparisonCertVerifierTest,LocallyTrustedLeaf)1839 TEST_F(TrialComparisonCertVerifierTest, LocallyTrustedLeaf) {
1840 // Platform verifier verifies the leaf directly.
1841 CertVerifyResult primary_result;
1842 primary_result.verified_cert = leaf_cert_1_;
1843 scoped_refptr<FakeCertVerifyProc> verify_proc1 =
1844 base::MakeRefCounted<FakeCertVerifyProc>(OK, primary_result);
1845
1846 // Trial verifier does not support directly-trusted leaf certs.
1847 CertVerifyResult secondary_result;
1848 secondary_result.cert_status = CERT_STATUS_AUTHORITY_INVALID;
1849 secondary_result.verified_cert = leaf_cert_1_;
1850 scoped_refptr<FakeCertVerifyProc> verify_proc2 =
1851 base::MakeRefCounted<FakeCertVerifyProc>(ERR_CERT_AUTHORITY_INVALID,
1852 secondary_result);
1853
1854 std::vector<TrialReportInfo> reports;
1855 TrialComparisonCertVerifier verifier(
1856 verify_proc1, verify_proc2,
1857 base::BindRepeating(&RecordTrialReport, &reports));
1858 verifier.set_trial_allowed(true);
1859
1860 CertVerifier::RequestParams params(leaf_cert_1_, "127.0.0.1", /*flags=*/0,
1861 /*ocsp_response=*/std::string(),
1862 /*sct_list=*/std::string());
1863 CertVerifyResult result;
1864 TestCompletionCallback callback;
1865 std::unique_ptr<CertVerifier::Request> request;
1866 int error = verifier.Verify(params, &result, callback.callback(), &request,
1867 NetLogWithSource());
1868 ASSERT_THAT(error, IsError(ERR_IO_PENDING));
1869 EXPECT_TRUE(request);
1870
1871 error = callback.WaitForResult();
1872 EXPECT_THAT(error, IsOk());
1873
1874 verify_proc2->WaitForVerifyCall();
1875 RunUntilIdle();
1876
1877 // Expect no report.
1878 EXPECT_TRUE(reports.empty());
1879
1880 EXPECT_EQ(1, verify_proc1->num_verifications());
1881 EXPECT_EQ(1, verify_proc2->num_verifications());
1882 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialPrimary", 1);
1883 histograms_.ExpectTotalCount("Net.CertVerifier_Job_Latency_TrialSecondary",
1884 1);
1885 histograms_.ExpectUniqueSample(
1886 "Net.CertVerifier_TrialComparisonResult",
1887 TrialComparisonCertVerifier::kIgnoredLocallyTrustedLeaf, 1);
1888 }
1889
1890 } // namespace net
1891