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

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: Created 5 years, 5 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
« no previous file with comments | « net/quic/crypto/proof_verifier_chromium.h ('k') | net/quic/quic_stream_factory.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/net_errors.h" 17 #include "net/base/net_errors.h"
18 #include "net/cert/asn1_util.h" 18 #include "net/cert/asn1_util.h"
19 #include "net/cert/cert_policy_enforcer.h"
19 #include "net/cert/cert_status_flags.h" 20 #include "net/cert/cert_status_flags.h"
20 #include "net/cert/cert_verifier.h" 21 #include "net/cert/cert_verifier.h"
21 #include "net/cert/cert_verify_result.h" 22 #include "net/cert/cert_verify_result.h"
23 #include "net/cert/ct_verify_result.h"
22 #include "net/cert/x509_certificate.h" 24 #include "net/cert/x509_certificate.h"
23 #include "net/cert/x509_util.h" 25 #include "net/cert/x509_util.h"
24 #include "net/http/transport_security_state.h" 26 #include "net/http/transport_security_state.h"
25 #include "net/log/net_log.h" 27 #include "net/log/net_log.h"
26 #include "net/quic/crypto/crypto_protocol.h" 28 #include "net/quic/crypto/crypto_protocol.h"
27 #include "net/ssl/ssl_config_service.h" 29 #include "net/ssl/ssl_config_service.h"
28 30
29 using base::StringPiece; 31 using base::StringPiece;
30 using base::StringPrintf; 32 using base::StringPrintf;
31 using std::string; 33 using std::string;
32 using std::vector; 34 using std::vector;
33 35
34 namespace net { 36 namespace net {
35 37
36 ProofVerifyDetails* ProofVerifyDetailsChromium::Clone() const { 38 ProofVerifyDetails* ProofVerifyDetailsChromium::Clone() const {
37 ProofVerifyDetailsChromium* other = new ProofVerifyDetailsChromium; 39 ProofVerifyDetailsChromium* other = new ProofVerifyDetailsChromium;
38 other->cert_verify_result = cert_verify_result; 40 other->cert_verify_result = cert_verify_result;
39 return other; 41 return other;
40 } 42 }
41 43
42 // A Job handles the verification of a single proof. It is owned by the 44 // A Job handles the verification of a single proof. It is owned by the
43 // ProofVerifier. If the verification can not complete synchronously, it 45 // ProofVerifier. If the verification can not complete synchronously, it
44 // will notify the ProofVerifier upon completion. 46 // will notify the ProofVerifier upon completion.
45 class ProofVerifierChromium::Job { 47 class ProofVerifierChromium::Job {
46 public: 48 public:
47 Job(ProofVerifierChromium* proof_verifier, 49 Job(ProofVerifierChromium* proof_verifier,
48 CertVerifier* cert_verifier, 50 CertVerifier* cert_verifier,
51 CertPolicyEnforcer* cert_policy_enforcer,
49 TransportSecurityState* transport_security_state, 52 TransportSecurityState* transport_security_state,
50 int cert_verify_flags, 53 int cert_verify_flags,
51 const BoundNetLog& net_log); 54 const BoundNetLog& net_log);
52 55
53 // Starts the proof verification. If |QUIC_PENDING| is returned, then 56 // Starts the proof verification. If |QUIC_PENDING| is returned, then
54 // |callback| will be invoked asynchronously when the verification completes. 57 // |callback| will be invoked asynchronously when the verification completes.
55 QuicAsyncStatus VerifyProof(const std::string& hostname, 58 QuicAsyncStatus VerifyProof(const std::string& hostname,
56 const std::string& server_config, 59 const std::string& server_config,
57 const std::vector<std::string>& certs, 60 const std::vector<std::string>& certs,
58 const std::string& signature, 61 const std::string& signature,
(...skipping 17 matching lines...) Expand all
76 const std::string& signature, 79 const std::string& signature,
77 const std::string& cert); 80 const std::string& cert);
78 81
79 // Proof verifier to notify when this jobs completes. 82 // Proof verifier to notify when this jobs completes.
80 ProofVerifierChromium* proof_verifier_; 83 ProofVerifierChromium* proof_verifier_;
81 84
82 // The underlying verifier used for verifying certificates. 85 // The underlying verifier used for verifying certificates.
83 CertVerifier* verifier_; 86 CertVerifier* verifier_;
84 scoped_ptr<CertVerifier::Request> cert_verifier_request_; 87 scoped_ptr<CertVerifier::Request> cert_verifier_request_;
85 88
89 CertPolicyEnforcer* policy_enforcer_;
90
86 TransportSecurityState* transport_security_state_; 91 TransportSecurityState* transport_security_state_;
87 92
88 // |hostname| specifies the hostname for which |certs| is a valid chain. 93 // |hostname| specifies the hostname for which |certs| is a valid chain.
89 std::string hostname_; 94 std::string hostname_;
90 95
91 scoped_ptr<ProofVerifierCallback> callback_; 96 scoped_ptr<ProofVerifierCallback> callback_;
92 scoped_ptr<ProofVerifyDetailsChromium> verify_details_; 97 scoped_ptr<ProofVerifyDetailsChromium> verify_details_;
93 std::string error_details_; 98 std::string error_details_;
94 99
95 // X509Certificate from a chain of DER encoded certificates. 100 // X509Certificate from a chain of DER encoded certificates.
96 scoped_refptr<X509Certificate> cert_; 101 scoped_refptr<X509Certificate> cert_;
97 102
98 // |cert_verify_flags| is bitwise OR'd of CertVerifier::VerifyFlags and it is 103 // |cert_verify_flags| is bitwise OR'd of CertVerifier::VerifyFlags and it is
99 // passed to CertVerifier::Verify. 104 // passed to CertVerifier::Verify.
100 int cert_verify_flags_; 105 int cert_verify_flags_;
101 106
102 State next_state_; 107 State next_state_;
103 108
104 BoundNetLog net_log_; 109 BoundNetLog net_log_;
105 110
106 DISALLOW_COPY_AND_ASSIGN(Job); 111 DISALLOW_COPY_AND_ASSIGN(Job);
107 }; 112 };
108 113
109 ProofVerifierChromium::Job::Job( 114 ProofVerifierChromium::Job::Job(
110 ProofVerifierChromium* proof_verifier, 115 ProofVerifierChromium* proof_verifier,
111 CertVerifier* cert_verifier, 116 CertVerifier* cert_verifier,
117 CertPolicyEnforcer* cert_policy_enforcer,
112 TransportSecurityState* transport_security_state, 118 TransportSecurityState* transport_security_state,
113 int cert_verify_flags, 119 int cert_verify_flags,
114 const BoundNetLog& net_log) 120 const BoundNetLog& net_log)
115 : proof_verifier_(proof_verifier), 121 : proof_verifier_(proof_verifier),
116 verifier_(cert_verifier), 122 verifier_(cert_verifier),
123 policy_enforcer_(cert_policy_enforcer),
117 transport_security_state_(transport_security_state), 124 transport_security_state_(transport_security_state),
118 cert_verify_flags_(cert_verify_flags), 125 cert_verify_flags_(cert_verify_flags),
119 next_state_(STATE_NONE), 126 next_state_(STATE_NONE),
120 net_log_(net_log) { 127 net_log_(net_log) {
121 } 128 }
122 129
123 QuicAsyncStatus ProofVerifierChromium::Job::VerifyProof( 130 QuicAsyncStatus ProofVerifierChromium::Job::VerifyProof(
124 const string& hostname, 131 const string& hostname,
125 const string& server_config, 132 const string& server_config,
126 const vector<string>& certs, 133 const vector<string>& certs,
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 base::Unretained(this)), 243 base::Unretained(this)),
237 &cert_verifier_request_, net_log_); 244 &cert_verifier_request_, net_log_);
238 } 245 }
239 246
240 int ProofVerifierChromium::Job::DoVerifyCertComplete(int result) { 247 int ProofVerifierChromium::Job::DoVerifyCertComplete(int result) {
241 cert_verifier_request_.reset(); 248 cert_verifier_request_.reset();
242 249
243 const CertVerifyResult& cert_verify_result = 250 const CertVerifyResult& cert_verify_result =
244 verify_details_->cert_verify_result; 251 verify_details_->cert_verify_result;
245 const CertStatus cert_status = cert_verify_result.cert_status; 252 const CertStatus cert_status = cert_verify_result.cert_status;
253
254 if (result == OK && policy_enforcer_ &&
255 (cert_verify_result.cert_status & CERT_STATUS_IS_EV)) {
256 // QUIC does not support OCSP stapling or the CT TLS extension; as a
257 // result, CT can never be verified, thus the result is always empty.
258 ct::CTVerifyResult empty_ct_result;
259 if (!policy_enforcer_->DoesConformToCTEVPolicy(
260 cert_verify_result.verified_cert.get(),
261 SSLConfigService::GetEVCertsWhitelist().get(), empty_ct_result,
262 net_log_)) {
263 verify_details_->cert_verify_result.cert_status &= ~CERT_STATUS_IS_EV;
264 }
265 }
266
246 if (transport_security_state_ && 267 if (transport_security_state_ &&
247 (result == OK || 268 (result == OK ||
248 (IsCertificateError(result) && IsCertStatusMinorError(cert_status))) && 269 (IsCertificateError(result) && IsCertStatusMinorError(cert_status))) &&
249 !transport_security_state_->CheckPublicKeyPins( 270 !transport_security_state_->CheckPublicKeyPins(
250 hostname_, 271 hostname_,
251 cert_verify_result.is_issued_by_known_root, 272 cert_verify_result.is_issued_by_known_root,
252 cert_verify_result.public_key_hashes, 273 cert_verify_result.public_key_hashes,
253 &verify_details_->pinning_failure_log)) { 274 &verify_details_->pinning_failure_log)) {
254 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN; 275 result = ERR_SSL_PINNED_KEY_NOT_IN_CERT_CHAIN;
255 } 276 }
256 277
257 scoped_refptr<ct::EVCertsWhitelist> ev_whitelist =
258 SSLConfigService::GetEVCertsWhitelist();
259 if ((cert_status & CERT_STATUS_IS_EV) && ev_whitelist.get() &&
260 ev_whitelist->IsValid()) {
261 const SHA256HashValue fingerprint(
262 X509Certificate::CalculateFingerprint256(cert_->os_cert_handle()));
263
264 UMA_HISTOGRAM_BOOLEAN(
265 "Net.SSL_EVCertificateInWhitelist",
266 ev_whitelist->ContainsCertificateHash(
267 std::string(reinterpret_cast<const char*>(fingerprint.data), 8)));
Ryan Hamilton 2015/07/06 17:36:48 You would know better than I would, of course, but
Ryan Sleevi 2015/07/06 17:38:51 This code should not have been histogramming here
Ryan Hamilton 2015/07/06 17:39:43 Ah, that makes sense. Thanks!
268 }
269
270 if (result != OK) { 278 if (result != OK) {
271 std::string error_string = ErrorToString(result); 279 std::string error_string = ErrorToString(result);
272 error_details_ = StringPrintf("Failed to verify certificate chain: %s", 280 error_details_ = StringPrintf("Failed to verify certificate chain: %s",
273 error_string.c_str()); 281 error_string.c_str());
274 DLOG(WARNING) << error_details_; 282 DLOG(WARNING) << error_details_;
275 } 283 }
276 284
277 // Exit DoLoop and return the result to the caller to VerifyProof. 285 // Exit DoLoop and return the result to the caller to VerifyProof.
278 DCHECK_EQ(STATE_NONE, next_state_); 286 DCHECK_EQ(STATE_NONE, next_state_);
279 return result; 287 return result;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 DLOG(WARNING) << "VerifyFinal failed"; 363 DLOG(WARNING) << "VerifyFinal failed";
356 return false; 364 return false;
357 } 365 }
358 366
359 DVLOG(1) << "VerifyFinal success"; 367 DVLOG(1) << "VerifyFinal success";
360 return true; 368 return true;
361 } 369 }
362 370
363 ProofVerifierChromium::ProofVerifierChromium( 371 ProofVerifierChromium::ProofVerifierChromium(
364 CertVerifier* cert_verifier, 372 CertVerifier* cert_verifier,
373 CertPolicyEnforcer* cert_policy_enforcer,
365 TransportSecurityState* transport_security_state) 374 TransportSecurityState* transport_security_state)
366 : cert_verifier_(cert_verifier), 375 : cert_verifier_(cert_verifier),
376 cert_policy_enforcer_(cert_policy_enforcer),
367 transport_security_state_(transport_security_state) { 377 transport_security_state_(transport_security_state) {
368 } 378 }
369 379
370 ProofVerifierChromium::~ProofVerifierChromium() { 380 ProofVerifierChromium::~ProofVerifierChromium() {
371 STLDeleteElements(&active_jobs_); 381 STLDeleteElements(&active_jobs_);
372 } 382 }
373 383
374 QuicAsyncStatus ProofVerifierChromium::VerifyProof( 384 QuicAsyncStatus ProofVerifierChromium::VerifyProof(
375 const std::string& hostname, 385 const std::string& hostname,
376 const std::string& server_config, 386 const std::string& server_config,
377 const std::vector<std::string>& certs, 387 const std::vector<std::string>& certs,
378 const std::string& signature, 388 const std::string& signature,
379 const ProofVerifyContext* verify_context, 389 const ProofVerifyContext* verify_context,
380 std::string* error_details, 390 std::string* error_details,
381 scoped_ptr<ProofVerifyDetails>* verify_details, 391 scoped_ptr<ProofVerifyDetails>* verify_details,
382 ProofVerifierCallback* callback) { 392 ProofVerifierCallback* callback) {
383 if (!verify_context) { 393 if (!verify_context) {
384 *error_details = "Missing context"; 394 *error_details = "Missing context";
385 return QUIC_FAILURE; 395 return QUIC_FAILURE;
386 } 396 }
387 const ProofVerifyContextChromium* chromium_context = 397 const ProofVerifyContextChromium* chromium_context =
388 reinterpret_cast<const ProofVerifyContextChromium*>(verify_context); 398 reinterpret_cast<const ProofVerifyContextChromium*>(verify_context);
389 scoped_ptr<Job> job(new Job(this, cert_verifier_, transport_security_state_, 399 scoped_ptr<Job> job(new Job(
390 chromium_context->cert_verify_flags, 400 this, cert_verifier_, cert_policy_enforcer_, transport_security_state_,
391 chromium_context->net_log)); 401 chromium_context->cert_verify_flags, chromium_context->net_log));
392 QuicAsyncStatus status = 402 QuicAsyncStatus status =
393 job->VerifyProof(hostname, server_config, certs, signature, error_details, 403 job->VerifyProof(hostname, server_config, certs, signature, error_details,
394 verify_details, callback); 404 verify_details, callback);
395 if (status == QUIC_PENDING) { 405 if (status == QUIC_PENDING) {
396 active_jobs_.insert(job.release()); 406 active_jobs_.insert(job.release());
397 } 407 }
398 return status; 408 return status;
399 } 409 }
400 410
401 void ProofVerifierChromium::OnJobComplete(Job* job) { 411 void ProofVerifierChromium::OnJobComplete(Job* job) {
402 active_jobs_.erase(job); 412 active_jobs_.erase(job);
403 delete job; 413 delete job;
404 } 414 }
405 415
406 } // namespace net 416 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/crypto/proof_verifier_chromium.h ('k') | net/quic/quic_stream_factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698