• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/quic/crypto/proof_verifier_chromium.h"
6 
7 #include <memory>
8 #include <utility>
9 
10 #include "base/memory/raw_ptr.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/strings/string_piece.h"
13 #include "base/test/metrics/histogram_tester.h"
14 #include "base/test/scoped_feature_list.h"
15 #include "net/base/completion_once_callback.h"
16 #include "net/base/features.h"
17 #include "net/base/net_errors.h"
18 #include "net/base/network_anonymization_key.h"
19 #include "net/cert/cert_and_ct_verifier.h"
20 #include "net/cert/cert_status_flags.h"
21 #include "net/cert/cert_verifier.h"
22 #include "net/cert/ct_log_verifier.h"
23 #include "net/cert/ct_policy_enforcer.h"
24 #include "net/cert/ct_policy_status.h"
25 #include "net/cert/ct_serialization.h"
26 #include "net/cert/mock_cert_verifier.h"
27 #include "net/cert/multi_log_ct_verifier.h"
28 #include "net/cert/sct_auditing_delegate.h"
29 #include "net/cert/x509_util.h"
30 #include "net/http/transport_security_state.h"
31 #include "net/http/transport_security_state_test_util.h"
32 #include "net/quic/crypto/proof_source_chromium.h"
33 #include "net/quic/quic_context.h"
34 #include "net/test/cert_test_util.h"
35 #include "net/test/ct_test_util.h"
36 #include "net/test/test_data_directory.h"
37 #include "net/third_party/quiche/src/quiche/quic/core/crypto/proof_verifier.h"
38 #include "net/third_party/quiche/src/quiche/quic/core/quic_error_codes.h"
39 #include "testing/gmock/include/gmock/gmock.h"
40 #include "testing/gtest/include/gtest/gtest.h"
41 
42 using ::testing::_;
43 using ::testing::Return;
44 
45 namespace net::test {
46 
47 namespace {
48 
49 const char kCTAndPKPHost[] = "hsts-hpkp-preloaded.test";
50 
51 // CertVerifier that will fail the test if it is ever called.
52 class FailsTestCertVerifier : public CertVerifier {
53  public:
54   FailsTestCertVerifier() = default;
55   ~FailsTestCertVerifier() override = default;
56 
57   // CertVerifier implementation
Verify(const RequestParams & params,CertVerifyResult * verify_result,CompletionOnceCallback callback,std::unique_ptr<Request> * out_req,const NetLogWithSource & net_log)58   int Verify(const RequestParams& params,
59              CertVerifyResult* verify_result,
60              CompletionOnceCallback callback,
61              std::unique_ptr<Request>* out_req,
62              const NetLogWithSource& net_log) override {
63     ADD_FAILURE() << "CertVerifier::Verify() should not be called";
64     return ERR_FAILED;
65   }
SetConfig(const Config & config)66   void SetConfig(const Config& config) override {}
AddObserver(Observer * observer)67   void AddObserver(Observer* observer) override {}
RemoveObserver(Observer * observer)68   void RemoveObserver(Observer* observer) override {}
69 };
70 
71 // A mock CTPolicyEnforcer that returns a custom verification result.
72 class MockCTPolicyEnforcer : public CTPolicyEnforcer {
73  public:
74   MOCK_METHOD3(CheckCompliance,
75                ct::CTPolicyCompliance(X509Certificate* cert,
76                                       const ct::SCTList&,
77                                       const NetLogWithSource&));
78 };
79 
80 class MockRequireCTDelegate : public TransportSecurityState::RequireCTDelegate {
81  public:
82   MOCK_METHOD3(IsCTRequiredForHost,
83                CTRequirementLevel(const std::string& host,
84                                   const X509Certificate* chain,
85                                   const HashValueVector& hashes));
86 };
87 
88 class MockSCTAuditingDelegate : public SCTAuditingDelegate {
89  public:
90   MOCK_METHOD(bool, IsSCTAuditingEnabled, ());
91   MOCK_METHOD(void,
92               MaybeEnqueueReport,
93               (const net::HostPortPair&,
94                const net::X509Certificate*,
95                const net::SignedCertificateTimestampAndStatusList&));
96 };
97 
98 // Proof source callback which saves the signature into |signature|.
99 class SignatureSaver : public quic::ProofSource::Callback {
100  public:
SignatureSaver(std::string * signature)101   explicit SignatureSaver(std::string* signature) : signature_(signature) {}
102   ~SignatureSaver() override = default;
103 
Run(bool,const quiche::QuicheReferenceCountedPointer<quic::ProofSource::Chain> &,const quic::QuicCryptoProof & proof,std::unique_ptr<quic::ProofSource::Details>)104   void Run(bool /*ok*/,
105            const quiche::QuicheReferenceCountedPointer<
106                quic::ProofSource::Chain>& /*chain*/,
107            const quic::QuicCryptoProof& proof,
108            std::unique_ptr<quic::ProofSource::Details> /*details*/) override {
109     *signature_ = proof.signature;
110   }
111 
112   raw_ptr<std::string> signature_;
113 };
114 
115 class DummyProofVerifierCallback : public quic::ProofVerifierCallback {
116  public:
117   DummyProofVerifierCallback() = default;
118   ~DummyProofVerifierCallback() override = default;
119 
Run(bool ok,const std::string & error_details,std::unique_ptr<quic::ProofVerifyDetails> * details)120   void Run(bool ok,
121            const std::string& error_details,
122            std::unique_ptr<quic::ProofVerifyDetails>* details) override {
123     // Do nothing
124   }
125 };
126 
127 const char kTestHostname[] = "test.example.com";
128 const uint16_t kTestPort = 8443;
129 const char kTestConfig[] = "server config bytes";
130 const char kTestChloHash[] = "CHLO hash";
131 const char kTestEmptyOCSPResponse[] = "";
132 const char kTestEmptySCT[] = "";
133 const char kTestEmptySignature[] = "";
134 
135 const char kLogDescription[] = "somelog";
136 
137 // This test exercises code that does not depend on the QUIC version in use
138 // but that still requires a version so we just use the first one.
139 const quic::QuicTransportVersion kTestTransportVersion =
140     AllSupportedQuicVersions().front().transport_version;
141 
142 }  // namespace
143 
144 // A mock ReportSenderInterface that just remembers the latest report
145 // URI and its NetworkAnonymizationKey.
146 class MockCertificateReportSender
147     : public TransportSecurityState::ReportSenderInterface {
148  public:
149   MockCertificateReportSender() = default;
150   ~MockCertificateReportSender() override = default;
151 
Send(const GURL & report_uri,base::StringPiece content_type,base::StringPiece report,const NetworkAnonymizationKey & network_anonymization_key,base::OnceCallback<void ()> success_callback,base::OnceCallback<void (const GURL &,int,int)> error_callback)152   void Send(
153       const GURL& report_uri,
154       base::StringPiece content_type,
155       base::StringPiece report,
156       const NetworkAnonymizationKey& network_anonymization_key,
157       base::OnceCallback<void()> success_callback,
158       base::OnceCallback<void(const GURL&, int, int)> error_callback) override {
159     latest_report_uri_ = report_uri;
160     latest_network_anonymization_key_ = network_anonymization_key;
161   }
162 
latest_report_uri()163   const GURL& latest_report_uri() { return latest_report_uri_; }
latest_network_anonymization_key()164   const NetworkAnonymizationKey& latest_network_anonymization_key() {
165     return latest_network_anonymization_key_;
166   }
167 
168  private:
169   GURL latest_report_uri_;
170   NetworkAnonymizationKey latest_network_anonymization_key_;
171 };
172 
173 class ProofVerifierChromiumTest : public ::testing::Test {
174  public:
ProofVerifierChromiumTest()175   ProofVerifierChromiumTest()
176       : verify_context_(std::make_unique<ProofVerifyContextChromium>(
177             0 /*cert_verify_flags*/,
178             NetLogWithSource())) {}
179 
SetUp()180   void SetUp() override {
181     EXPECT_CALL(ct_policy_enforcer_, CheckCompliance(_, _, _))
182         .WillRepeatedly(
183             Return(ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
184 
185     static const char kTestCert[] = "quic-chain.pem";
186     test_cert_ = ImportCertFromFile(GetTestCertsDirectory(), kTestCert);
187     ASSERT_TRUE(test_cert_);
188     certs_.clear();
189     certs_.emplace_back(
190         x509_util::CryptoBufferAsStringPiece(test_cert_->cert_buffer()));
191 
192     dummy_result_.verified_cert = test_cert_;
193     dummy_result_.is_issued_by_known_root = true;
194   }
195 
GetTestSignature()196   std::string GetTestSignature() {
197     ProofSourceChromium source;
198     source.Initialize(GetTestCertsDirectory().AppendASCII("quic-chain.pem"),
199                       GetTestCertsDirectory().AppendASCII("quic-leaf-cert.key"),
200                       base::FilePath());
201     std::string signature;
202     source.GetProof(quic::QuicSocketAddress(), quic::QuicSocketAddress(),
203                     kTestHostname, kTestConfig, kTestTransportVersion,
204                     kTestChloHash,
205                     std::make_unique<SignatureSaver>(&signature));
206     return signature;
207   }
208 
GetSCTTestCertificates(std::vector<std::string> * certs)209   void GetSCTTestCertificates(std::vector<std::string>* certs) {
210     std::string der_test_cert(ct::GetDerEncodedX509Cert());
211     scoped_refptr<X509Certificate> test_cert = X509Certificate::CreateFromBytes(
212         base::as_bytes(base::make_span(der_test_cert)));
213     ASSERT_TRUE(test_cert.get());
214 
215     certs->clear();
216     certs->emplace_back(
217         x509_util::CryptoBufferAsStringPiece(test_cert->cert_buffer()));
218   }
219 
CheckSCT(bool sct_expected_ok)220   void CheckSCT(bool sct_expected_ok) {
221     ProofVerifyDetailsChromium* proof_details =
222         reinterpret_cast<ProofVerifyDetailsChromium*>(details_.get());
223     const CertVerifyResult& cert_verify_result =
224         proof_details->cert_verify_result;
225     if (sct_expected_ok) {
226       EXPECT_TRUE(ct::CheckForSingleVerifiedSCTInResult(cert_verify_result.scts,
227                                                         kLogDescription));
228       EXPECT_TRUE(ct::CheckForSCTOrigin(
229           cert_verify_result.scts,
230           ct::SignedCertificateTimestamp::SCT_FROM_TLS_EXTENSION));
231     } else {
232       ASSERT_EQ(1U, cert_verify_result.scts.size());
233       EXPECT_EQ(ct::SCT_STATUS_LOG_UNKNOWN, cert_verify_result.scts[0].status);
234     }
235   }
236 
237  protected:
238   TransportSecurityState transport_security_state_;
239   MockCTPolicyEnforcer ct_policy_enforcer_;
240 
241   std::unique_ptr<quic::ProofVerifyContext> verify_context_;
242   std::unique_ptr<quic::ProofVerifyDetails> details_;
243   std::string error_details_;
244   uint8_t tls_alert_;
245   std::vector<std::string> certs_;
246   CertVerifyResult dummy_result_;
247   scoped_refptr<X509Certificate> test_cert_;
248 };
249 
TEST_F(ProofVerifierChromiumTest,VerifyProof)250 TEST_F(ProofVerifierChromiumTest, VerifyProof) {
251   MockCertVerifier dummy_verifier;
252   dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_, OK);
253 
254   ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
255                                        &transport_security_state_, nullptr, {},
256                                        NetworkAnonymizationKey());
257 
258   auto callback = std::make_unique<DummyProofVerifierCallback>();
259   quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
260       kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
261       kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
262       verify_context_.get(), &error_details_, &details_, std::move(callback));
263   ASSERT_EQ(quic::QUIC_SUCCESS, status);
264 
265   ASSERT_TRUE(details_.get());
266   ProofVerifyDetailsChromium* verify_details =
267       static_cast<ProofVerifyDetailsChromium*>(details_.get());
268   EXPECT_EQ(dummy_result_.cert_status,
269             verify_details->cert_verify_result.cert_status);
270 
271   callback = std::make_unique<DummyProofVerifierCallback>();
272   status = proof_verifier.VerifyCertChain(
273       kTestHostname, kTestPort, certs_, kTestEmptyOCSPResponse, kTestEmptySCT,
274       verify_context_.get(), &error_details_, &details_, &tls_alert_,
275       std::move(callback));
276   ASSERT_EQ(quic::QUIC_SUCCESS, status);
277 
278   ASSERT_TRUE(details_.get());
279   verify_details = static_cast<ProofVerifyDetailsChromium*>(details_.get());
280   EXPECT_EQ(dummy_result_.cert_status,
281             verify_details->cert_verify_result.cert_status);
282 }
283 
284 // Tests that the quic::ProofVerifier fails verification if certificate
285 // verification fails.
TEST_F(ProofVerifierChromiumTest,FailsIfCertFails)286 TEST_F(ProofVerifierChromiumTest, FailsIfCertFails) {
287   MockCertVerifier dummy_verifier;
288   ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
289                                        &transport_security_state_, nullptr, {},
290                                        NetworkAnonymizationKey());
291 
292   auto callback = std::make_unique<DummyProofVerifierCallback>();
293   quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
294       kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
295       kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
296       verify_context_.get(), &error_details_, &details_, std::move(callback));
297   ASSERT_EQ(quic::QUIC_FAILURE, status);
298 
299   callback = std::make_unique<DummyProofVerifierCallback>();
300   status = proof_verifier.VerifyCertChain(
301       kTestHostname, kTestPort, certs_, kTestEmptyOCSPResponse, kTestEmptySCT,
302       verify_context_.get(), &error_details_, &details_, &tls_alert_,
303       std::move(callback));
304   ASSERT_EQ(quic::QUIC_FAILURE, status);
305 }
306 
307 class DoNothingLogNotifier : public MultiLogCTVerifier::CTLogProvider {
308  public:
309   DoNothingLogNotifier() = default;
310   ~DoNothingLogNotifier() = default;
311 };
312 
313 // Valid SCT and cert
TEST_F(ProofVerifierChromiumTest,ValidSCTList)314 TEST_F(ProofVerifierChromiumTest, ValidSCTList) {
315   // Use different certificates for SCT tests.
316   ASSERT_NO_FATAL_FAILURE(GetSCTTestCertificates(&certs_));
317 
318   std::string der_test_cert(ct::GetDerEncodedX509Cert());
319   scoped_refptr<X509Certificate> test_cert = X509Certificate::CreateFromBytes(
320       base::as_bytes(base::make_span(der_test_cert)));
321   ASSERT_TRUE(test_cert);
322   CertVerifyResult dummy_result;
323   dummy_result.verified_cert = test_cert;
324   dummy_result.is_issued_by_known_root = true;
325   auto dummy_verifier = std::make_unique<MockCertVerifier>();
326   dummy_verifier->AddResultForCert(test_cert.get(), dummy_result, OK);
327 
328   // Combine the mocked cert verify result with the results of the
329   // MultiLogCTVerifier.
330   std::vector<scoped_refptr<const CTLogVerifier>> log_verifiers;
331   scoped_refptr<const CTLogVerifier> log(
332       CTLogVerifier::Create(ct::GetTestPublicKey(), kLogDescription));
333   ASSERT_TRUE(log);
334   log_verifiers.push_back(log);
335   DoNothingLogNotifier notifier;
336   auto ct_verifier = std::make_unique<MultiLogCTVerifier>(&notifier);
337   ct_verifier->SetLogs(log_verifiers);
338 
339   CertAndCTVerifier cert_verifier(std::move(dummy_verifier),
340                                   std::move(ct_verifier));
341 
342   ProofVerifierChromium proof_verifier(&cert_verifier, &ct_policy_enforcer_,
343                                        &transport_security_state_, nullptr, {},
344                                        NetworkAnonymizationKey());
345 
346   auto callback = std::make_unique<DummyProofVerifierCallback>();
347   quic::QuicAsyncStatus status = proof_verifier.VerifyCertChain(
348       kTestHostname, kTestPort, certs_, kTestEmptyOCSPResponse,
349       ct::GetSCTListForTesting(), verify_context_.get(), &error_details_,
350       &details_, &tls_alert_, std::move(callback));
351   ASSERT_EQ(quic::QUIC_SUCCESS, status);
352   CheckSCT(/*sct_expected_ok=*/true);
353 }
354 
355 // Invalid SCT, but valid cert
TEST_F(ProofVerifierChromiumTest,InvalidSCTList)356 TEST_F(ProofVerifierChromiumTest, InvalidSCTList) {
357   // Use different certificates for SCT tests.
358   ASSERT_NO_FATAL_FAILURE(GetSCTTestCertificates(&certs_));
359 
360   std::string der_test_cert(ct::GetDerEncodedX509Cert());
361   scoped_refptr<X509Certificate> test_cert = X509Certificate::CreateFromBytes(
362       base::as_bytes(base::make_span(der_test_cert)));
363   ASSERT_TRUE(test_cert);
364   CertVerifyResult dummy_result;
365   dummy_result.verified_cert = test_cert;
366   dummy_result.is_issued_by_known_root = true;
367   auto dummy_verifier = std::make_unique<MockCertVerifier>();
368   dummy_verifier->AddResultForCert(test_cert.get(), dummy_result, OK);
369 
370   // Combine the mocked cert verify result with the results of the
371   // MultiLogCTVerifier.
372   std::vector<scoped_refptr<const CTLogVerifier>> log_verifiers;
373   scoped_refptr<const CTLogVerifier> log(
374       CTLogVerifier::Create(ct::GetTestPublicKey(), kLogDescription));
375   ASSERT_TRUE(log);
376   log_verifiers.push_back(log);
377   DoNothingLogNotifier notifier;
378   auto ct_verifier = std::make_unique<MultiLogCTVerifier>(&notifier);
379   ct_verifier->SetLogs(log_verifiers);
380 
381   CertAndCTVerifier cert_verifier(std::move(dummy_verifier),
382                                   std::move(ct_verifier));
383 
384   ProofVerifierChromium proof_verifier(&cert_verifier, &ct_policy_enforcer_,
385                                        &transport_security_state_, nullptr, {},
386                                        NetworkAnonymizationKey());
387 
388   auto callback = std::make_unique<DummyProofVerifierCallback>();
389   quic::QuicAsyncStatus status = proof_verifier.VerifyCertChain(
390       kTestHostname, kTestPort, certs_, kTestEmptyOCSPResponse,
391       ct::GetSCTListWithInvalidSCT(), verify_context_.get(), &error_details_,
392       &details_, &tls_alert_, std::move(callback));
393   ASSERT_EQ(quic::QUIC_SUCCESS, status);
394   CheckSCT(/*sct_expected_ok=*/false);
395 }
396 
397 // Tests that the quic::ProofVerifier doesn't verify certificates if the config
398 // signature fails.
TEST_F(ProofVerifierChromiumTest,FailsIfSignatureFails)399 TEST_F(ProofVerifierChromiumTest, FailsIfSignatureFails) {
400   FailsTestCertVerifier cert_verifier;
401   ProofVerifierChromium proof_verifier(&cert_verifier, &ct_policy_enforcer_,
402                                        &transport_security_state_, nullptr, {},
403                                        NetworkAnonymizationKey());
404 
405   auto callback = std::make_unique<DummyProofVerifierCallback>();
406   quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
407       kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
408       kTestChloHash, certs_, kTestEmptySCT, kTestEmptySignature,
409       verify_context_.get(), &error_details_, &details_, std::move(callback));
410   ASSERT_EQ(quic::QUIC_FAILURE, status);
411 }
412 
413 // Tests that the certificate policy enforcer is consulted for EV
414 // and the certificate is allowed to be EV.
TEST_F(ProofVerifierChromiumTest,PreservesEVIfAllowed)415 TEST_F(ProofVerifierChromiumTest, PreservesEVIfAllowed) {
416   dummy_result_.cert_status = CERT_STATUS_IS_EV;
417 
418   MockCertVerifier dummy_verifier;
419   dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_, OK);
420 
421   EXPECT_CALL(ct_policy_enforcer_, CheckCompliance(_, _, _))
422       .WillRepeatedly(
423           Return(ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));
424 
425   ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
426                                        &transport_security_state_, nullptr, {},
427                                        NetworkAnonymizationKey());
428 
429   auto callback = std::make_unique<DummyProofVerifierCallback>();
430   quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
431       kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
432       kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
433       verify_context_.get(), &error_details_, &details_, std::move(callback));
434   ASSERT_EQ(quic::QUIC_SUCCESS, status);
435 
436   ASSERT_TRUE(details_.get());
437   ProofVerifyDetailsChromium* verify_details =
438       static_cast<ProofVerifyDetailsChromium*>(details_.get());
439   EXPECT_EQ(dummy_result_.cert_status,
440             verify_details->cert_verify_result.cert_status);
441 
442   // Repeat the test with VerifyCertChain.
443   callback = std::make_unique<DummyProofVerifierCallback>();
444   status = proof_verifier.VerifyCertChain(
445       kTestHostname, kTestPort, certs_, kTestEmptyOCSPResponse, kTestEmptySCT,
446       verify_context_.get(), &error_details_, &details_, &tls_alert_,
447       std::move(callback));
448   ASSERT_EQ(quic::QUIC_SUCCESS, status);
449 
450   ASSERT_TRUE(details_.get());
451   verify_details = static_cast<ProofVerifyDetailsChromium*>(details_.get());
452   EXPECT_EQ(dummy_result_.cert_status,
453             verify_details->cert_verify_result.cert_status);
454 }
455 
MakeHashValueVector(uint8_t tag)456 HashValueVector MakeHashValueVector(uint8_t tag) {
457   HashValue hash(HASH_VALUE_SHA256);
458   memset(hash.data(), tag, hash.size());
459   HashValueVector hashes;
460   hashes.push_back(hash);
461   return hashes;
462 }
463 
TEST_F(ProofVerifierChromiumTest,IsFatalErrorNotSetForNonFatalError)464 TEST_F(ProofVerifierChromiumTest, IsFatalErrorNotSetForNonFatalError) {
465   dummy_result_.cert_status = CERT_STATUS_DATE_INVALID;
466 
467   MockCertVerifier dummy_verifier;
468   dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_,
469                                   ERR_CERT_DATE_INVALID);
470 
471   ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
472                                        &transport_security_state_, nullptr, {},
473                                        NetworkAnonymizationKey());
474 
475   auto callback = std::make_unique<DummyProofVerifierCallback>();
476   quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
477       kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
478       kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
479       verify_context_.get(), &error_details_, &details_, std::move(callback));
480   ASSERT_EQ(quic::QUIC_FAILURE, status);
481 
482   ProofVerifyDetailsChromium* verify_details =
483       static_cast<ProofVerifyDetailsChromium*>(details_.get());
484   EXPECT_FALSE(verify_details->is_fatal_cert_error);
485 
486   callback = std::make_unique<DummyProofVerifierCallback>();
487   status = proof_verifier.VerifyCertChain(
488       kTestHostname, kTestPort, certs_, kTestEmptyOCSPResponse, kTestEmptySCT,
489       verify_context_.get(), &error_details_, &details_, &tls_alert_,
490       std::move(callback));
491   ASSERT_EQ(quic::QUIC_FAILURE, status);
492 
493   verify_details = static_cast<ProofVerifyDetailsChromium*>(details_.get());
494   EXPECT_FALSE(verify_details->is_fatal_cert_error);
495 }
496 
TEST_F(ProofVerifierChromiumTest,IsFatalErrorSetForFatalError)497 TEST_F(ProofVerifierChromiumTest, IsFatalErrorSetForFatalError) {
498   dummy_result_.cert_status = CERT_STATUS_DATE_INVALID;
499 
500   MockCertVerifier dummy_verifier;
501   dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_,
502                                   ERR_CERT_DATE_INVALID);
503 
504   const base::Time expiry = base::Time::Now() + base::Seconds(1000);
505   transport_security_state_.AddHSTS(kTestHostname, expiry, true);
506 
507   ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
508                                        &transport_security_state_, nullptr, {},
509                                        NetworkAnonymizationKey());
510 
511   auto callback = std::make_unique<DummyProofVerifierCallback>();
512   quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
513       kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
514       kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
515       verify_context_.get(), &error_details_, &details_, std::move(callback));
516   ASSERT_EQ(quic::QUIC_FAILURE, status);
517   ProofVerifyDetailsChromium* verify_details =
518       static_cast<ProofVerifyDetailsChromium*>(details_.get());
519   EXPECT_TRUE(verify_details->is_fatal_cert_error);
520 
521   callback = std::make_unique<DummyProofVerifierCallback>();
522   status = proof_verifier.VerifyCertChain(
523       kTestHostname, kTestPort, certs_, kTestEmptyOCSPResponse, kTestEmptySCT,
524       verify_context_.get(), &error_details_, &details_, &tls_alert_,
525       std::move(callback));
526   ASSERT_EQ(quic::QUIC_FAILURE, status);
527   verify_details = static_cast<ProofVerifyDetailsChromium*>(details_.get());
528   EXPECT_TRUE(verify_details->is_fatal_cert_error);
529 }
530 
531 // Test that PKP is enforced for certificates that chain up to known roots.
TEST_F(ProofVerifierChromiumTest,PKPEnforced)532 TEST_F(ProofVerifierChromiumTest, PKPEnforced) {
533   base::test::ScopedFeatureList scoped_feature_list_;
534   scoped_feature_list_.InitAndEnableFeature(
535       net::features::kStaticKeyPinningEnforcement);
536   dummy_result_.is_issued_by_known_root = true;
537   dummy_result_.public_key_hashes = MakeHashValueVector(0x01);
538 
539   MockCertVerifier dummy_verifier;
540   dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_, OK);
541 
542   transport_security_state_.EnableStaticPinsForTesting();
543   transport_security_state_.SetPinningListAlwaysTimelyForTesting(true);
544   ScopedTransportSecurityStateSource scoped_security_state_source;
545 
546   ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
547                                        &transport_security_state_, nullptr, {},
548                                        NetworkAnonymizationKey());
549 
550   auto callback = std::make_unique<DummyProofVerifierCallback>();
551   quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
552       kCTAndPKPHost, kTestPort, kTestConfig, kTestTransportVersion,
553       kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
554       verify_context_.get(), &error_details_, &details_, std::move(callback));
555   ASSERT_EQ(quic::QUIC_FAILURE, status);
556 
557   ASSERT_TRUE(details_.get());
558   ProofVerifyDetailsChromium* verify_details =
559       static_cast<ProofVerifyDetailsChromium*>(details_.get());
560   EXPECT_TRUE(verify_details->cert_verify_result.cert_status &
561               CERT_STATUS_PINNED_KEY_MISSING);
562   EXPECT_FALSE(verify_details->pkp_bypassed);
563   EXPECT_NE("", verify_details->pinning_failure_log);
564 
565   callback = std::make_unique<DummyProofVerifierCallback>();
566   status = proof_verifier.VerifyCertChain(
567       kCTAndPKPHost, kTestPort, certs_, kTestEmptyOCSPResponse, kTestEmptySCT,
568       verify_context_.get(), &error_details_, &details_, &tls_alert_,
569       std::move(callback));
570   ASSERT_EQ(quic::QUIC_FAILURE, status);
571 
572   ASSERT_TRUE(details_.get());
573   verify_details = static_cast<ProofVerifyDetailsChromium*>(details_.get());
574   EXPECT_TRUE(verify_details->cert_verify_result.cert_status &
575               CERT_STATUS_PINNED_KEY_MISSING);
576   EXPECT_FALSE(verify_details->pkp_bypassed);
577   EXPECT_NE("", verify_details->pinning_failure_log);
578 }
579 
580 // Test |pkp_bypassed| is set when PKP is bypassed due to a local
581 // trust anchor
TEST_F(ProofVerifierChromiumTest,PKPBypassFlagSet)582 TEST_F(ProofVerifierChromiumTest, PKPBypassFlagSet) {
583   base::test::ScopedFeatureList scoped_feature_list_;
584   scoped_feature_list_.InitAndEnableFeature(
585       net::features::kStaticKeyPinningEnforcement);
586   dummy_result_.is_issued_by_known_root = false;
587   dummy_result_.public_key_hashes = MakeHashValueVector(0x01);
588 
589   MockCertVerifier dummy_verifier;
590   dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_, OK);
591 
592   transport_security_state_.EnableStaticPinsForTesting();
593   transport_security_state_.SetPinningListAlwaysTimelyForTesting(true);
594   ScopedTransportSecurityStateSource scoped_security_state_source;
595 
596   ProofVerifierChromium proof_verifier(
597       &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_,
598       nullptr, {kCTAndPKPHost}, NetworkAnonymizationKey());
599 
600   auto callback = std::make_unique<DummyProofVerifierCallback>();
601   quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
602       kCTAndPKPHost, kTestPort, kTestConfig, kTestTransportVersion,
603       kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
604       verify_context_.get(), &error_details_, &details_, std::move(callback));
605   ASSERT_EQ(quic::QUIC_SUCCESS, status);
606 
607   ASSERT_TRUE(details_.get());
608   ProofVerifyDetailsChromium* verify_details =
609       static_cast<ProofVerifyDetailsChromium*>(details_.get());
610   EXPECT_TRUE(verify_details->pkp_bypassed);
611 
612   callback = std::make_unique<DummyProofVerifierCallback>();
613   status = proof_verifier.VerifyCertChain(
614       kCTAndPKPHost, kTestPort, certs_, kTestEmptyOCSPResponse, kTestEmptySCT,
615       verify_context_.get(), &error_details_, &details_, &tls_alert_,
616       std::move(callback));
617   ASSERT_EQ(quic::QUIC_SUCCESS, status);
618 
619   ASSERT_TRUE(details_.get());
620   verify_details = static_cast<ProofVerifyDetailsChromium*>(details_.get());
621   EXPECT_TRUE(verify_details->pkp_bypassed);
622 }
623 
624 // Test that PKP errors result in sending reports.
TEST_F(ProofVerifierChromiumTest,PKPReport)625 TEST_F(ProofVerifierChromiumTest, PKPReport) {
626   NetworkAnonymizationKey network_anonymization_key =
627       NetworkAnonymizationKey::CreateTransient();
628 
629   MockCertificateReportSender report_sender;
630   transport_security_state_.SetReportSender(&report_sender);
631 
632   HashValueVector spki_hashes;
633   HashValue hash(HASH_VALUE_SHA256);
634   memset(hash.data(), 0, hash.size());
635   spki_hashes.push_back(hash);
636 
637   GURL report_uri("https://foo.test/");
638   transport_security_state_.AddHPKP(
639       kCTAndPKPHost, base::Time::Now() + base::Days(1),
640       false /* include_subdomains */, spki_hashes, report_uri);
641   ScopedTransportSecurityStateSource scoped_security_state_source;
642 
643   dummy_result_.is_issued_by_known_root = true;
644   dummy_result_.public_key_hashes = MakeHashValueVector(0x01);
645 
646   MockCertVerifier dummy_verifier;
647   dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_, OK);
648 
649   ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
650                                        &transport_security_state_, nullptr, {},
651                                        network_anonymization_key);
652 
653   auto callback = std::make_unique<DummyProofVerifierCallback>();
654   quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
655       kCTAndPKPHost, kTestPort, kTestConfig, kTestTransportVersion,
656       kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
657       verify_context_.get(), &error_details_, &details_, std::move(callback));
658   ASSERT_EQ(quic::QUIC_FAILURE, status);
659 
660   ASSERT_TRUE(details_.get());
661   ProofVerifyDetailsChromium* verify_details =
662       static_cast<ProofVerifyDetailsChromium*>(details_.get());
663   EXPECT_TRUE(verify_details->cert_verify_result.cert_status &
664               CERT_STATUS_PINNED_KEY_MISSING);
665   EXPECT_FALSE(verify_details->pkp_bypassed);
666   EXPECT_NE("", verify_details->pinning_failure_log);
667 
668   callback = std::make_unique<DummyProofVerifierCallback>();
669   status = proof_verifier.VerifyCertChain(
670       kCTAndPKPHost, kTestPort, certs_, kTestEmptyOCSPResponse, kTestEmptySCT,
671       verify_context_.get(), &error_details_, &details_, &tls_alert_,
672       std::move(callback));
673   ASSERT_EQ(quic::QUIC_FAILURE, status);
674 
675   ASSERT_TRUE(details_.get());
676   verify_details = static_cast<ProofVerifyDetailsChromium*>(details_.get());
677   EXPECT_TRUE(verify_details->cert_verify_result.cert_status &
678               CERT_STATUS_PINNED_KEY_MISSING);
679   EXPECT_FALSE(verify_details->pkp_bypassed);
680   EXPECT_NE("", verify_details->pinning_failure_log);
681 
682   EXPECT_EQ(report_uri, report_sender.latest_report_uri());
683   EXPECT_EQ(network_anonymization_key,
684             report_sender.latest_network_anonymization_key());
685 
686   transport_security_state_.SetReportSender(nullptr);
687 }
688 
689 // Test that when CT is required (in this case, by the delegate), the
690 // absence of CT information is a socket error.
TEST_F(ProofVerifierChromiumTest,CTIsRequired)691 TEST_F(ProofVerifierChromiumTest, CTIsRequired) {
692   dummy_result_.is_issued_by_known_root = true;
693   dummy_result_.public_key_hashes = MakeHashValueVector(0x01);
694 
695   MockCertVerifier dummy_verifier;
696   dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_, OK);
697 
698   // Set up CT.
699   MockRequireCTDelegate require_ct_delegate;
700   transport_security_state_.SetRequireCTDelegate(&require_ct_delegate);
701   EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(_, _, _))
702       .WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
703                                  CTRequirementLevel::NOT_REQUIRED));
704   EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(kTestHostname, _, _))
705       .WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
706                                  CTRequirementLevel::REQUIRED));
707   EXPECT_CALL(ct_policy_enforcer_, CheckCompliance(_, _, _))
708       .WillRepeatedly(
709           Return(ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
710 
711   ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
712                                        &transport_security_state_, nullptr, {},
713                                        NetworkAnonymizationKey());
714 
715   auto callback = std::make_unique<DummyProofVerifierCallback>();
716   quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
717       kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
718       kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
719       verify_context_.get(), &error_details_, &details_, std::move(callback));
720   ASSERT_EQ(quic::QUIC_FAILURE, status);
721 
722   ASSERT_TRUE(details_.get());
723   ProofVerifyDetailsChromium* verify_details =
724       static_cast<ProofVerifyDetailsChromium*>(details_.get());
725   EXPECT_TRUE(verify_details->cert_verify_result.cert_status &
726               CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED);
727 
728   callback = std::make_unique<DummyProofVerifierCallback>();
729   status = proof_verifier.VerifyCertChain(
730       kTestHostname, kTestPort, certs_, kTestEmptyOCSPResponse, kTestEmptySCT,
731       verify_context_.get(), &error_details_, &details_, &tls_alert_,
732       std::move(callback));
733   ASSERT_EQ(quic::QUIC_FAILURE, status);
734 
735   ASSERT_TRUE(details_.get());
736   verify_details = static_cast<ProofVerifyDetailsChromium*>(details_.get());
737   EXPECT_TRUE(verify_details->cert_verify_result.cert_status &
738               CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED);
739 
740   transport_security_state_.SetRequireCTDelegate(nullptr);
741 }
742 
743 // Test that CT is considered even when PKP fails.
TEST_F(ProofVerifierChromiumTest,PKPAndCTBothTested)744 TEST_F(ProofVerifierChromiumTest, PKPAndCTBothTested) {
745   base::test::ScopedFeatureList scoped_feature_list_;
746   scoped_feature_list_.InitAndEnableFeature(
747       net::features::kStaticKeyPinningEnforcement);
748   dummy_result_.is_issued_by_known_root = true;
749   dummy_result_.public_key_hashes = MakeHashValueVector(0x01);
750 
751   MockCertVerifier dummy_verifier;
752   dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_, OK);
753 
754   // Set up PKP.
755   transport_security_state_.EnableStaticPinsForTesting();
756   transport_security_state_.SetPinningListAlwaysTimelyForTesting(true);
757   ScopedTransportSecurityStateSource scoped_security_state_source;
758 
759   // Set up CT.
760   MockRequireCTDelegate require_ct_delegate;
761   transport_security_state_.SetRequireCTDelegate(&require_ct_delegate);
762   EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(_, _, _))
763       .WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
764                                  CTRequirementLevel::NOT_REQUIRED));
765   EXPECT_CALL(require_ct_delegate, IsCTRequiredForHost(kCTAndPKPHost, _, _))
766       .WillRepeatedly(Return(TransportSecurityState::RequireCTDelegate::
767                                  CTRequirementLevel::REQUIRED));
768   EXPECT_CALL(ct_policy_enforcer_, CheckCompliance(_, _, _))
769       .WillRepeatedly(
770           Return(ct::CTPolicyCompliance::CT_POLICY_NOT_ENOUGH_SCTS));
771 
772   ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
773                                        &transport_security_state_, nullptr, {},
774                                        NetworkAnonymizationKey());
775 
776   auto callback = std::make_unique<DummyProofVerifierCallback>();
777   quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
778       kCTAndPKPHost, kTestPort, kTestConfig, kTestTransportVersion,
779       kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
780       verify_context_.get(), &error_details_, &details_, std::move(callback));
781   ASSERT_EQ(quic::QUIC_FAILURE, status);
782 
783   ASSERT_TRUE(details_.get());
784   ProofVerifyDetailsChromium* verify_details =
785       static_cast<ProofVerifyDetailsChromium*>(details_.get());
786   EXPECT_TRUE(verify_details->cert_verify_result.cert_status &
787               CERT_STATUS_PINNED_KEY_MISSING);
788   EXPECT_TRUE(verify_details->cert_verify_result.cert_status &
789               CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED);
790 
791   callback = std::make_unique<DummyProofVerifierCallback>();
792   status = proof_verifier.VerifyCertChain(
793       kCTAndPKPHost, kTestPort, certs_, kTestEmptyOCSPResponse, kTestEmptySCT,
794       verify_context_.get(), &error_details_, &details_, &tls_alert_,
795       std::move(callback));
796   ASSERT_EQ(quic::QUIC_FAILURE, status);
797 
798   ASSERT_TRUE(details_.get());
799   verify_details = static_cast<ProofVerifyDetailsChromium*>(details_.get());
800   EXPECT_TRUE(verify_details->cert_verify_result.cert_status &
801               CERT_STATUS_PINNED_KEY_MISSING);
802   EXPECT_TRUE(verify_details->cert_verify_result.cert_status &
803               CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED);
804 
805   transport_security_state_.SetRequireCTDelegate(nullptr);
806 }
807 
TEST_F(ProofVerifierChromiumTest,UnknownRootRejected)808 TEST_F(ProofVerifierChromiumTest, UnknownRootRejected) {
809   dummy_result_.is_issued_by_known_root = false;
810 
811   MockCertVerifier dummy_verifier;
812   dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_, OK);
813 
814   ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
815                                        &transport_security_state_, nullptr, {},
816                                        NetworkAnonymizationKey());
817 
818   auto callback = std::make_unique<DummyProofVerifierCallback>();
819   quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
820       kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
821       kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
822       verify_context_.get(), &error_details_, &details_, std::move(callback));
823   ASSERT_EQ(quic::QUIC_FAILURE, status);
824   EXPECT_EQ(
825       "Failed to verify certificate chain: net::ERR_QUIC_CERT_ROOT_NOT_KNOWN",
826       error_details_);
827 
828   callback = std::make_unique<DummyProofVerifierCallback>();
829   status = proof_verifier.VerifyCertChain(
830       kTestHostname, kTestPort, certs_, kTestEmptyOCSPResponse, kTestEmptySCT,
831       verify_context_.get(), &error_details_, &details_, &tls_alert_,
832       std::move(callback));
833   ASSERT_EQ(quic::QUIC_FAILURE, status);
834   EXPECT_EQ(
835       "Failed to verify certificate chain: net::ERR_QUIC_CERT_ROOT_NOT_KNOWN",
836       error_details_);
837 }
838 
TEST_F(ProofVerifierChromiumTest,UnknownRootAcceptedWithOverride)839 TEST_F(ProofVerifierChromiumTest, UnknownRootAcceptedWithOverride) {
840   dummy_result_.is_issued_by_known_root = false;
841 
842   MockCertVerifier dummy_verifier;
843   dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_, OK);
844 
845   ProofVerifierChromium proof_verifier(
846       &dummy_verifier, &ct_policy_enforcer_, &transport_security_state_,
847       nullptr, {kTestHostname}, NetworkAnonymizationKey());
848 
849   auto callback = std::make_unique<DummyProofVerifierCallback>();
850   quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
851       kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
852       kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
853       verify_context_.get(), &error_details_, &details_, std::move(callback));
854   ASSERT_EQ(quic::QUIC_SUCCESS, status);
855 
856   ASSERT_TRUE(details_.get());
857   ProofVerifyDetailsChromium* verify_details =
858       static_cast<ProofVerifyDetailsChromium*>(details_.get());
859   EXPECT_EQ(dummy_result_.cert_status,
860             verify_details->cert_verify_result.cert_status);
861 
862   callback = std::make_unique<DummyProofVerifierCallback>();
863   status = proof_verifier.VerifyCertChain(
864       kTestHostname, kTestPort, certs_, kTestEmptyOCSPResponse, kTestEmptySCT,
865       verify_context_.get(), &error_details_, &details_, &tls_alert_,
866       std::move(callback));
867   ASSERT_EQ(quic::QUIC_SUCCESS, status);
868 
869   ASSERT_TRUE(details_.get());
870   verify_details = static_cast<ProofVerifyDetailsChromium*>(details_.get());
871   EXPECT_EQ(dummy_result_.cert_status,
872             verify_details->cert_verify_result.cert_status);
873 }
874 
TEST_F(ProofVerifierChromiumTest,UnknownRootAcceptedWithWildcardOverride)875 TEST_F(ProofVerifierChromiumTest, UnknownRootAcceptedWithWildcardOverride) {
876   dummy_result_.is_issued_by_known_root = false;
877 
878   MockCertVerifier dummy_verifier;
879   dummy_verifier.AddResultForCert(test_cert_.get(), dummy_result_, OK);
880 
881   ProofVerifierChromium proof_verifier(&dummy_verifier, &ct_policy_enforcer_,
882                                        &transport_security_state_, nullptr,
883                                        {""}, NetworkAnonymizationKey());
884 
885   auto callback = std::make_unique<DummyProofVerifierCallback>();
886   quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
887       kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
888       kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
889       verify_context_.get(), &error_details_, &details_, std::move(callback));
890   ASSERT_EQ(quic::QUIC_SUCCESS, status);
891 
892   ASSERT_TRUE(details_.get());
893   ProofVerifyDetailsChromium* verify_details =
894       static_cast<ProofVerifyDetailsChromium*>(details_.get());
895   EXPECT_EQ(dummy_result_.cert_status,
896             verify_details->cert_verify_result.cert_status);
897 
898   callback = std::make_unique<DummyProofVerifierCallback>();
899   status = proof_verifier.VerifyCertChain(
900       kTestHostname, kTestPort, certs_, kTestEmptyOCSPResponse, kTestEmptySCT,
901       verify_context_.get(), &error_details_, &details_, &tls_alert_,
902       std::move(callback));
903   ASSERT_EQ(quic::QUIC_SUCCESS, status);
904 
905   ASSERT_TRUE(details_.get());
906   verify_details = static_cast<ProofVerifyDetailsChromium*>(details_.get());
907   EXPECT_EQ(dummy_result_.cert_status,
908             verify_details->cert_verify_result.cert_status);
909 }
910 
911 // Tests that the SCTAuditingDelegate is called to enqueue SCT reports when
912 // verifying a good proof and cert.
TEST_F(ProofVerifierChromiumTest,SCTAuditingReportCollected)913 TEST_F(ProofVerifierChromiumTest, SCTAuditingReportCollected) {
914   MockCertVerifier cert_verifier;
915   cert_verifier.AddResultForCert(test_cert_.get(), dummy_result_, OK);
916 
917   EXPECT_CALL(ct_policy_enforcer_, CheckCompliance(_, _, _))
918       .WillRepeatedly(
919           Return(ct::CTPolicyCompliance::CT_POLICY_COMPLIES_VIA_SCTS));
920 
921   MockSCTAuditingDelegate sct_auditing_delegate;
922   EXPECT_CALL(sct_auditing_delegate, IsSCTAuditingEnabled())
923       .WillRepeatedly(Return(true));
924   // MaybeEnqueueReport() will be called twice: once in VerifyProof() (which
925   // calls VerifyCert()) and once in VerifyCertChain().
926   HostPortPair host_port_pair(kTestHostname, kTestPort);
927   EXPECT_CALL(sct_auditing_delegate, MaybeEnqueueReport(host_port_pair, _, _))
928       .Times(2);
929 
930   ProofVerifierChromium proof_verifier(
931       &cert_verifier, &ct_policy_enforcer_, &transport_security_state_,
932       &sct_auditing_delegate, {}, NetworkAnonymizationKey());
933 
934   auto callback = std::make_unique<DummyProofVerifierCallback>();
935   quic::QuicAsyncStatus status = proof_verifier.VerifyProof(
936       kTestHostname, kTestPort, kTestConfig, kTestTransportVersion,
937       kTestChloHash, certs_, kTestEmptySCT, GetTestSignature(),
938       verify_context_.get(), &error_details_, &details_, std::move(callback));
939   ASSERT_EQ(quic::QUIC_SUCCESS, status);
940 
941   callback = std::make_unique<DummyProofVerifierCallback>();
942   status = proof_verifier.VerifyCertChain(
943       kTestHostname, kTestPort, certs_, kTestEmptyOCSPResponse, kTestEmptySCT,
944       verify_context_.get(), &error_details_, &details_, &tls_alert_,
945       std::move(callback));
946   ASSERT_EQ(quic::QUIC_SUCCESS, status);
947 }
948 
949 }  // namespace net::test
950