xref: /aosp_15_r20/external/cronet/net/quic/crypto/proof_verifier_chromium.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2013 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 <string_view>
8 #include <utility>
9 
10 #include "base/containers/contains.h"
11 #include "base/containers/span.h"
12 #include "base/functional/bind.h"
13 #include "base/functional/callback_helpers.h"
14 #include "base/logging.h"
15 #include "base/memory/raw_ptr.h"
16 #include "base/metrics/histogram_functions.h"
17 #include "base/metrics/histogram_macros.h"
18 #include "base/strings/stringprintf.h"
19 #include "base/time/time.h"
20 #include "crypto/signature_verifier.h"
21 #include "net/base/host_port_pair.h"
22 #include "net/base/net_errors.h"
23 #include "net/base/network_anonymization_key.h"
24 #include "net/cert/cert_status_flags.h"
25 #include "net/cert/cert_verifier.h"
26 #include "net/cert/ct_verifier.h"
27 #include "net/cert/sct_auditing_delegate.h"
28 #include "net/cert/x509_util.h"
29 #include "net/http/transport_security_state.h"
30 #include "net/third_party/quiche/src/quiche/quic/core/crypto/crypto_protocol.h"
31 
32 using base::StringPrintf;
33 using std::string;
34 
35 namespace net {
36 
37 ProofVerifyDetailsChromium::ProofVerifyDetailsChromium() = default;
38 
39 ProofVerifyDetailsChromium::~ProofVerifyDetailsChromium() = default;
40 
41 ProofVerifyDetailsChromium::ProofVerifyDetailsChromium(
42     const ProofVerifyDetailsChromium&) = default;
43 
Clone() const44 quic::ProofVerifyDetails* ProofVerifyDetailsChromium::Clone() const {
45   ProofVerifyDetailsChromium* other = new ProofVerifyDetailsChromium;
46   other->cert_verify_result = cert_verify_result;
47   return other;
48 }
49 
50 // A Job handles the verification of a single proof.  It is owned by the
51 // quic::ProofVerifier. If the verification can not complete synchronously, it
52 // will notify the quic::ProofVerifier upon completion.
53 class ProofVerifierChromium::Job {
54  public:
55   Job(ProofVerifierChromium* proof_verifier,
56       CertVerifier* cert_verifier,
57       TransportSecurityState* transport_security_state,
58       SCTAuditingDelegate* sct_auditing_delegate,
59       int cert_verify_flags,
60       const NetLogWithSource& net_log);
61 
62   Job(const Job&) = delete;
63   Job& operator=(const Job&) = delete;
64 
65   ~Job();
66 
67   // Starts the proof verification.  If |quic::QUIC_PENDING| is returned, then
68   // |callback| will be invoked asynchronously when the verification completes.
69   quic::QuicAsyncStatus VerifyProof(
70       const std::string& hostname,
71       const uint16_t port,
72       const std::string& server_config,
73       quic::QuicTransportVersion quic_version,
74       std::string_view chlo_hash,
75       const std::vector<std::string>& certs,
76       const std::string& cert_sct,
77       const std::string& signature,
78       std::string* error_details,
79       std::unique_ptr<quic::ProofVerifyDetails>* verify_details,
80       std::unique_ptr<quic::ProofVerifierCallback> callback);
81 
82   // Starts the certificate chain verification of |certs|.  If
83   // |quic::QUIC_PENDING| is returned, then |callback| will be invoked
84   // asynchronously when the verification completes.
85   quic::QuicAsyncStatus VerifyCertChain(
86       const std::string& hostname,
87       const uint16_t port,
88       const std::vector<std::string>& certs,
89       const std::string& ocsp_response,
90       const std::string& cert_sct,
91       std::string* error_details,
92       std::unique_ptr<quic::ProofVerifyDetails>* verify_details,
93       std::unique_ptr<quic::ProofVerifierCallback> callback);
94 
95  private:
96   enum State {
97     STATE_NONE,
98     STATE_VERIFY_CERT,
99     STATE_VERIFY_CERT_COMPLETE,
100   };
101 
102   // Convert |certs| to |cert_|(X509Certificate). Returns true if successful.
103   bool GetX509Certificate(
104       const std::vector<string>& certs,
105       std::string* error_details,
106       std::unique_ptr<quic::ProofVerifyDetails>* verify_details);
107 
108   // Start the cert verification.
109   quic::QuicAsyncStatus VerifyCert(
110       const string& hostname,
111       const uint16_t port,
112       const std::string& ocsp_response,
113       const std::string& cert_sct,
114       std::string* error_details,
115       std::unique_ptr<quic::ProofVerifyDetails>* verify_details,
116       std::unique_ptr<quic::ProofVerifierCallback> callback);
117 
118   int DoLoop(int last_io_result);
119   void OnIOComplete(int result);
120   int DoVerifyCert(int result);
121   int DoVerifyCertComplete(int result);
122 
123   bool VerifySignature(const std::string& signed_data,
124                        quic::QuicTransportVersion quic_version,
125                        std::string_view chlo_hash,
126                        const std::string& signature,
127                        const std::string& cert);
128 
129   bool ShouldAllowUnknownRootForHost(const std::string& hostname);
130 
131   int CheckCTRequirements();
132 
133   // Proof verifier to notify when this jobs completes.
134   raw_ptr<ProofVerifierChromium> proof_verifier_;
135 
136   // The underlying verifier used for verifying certificates.
137   raw_ptr<CertVerifier> verifier_;
138   std::unique_ptr<CertVerifier::Request> cert_verifier_request_;
139 
140   raw_ptr<TransportSecurityState> transport_security_state_;
141 
142   raw_ptr<SCTAuditingDelegate> sct_auditing_delegate_;
143 
144   // |hostname| specifies the hostname for which |certs| is a valid chain.
145   std::string hostname_;
146   // |port| specifies the target port for the connection.
147   uint16_t port_;
148   // Encoded stapled OCSP response for |certs|.
149   std::string ocsp_response_;
150   // Encoded SignedCertificateTimestampList for |certs|.
151   std::string cert_sct_;
152 
153   std::unique_ptr<quic::ProofVerifierCallback> callback_;
154   std::unique_ptr<ProofVerifyDetailsChromium> verify_details_;
155   std::string error_details_;
156 
157   // X509Certificate from a chain of DER encoded certificates.
158   scoped_refptr<X509Certificate> cert_;
159 
160   // |cert_verify_flags| is bitwise OR'd of CertVerifier::VerifyFlags and it is
161   // passed to CertVerifier::Verify.
162   int cert_verify_flags_;
163 
164   State next_state_ = STATE_NONE;
165 
166   base::TimeTicks start_time_;
167 
168   NetLogWithSource net_log_;
169 };
170 
Job(ProofVerifierChromium * proof_verifier,CertVerifier * cert_verifier,TransportSecurityState * transport_security_state,SCTAuditingDelegate * sct_auditing_delegate,int cert_verify_flags,const NetLogWithSource & net_log)171 ProofVerifierChromium::Job::Job(
172     ProofVerifierChromium* proof_verifier,
173     CertVerifier* cert_verifier,
174     TransportSecurityState* transport_security_state,
175     SCTAuditingDelegate* sct_auditing_delegate,
176     int cert_verify_flags,
177     const NetLogWithSource& net_log)
178     : proof_verifier_(proof_verifier),
179       verifier_(cert_verifier),
180       transport_security_state_(transport_security_state),
181       sct_auditing_delegate_(sct_auditing_delegate),
182       cert_verify_flags_(cert_verify_flags),
183       start_time_(base::TimeTicks::Now()),
184       net_log_(net_log) {
185   CHECK(proof_verifier_);
186   CHECK(verifier_);
187   CHECK(transport_security_state_);
188 }
189 
~Job()190 ProofVerifierChromium::Job::~Job() {
191   base::TimeTicks end_time = base::TimeTicks::Now();
192   UMA_HISTOGRAM_TIMES("Net.QuicSession.VerifyProofTime",
193                       end_time - start_time_);
194   // |hostname_| will always be canonicalized to lowercase.
195   if (hostname_.compare("www.google.com") == 0) {
196     UMA_HISTOGRAM_TIMES("Net.QuicSession.VerifyProofTime.google",
197                         end_time - start_time_);
198   }
199 }
200 
VerifyProof(const string & hostname,const uint16_t port,const string & server_config,quic::QuicTransportVersion quic_version,std::string_view chlo_hash,const std::vector<string> & certs,const std::string & cert_sct,const string & signature,std::string * error_details,std::unique_ptr<quic::ProofVerifyDetails> * verify_details,std::unique_ptr<quic::ProofVerifierCallback> callback)201 quic::QuicAsyncStatus ProofVerifierChromium::Job::VerifyProof(
202     const string& hostname,
203     const uint16_t port,
204     const string& server_config,
205     quic::QuicTransportVersion quic_version,
206     std::string_view chlo_hash,
207     const std::vector<string>& certs,
208     const std::string& cert_sct,
209     const string& signature,
210     std::string* error_details,
211     std::unique_ptr<quic::ProofVerifyDetails>* verify_details,
212     std::unique_ptr<quic::ProofVerifierCallback> callback) {
213   DCHECK(error_details);
214   DCHECK(verify_details);
215   DCHECK(callback);
216 
217   error_details->clear();
218 
219   if (STATE_NONE != next_state_) {
220     *error_details = "Certificate is already set and VerifyProof has begun";
221     DLOG(DFATAL) << *error_details;
222     return quic::QUIC_FAILURE;
223   }
224 
225   verify_details_ = std::make_unique<ProofVerifyDetailsChromium>();
226 
227   // Converts |certs| to |cert_|.
228   if (!GetX509Certificate(certs, error_details, verify_details))
229     return quic::QUIC_FAILURE;
230 
231   // We call VerifySignature first to avoid copying of server_config and
232   // signature.
233   if (!VerifySignature(server_config, quic_version, chlo_hash, signature,
234                        certs[0])) {
235     *error_details = "Failed to verify signature of server config";
236     DLOG(WARNING) << *error_details;
237     verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID;
238     *verify_details = std::move(verify_details_);
239     return quic::QUIC_FAILURE;
240   }
241 
242   return VerifyCert(hostname, port, /*ocsp_response=*/std::string(), cert_sct,
243                     error_details, verify_details, std::move(callback));
244 }
245 
VerifyCertChain(const string & hostname,const uint16_t port,const std::vector<string> & certs,const std::string & ocsp_response,const std::string & cert_sct,std::string * error_details,std::unique_ptr<quic::ProofVerifyDetails> * verify_details,std::unique_ptr<quic::ProofVerifierCallback> callback)246 quic::QuicAsyncStatus ProofVerifierChromium::Job::VerifyCertChain(
247     const string& hostname,
248     const uint16_t port,
249     const std::vector<string>& certs,
250     const std::string& ocsp_response,
251     const std::string& cert_sct,
252     std::string* error_details,
253     std::unique_ptr<quic::ProofVerifyDetails>* verify_details,
254     std::unique_ptr<quic::ProofVerifierCallback> callback) {
255   DCHECK(error_details);
256   DCHECK(verify_details);
257   DCHECK(callback);
258 
259   error_details->clear();
260 
261   if (STATE_NONE != next_state_) {
262     *error_details = "Certificate is already set and VerifyCertChain has begun";
263     DLOG(DFATAL) << *error_details;
264     return quic::QUIC_FAILURE;
265   }
266 
267   verify_details_ = std::make_unique<ProofVerifyDetailsChromium>();
268 
269   // Converts |certs| to |cert_|.
270   if (!GetX509Certificate(certs, error_details, verify_details))
271     return quic::QUIC_FAILURE;
272 
273   return VerifyCert(hostname, port, ocsp_response, cert_sct, error_details,
274                     verify_details, std::move(callback));
275 }
276 
GetX509Certificate(const std::vector<string> & certs,std::string * error_details,std::unique_ptr<quic::ProofVerifyDetails> * verify_details)277 bool ProofVerifierChromium::Job::GetX509Certificate(
278     const std::vector<string>& certs,
279     std::string* error_details,
280     std::unique_ptr<quic::ProofVerifyDetails>* verify_details) {
281   if (certs.empty()) {
282     *error_details = "Failed to create certificate chain. Certs are empty.";
283     DLOG(WARNING) << *error_details;
284     verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID;
285     *verify_details = std::move(verify_details_);
286     return false;
287   }
288 
289   // Convert certs to X509Certificate.
290   std::vector<std::string_view> cert_pieces(certs.size());
291   for (unsigned i = 0; i < certs.size(); i++) {
292     cert_pieces[i] = std::string_view(certs[i]);
293   }
294   cert_ = X509Certificate::CreateFromDERCertChain(cert_pieces);
295   if (!cert_.get()) {
296     *error_details = "Failed to create certificate chain";
297     DLOG(WARNING) << *error_details;
298     verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID;
299     *verify_details = std::move(verify_details_);
300     return false;
301   }
302   return true;
303 }
304 
VerifyCert(const string & hostname,const uint16_t port,const std::string & ocsp_response,const std::string & cert_sct,std::string * error_details,std::unique_ptr<quic::ProofVerifyDetails> * verify_details,std::unique_ptr<quic::ProofVerifierCallback> callback)305 quic::QuicAsyncStatus ProofVerifierChromium::Job::VerifyCert(
306     const string& hostname,
307     const uint16_t port,
308     const std::string& ocsp_response,
309     const std::string& cert_sct,
310     std::string* error_details,
311     std::unique_ptr<quic::ProofVerifyDetails>* verify_details,
312     std::unique_ptr<quic::ProofVerifierCallback> callback) {
313   hostname_ = hostname;
314   port_ = port;
315   ocsp_response_ = ocsp_response;
316   cert_sct_ = cert_sct;
317 
318   next_state_ = STATE_VERIFY_CERT;
319   switch (DoLoop(OK)) {
320     case OK:
321       *verify_details = std::move(verify_details_);
322       return quic::QUIC_SUCCESS;
323     case ERR_IO_PENDING:
324       callback_ = std::move(callback);
325       return quic::QUIC_PENDING;
326     default:
327       *error_details = error_details_;
328       *verify_details = std::move(verify_details_);
329       return quic::QUIC_FAILURE;
330   }
331 }
332 
DoLoop(int last_result)333 int ProofVerifierChromium::Job::DoLoop(int last_result) {
334   int rv = last_result;
335   do {
336     State state = next_state_;
337     next_state_ = STATE_NONE;
338     switch (state) {
339       case STATE_VERIFY_CERT:
340         DCHECK(rv == OK);
341         rv = DoVerifyCert(rv);
342         break;
343       case STATE_VERIFY_CERT_COMPLETE:
344         rv = DoVerifyCertComplete(rv);
345         break;
346       case STATE_NONE:
347       default:
348         rv = ERR_UNEXPECTED;
349         LOG(DFATAL) << "unexpected state " << state;
350         break;
351     }
352   } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
353   return rv;
354 }
355 
OnIOComplete(int result)356 void ProofVerifierChromium::Job::OnIOComplete(int result) {
357   int rv = DoLoop(result);
358   if (rv != ERR_IO_PENDING) {
359     std::unique_ptr<quic::ProofVerifierCallback> callback(std::move(callback_));
360     // Callback expects quic::ProofVerifyDetails not ProofVerifyDetailsChromium.
361     std::unique_ptr<quic::ProofVerifyDetails> verify_details(
362         std::move(verify_details_));
363     callback->Run(rv == OK, error_details_, &verify_details);
364     // Will delete |this|.
365     proof_verifier_->OnJobComplete(this);
366   }
367 }
368 
DoVerifyCert(int result)369 int ProofVerifierChromium::Job::DoVerifyCert(int result) {
370   next_state_ = STATE_VERIFY_CERT_COMPLETE;
371 
372   return verifier_->Verify(
373       CertVerifier::RequestParams(cert_, hostname_, cert_verify_flags_,
374                                   ocsp_response_, cert_sct_),
375       &verify_details_->cert_verify_result,
376       base::BindOnce(&ProofVerifierChromium::Job::OnIOComplete,
377                      base::Unretained(this)),
378       &cert_verifier_request_, net_log_);
379 }
380 
ShouldAllowUnknownRootForHost(const std::string & hostname)381 bool ProofVerifierChromium::Job::ShouldAllowUnknownRootForHost(
382     const std::string& hostname) {
383   if (base::Contains(proof_verifier_->hostnames_to_allow_unknown_roots_, "")) {
384     return true;
385   }
386   return base::Contains(proof_verifier_->hostnames_to_allow_unknown_roots_,
387                         hostname);
388 }
389 
DoVerifyCertComplete(int result)390 int ProofVerifierChromium::Job::DoVerifyCertComplete(int result) {
391   base::UmaHistogramSparse("Net.QuicSession.CertVerificationResult", -result);
392   cert_verifier_request_.reset();
393 
394   const CertVerifyResult& cert_verify_result =
395       verify_details_->cert_verify_result;
396   const CertStatus cert_status = cert_verify_result.cert_status;
397 
398   // If the connection was good, check HPKP and CT status simultaneously,
399   // but prefer to treat the HPKP error as more serious, if there was one.
400   if (result == OK) {
401     int ct_result = CheckCTRequirements();
402     TransportSecurityState::PKPStatus pin_validity =
403         transport_security_state_->CheckPublicKeyPins(
404             HostPortPair(hostname_, port_),
405             cert_verify_result.is_issued_by_known_root,
406             cert_verify_result.public_key_hashes);
407     switch (pin_validity) {
408       case TransportSecurityState::PKPStatus::VIOLATED:
409         result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN;
410         verify_details_->cert_verify_result.cert_status |=
411             CERT_STATUS_PINNED_KEY_MISSING;
412         break;
413       case TransportSecurityState::PKPStatus::BYPASSED:
414         verify_details_->pkp_bypassed = true;
415         [[fallthrough]];
416       case TransportSecurityState::PKPStatus::OK:
417         // Do nothing.
418         break;
419     }
420     if (result != ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN && ct_result != OK)
421       result = ct_result;
422   }
423 
424   if (result == OK &&
425       !verify_details_->cert_verify_result.is_issued_by_known_root &&
426       !ShouldAllowUnknownRootForHost(hostname_)) {
427     result = ERR_QUIC_CERT_ROOT_NOT_KNOWN;
428   }
429 
430   verify_details_->is_fatal_cert_error =
431       IsCertStatusError(cert_status) &&
432       result != ERR_CERT_KNOWN_INTERCEPTION_BLOCKED &&
433       transport_security_state_->ShouldSSLErrorsBeFatal(hostname_);
434 
435   if (result != OK) {
436     std::string error_string = ErrorToString(result);
437     error_details_ = StringPrintf("Failed to verify certificate chain: %s",
438                                   error_string.c_str());
439     DLOG(WARNING) << error_details_;
440   }
441 
442   // Exit DoLoop and return the result to the caller to VerifyProof.
443   DCHECK_EQ(STATE_NONE, next_state_);
444   return result;
445 }
446 
VerifySignature(const string & signed_data,quic::QuicTransportVersion quic_version,std::string_view chlo_hash,const string & signature,const string & cert)447 bool ProofVerifierChromium::Job::VerifySignature(
448     const string& signed_data,
449     quic::QuicTransportVersion quic_version,
450     std::string_view chlo_hash,
451     const string& signature,
452     const string& cert) {
453   size_t size_bits;
454   X509Certificate::PublicKeyType type;
455   X509Certificate::GetPublicKeyInfo(cert_->cert_buffer(), &size_bits, &type);
456   crypto::SignatureVerifier::SignatureAlgorithm algorithm;
457   switch (type) {
458     case X509Certificate::kPublicKeyTypeRSA:
459       algorithm = crypto::SignatureVerifier::RSA_PSS_SHA256;
460       break;
461     case X509Certificate::kPublicKeyTypeECDSA:
462       algorithm = crypto::SignatureVerifier::ECDSA_SHA256;
463       break;
464     default:
465       LOG(ERROR) << "Unsupported public key type " << type;
466       return false;
467   }
468 
469   if (signature.empty()) {
470     DLOG(WARNING) << "Signature is empty, thus cannot possibly be valid";
471     return false;
472   }
473 
474   crypto::SignatureVerifier verifier;
475   if (!x509_util::SignatureVerifierInitWithCertificate(
476           &verifier, algorithm, base::as_byte_span(signature),
477           cert_->cert_buffer())) {
478     DLOG(WARNING) << "SignatureVerifierInitWithCertificate failed";
479     return false;
480   }
481 
482   verifier.VerifyUpdate(base::as_byte_span(quic::kProofSignatureLabel));
483   uint32_t len = chlo_hash.length();
484   verifier.VerifyUpdate(base::as_bytes(base::make_span(&len, 1u)));
485   verifier.VerifyUpdate(base::as_byte_span(chlo_hash));
486   verifier.VerifyUpdate(base::as_byte_span(signed_data));
487 
488   if (!verifier.VerifyFinal()) {
489     DLOG(WARNING) << "VerifyFinal failed";
490     return false;
491   }
492 
493   DVLOG(1) << "VerifyFinal success";
494   return true;
495 }
496 
CheckCTRequirements()497 int ProofVerifierChromium::Job::CheckCTRequirements() {
498   const CertVerifyResult& cert_verify_result =
499       verify_details_->cert_verify_result;
500 
501   TransportSecurityState::CTRequirementsStatus ct_requirement_status =
502       transport_security_state_->CheckCTRequirements(
503           HostPortPair(hostname_, port_),
504           cert_verify_result.is_issued_by_known_root,
505           cert_verify_result.public_key_hashes,
506           cert_verify_result.verified_cert.get(),
507           cert_verify_result.policy_compliance);
508 
509   if (sct_auditing_delegate_) {
510     sct_auditing_delegate_->MaybeEnqueueReport(
511         HostPortPair(hostname_, port_), cert_verify_result.verified_cert.get(),
512         cert_verify_result.scts);
513   }
514 
515   switch (ct_requirement_status) {
516     case TransportSecurityState::CT_REQUIREMENTS_NOT_MET:
517       verify_details_->cert_verify_result.cert_status |=
518           CERT_STATUS_CERTIFICATE_TRANSPARENCY_REQUIRED;
519       return ERR_CERTIFICATE_TRANSPARENCY_REQUIRED;
520     case TransportSecurityState::CT_REQUIREMENTS_MET:
521     case TransportSecurityState::CT_NOT_REQUIRED:
522       return OK;
523   }
524 }
525 
ProofVerifierChromium(CertVerifier * cert_verifier,TransportSecurityState * transport_security_state,SCTAuditingDelegate * sct_auditing_delegate,std::set<std::string> hostnames_to_allow_unknown_roots,const NetworkAnonymizationKey & network_anonymization_key)526 ProofVerifierChromium::ProofVerifierChromium(
527     CertVerifier* cert_verifier,
528     TransportSecurityState* transport_security_state,
529     SCTAuditingDelegate* sct_auditing_delegate,
530     std::set<std::string> hostnames_to_allow_unknown_roots,
531     const NetworkAnonymizationKey& network_anonymization_key)
532     : cert_verifier_(cert_verifier),
533       transport_security_state_(transport_security_state),
534       sct_auditing_delegate_(sct_auditing_delegate),
535       hostnames_to_allow_unknown_roots_(hostnames_to_allow_unknown_roots),
536       network_anonymization_key_(network_anonymization_key) {
537   DCHECK(cert_verifier_);
538   DCHECK(transport_security_state_);
539 }
540 
541 ProofVerifierChromium::~ProofVerifierChromium() = default;
542 
VerifyProof(const std::string & hostname,const uint16_t port,const std::string & server_config,quic::QuicTransportVersion quic_version,std::string_view chlo_hash,const std::vector<std::string> & certs,const std::string & cert_sct,const std::string & signature,const quic::ProofVerifyContext * verify_context,std::string * error_details,std::unique_ptr<quic::ProofVerifyDetails> * verify_details,std::unique_ptr<quic::ProofVerifierCallback> callback)543 quic::QuicAsyncStatus ProofVerifierChromium::VerifyProof(
544     const std::string& hostname,
545     const uint16_t port,
546     const std::string& server_config,
547     quic::QuicTransportVersion quic_version,
548     std::string_view chlo_hash,
549     const std::vector<std::string>& certs,
550     const std::string& cert_sct,
551     const std::string& signature,
552     const quic::ProofVerifyContext* verify_context,
553     std::string* error_details,
554     std::unique_ptr<quic::ProofVerifyDetails>* verify_details,
555     std::unique_ptr<quic::ProofVerifierCallback> callback) {
556   if (!verify_context) {
557     DLOG(FATAL) << "Missing proof verify context";
558     *error_details = "Missing context";
559     return quic::QUIC_FAILURE;
560   }
561   const ProofVerifyContextChromium* chromium_context =
562       reinterpret_cast<const ProofVerifyContextChromium*>(verify_context);
563   std::unique_ptr<Job> job = std::make_unique<Job>(
564       this, cert_verifier_, transport_security_state_, sct_auditing_delegate_,
565       chromium_context->cert_verify_flags, chromium_context->net_log);
566   quic::QuicAsyncStatus status = job->VerifyProof(
567       hostname, port, server_config, quic_version, chlo_hash, certs, cert_sct,
568       signature, error_details, verify_details, std::move(callback));
569   if (status == quic::QUIC_PENDING) {
570     Job* job_ptr = job.get();
571     active_jobs_[job_ptr] = std::move(job);
572   }
573   return status;
574 }
575 
VerifyCertChain(const std::string & hostname,const uint16_t port,const std::vector<std::string> & certs,const std::string & ocsp_response,const std::string & cert_sct,const quic::ProofVerifyContext * verify_context,std::string * error_details,std::unique_ptr<quic::ProofVerifyDetails> * verify_details,uint8_t *,std::unique_ptr<quic::ProofVerifierCallback> callback)576 quic::QuicAsyncStatus ProofVerifierChromium::VerifyCertChain(
577     const std::string& hostname,
578     const uint16_t port,
579     const std::vector<std::string>& certs,
580     const std::string& ocsp_response,
581     const std::string& cert_sct,
582     const quic::ProofVerifyContext* verify_context,
583     std::string* error_details,
584     std::unique_ptr<quic::ProofVerifyDetails>* verify_details,
585     uint8_t* /*out_alert*/,
586     std::unique_ptr<quic::ProofVerifierCallback> callback) {
587   if (!verify_context) {
588     *error_details = "Missing context";
589     return quic::QUIC_FAILURE;
590   }
591   const ProofVerifyContextChromium* chromium_context =
592       reinterpret_cast<const ProofVerifyContextChromium*>(verify_context);
593   std::unique_ptr<Job> job = std::make_unique<Job>(
594       this, cert_verifier_, transport_security_state_, sct_auditing_delegate_,
595       chromium_context->cert_verify_flags, chromium_context->net_log);
596   quic::QuicAsyncStatus status =
597       job->VerifyCertChain(hostname, port, certs, ocsp_response, cert_sct,
598                            error_details, verify_details, std::move(callback));
599   if (status == quic::QUIC_PENDING) {
600     Job* job_ptr = job.get();
601     active_jobs_[job_ptr] = std::move(job);
602   }
603   return status;
604 }
605 
606 std::unique_ptr<quic::ProofVerifyContext>
CreateDefaultContext()607 ProofVerifierChromium::CreateDefaultContext() {
608   return std::make_unique<ProofVerifyContextChromium>(0,
609                                                       net::NetLogWithSource());
610 }
611 
OnJobComplete(Job * job)612 void ProofVerifierChromium::OnJobComplete(Job* job) {
613   active_jobs_.erase(job);
614 }
615 
616 }  // namespace net
617