blob: e6e9516eef078f10cbed121bc1c58f5117eb1a64 [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"
22#include "net/cert/cert_status_flags.h"
23#include "net/cert/cert_verifier.h"
24#include "net/cert/cert_verify_result.h"
estark6f9b3d82016-01-12 21:37:0525#include "net/cert/ct_policy_enforcer.h"
estark723b5eeb2016-02-18 21:01:1226#include "net/cert/ct_policy_status.h"
rtenneti052774e2015-11-24 21:00:1227#include "net/cert/ct_verifier.h"
[email protected]2662ed562013-07-03 10:27:4628#include "net/cert/x509_certificate.h"
29#include "net/cert/x509_util.h"
[email protected]080b77932014-08-04 01:22:4630#include "net/http/transport_security_state.h"
eroman87c53d62015-04-02 06:51:0731#include "net/log/net_log.h"
[email protected]2662ed562013-07-03 10:27:4632#include "net/quic/crypto/crypto_protocol.h"
33#include "net/ssl/ssl_config_service.h"
34
35using base::StringPiece;
36using base::StringPrintf;
37using std::string;
38using std::vector;
39
40namespace net {
41
[email protected]92bc621d2014-07-29 21:42:1342ProofVerifyDetails* ProofVerifyDetailsChromium::Clone() const {
43 ProofVerifyDetailsChromium* other = new ProofVerifyDetailsChromium;
44 other->cert_verify_result = cert_verify_result;
rtenneti052774e2015-11-24 21:00:1245 other->ct_verify_result = ct_verify_result;
[email protected]92bc621d2014-07-29 21:42:1346 return other;
47}
48
[email protected]5c78ce62014-03-13 19:48:0149// A Job handles the verification of a single proof. It is owned by the
50// ProofVerifier. If the verification can not complete synchronously, it
51// will notify the ProofVerifier upon completion.
52class ProofVerifierChromium::Job {
53 public:
54 Job(ProofVerifierChromium* proof_verifier,
55 CertVerifier* cert_verifier,
estark6f9b3d82016-01-12 21:37:0556 CTPolicyEnforcer* ct_policy_enforcer,
[email protected]080b77932014-08-04 01:22:4657 TransportSecurityState* transport_security_state,
rtenneti052774e2015-11-24 21:00:1258 CTVerifier* cert_transparency_verifier,
rtennetia75df622015-06-21 23:59:5059 int cert_verify_flags,
[email protected]5c78ce62014-03-13 19:48:0160 const BoundNetLog& net_log);
rtennetidd4f1bd72015-12-23 19:17:5061 ~Job();
[email protected]5c78ce62014-03-13 19:48:0162
[email protected]05bfc260f2014-06-07 06:31:2563 // Starts the proof verification. If |QUIC_PENDING| is returned, then
64 // |callback| will be invoked asynchronously when the verification completes.
danakjad1777e2016-04-16 00:56:4265 QuicAsyncStatus VerifyProof(
66 const std::string& hostname,
67 const uint16_t port,
68 const std::string& server_config,
69 QuicVersion quic_version,
70 base::StringPiece chlo_hash,
71 const std::vector<std::string>& certs,
72 const std::string& cert_sct,
73 const std::string& signature,
74 std::string* error_details,
75 std::unique_ptr<ProofVerifyDetails>* verify_details,
76 ProofVerifierCallback* callback);
[email protected]5c78ce62014-03-13 19:48:0177
78 private:
79 enum State {
80 STATE_NONE,
81 STATE_VERIFY_CERT,
82 STATE_VERIFY_CERT_COMPLETE,
83 };
84
85 int DoLoop(int last_io_result);
86 void OnIOComplete(int result);
87 int DoVerifyCert(int result);
88 int DoVerifyCertComplete(int result);
89
90 bool VerifySignature(const std::string& signed_data,
rch28f6469d2016-03-13 21:13:0891 QuicVersion quic_version,
92 StringPiece chlo_hash,
[email protected]5c78ce62014-03-13 19:48:0193 const std::string& signature,
94 const std::string& cert);
95
96 // Proof verifier to notify when this jobs completes.
97 ProofVerifierChromium* proof_verifier_;
98
99 // The underlying verifier used for verifying certificates.
eroman7f9236a2015-05-11 21:23:43100 CertVerifier* verifier_;
danakjad1777e2016-04-16 00:56:42101 std::unique_ptr<CertVerifier::Request> cert_verifier_request_;
[email protected]5c78ce62014-03-13 19:48:01102
estark6f9b3d82016-01-12 21:37:05103 CTPolicyEnforcer* policy_enforcer_;
rsleevi9541f8632015-07-31 00:07:00104
[email protected]080b77932014-08-04 01:22:46105 TransportSecurityState* transport_security_state_;
106
rtenneti052774e2015-11-24 21:00:12107 CTVerifier* cert_transparency_verifier_;
108
[email protected]5c78ce62014-03-13 19:48:01109 // |hostname| specifies the hostname for which |certs| is a valid chain.
110 std::string hostname_;
elawrence954bb5472016-04-04 22:03:11111 // |port| specifies the target port for the connection.
112 uint16_t port_;
[email protected]5c78ce62014-03-13 19:48:01113
danakjad1777e2016-04-16 00:56:42114 std::unique_ptr<ProofVerifierCallback> callback_;
115 std::unique_ptr<ProofVerifyDetailsChromium> verify_details_;
[email protected]5c78ce62014-03-13 19:48:01116 std::string error_details_;
117
118 // X509Certificate from a chain of DER encoded certificates.
119 scoped_refptr<X509Certificate> cert_;
120
rtennetia75df622015-06-21 23:59:50121 // |cert_verify_flags| is bitwise OR'd of CertVerifier::VerifyFlags and it is
122 // passed to CertVerifier::Verify.
123 int cert_verify_flags_;
124
[email protected]5c78ce62014-03-13 19:48:01125 State next_state_;
126
rtennetidd4f1bd72015-12-23 19:17:50127 base::TimeTicks start_time_;
128
[email protected]5c78ce62014-03-13 19:48:01129 BoundNetLog net_log_;
130
131 DISALLOW_COPY_AND_ASSIGN(Job);
132};
133
[email protected]080b77932014-08-04 01:22:46134ProofVerifierChromium::Job::Job(
135 ProofVerifierChromium* proof_verifier,
136 CertVerifier* cert_verifier,
estark6f9b3d82016-01-12 21:37:05137 CTPolicyEnforcer* ct_policy_enforcer,
[email protected]080b77932014-08-04 01:22:46138 TransportSecurityState* transport_security_state,
rtenneti052774e2015-11-24 21:00:12139 CTVerifier* cert_transparency_verifier,
rtennetia75df622015-06-21 23:59:50140 int cert_verify_flags,
[email protected]080b77932014-08-04 01:22:46141 const BoundNetLog& net_log)
[email protected]5c78ce62014-03-13 19:48:01142 : proof_verifier_(proof_verifier),
eroman7f9236a2015-05-11 21:23:43143 verifier_(cert_verifier),
estark6f9b3d82016-01-12 21:37:05144 policy_enforcer_(ct_policy_enforcer),
[email protected]080b77932014-08-04 01:22:46145 transport_security_state_(transport_security_state),
rtenneti052774e2015-11-24 21:00:12146 cert_transparency_verifier_(cert_transparency_verifier),
rtennetia75df622015-06-21 23:59:50147 cert_verify_flags_(cert_verify_flags),
[email protected]5c78ce62014-03-13 19:48:01148 next_state_(STATE_NONE),
rtennetidd4f1bd72015-12-23 19:17:50149 start_time_(base::TimeTicks::Now()),
rsleevi9541f8632015-07-31 00:07:00150 net_log_(net_log) {}
[email protected]2662ed562013-07-03 10:27:46151
rtennetidd4f1bd72015-12-23 19:17:50152ProofVerifierChromium::Job::~Job() {
153 base::TimeTicks end_time = base::TimeTicks::Now();
154 UMA_HISTOGRAM_TIMES("Net.QuicSession.VerifyProofTime",
155 end_time - start_time_);
156 // |hostname_| will always be canonicalized to lowercase.
157 if (hostname_.compare("www.google.com") == 0) {
158 UMA_HISTOGRAM_TIMES("Net.QuicSession.VerifyProofTime.google",
159 end_time - start_time_);
160 }
161}
162
[email protected]730b35d72014-06-05 03:23:22163QuicAsyncStatus ProofVerifierChromium::Job::VerifyProof(
[email protected]72e65992013-07-30 17:16:14164 const string& hostname,
elawrence954bb5472016-04-04 22:03:11165 const uint16_t port,
[email protected]72e65992013-07-30 17:16:14166 const string& server_config,
rch28f6469d2016-03-13 21:13:08167 QuicVersion quic_version,
168 StringPiece chlo_hash,
[email protected]72e65992013-07-30 17:16:14169 const vector<string>& certs,
rjshadec86dbfa2015-11-12 20:16:25170 const std::string& cert_sct,
[email protected]72e65992013-07-30 17:16:14171 const string& signature,
172 std::string* error_details,
danakjad1777e2016-04-16 00:56:42173 std::unique_ptr<ProofVerifyDetails>* verify_details,
[email protected]72e65992013-07-30 17:16:14174 ProofVerifierCallback* callback) {
[email protected]2662ed562013-07-03 10:27:46175 DCHECK(error_details);
[email protected]c817c672014-03-21 22:25:34176 DCHECK(verify_details);
[email protected]72e65992013-07-30 17:16:14177 DCHECK(callback);
178
[email protected]2662ed562013-07-03 10:27:46179 error_details->clear();
180
[email protected]2662ed562013-07-03 10:27:46181 if (STATE_NONE != next_state_) {
182 *error_details = "Certificate is already set and VerifyProof has begun";
[email protected]5c78ce62014-03-13 19:48:01183 DLOG(DFATAL) << *error_details;
[email protected]730b35d72014-06-05 03:23:22184 return QUIC_FAILURE;
[email protected]2662ed562013-07-03 10:27:46185 }
186
[email protected]72e65992013-07-30 17:16:14187 verify_details_.reset(new ProofVerifyDetailsChromium);
188
[email protected]2662ed562013-07-03 10:27:46189 if (certs.empty()) {
190 *error_details = "Failed to create certificate chain. Certs are empty.";
191 DLOG(WARNING) << *error_details;
[email protected]72e65992013-07-30 17:16:14192 verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID;
dchengc7eeda422015-12-26 03:56:48193 *verify_details = std::move(verify_details_);
[email protected]730b35d72014-06-05 03:23:22194 return QUIC_FAILURE;
[email protected]2662ed562013-07-03 10:27:46195 }
196
197 // Convert certs to X509Certificate.
198 vector<StringPiece> cert_pieces(certs.size());
199 for (unsigned i = 0; i < certs.size(); i++) {
200 cert_pieces[i] = base::StringPiece(certs[i]);
201 }
202 cert_ = X509Certificate::CreateFromDERCertChain(cert_pieces);
203 if (!cert_.get()) {
[email protected]2662ed562013-07-03 10:27:46204 *error_details = "Failed to create certificate chain";
205 DLOG(WARNING) << *error_details;
[email protected]72e65992013-07-30 17:16:14206 verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID;
dchengc7eeda422015-12-26 03:56:48207 *verify_details = std::move(verify_details_);
[email protected]730b35d72014-06-05 03:23:22208 return QUIC_FAILURE;
[email protected]2662ed562013-07-03 10:27:46209 }
210
rtenneti052774e2015-11-24 21:00:12211 if (cert_transparency_verifier_ && !cert_sct.empty()) {
212 // Note that this is a completely synchronous operation: The CT Log Verifier
213 // gets all the data it needs for SCT verification and does not do any
214 // external communication.
rtenneti3903514d2016-05-05 23:36:38215 int result = cert_transparency_verifier_->Verify(
216 cert_.get(), std::string(), cert_sct,
217 &verify_details_->ct_verify_result, net_log_);
218 // TODO(rtenneti): Delete this debugging code.
219 if (result == OK) {
220 VLOG(1) << "CTVerifier::Verify success";
221 } else {
222 VLOG(1) << "CTVerifier::Verify failed: " << result;
223 }
224 } else {
225 // TODO(rtenneti): Delete this debugging code.
226 if (cert_transparency_verifier_) {
227 VLOG(1) << "cert_sct is empty";
228 } else {
229 VLOG(1) << "cert_transparency_verifier_ is null";
230 }
rtenneti052774e2015-11-24 21:00:12231 }
232
[email protected]2662ed562013-07-03 10:27:46233 // We call VerifySignature first to avoid copying of server_config and
234 // signature.
rch28f6469d2016-03-13 21:13:08235 if (!VerifySignature(server_config, quic_version, chlo_hash, signature,
236 certs[0])) {
[email protected]2662ed562013-07-03 10:27:46237 *error_details = "Failed to verify signature of server config";
238 DLOG(WARNING) << *error_details;
[email protected]72e65992013-07-30 17:16:14239 verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID;
dchengc7eeda422015-12-26 03:56:48240 *verify_details = std::move(verify_details_);
[email protected]730b35d72014-06-05 03:23:22241 return QUIC_FAILURE;
[email protected]2662ed562013-07-03 10:27:46242 }
243
244 hostname_ = hostname;
elawrence954bb5472016-04-04 22:03:11245 port_ = port;
[email protected]2662ed562013-07-03 10:27:46246
247 next_state_ = STATE_VERIFY_CERT;
[email protected]72e65992013-07-30 17:16:14248 switch (DoLoop(OK)) {
249 case OK:
dchengc7eeda422015-12-26 03:56:48250 *verify_details = std::move(verify_details_);
[email protected]730b35d72014-06-05 03:23:22251 return QUIC_SUCCESS;
[email protected]72e65992013-07-30 17:16:14252 case ERR_IO_PENDING:
[email protected]3ce3bf22014-04-03 08:02:01253 callback_.reset(callback);
[email protected]730b35d72014-06-05 03:23:22254 return QUIC_PENDING;
[email protected]72e65992013-07-30 17:16:14255 default:
256 *error_details = error_details_;
dchengc7eeda422015-12-26 03:56:48257 *verify_details = std::move(verify_details_);
[email protected]730b35d72014-06-05 03:23:22258 return QUIC_FAILURE;
[email protected]72e65992013-07-30 17:16:14259 }
[email protected]2662ed562013-07-03 10:27:46260}
261
[email protected]5c78ce62014-03-13 19:48:01262int ProofVerifierChromium::Job::DoLoop(int last_result) {
[email protected]2662ed562013-07-03 10:27:46263 int rv = last_result;
264 do {
265 State state = next_state_;
266 next_state_ = STATE_NONE;
267 switch (state) {
268 case STATE_VERIFY_CERT:
269 DCHECK(rv == OK);
270 rv = DoVerifyCert(rv);
271 break;
272 case STATE_VERIFY_CERT_COMPLETE:
273 rv = DoVerifyCertComplete(rv);
274 break;
275 case STATE_NONE:
276 default:
277 rv = ERR_UNEXPECTED;
278 LOG(DFATAL) << "unexpected state " << state;
279 break;
280 }
281 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
282 return rv;
283}
284
[email protected]5c78ce62014-03-13 19:48:01285void ProofVerifierChromium::Job::OnIOComplete(int result) {
[email protected]2662ed562013-07-03 10:27:46286 int rv = DoLoop(result);
287 if (rv != ERR_IO_PENDING) {
danakjad1777e2016-04-16 00:56:42288 std::unique_ptr<ProofVerifierCallback> callback(std::move(callback_));
[email protected]5c78ce62014-03-13 19:48:01289 // Callback expects ProofVerifyDetails not ProofVerifyDetailsChromium.
danakjad1777e2016-04-16 00:56:42290 std::unique_ptr<ProofVerifyDetails> verify_details(
291 std::move(verify_details_));
[email protected]5c78ce62014-03-13 19:48:01292 callback->Run(rv == OK, error_details_, &verify_details);
293 // Will delete |this|.
294 proof_verifier_->OnJobComplete(this);
[email protected]2662ed562013-07-03 10:27:46295 }
296}
297
[email protected]5c78ce62014-03-13 19:48:01298int ProofVerifierChromium::Job::DoVerifyCert(int result) {
[email protected]2662ed562013-07-03 10:27:46299 next_state_ = STATE_VERIFY_CERT_COMPLETE;
300
rtennetia75df622015-06-21 23:59:50301 return verifier_->Verify(
302 cert_.get(), hostname_, std::string(), cert_verify_flags_,
303 SSLConfigService::GetCRLSet().get(), &verify_details_->cert_verify_result,
304 base::Bind(&ProofVerifierChromium::Job::OnIOComplete,
305 base::Unretained(this)),
306 &cert_verifier_request_, net_log_);
[email protected]2662ed562013-07-03 10:27:46307}
308
[email protected]5c78ce62014-03-13 19:48:01309int ProofVerifierChromium::Job::DoVerifyCertComplete(int result) {
eroman7f9236a2015-05-11 21:23:43310 cert_verifier_request_.reset();
[email protected]2662ed562013-07-03 10:27:46311
[email protected]080b77932014-08-04 01:22:46312 const CertVerifyResult& cert_verify_result =
313 verify_details_->cert_verify_result;
[email protected]080b77932014-08-04 01:22:46314 const CertStatus cert_status = cert_verify_result.cert_status;
estark723b5eeb2016-02-18 21:01:12315 verify_details_->ct_verify_result.ct_policies_applied =
316 (result == OK && policy_enforcer_ != nullptr);
317 verify_details_->ct_verify_result.ev_policy_compliance =
318 ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY;
estark0fc8d0782016-02-25 20:41:20319 if (result == OK && policy_enforcer_) {
320 if ((cert_verify_result.cert_status & CERT_STATUS_IS_EV)) {
321 ct::EVPolicyCompliance ev_policy_compliance =
322 policy_enforcer_->DoesConformToCTEVPolicy(
323 cert_verify_result.verified_cert.get(),
324 SSLConfigService::GetEVCertsWhitelist().get(),
325 verify_details_->ct_verify_result.verified_scts, net_log_);
326 verify_details_->ct_verify_result.ev_policy_compliance =
327 ev_policy_compliance;
328 if (ev_policy_compliance !=
329 ct::EVPolicyCompliance::EV_POLICY_DOES_NOT_APPLY &&
330 ev_policy_compliance !=
331 ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_WHITELIST &&
332 ev_policy_compliance !=
333 ct::EVPolicyCompliance::EV_POLICY_COMPLIES_VIA_SCTS) {
334 verify_details_->cert_verify_result.cert_status |=
335 CERT_STATUS_CT_COMPLIANCE_FAILED;
336 verify_details_->cert_verify_result.cert_status &= ~CERT_STATUS_IS_EV;
337 }
rsleevi9541f8632015-07-31 00:07:00338 }
estark0fc8d0782016-02-25 20:41:20339
340 verify_details_->ct_verify_result.cert_policy_compliance =
341 policy_enforcer_->DoesConformToCertPolicy(
342 cert_verify_result.verified_cert.get(),
343 verify_details_->ct_verify_result.verified_scts, net_log_);
rsleevi9541f8632015-07-31 00:07:00344 }
345
[email protected]8d60aa52014-08-08 21:22:45346 if (transport_security_state_ &&
[email protected]080b77932014-08-04 01:22:46347 (result == OK ||
348 (IsCertificateError(result) && IsCertStatusMinorError(cert_status))) &&
[email protected]8d60aa52014-08-08 21:22:45349 !transport_security_state_->CheckPublicKeyPins(
elawrence954bb5472016-04-04 22:03:11350 HostPortPair(hostname_, port_),
[email protected]8d60aa52014-08-08 21:22:45351 cert_verify_result.is_issued_by_known_root,
estark1a66df72015-07-28 15:24:00352 cert_verify_result.public_key_hashes, cert_.get(),
353 cert_verify_result.verified_cert.get(),
354 TransportSecurityState::ENABLE_PIN_REPORTS,
[email protected]8d60aa52014-08-08 21:22:45355 &verify_details_->pinning_failure_log)) {
356 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN;
[email protected]080b77932014-08-04 01:22:46357 }
[email protected]080b77932014-08-04 01:22:46358
[email protected]0cceb922014-07-01 02:00:56359 if (result != OK) {
[email protected]3030374e32014-08-07 16:12:06360 std::string error_string = ErrorToString(result);
[email protected]72e65992013-07-30 17:16:14361 error_details_ = StringPrintf("Failed to verify certificate chain: %s",
[email protected]3030374e32014-08-07 16:12:06362 error_string.c_str());
[email protected]72e65992013-07-30 17:16:14363 DLOG(WARNING) << error_details_;
[email protected]2662ed562013-07-03 10:27:46364 }
365
366 // Exit DoLoop and return the result to the caller to VerifyProof.
367 DCHECK_EQ(STATE_NONE, next_state_);
368 return result;
369}
370
[email protected]5c78ce62014-03-13 19:48:01371bool ProofVerifierChromium::Job::VerifySignature(const string& signed_data,
rch28f6469d2016-03-13 21:13:08372 QuicVersion quic_version,
373 StringPiece chlo_hash,
[email protected]3030374e32014-08-07 16:12:06374 const string& signature,
375 const string& cert) {
[email protected]2662ed562013-07-03 10:27:46376 StringPiece spki;
377 if (!asn1::ExtractSPKIFromDERCert(cert, &spki)) {
378 DLOG(WARNING) << "ExtractSPKIFromDERCert failed";
379 return false;
380 }
381
382 crypto::SignatureVerifier verifier;
383
384 size_t size_bits;
385 X509Certificate::PublicKeyType type;
rjshaded5ced072015-12-18 19:26:02386 X509Certificate::GetPublicKeyInfo(cert_->os_cert_handle(), &size_bits, &type);
[email protected]2662ed562013-07-03 10:27:46387 if (type == X509Certificate::kPublicKeyTypeRSA) {
388 crypto::SignatureVerifier::HashAlgorithm hash_alg =
389 crypto::SignatureVerifier::SHA256;
390 crypto::SignatureVerifier::HashAlgorithm mask_hash_alg = hash_alg;
391 unsigned int hash_len = 32; // 32 is the length of a SHA-256 hash.
[email protected]2662ed562013-07-03 10:27:46392
393 bool ok = verifier.VerifyInitRSAPSS(
[email protected]d5c9e4ba2013-09-14 05:25:58394 hash_alg, mask_hash_alg, hash_len,
Avi Drissman13fc8932015-12-20 04:40:46395 reinterpret_cast<const uint8_t*>(signature.data()), signature.size(),
396 reinterpret_cast<const uint8_t*>(spki.data()), spki.size());
[email protected]2662ed562013-07-03 10:27:46397 if (!ok) {
398 DLOG(WARNING) << "VerifyInitRSAPSS failed";
399 return false;
400 }
401 } else if (type == X509Certificate::kPublicKeyTypeECDSA) {
davidben9c97a362016-03-03 16:18:26402 if (!verifier.VerifyInit(crypto::SignatureVerifier::ECDSA_SHA256,
403 reinterpret_cast<const uint8_t*>(signature.data()),
404 signature.size(),
405 reinterpret_cast<const uint8_t*>(spki.data()),
406 spki.size())) {
[email protected]2662ed562013-07-03 10:27:46407 DLOG(WARNING) << "VerifyInit failed";
408 return false;
409 }
410 } else {
411 LOG(ERROR) << "Unsupported public key type " << type;
412 return false;
413 }
414
rch28f6469d2016-03-13 21:13:08415 if (quic_version <= QUIC_VERSION_30) {
416 verifier.VerifyUpdate(
417 reinterpret_cast<const uint8_t*>(kProofSignatureLabelOld),
418 sizeof(kProofSignatureLabelOld));
419 } else {
420 verifier.VerifyUpdate(
421 reinterpret_cast<const uint8_t*>(kProofSignatureLabel),
422 sizeof(kProofSignatureLabel));
423 uint32_t len = chlo_hash.length();
424 verifier.VerifyUpdate(reinterpret_cast<const uint8_t*>(&len), sizeof(len));
425 verifier.VerifyUpdate(reinterpret_cast<const uint8_t*>(chlo_hash.data()),
426 len);
427 }
428
Avi Drissman13fc8932015-12-20 04:40:46429 verifier.VerifyUpdate(reinterpret_cast<const uint8_t*>(signed_data.data()),
[email protected]2662ed562013-07-03 10:27:46430 signed_data.size());
431
432 if (!verifier.VerifyFinal()) {
433 DLOG(WARNING) << "VerifyFinal failed";
434 return false;
435 }
436
[email protected]3e5fed12013-11-22 22:21:41437 DVLOG(1) << "VerifyFinal success";
[email protected]2662ed562013-07-03 10:27:46438 return true;
439}
440
[email protected]080b77932014-08-04 01:22:46441ProofVerifierChromium::ProofVerifierChromium(
442 CertVerifier* cert_verifier,
estark6f9b3d82016-01-12 21:37:05443 CTPolicyEnforcer* ct_policy_enforcer,
rtenneti052774e2015-11-24 21:00:12444 TransportSecurityState* transport_security_state,
445 CTVerifier* cert_transparency_verifier)
[email protected]080b77932014-08-04 01:22:46446 : cert_verifier_(cert_verifier),
estark6f9b3d82016-01-12 21:37:05447 ct_policy_enforcer_(ct_policy_enforcer),
rtenneti052774e2015-11-24 21:00:12448 transport_security_state_(transport_security_state),
449 cert_transparency_verifier_(cert_transparency_verifier) {}
[email protected]5c78ce62014-03-13 19:48:01450
451ProofVerifierChromium::~ProofVerifierChromium() {
452 STLDeleteElements(&active_jobs_);
453}
454
[email protected]730b35d72014-06-05 03:23:22455QuicAsyncStatus ProofVerifierChromium::VerifyProof(
[email protected]5c78ce62014-03-13 19:48:01456 const std::string& hostname,
elawrence954bb5472016-04-04 22:03:11457 const uint16_t port,
[email protected]5c78ce62014-03-13 19:48:01458 const std::string& server_config,
rch28f6469d2016-03-13 21:13:08459 QuicVersion quic_version,
460 base::StringPiece chlo_hash,
[email protected]5c78ce62014-03-13 19:48:01461 const std::vector<std::string>& certs,
rjshadec86dbfa2015-11-12 20:16:25462 const std::string& cert_sct,
[email protected]5c78ce62014-03-13 19:48:01463 const std::string& signature,
[email protected]c817c672014-03-21 22:25:34464 const ProofVerifyContext* verify_context,
[email protected]5c78ce62014-03-13 19:48:01465 std::string* error_details,
danakjad1777e2016-04-16 00:56:42466 std::unique_ptr<ProofVerifyDetails>* verify_details,
[email protected]5c78ce62014-03-13 19:48:01467 ProofVerifierCallback* callback) {
[email protected]c817c672014-03-21 22:25:34468 if (!verify_context) {
469 *error_details = "Missing context";
[email protected]730b35d72014-06-05 03:23:22470 return QUIC_FAILURE;
[email protected]c817c672014-03-21 22:25:34471 }
472 const ProofVerifyContextChromium* chromium_context =
473 reinterpret_cast<const ProofVerifyContextChromium*>(verify_context);
danakjad1777e2016-04-16 00:56:42474 std::unique_ptr<Job> job(
estark6f9b3d82016-01-12 21:37:05475 new Job(this, cert_verifier_, ct_policy_enforcer_,
rtenneti052774e2015-11-24 21:00:12476 transport_security_state_, cert_transparency_verifier_,
477 chromium_context->cert_verify_flags, chromium_context->net_log));
rch28f6469d2016-03-13 21:13:08478 QuicAsyncStatus status = job->VerifyProof(
elawrence954bb5472016-04-04 22:03:11479 hostname, port, server_config, quic_version, chlo_hash, certs, cert_sct,
rch28f6469d2016-03-13 21:13:08480 signature, error_details, verify_details, callback);
[email protected]730b35d72014-06-05 03:23:22481 if (status == QUIC_PENDING) {
[email protected]5c78ce62014-03-13 19:48:01482 active_jobs_.insert(job.release());
483 }
484 return status;
485}
486
487void ProofVerifierChromium::OnJobComplete(Job* job) {
488 active_jobs_.erase(job);
489 delete job;
490}
491
[email protected]2662ed562013-07-03 10:27:46492} // namespace net