Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(356)

Side by Side Diff: net/quic/crypto/proof_verifier_chromium.cc

Issue 1216943003: Use the CT policy enforcer for QUIC, if specified. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/quic/crypto/proof_verifier_chromium.h" 5 #include "net/quic/crypto/proof_verifier_chromium.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/callback_helpers.h" 9 #include "base/callback_helpers.h"
10 #include "base/compiler_specific.h" 10 #include "base/compiler_specific.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/metrics/histogram_macros.h" 12 #include "base/metrics/histogram_macros.h"
13 #include "base/profiler/scoped_tracker.h" 13 #include "base/profiler/scoped_tracker.h"
14 #include "base/stl_util.h" 14 #include "base/stl_util.h"
15 #include "base/strings/stringprintf.h" 15 #include "base/strings/stringprintf.h"
16 #include "crypto/signature_verifier.h" 16 #include "crypto/signature_verifier.h"
17 #include "net/base/host_port_pair.h" 17 #include "net/base/host_port_pair.h"
18 #include "net/base/net_errors.h" 18 #include "net/base/net_errors.h"
19 #include "net/cert/asn1_util.h" 19 #include "net/cert/asn1_util.h"
20 #include "net/cert/cert_policy_enforcer.h"
20 #include "net/cert/cert_status_flags.h" 21 #include "net/cert/cert_status_flags.h"
21 #include "net/cert/cert_verifier.h" 22 #include "net/cert/cert_verifier.h"
22 #include "net/cert/cert_verify_result.h" 23 #include "net/cert/cert_verify_result.h"
24 #include "net/cert/ct_verify_result.h"
23 #include "net/cert/x509_certificate.h" 25 #include "net/cert/x509_certificate.h"
24 #include "net/cert/x509_util.h" 26 #include "net/cert/x509_util.h"
25 #include "net/http/transport_security_state.h" 27 #include "net/http/transport_security_state.h"
26 #include "net/log/net_log.h" 28 #include "net/log/net_log.h"
27 #include "net/quic/crypto/crypto_protocol.h" 29 #include "net/quic/crypto/crypto_protocol.h"
28 #include "net/ssl/ssl_config_service.h" 30 #include "net/ssl/ssl_config_service.h"
29 31
30 using base::StringPiece; 32 using base::StringPiece;
31 using base::StringPrintf; 33 using base::StringPrintf;
32 using std::string; 34 using std::string;
33 using std::vector; 35 using std::vector;
34 36
35 namespace net { 37 namespace net {
36 38
37 ProofVerifyDetails* ProofVerifyDetailsChromium::Clone() const { 39 ProofVerifyDetails* ProofVerifyDetailsChromium::Clone() const {
38 ProofVerifyDetailsChromium* other = new ProofVerifyDetailsChromium; 40 ProofVerifyDetailsChromium* other = new ProofVerifyDetailsChromium;
39 other->cert_verify_result = cert_verify_result; 41 other->cert_verify_result = cert_verify_result;
40 return other; 42 return other;
41 } 43 }
42 44
43 // A Job handles the verification of a single proof. It is owned by the 45 // A Job handles the verification of a single proof. It is owned by the
44 // ProofVerifier. If the verification can not complete synchronously, it 46 // ProofVerifier. If the verification can not complete synchronously, it
45 // will notify the ProofVerifier upon completion. 47 // will notify the ProofVerifier upon completion.
46 class ProofVerifierChromium::Job { 48 class ProofVerifierChromium::Job {
47 public: 49 public:
48 Job(ProofVerifierChromium* proof_verifier, 50 Job(ProofVerifierChromium* proof_verifier,
49 CertVerifier* cert_verifier, 51 CertVerifier* cert_verifier,
52 CertPolicyEnforcer* cert_policy_enforcer,
50 TransportSecurityState* transport_security_state, 53 TransportSecurityState* transport_security_state,
51 int cert_verify_flags, 54 int cert_verify_flags,
52 const BoundNetLog& net_log); 55 const BoundNetLog& net_log);
53 56
54 // Starts the proof verification. If |QUIC_PENDING| is returned, then 57 // Starts the proof verification. If |QUIC_PENDING| is returned, then
55 // |callback| will be invoked asynchronously when the verification completes. 58 // |callback| will be invoked asynchronously when the verification completes.
56 QuicAsyncStatus VerifyProof(const std::string& hostname, 59 QuicAsyncStatus VerifyProof(const std::string& hostname,
57 const std::string& server_config, 60 const std::string& server_config,
58 const std::vector<std::string>& certs, 61 const std::vector<std::string>& certs,
59 const std::string& signature, 62 const std::string& signature,
(...skipping 17 matching lines...) Expand all
77 const std::string& signature, 80 const std::string& signature,
78 const std::string& cert); 81 const std::string& cert);
79 82
80 // Proof verifier to notify when this jobs completes. 83 // Proof verifier to notify when this jobs completes.
81 ProofVerifierChromium* proof_verifier_; 84 ProofVerifierChromium* proof_verifier_;
82 85
83 // The underlying verifier used for verifying certificates. 86 // The underlying verifier used for verifying certificates.
84 CertVerifier* verifier_; 87 CertVerifier* verifier_;
85 scoped_ptr<CertVerifier::Request> cert_verifier_request_; 88 scoped_ptr<CertVerifier::Request> cert_verifier_request_;
86 89
90 CertPolicyEnforcer* policy_enforcer_;
91
87 TransportSecurityState* transport_security_state_; 92 TransportSecurityState* transport_security_state_;
88 93
89 // |hostname| specifies the hostname for which |certs| is a valid chain. 94 // |hostname| specifies the hostname for which |certs| is a valid chain.
90 std::string hostname_; 95 std::string hostname_;
91 96
92 scoped_ptr<ProofVerifierCallback> callback_; 97 scoped_ptr<ProofVerifierCallback> callback_;
93 scoped_ptr<ProofVerifyDetailsChromium> verify_details_; 98 scoped_ptr<ProofVerifyDetailsChromium> verify_details_;
94 std::string error_details_; 99 std::string error_details_;
95 100
96 // X509Certificate from a chain of DER encoded certificates. 101 // X509Certificate from a chain of DER encoded certificates.
97 scoped_refptr<X509Certificate> cert_; 102 scoped_refptr<X509Certificate> cert_;
98 103
99 // |cert_verify_flags| is bitwise OR'd of CertVerifier::VerifyFlags and it is 104 // |cert_verify_flags| is bitwise OR'd of CertVerifier::VerifyFlags and it is
100 // passed to CertVerifier::Verify. 105 // passed to CertVerifier::Verify.
101 int cert_verify_flags_; 106 int cert_verify_flags_;
102 107
103 State next_state_; 108 State next_state_;
104 109
105 BoundNetLog net_log_; 110 BoundNetLog net_log_;
106 111
107 DISALLOW_COPY_AND_ASSIGN(Job); 112 DISALLOW_COPY_AND_ASSIGN(Job);
108 }; 113 };
109 114
110 ProofVerifierChromium::Job::Job( 115 ProofVerifierChromium::Job::Job(
111 ProofVerifierChromium* proof_verifier, 116 ProofVerifierChromium* proof_verifier,
112 CertVerifier* cert_verifier, 117 CertVerifier* cert_verifier,
118 CertPolicyEnforcer* cert_policy_enforcer,
113 TransportSecurityState* transport_security_state, 119 TransportSecurityState* transport_security_state,
114 int cert_verify_flags, 120 int cert_verify_flags,
115 const BoundNetLog& net_log) 121 const BoundNetLog& net_log)
116 : proof_verifier_(proof_verifier), 122 : proof_verifier_(proof_verifier),
117 verifier_(cert_verifier), 123 verifier_(cert_verifier),
124 policy_enforcer_(cert_policy_enforcer),
118 transport_security_state_(transport_security_state), 125 transport_security_state_(transport_security_state),
119 cert_verify_flags_(cert_verify_flags), 126 cert_verify_flags_(cert_verify_flags),
120 next_state_(STATE_NONE), 127 next_state_(STATE_NONE),
121 net_log_(net_log) { 128 net_log_(net_log) {}
122 }
123 129
124 QuicAsyncStatus ProofVerifierChromium::Job::VerifyProof( 130 QuicAsyncStatus ProofVerifierChromium::Job::VerifyProof(
125 const string& hostname, 131 const string& hostname,
126 const string& server_config, 132 const string& server_config,
127 const vector<string>& certs, 133 const vector<string>& certs,
128 const string& signature, 134 const string& signature,
129 std::string* error_details, 135 std::string* error_details,
130 scoped_ptr<ProofVerifyDetails>* verify_details, 136 scoped_ptr<ProofVerifyDetails>* verify_details,
131 ProofVerifierCallback* callback) { 137 ProofVerifierCallback* callback) {
132 DCHECK(error_details); 138 DCHECK(error_details);
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 base::Unretained(this)), 243 base::Unretained(this)),
238 &cert_verifier_request_, net_log_); 244 &cert_verifier_request_, net_log_);
239 } 245 }
240 246
241 int ProofVerifierChromium::Job::DoVerifyCertComplete(int result) { 247 int ProofVerifierChromium::Job::DoVerifyCertComplete(int result) {
242 cert_verifier_request_.reset(); 248 cert_verifier_request_.reset();
243 249
244 const CertVerifyResult& cert_verify_result = 250 const CertVerifyResult& cert_verify_result =
245 verify_details_->cert_verify_result; 251 verify_details_->cert_verify_result;
246 const CertStatus cert_status = cert_verify_result.cert_status; 252 const CertStatus cert_status = cert_verify_result.cert_status;
253 if (result == OK && policy_enforcer_ &&
254 (cert_verify_result.cert_status & CERT_STATUS_IS_EV)) {
255 // QUIC does not support OCSP stapling or the CT TLS extension; as a
256 // result, CT can never be verified, thus the result is always empty.
257 ct::CTVerifyResult empty_ct_result;
258 if (!policy_enforcer_->DoesConformToCTEVPolicy(
259 cert_verify_result.verified_cert.get(),
260 SSLConfigService::GetEVCertsWhitelist().get(), empty_ct_result,
261 net_log_)) {
262 verify_details_->cert_verify_result.cert_status &= ~CERT_STATUS_IS_EV;
263 }
264 }
265
247 // TODO(estark): replace 0 below with the port of the connection. 266 // TODO(estark): replace 0 below with the port of the connection.
248 if (transport_security_state_ && 267 if (transport_security_state_ &&
249 (result == OK || 268 (result == OK ||
250 (IsCertificateError(result) && IsCertStatusMinorError(cert_status))) && 269 (IsCertificateError(result) && IsCertStatusMinorError(cert_status))) &&
251 !transport_security_state_->CheckPublicKeyPins( 270 !transport_security_state_->CheckPublicKeyPins(
252 HostPortPair(hostname_, 0), 271 HostPortPair(hostname_, 0),
253 cert_verify_result.is_issued_by_known_root, 272 cert_verify_result.is_issued_by_known_root,
254 cert_verify_result.public_key_hashes, cert_.get(), 273 cert_verify_result.public_key_hashes, cert_.get(),
255 cert_verify_result.verified_cert.get(), 274 cert_verify_result.verified_cert.get(),
256 TransportSecurityState::ENABLE_PIN_REPORTS, 275 TransportSecurityState::ENABLE_PIN_REPORTS,
257 &verify_details_->pinning_failure_log)) { 276 &verify_details_->pinning_failure_log)) {
258 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN; 277 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN;
259 } 278 }
260 279
261 scoped_refptr<ct::EVCertsWhitelist> ev_whitelist =
262 SSLConfigService::GetEVCertsWhitelist();
263 if ((cert_status & CERT_STATUS_IS_EV) && ev_whitelist.get() &&
264 ev_whitelist->IsValid()) {
265 const SHA256HashValue fingerprint(
266 X509Certificate::CalculateFingerprint256(cert_->os_cert_handle()));
267
268 UMA_HISTOGRAM_BOOLEAN(
269 "Net.SSL_EVCertificateInWhitelist",
270 ev_whitelist->ContainsCertificateHash(
271 std::string(reinterpret_cast<const char*>(fingerprint.data), 8)));
272 }
273
274 if (result != OK) { 280 if (result != OK) {
275 std::string error_string = ErrorToString(result); 281 std::string error_string = ErrorToString(result);
276 error_details_ = StringPrintf("Failed to verify certificate chain: %s", 282 error_details_ = StringPrintf("Failed to verify certificate chain: %s",
277 error_string.c_str()); 283 error_string.c_str());
278 DLOG(WARNING) << error_details_; 284 DLOG(WARNING) << error_details_;
279 } 285 }
280 286
281 // Exit DoLoop and return the result to the caller to VerifyProof. 287 // Exit DoLoop and return the result to the caller to VerifyProof.
282 DCHECK_EQ(STATE_NONE, next_state_); 288 DCHECK_EQ(STATE_NONE, next_state_);
283 return result; 289 return result;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 DLOG(WARNING) << "VerifyFinal failed"; 365 DLOG(WARNING) << "VerifyFinal failed";
360 return false; 366 return false;
361 } 367 }
362 368
363 DVLOG(1) << "VerifyFinal success"; 369 DVLOG(1) << "VerifyFinal success";
364 return true; 370 return true;
365 } 371 }
366 372
367 ProofVerifierChromium::ProofVerifierChromium( 373 ProofVerifierChromium::ProofVerifierChromium(
368 CertVerifier* cert_verifier, 374 CertVerifier* cert_verifier,
375 CertPolicyEnforcer* cert_policy_enforcer,
369 TransportSecurityState* transport_security_state) 376 TransportSecurityState* transport_security_state)
370 : cert_verifier_(cert_verifier), 377 : cert_verifier_(cert_verifier),
371 transport_security_state_(transport_security_state) { 378 cert_policy_enforcer_(cert_policy_enforcer),
372 } 379 transport_security_state_(transport_security_state) {}
373 380
374 ProofVerifierChromium::~ProofVerifierChromium() { 381 ProofVerifierChromium::~ProofVerifierChromium() {
375 STLDeleteElements(&active_jobs_); 382 STLDeleteElements(&active_jobs_);
376 } 383 }
377 384
378 QuicAsyncStatus ProofVerifierChromium::VerifyProof( 385 QuicAsyncStatus ProofVerifierChromium::VerifyProof(
379 const std::string& hostname, 386 const std::string& hostname,
380 const std::string& server_config, 387 const std::string& server_config,
381 const std::vector<std::string>& certs, 388 const std::vector<std::string>& certs,
382 const std::string& signature, 389 const std::string& signature,
383 const ProofVerifyContext* verify_context, 390 const ProofVerifyContext* verify_context,
384 std::string* error_details, 391 std::string* error_details,
385 scoped_ptr<ProofVerifyDetails>* verify_details, 392 scoped_ptr<ProofVerifyDetails>* verify_details,
386 ProofVerifierCallback* callback) { 393 ProofVerifierCallback* callback) {
387 if (!verify_context) { 394 if (!verify_context) {
388 *error_details = "Missing context"; 395 *error_details = "Missing context";
389 return QUIC_FAILURE; 396 return QUIC_FAILURE;
390 } 397 }
391 const ProofVerifyContextChromium* chromium_context = 398 const ProofVerifyContextChromium* chromium_context =
392 reinterpret_cast<const ProofVerifyContextChromium*>(verify_context); 399 reinterpret_cast<const ProofVerifyContextChromium*>(verify_context);
393 scoped_ptr<Job> job(new Job(this, cert_verifier_, transport_security_state_, 400 scoped_ptr<Job> job(new Job(
394 chromium_context->cert_verify_flags, 401 this, cert_verifier_, cert_policy_enforcer_, transport_security_state_,
395 chromium_context->net_log)); 402 chromium_context->cert_verify_flags, chromium_context->net_log));
396 QuicAsyncStatus status = 403 QuicAsyncStatus status =
397 job->VerifyProof(hostname, server_config, certs, signature, error_details, 404 job->VerifyProof(hostname, server_config, certs, signature, error_details,
398 verify_details, callback); 405 verify_details, callback);
399 if (status == QUIC_PENDING) { 406 if (status == QUIC_PENDING) {
400 active_jobs_.insert(job.release()); 407 active_jobs_.insert(job.release());
401 } 408 }
402 return status; 409 return status;
403 } 410 }
404 411
405 void ProofVerifierChromium::OnJobComplete(Job* job) { 412 void ProofVerifierChromium::OnJobComplete(Job* job) {
406 active_jobs_.erase(job); 413 active_jobs_.erase(job);
407 delete job; 414 delete job;
408 } 415 }
409 416
410 } // namespace net 417 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/crypto/proof_verifier_chromium.h ('k') | net/quic/crypto/proof_verifier_chromium_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698