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>(¬ifier);
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>(¬ifier);
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