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