blob: d7ee393f762f98fcc6a1a0df7bef6341df1a0a1c [file] [log] [blame]
[email protected]2662ed562013-07-03 10:27:461// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/quic/crypto/proof_verifier_chromium.h"
6
dchengc7eeda422015-12-26 03:56:487#include <utility>
8
[email protected]2662ed562013-07-03 10:27:469#include "base/bind.h"
10#include "base/bind_helpers.h"
11#include "base/callback_helpers.h"
12#include "base/compiler_specific.h"
13#include "base/logging.h"
Avi Drissman13fc8932015-12-20 04:40:4614#include "base/macros.h"
asvitkinec3c93722015-06-17 14:48:3715#include "base/metrics/histogram_macros.h"
[email protected]5c78ce62014-03-13 19:48:0116#include "base/stl_util.h"
[email protected]2662ed562013-07-03 10:27:4617#include "base/strings/stringprintf.h"
18#include "crypto/signature_verifier.h"
estark1a66df72015-07-28 15:24:0019#include "net/base/host_port_pair.h"
[email protected]2662ed562013-07-03 10:27:4620#include "net/base/net_errors.h"
[email protected]2662ed562013-07-03 10:27:4621#include "net/cert/asn1_util.h"
rsleevi9541f8632015-07-31 00:07:0022#include "net/cert/cert_policy_enforcer.h"
[email protected]2662ed562013-07-03 10:27:4623#include "net/cert/cert_status_flags.h"
24#include "net/cert/cert_verifier.h"
25#include "net/cert/cert_verify_result.h"
rtenneti052774e2015-11-24 21:00:1226#include "net/cert/ct_verifier.h"
[email protected]2662ed562013-07-03 10:27:4627#include "net/cert/x509_certificate.h"
28#include "net/cert/x509_util.h"
[email protected]080b77932014-08-04 01:22:4629#include "net/http/transport_security_state.h"
eroman87c53d62015-04-02 06:51:0730#include "net/log/net_log.h"
[email protected]2662ed562013-07-03 10:27:4631#include "net/quic/crypto/crypto_protocol.h"
32#include "net/ssl/ssl_config_service.h"
33
34using base::StringPiece;
35using base::StringPrintf;
36using std::string;
37using std::vector;
38
39namespace net {
40
[email protected]92bc621d2014-07-29 21:42:1341ProofVerifyDetails* ProofVerifyDetailsChromium::Clone() const {
42 ProofVerifyDetailsChromium* other = new ProofVerifyDetailsChromium;
43 other->cert_verify_result = cert_verify_result;
rtenneti052774e2015-11-24 21:00:1244 other->ct_verify_result = ct_verify_result;
[email protected]92bc621d2014-07-29 21:42:1345 return other;
46}
47
[email protected]5c78ce62014-03-13 19:48:0148// A Job handles the verification of a single proof. It is owned by the
49// ProofVerifier. If the verification can not complete synchronously, it
50// will notify the ProofVerifier upon completion.
51class ProofVerifierChromium::Job {
52 public:
53 Job(ProofVerifierChromium* proof_verifier,
54 CertVerifier* cert_verifier,
rsleevi9541f8632015-07-31 00:07:0055 CertPolicyEnforcer* cert_policy_enforcer,
[email protected]080b77932014-08-04 01:22:4656 TransportSecurityState* transport_security_state,
rtenneti052774e2015-11-24 21:00:1257 CTVerifier* cert_transparency_verifier,
rtennetia75df622015-06-21 23:59:5058 int cert_verify_flags,
[email protected]5c78ce62014-03-13 19:48:0159 const BoundNetLog& net_log);
rtennetidd4f1bd72015-12-23 19:17:5060 ~Job();
[email protected]5c78ce62014-03-13 19:48:0161
[email protected]05bfc260f2014-06-07 06:31:2562 // Starts the proof verification. If |QUIC_PENDING| is returned, then
63 // |callback| will be invoked asynchronously when the verification completes.
[email protected]730b35d72014-06-05 03:23:2264 QuicAsyncStatus VerifyProof(const std::string& hostname,
65 const std::string& server_config,
66 const std::vector<std::string>& certs,
rjshadec86dbfa2015-11-12 20:16:2567 const std::string& cert_sct,
[email protected]730b35d72014-06-05 03:23:2268 const std::string& signature,
69 std::string* error_details,
70 scoped_ptr<ProofVerifyDetails>* verify_details,
71 ProofVerifierCallback* callback);
[email protected]5c78ce62014-03-13 19:48:0172
73 private:
74 enum State {
75 STATE_NONE,
76 STATE_VERIFY_CERT,
77 STATE_VERIFY_CERT_COMPLETE,
78 };
79
80 int DoLoop(int last_io_result);
81 void OnIOComplete(int result);
82 int DoVerifyCert(int result);
83 int DoVerifyCertComplete(int result);
84
85 bool VerifySignature(const std::string& signed_data,
86 const std::string& signature,
87 const std::string& cert);
88
89 // Proof verifier to notify when this jobs completes.
90 ProofVerifierChromium* proof_verifier_;
91
92 // The underlying verifier used for verifying certificates.
eroman7f9236a2015-05-11 21:23:4393 CertVerifier* verifier_;
94 scoped_ptr<CertVerifier::Request> cert_verifier_request_;
[email protected]5c78ce62014-03-13 19:48:0195
rsleevi9541f8632015-07-31 00:07:0096 CertPolicyEnforcer* policy_enforcer_;
97
[email protected]080b77932014-08-04 01:22:4698 TransportSecurityState* transport_security_state_;
99
rtenneti052774e2015-11-24 21:00:12100 CTVerifier* cert_transparency_verifier_;
101
[email protected]5c78ce62014-03-13 19:48:01102 // |hostname| specifies the hostname for which |certs| is a valid chain.
103 std::string hostname_;
104
105 scoped_ptr<ProofVerifierCallback> callback_;
106 scoped_ptr<ProofVerifyDetailsChromium> verify_details_;
107 std::string error_details_;
108
109 // X509Certificate from a chain of DER encoded certificates.
110 scoped_refptr<X509Certificate> cert_;
111
rtennetia75df622015-06-21 23:59:50112 // |cert_verify_flags| is bitwise OR'd of CertVerifier::VerifyFlags and it is
113 // passed to CertVerifier::Verify.
114 int cert_verify_flags_;
115
[email protected]5c78ce62014-03-13 19:48:01116 State next_state_;
117
rtennetidd4f1bd72015-12-23 19:17:50118 base::TimeTicks start_time_;
119
[email protected]5c78ce62014-03-13 19:48:01120 BoundNetLog net_log_;
121
122 DISALLOW_COPY_AND_ASSIGN(Job);
123};
124
[email protected]080b77932014-08-04 01:22:46125ProofVerifierChromium::Job::Job(
126 ProofVerifierChromium* proof_verifier,
127 CertVerifier* cert_verifier,
rsleevi9541f8632015-07-31 00:07:00128 CertPolicyEnforcer* cert_policy_enforcer,
[email protected]080b77932014-08-04 01:22:46129 TransportSecurityState* transport_security_state,
rtenneti052774e2015-11-24 21:00:12130 CTVerifier* cert_transparency_verifier,
rtennetia75df622015-06-21 23:59:50131 int cert_verify_flags,
[email protected]080b77932014-08-04 01:22:46132 const BoundNetLog& net_log)
[email protected]5c78ce62014-03-13 19:48:01133 : proof_verifier_(proof_verifier),
eroman7f9236a2015-05-11 21:23:43134 verifier_(cert_verifier),
rsleevi9541f8632015-07-31 00:07:00135 policy_enforcer_(cert_policy_enforcer),
[email protected]080b77932014-08-04 01:22:46136 transport_security_state_(transport_security_state),
rtenneti052774e2015-11-24 21:00:12137 cert_transparency_verifier_(cert_transparency_verifier),
rtennetia75df622015-06-21 23:59:50138 cert_verify_flags_(cert_verify_flags),
[email protected]5c78ce62014-03-13 19:48:01139 next_state_(STATE_NONE),
rtennetidd4f1bd72015-12-23 19:17:50140 start_time_(base::TimeTicks::Now()),
rsleevi9541f8632015-07-31 00:07:00141 net_log_(net_log) {}
[email protected]2662ed562013-07-03 10:27:46142
rtennetidd4f1bd72015-12-23 19:17:50143ProofVerifierChromium::Job::~Job() {
144 base::TimeTicks end_time = base::TimeTicks::Now();
145 UMA_HISTOGRAM_TIMES("Net.QuicSession.VerifyProofTime",
146 end_time - start_time_);
147 // |hostname_| will always be canonicalized to lowercase.
148 if (hostname_.compare("www.google.com") == 0) {
149 UMA_HISTOGRAM_TIMES("Net.QuicSession.VerifyProofTime.google",
150 end_time - start_time_);
151 }
152}
153
[email protected]730b35d72014-06-05 03:23:22154QuicAsyncStatus ProofVerifierChromium::Job::VerifyProof(
[email protected]72e65992013-07-30 17:16:14155 const string& hostname,
156 const string& server_config,
157 const vector<string>& certs,
rjshadec86dbfa2015-11-12 20:16:25158 const std::string& cert_sct,
[email protected]72e65992013-07-30 17:16:14159 const string& signature,
160 std::string* error_details,
[email protected]c817c672014-03-21 22:25:34161 scoped_ptr<ProofVerifyDetails>* verify_details,
[email protected]72e65992013-07-30 17:16:14162 ProofVerifierCallback* callback) {
[email protected]2662ed562013-07-03 10:27:46163 DCHECK(error_details);
[email protected]c817c672014-03-21 22:25:34164 DCHECK(verify_details);
[email protected]72e65992013-07-30 17:16:14165 DCHECK(callback);
166
[email protected]2662ed562013-07-03 10:27:46167 error_details->clear();
168
[email protected]2662ed562013-07-03 10:27:46169 if (STATE_NONE != next_state_) {
170 *error_details = "Certificate is already set and VerifyProof has begun";
[email protected]5c78ce62014-03-13 19:48:01171 DLOG(DFATAL) << *error_details;
[email protected]730b35d72014-06-05 03:23:22172 return QUIC_FAILURE;
[email protected]2662ed562013-07-03 10:27:46173 }
174
[email protected]72e65992013-07-30 17:16:14175 verify_details_.reset(new ProofVerifyDetailsChromium);
176
[email protected]2662ed562013-07-03 10:27:46177 if (certs.empty()) {
178 *error_details = "Failed to create certificate chain. Certs are empty.";
179 DLOG(WARNING) << *error_details;
[email protected]72e65992013-07-30 17:16:14180 verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID;
dchengc7eeda422015-12-26 03:56:48181 *verify_details = std::move(verify_details_);
[email protected]730b35d72014-06-05 03:23:22182 return QUIC_FAILURE;
[email protected]2662ed562013-07-03 10:27:46183 }
184
185 // Convert certs to X509Certificate.
186 vector<StringPiece> cert_pieces(certs.size());
187 for (unsigned i = 0; i < certs.size(); i++) {
188 cert_pieces[i] = base::StringPiece(certs[i]);
189 }
190 cert_ = X509Certificate::CreateFromDERCertChain(cert_pieces);
191 if (!cert_.get()) {
[email protected]2662ed562013-07-03 10:27:46192 *error_details = "Failed to create certificate chain";
193 DLOG(WARNING) << *error_details;
[email protected]72e65992013-07-30 17:16:14194 verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID;
dchengc7eeda422015-12-26 03:56:48195 *verify_details = std::move(verify_details_);
[email protected]730b35d72014-06-05 03:23:22196 return QUIC_FAILURE;
[email protected]2662ed562013-07-03 10:27:46197 }
198
rtenneti052774e2015-11-24 21:00:12199 if (cert_transparency_verifier_ && !cert_sct.empty()) {
200 // Note that this is a completely synchronous operation: The CT Log Verifier
201 // gets all the data it needs for SCT verification and does not do any
202 // external communication.
203 cert_transparency_verifier_->Verify(cert_.get(), std::string(), cert_sct,
204 &verify_details_->ct_verify_result,
205 net_log_);
206 }
207
[email protected]2662ed562013-07-03 10:27:46208 // We call VerifySignature first to avoid copying of server_config and
209 // signature.
[email protected]d5c9e4ba2013-09-14 05:25:58210 if (!VerifySignature(server_config, signature, certs[0])) {
[email protected]2662ed562013-07-03 10:27:46211 *error_details = "Failed to verify signature of server config";
212 DLOG(WARNING) << *error_details;
[email protected]72e65992013-07-30 17:16:14213 verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID;
dchengc7eeda422015-12-26 03:56:48214 *verify_details = std::move(verify_details_);
[email protected]730b35d72014-06-05 03:23:22215 return QUIC_FAILURE;
[email protected]2662ed562013-07-03 10:27:46216 }
217
218 hostname_ = hostname;
[email protected]2662ed562013-07-03 10:27:46219
220 next_state_ = STATE_VERIFY_CERT;
[email protected]72e65992013-07-30 17:16:14221 switch (DoLoop(OK)) {
222 case OK:
dchengc7eeda422015-12-26 03:56:48223 *verify_details = std::move(verify_details_);
[email protected]730b35d72014-06-05 03:23:22224 return QUIC_SUCCESS;
[email protected]72e65992013-07-30 17:16:14225 case ERR_IO_PENDING:
[email protected]3ce3bf22014-04-03 08:02:01226 callback_.reset(callback);
[email protected]730b35d72014-06-05 03:23:22227 return QUIC_PENDING;
[email protected]72e65992013-07-30 17:16:14228 default:
229 *error_details = error_details_;
dchengc7eeda422015-12-26 03:56:48230 *verify_details = std::move(verify_details_);
[email protected]730b35d72014-06-05 03:23:22231 return QUIC_FAILURE;
[email protected]72e65992013-07-30 17:16:14232 }
[email protected]2662ed562013-07-03 10:27:46233}
234
[email protected]5c78ce62014-03-13 19:48:01235int ProofVerifierChromium::Job::DoLoop(int last_result) {
[email protected]2662ed562013-07-03 10:27:46236 int rv = last_result;
237 do {
238 State state = next_state_;
239 next_state_ = STATE_NONE;
240 switch (state) {
241 case STATE_VERIFY_CERT:
242 DCHECK(rv == OK);
243 rv = DoVerifyCert(rv);
244 break;
245 case STATE_VERIFY_CERT_COMPLETE:
246 rv = DoVerifyCertComplete(rv);
247 break;
248 case STATE_NONE:
249 default:
250 rv = ERR_UNEXPECTED;
251 LOG(DFATAL) << "unexpected state " << state;
252 break;
253 }
254 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
255 return rv;
256}
257
[email protected]5c78ce62014-03-13 19:48:01258void ProofVerifierChromium::Job::OnIOComplete(int result) {
[email protected]2662ed562013-07-03 10:27:46259 int rv = DoLoop(result);
260 if (rv != ERR_IO_PENDING) {
dchengc7eeda422015-12-26 03:56:48261 scoped_ptr<ProofVerifierCallback> callback(std::move(callback_));
[email protected]5c78ce62014-03-13 19:48:01262 // Callback expects ProofVerifyDetails not ProofVerifyDetailsChromium.
dchengc7eeda422015-12-26 03:56:48263 scoped_ptr<ProofVerifyDetails> verify_details(std::move(verify_details_));
[email protected]5c78ce62014-03-13 19:48:01264 callback->Run(rv == OK, error_details_, &verify_details);
265 // Will delete |this|.
266 proof_verifier_->OnJobComplete(this);
[email protected]2662ed562013-07-03 10:27:46267 }
268}
269
[email protected]5c78ce62014-03-13 19:48:01270int ProofVerifierChromium::Job::DoVerifyCert(int result) {
[email protected]2662ed562013-07-03 10:27:46271 next_state_ = STATE_VERIFY_CERT_COMPLETE;
272
rtennetia75df622015-06-21 23:59:50273 return verifier_->Verify(
274 cert_.get(), hostname_, std::string(), cert_verify_flags_,
275 SSLConfigService::GetCRLSet().get(), &verify_details_->cert_verify_result,
276 base::Bind(&ProofVerifierChromium::Job::OnIOComplete,
277 base::Unretained(this)),
278 &cert_verifier_request_, net_log_);
[email protected]2662ed562013-07-03 10:27:46279}
280
[email protected]5c78ce62014-03-13 19:48:01281int ProofVerifierChromium::Job::DoVerifyCertComplete(int result) {
eroman7f9236a2015-05-11 21:23:43282 cert_verifier_request_.reset();
[email protected]2662ed562013-07-03 10:27:46283
[email protected]080b77932014-08-04 01:22:46284 const CertVerifyResult& cert_verify_result =
285 verify_details_->cert_verify_result;
[email protected]080b77932014-08-04 01:22:46286 const CertStatus cert_status = cert_verify_result.cert_status;
rsleevi9541f8632015-07-31 00:07:00287 if (result == OK && policy_enforcer_ &&
288 (cert_verify_result.cert_status & CERT_STATUS_IS_EV)) {
rsleevi9541f8632015-07-31 00:07:00289 if (!policy_enforcer_->DoesConformToCTEVPolicy(
290 cert_verify_result.verified_cert.get(),
rtenneti052774e2015-11-24 21:00:12291 SSLConfigService::GetEVCertsWhitelist().get(),
292 verify_details_->ct_verify_result, net_log_)) {
haavardm533c27b2015-08-13 09:27:29293 verify_details_->cert_verify_result.cert_status |=
294 CERT_STATUS_CT_COMPLIANCE_FAILED;
rsleevi9541f8632015-07-31 00:07:00295 verify_details_->cert_verify_result.cert_status &= ~CERT_STATUS_IS_EV;
296 }
297 }
298
estark1a66df72015-07-28 15:24:00299 // TODO(estark): replace 0 below with the port of the connection.
[email protected]8d60aa52014-08-08 21:22:45300 if (transport_security_state_ &&
[email protected]080b77932014-08-04 01:22:46301 (result == OK ||
302 (IsCertificateError(result) && IsCertStatusMinorError(cert_status))) &&
[email protected]8d60aa52014-08-08 21:22:45303 !transport_security_state_->CheckPublicKeyPins(
estark1a66df72015-07-28 15:24:00304 HostPortPair(hostname_, 0),
[email protected]8d60aa52014-08-08 21:22:45305 cert_verify_result.is_issued_by_known_root,
estark1a66df72015-07-28 15:24:00306 cert_verify_result.public_key_hashes, cert_.get(),
307 cert_verify_result.verified_cert.get(),
308 TransportSecurityState::ENABLE_PIN_REPORTS,
[email protected]8d60aa52014-08-08 21:22:45309 &verify_details_->pinning_failure_log)) {
310 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN;
[email protected]080b77932014-08-04 01:22:46311 }
[email protected]080b77932014-08-04 01:22:46312
[email protected]0cceb922014-07-01 02:00:56313 if (result != OK) {
[email protected]3030374e32014-08-07 16:12:06314 std::string error_string = ErrorToString(result);
[email protected]72e65992013-07-30 17:16:14315 error_details_ = StringPrintf("Failed to verify certificate chain: %s",
[email protected]3030374e32014-08-07 16:12:06316 error_string.c_str());
[email protected]72e65992013-07-30 17:16:14317 DLOG(WARNING) << error_details_;
[email protected]2662ed562013-07-03 10:27:46318 }
319
320 // Exit DoLoop and return the result to the caller to VerifyProof.
321 DCHECK_EQ(STATE_NONE, next_state_);
322 return result;
323}
324
[email protected]5c78ce62014-03-13 19:48:01325bool ProofVerifierChromium::Job::VerifySignature(const string& signed_data,
[email protected]3030374e32014-08-07 16:12:06326 const string& signature,
327 const string& cert) {
[email protected]2662ed562013-07-03 10:27:46328 StringPiece spki;
329 if (!asn1::ExtractSPKIFromDERCert(cert, &spki)) {
330 DLOG(WARNING) << "ExtractSPKIFromDERCert failed";
331 return false;
332 }
333
334 crypto::SignatureVerifier verifier;
335
336 size_t size_bits;
337 X509Certificate::PublicKeyType type;
rjshaded5ced072015-12-18 19:26:02338 X509Certificate::GetPublicKeyInfo(cert_->os_cert_handle(), &size_bits, &type);
[email protected]2662ed562013-07-03 10:27:46339 if (type == X509Certificate::kPublicKeyTypeRSA) {
340 crypto::SignatureVerifier::HashAlgorithm hash_alg =
341 crypto::SignatureVerifier::SHA256;
342 crypto::SignatureVerifier::HashAlgorithm mask_hash_alg = hash_alg;
343 unsigned int hash_len = 32; // 32 is the length of a SHA-256 hash.
[email protected]2662ed562013-07-03 10:27:46344
345 bool ok = verifier.VerifyInitRSAPSS(
[email protected]d5c9e4ba2013-09-14 05:25:58346 hash_alg, mask_hash_alg, hash_len,
Avi Drissman13fc8932015-12-20 04:40:46347 reinterpret_cast<const uint8_t*>(signature.data()), signature.size(),
348 reinterpret_cast<const uint8_t*>(spki.data()), spki.size());
[email protected]2662ed562013-07-03 10:27:46349 if (!ok) {
350 DLOG(WARNING) << "VerifyInitRSAPSS failed";
351 return false;
352 }
353 } else if (type == X509Certificate::kPublicKeyTypeECDSA) {
354 // This is the algorithm ID for ECDSA with SHA-256. Parameters are ABSENT.
355 // RFC 5758:
356 // ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
357 // us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 2 }
358 // ...
359 // When the ecdsa-with-SHA224, ecdsa-with-SHA256, ecdsa-with-SHA384, or
360 // ecdsa-with-SHA512 algorithm identifier appears in the algorithm field
361 // as an AlgorithmIdentifier, the encoding MUST omit the parameters
362 // field. That is, the AlgorithmIdentifier SHALL be a SEQUENCE of one
363 // component, the OID ecdsa-with-SHA224, ecdsa-with-SHA256, ecdsa-with-
364 // SHA384, or ecdsa-with-SHA512.
365 // See also RFC 5480, Appendix A.
Avi Drissman13fc8932015-12-20 04:40:46366 static const uint8_t kECDSAWithSHA256AlgorithmID[] = {
rjshaded5ced072015-12-18 19:26:02367 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02,
[email protected]2662ed562013-07-03 10:27:46368 };
369
370 if (!verifier.VerifyInit(
371 kECDSAWithSHA256AlgorithmID, sizeof(kECDSAWithSHA256AlgorithmID),
Avi Drissman13fc8932015-12-20 04:40:46372 reinterpret_cast<const uint8_t*>(signature.data()),
373 signature.size(), reinterpret_cast<const uint8_t*>(spki.data()),
374 spki.size())) {
[email protected]2662ed562013-07-03 10:27:46375 DLOG(WARNING) << "VerifyInit failed";
376 return false;
377 }
378 } else {
379 LOG(ERROR) << "Unsupported public key type " << type;
380 return false;
381 }
382
Avi Drissman13fc8932015-12-20 04:40:46383 verifier.VerifyUpdate(reinterpret_cast<const uint8_t*>(kProofSignatureLabel),
[email protected]2662ed562013-07-03 10:27:46384 sizeof(kProofSignatureLabel));
Avi Drissman13fc8932015-12-20 04:40:46385 verifier.VerifyUpdate(reinterpret_cast<const uint8_t*>(signed_data.data()),
[email protected]2662ed562013-07-03 10:27:46386 signed_data.size());
387
388 if (!verifier.VerifyFinal()) {
389 DLOG(WARNING) << "VerifyFinal failed";
390 return false;
391 }
392
[email protected]3e5fed12013-11-22 22:21:41393 DVLOG(1) << "VerifyFinal success";
[email protected]2662ed562013-07-03 10:27:46394 return true;
395}
396
[email protected]080b77932014-08-04 01:22:46397ProofVerifierChromium::ProofVerifierChromium(
398 CertVerifier* cert_verifier,
rsleevi9541f8632015-07-31 00:07:00399 CertPolicyEnforcer* cert_policy_enforcer,
rtenneti052774e2015-11-24 21:00:12400 TransportSecurityState* transport_security_state,
401 CTVerifier* cert_transparency_verifier)
[email protected]080b77932014-08-04 01:22:46402 : cert_verifier_(cert_verifier),
rsleevi9541f8632015-07-31 00:07:00403 cert_policy_enforcer_(cert_policy_enforcer),
rtenneti052774e2015-11-24 21:00:12404 transport_security_state_(transport_security_state),
405 cert_transparency_verifier_(cert_transparency_verifier) {}
[email protected]5c78ce62014-03-13 19:48:01406
407ProofVerifierChromium::~ProofVerifierChromium() {
408 STLDeleteElements(&active_jobs_);
409}
410
[email protected]730b35d72014-06-05 03:23:22411QuicAsyncStatus ProofVerifierChromium::VerifyProof(
[email protected]5c78ce62014-03-13 19:48:01412 const std::string& hostname,
413 const std::string& server_config,
414 const std::vector<std::string>& certs,
rjshadec86dbfa2015-11-12 20:16:25415 const std::string& cert_sct,
[email protected]5c78ce62014-03-13 19:48:01416 const std::string& signature,
[email protected]c817c672014-03-21 22:25:34417 const ProofVerifyContext* verify_context,
[email protected]5c78ce62014-03-13 19:48:01418 std::string* error_details,
[email protected]c817c672014-03-21 22:25:34419 scoped_ptr<ProofVerifyDetails>* verify_details,
[email protected]5c78ce62014-03-13 19:48:01420 ProofVerifierCallback* callback) {
[email protected]c817c672014-03-21 22:25:34421 if (!verify_context) {
422 *error_details = "Missing context";
[email protected]730b35d72014-06-05 03:23:22423 return QUIC_FAILURE;
[email protected]c817c672014-03-21 22:25:34424 }
425 const ProofVerifyContextChromium* chromium_context =
426 reinterpret_cast<const ProofVerifyContextChromium*>(verify_context);
rtenneti052774e2015-11-24 21:00:12427 scoped_ptr<Job> job(
428 new Job(this, cert_verifier_, cert_policy_enforcer_,
429 transport_security_state_, cert_transparency_verifier_,
430 chromium_context->cert_verify_flags, chromium_context->net_log));
rtennetia75df622015-06-21 23:59:50431 QuicAsyncStatus status =
rjshadec86dbfa2015-11-12 20:16:25432 job->VerifyProof(hostname, server_config, certs, cert_sct, signature,
433 error_details, verify_details, callback);
[email protected]730b35d72014-06-05 03:23:22434 if (status == QUIC_PENDING) {
[email protected]5c78ce62014-03-13 19:48:01435 active_jobs_.insert(job.release());
436 }
437 return status;
438}
439
440void ProofVerifierChromium::OnJobComplete(Job* job) {
441 active_jobs_.erase(job);
442 delete job;
443}
444
[email protected]2662ed562013-07-03 10:27:46445} // namespace net