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

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

Issue 1454993002: QUIC - Code to verify SCT tag with certificate transparency verifier (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase with TOT - use scoped_refptr<const CTLogVerifier> Created 5 years 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/stl_util.h" 13 #include "base/stl_util.h"
14 #include "base/strings/stringprintf.h" 14 #include "base/strings/stringprintf.h"
15 #include "crypto/signature_verifier.h" 15 #include "crypto/signature_verifier.h"
16 #include "net/base/host_port_pair.h" 16 #include "net/base/host_port_pair.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_policy_enforcer.h"
20 #include "net/cert/cert_status_flags.h" 20 #include "net/cert/cert_status_flags.h"
21 #include "net/cert/cert_verifier.h" 21 #include "net/cert/cert_verifier.h"
22 #include "net/cert/cert_verify_result.h" 22 #include "net/cert/cert_verify_result.h"
23 #include "net/cert/ct_verify_result.h" 23 #include "net/cert/ct_verifier.h"
24 #include "net/cert/x509_certificate.h" 24 #include "net/cert/x509_certificate.h"
25 #include "net/cert/x509_util.h" 25 #include "net/cert/x509_util.h"
26 #include "net/http/transport_security_state.h" 26 #include "net/http/transport_security_state.h"
27 #include "net/log/net_log.h" 27 #include "net/log/net_log.h"
28 #include "net/quic/crypto/crypto_protocol.h" 28 #include "net/quic/crypto/crypto_protocol.h"
29 #include "net/ssl/ssl_config_service.h" 29 #include "net/ssl/ssl_config_service.h"
30 30
31 using base::StringPiece; 31 using base::StringPiece;
32 using base::StringPrintf; 32 using base::StringPrintf;
33 using std::string; 33 using std::string;
34 using std::vector; 34 using std::vector;
35 35
36 namespace net { 36 namespace net {
37 37
38 ProofVerifyDetails* ProofVerifyDetailsChromium::Clone() const { 38 ProofVerifyDetails* ProofVerifyDetailsChromium::Clone() const {
39 ProofVerifyDetailsChromium* other = new ProofVerifyDetailsChromium; 39 ProofVerifyDetailsChromium* other = new ProofVerifyDetailsChromium;
40 other->cert_verify_result = cert_verify_result; 40 other->cert_verify_result = cert_verify_result;
41 other->ct_verify_result = ct_verify_result;
41 return other; 42 return other;
42 } 43 }
43 44
44 // 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
45 // ProofVerifier. If the verification can not complete synchronously, it 46 // ProofVerifier. If the verification can not complete synchronously, it
46 // will notify the ProofVerifier upon completion. 47 // will notify the ProofVerifier upon completion.
47 class ProofVerifierChromium::Job { 48 class ProofVerifierChromium::Job {
48 public: 49 public:
49 Job(ProofVerifierChromium* proof_verifier, 50 Job(ProofVerifierChromium* proof_verifier,
50 CertVerifier* cert_verifier, 51 CertVerifier* cert_verifier,
51 CertPolicyEnforcer* cert_policy_enforcer, 52 CertPolicyEnforcer* cert_policy_enforcer,
52 TransportSecurityState* transport_security_state, 53 TransportSecurityState* transport_security_state,
54 CTVerifier* cert_transparency_verifier,
53 int cert_verify_flags, 55 int cert_verify_flags,
54 const BoundNetLog& net_log); 56 const BoundNetLog& net_log);
55 57
56 // Starts the proof verification. If |QUIC_PENDING| is returned, then 58 // Starts the proof verification. If |QUIC_PENDING| is returned, then
57 // |callback| will be invoked asynchronously when the verification completes. 59 // |callback| will be invoked asynchronously when the verification completes.
58 QuicAsyncStatus VerifyProof(const std::string& hostname, 60 QuicAsyncStatus VerifyProof(const std::string& hostname,
59 const std::string& server_config, 61 const std::string& server_config,
60 const std::vector<std::string>& certs, 62 const std::vector<std::string>& certs,
61 const std::string& cert_sct, 63 const std::string& cert_sct,
62 const std::string& signature, 64 const std::string& signature,
(...skipping 21 matching lines...) Expand all
84 ProofVerifierChromium* proof_verifier_; 86 ProofVerifierChromium* proof_verifier_;
85 87
86 // The underlying verifier used for verifying certificates. 88 // The underlying verifier used for verifying certificates.
87 CertVerifier* verifier_; 89 CertVerifier* verifier_;
88 scoped_ptr<CertVerifier::Request> cert_verifier_request_; 90 scoped_ptr<CertVerifier::Request> cert_verifier_request_;
89 91
90 CertPolicyEnforcer* policy_enforcer_; 92 CertPolicyEnforcer* policy_enforcer_;
91 93
92 TransportSecurityState* transport_security_state_; 94 TransportSecurityState* transport_security_state_;
93 95
96 CTVerifier* cert_transparency_verifier_;
97
94 // |hostname| specifies the hostname for which |certs| is a valid chain. 98 // |hostname| specifies the hostname for which |certs| is a valid chain.
95 std::string hostname_; 99 std::string hostname_;
96 100
97 scoped_ptr<ProofVerifierCallback> callback_; 101 scoped_ptr<ProofVerifierCallback> callback_;
98 scoped_ptr<ProofVerifyDetailsChromium> verify_details_; 102 scoped_ptr<ProofVerifyDetailsChromium> verify_details_;
99 std::string error_details_; 103 std::string error_details_;
100 104
101 // X509Certificate from a chain of DER encoded certificates. 105 // X509Certificate from a chain of DER encoded certificates.
102 scoped_refptr<X509Certificate> cert_; 106 scoped_refptr<X509Certificate> cert_;
103 107
104 // |cert_verify_flags| is bitwise OR'd of CertVerifier::VerifyFlags and it is 108 // |cert_verify_flags| is bitwise OR'd of CertVerifier::VerifyFlags and it is
105 // passed to CertVerifier::Verify. 109 // passed to CertVerifier::Verify.
106 int cert_verify_flags_; 110 int cert_verify_flags_;
107 111
108 State next_state_; 112 State next_state_;
109 113
110 BoundNetLog net_log_; 114 BoundNetLog net_log_;
111 115
112 DISALLOW_COPY_AND_ASSIGN(Job); 116 DISALLOW_COPY_AND_ASSIGN(Job);
113 }; 117 };
114 118
115 ProofVerifierChromium::Job::Job( 119 ProofVerifierChromium::Job::Job(
116 ProofVerifierChromium* proof_verifier, 120 ProofVerifierChromium* proof_verifier,
117 CertVerifier* cert_verifier, 121 CertVerifier* cert_verifier,
118 CertPolicyEnforcer* cert_policy_enforcer, 122 CertPolicyEnforcer* cert_policy_enforcer,
119 TransportSecurityState* transport_security_state, 123 TransportSecurityState* transport_security_state,
124 CTVerifier* cert_transparency_verifier,
120 int cert_verify_flags, 125 int cert_verify_flags,
121 const BoundNetLog& net_log) 126 const BoundNetLog& net_log)
122 : proof_verifier_(proof_verifier), 127 : proof_verifier_(proof_verifier),
123 verifier_(cert_verifier), 128 verifier_(cert_verifier),
124 policy_enforcer_(cert_policy_enforcer), 129 policy_enforcer_(cert_policy_enforcer),
125 transport_security_state_(transport_security_state), 130 transport_security_state_(transport_security_state),
131 cert_transparency_verifier_(cert_transparency_verifier),
126 cert_verify_flags_(cert_verify_flags), 132 cert_verify_flags_(cert_verify_flags),
127 next_state_(STATE_NONE), 133 next_state_(STATE_NONE),
128 net_log_(net_log) {} 134 net_log_(net_log) {}
129 135
130 QuicAsyncStatus ProofVerifierChromium::Job::VerifyProof( 136 QuicAsyncStatus ProofVerifierChromium::Job::VerifyProof(
131 const string& hostname, 137 const string& hostname,
132 const string& server_config, 138 const string& server_config,
133 const vector<string>& certs, 139 const vector<string>& certs,
134 const std::string& cert_sct, 140 const std::string& cert_sct,
135 const string& signature, 141 const string& signature,
(...skipping 29 matching lines...) Expand all
165 } 171 }
166 cert_ = X509Certificate::CreateFromDERCertChain(cert_pieces); 172 cert_ = X509Certificate::CreateFromDERCertChain(cert_pieces);
167 if (!cert_.get()) { 173 if (!cert_.get()) {
168 *error_details = "Failed to create certificate chain"; 174 *error_details = "Failed to create certificate chain";
169 DLOG(WARNING) << *error_details; 175 DLOG(WARNING) << *error_details;
170 verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID; 176 verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID;
171 *verify_details = verify_details_.Pass(); 177 *verify_details = verify_details_.Pass();
172 return QUIC_FAILURE; 178 return QUIC_FAILURE;
173 } 179 }
174 180
181 if (cert_transparency_verifier_ && !cert_sct.empty()) {
182 // Note that this is a completely synchronous operation: The CT Log Verifier
183 // gets all the data it needs for SCT verification and does not do any
184 // external communication.
185 cert_transparency_verifier_->Verify(cert_.get(), std::string(), cert_sct,
186 &verify_details_->ct_verify_result,
187 net_log_);
188 }
189
175 // We call VerifySignature first to avoid copying of server_config and 190 // We call VerifySignature first to avoid copying of server_config and
176 // signature. 191 // signature.
177 if (!VerifySignature(server_config, signature, certs[0])) { 192 if (!VerifySignature(server_config, signature, certs[0])) {
178 *error_details = "Failed to verify signature of server config"; 193 *error_details = "Failed to verify signature of server config";
179 DLOG(WARNING) << *error_details; 194 DLOG(WARNING) << *error_details;
180 verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID; 195 verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID;
181 *verify_details = verify_details_.Pass(); 196 *verify_details = verify_details_.Pass();
182 return QUIC_FAILURE; 197 return QUIC_FAILURE;
183 } 198 }
184 199
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 } 261 }
247 262
248 int ProofVerifierChromium::Job::DoVerifyCertComplete(int result) { 263 int ProofVerifierChromium::Job::DoVerifyCertComplete(int result) {
249 cert_verifier_request_.reset(); 264 cert_verifier_request_.reset();
250 265
251 const CertVerifyResult& cert_verify_result = 266 const CertVerifyResult& cert_verify_result =
252 verify_details_->cert_verify_result; 267 verify_details_->cert_verify_result;
253 const CertStatus cert_status = cert_verify_result.cert_status; 268 const CertStatus cert_status = cert_verify_result.cert_status;
254 if (result == OK && policy_enforcer_ && 269 if (result == OK && policy_enforcer_ &&
255 (cert_verify_result.cert_status & CERT_STATUS_IS_EV)) { 270 (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( 271 if (!policy_enforcer_->DoesConformToCTEVPolicy(
260 cert_verify_result.verified_cert.get(), 272 cert_verify_result.verified_cert.get(),
261 SSLConfigService::GetEVCertsWhitelist().get(), empty_ct_result, 273 SSLConfigService::GetEVCertsWhitelist().get(),
262 net_log_)) { 274 verify_details_->ct_verify_result, net_log_)) {
263 verify_details_->cert_verify_result.cert_status |= 275 verify_details_->cert_verify_result.cert_status |=
264 CERT_STATUS_CT_COMPLIANCE_FAILED; 276 CERT_STATUS_CT_COMPLIANCE_FAILED;
265 verify_details_->cert_verify_result.cert_status &= ~CERT_STATUS_IS_EV; 277 verify_details_->cert_verify_result.cert_status &= ~CERT_STATUS_IS_EV;
266 } 278 }
267 } 279 }
268 280
269 // TODO(estark): replace 0 below with the port of the connection. 281 // TODO(estark): replace 0 below with the port of the connection.
270 if (transport_security_state_ && 282 if (transport_security_state_ &&
271 (result == OK || 283 (result == OK ||
272 (IsCertificateError(result) && IsCertStatusMinorError(cert_status))) && 284 (IsCertificateError(result) && IsCertStatusMinorError(cert_status))) &&
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 return false; 376 return false;
365 } 377 }
366 378
367 DVLOG(1) << "VerifyFinal success"; 379 DVLOG(1) << "VerifyFinal success";
368 return true; 380 return true;
369 } 381 }
370 382
371 ProofVerifierChromium::ProofVerifierChromium( 383 ProofVerifierChromium::ProofVerifierChromium(
372 CertVerifier* cert_verifier, 384 CertVerifier* cert_verifier,
373 CertPolicyEnforcer* cert_policy_enforcer, 385 CertPolicyEnforcer* cert_policy_enforcer,
374 TransportSecurityState* transport_security_state) 386 TransportSecurityState* transport_security_state,
387 CTVerifier* cert_transparency_verifier)
375 : cert_verifier_(cert_verifier), 388 : cert_verifier_(cert_verifier),
376 cert_policy_enforcer_(cert_policy_enforcer), 389 cert_policy_enforcer_(cert_policy_enforcer),
377 transport_security_state_(transport_security_state) {} 390 transport_security_state_(transport_security_state),
391 cert_transparency_verifier_(cert_transparency_verifier) {}
378 392
379 ProofVerifierChromium::~ProofVerifierChromium() { 393 ProofVerifierChromium::~ProofVerifierChromium() {
380 STLDeleteElements(&active_jobs_); 394 STLDeleteElements(&active_jobs_);
381 } 395 }
382 396
383 QuicAsyncStatus ProofVerifierChromium::VerifyProof( 397 QuicAsyncStatus ProofVerifierChromium::VerifyProof(
384 const std::string& hostname, 398 const std::string& hostname,
385 const std::string& server_config, 399 const std::string& server_config,
386 const std::vector<std::string>& certs, 400 const std::vector<std::string>& certs,
387 const std::string& cert_sct, 401 const std::string& cert_sct,
388 const std::string& signature, 402 const std::string& signature,
389 const ProofVerifyContext* verify_context, 403 const ProofVerifyContext* verify_context,
390 std::string* error_details, 404 std::string* error_details,
391 scoped_ptr<ProofVerifyDetails>* verify_details, 405 scoped_ptr<ProofVerifyDetails>* verify_details,
392 ProofVerifierCallback* callback) { 406 ProofVerifierCallback* callback) {
393 if (!verify_context) { 407 if (!verify_context) {
394 *error_details = "Missing context"; 408 *error_details = "Missing context";
395 return QUIC_FAILURE; 409 return QUIC_FAILURE;
396 } 410 }
397 const ProofVerifyContextChromium* chromium_context = 411 const ProofVerifyContextChromium* chromium_context =
398 reinterpret_cast<const ProofVerifyContextChromium*>(verify_context); 412 reinterpret_cast<const ProofVerifyContextChromium*>(verify_context);
399 scoped_ptr<Job> job(new Job( 413 scoped_ptr<Job> job(
400 this, cert_verifier_, cert_policy_enforcer_, transport_security_state_, 414 new Job(this, cert_verifier_, cert_policy_enforcer_,
401 chromium_context->cert_verify_flags, chromium_context->net_log)); 415 transport_security_state_, cert_transparency_verifier_,
416 chromium_context->cert_verify_flags, chromium_context->net_log));
402 QuicAsyncStatus status = 417 QuicAsyncStatus status =
403 job->VerifyProof(hostname, server_config, certs, cert_sct, signature, 418 job->VerifyProof(hostname, server_config, certs, cert_sct, signature,
404 error_details, verify_details, callback); 419 error_details, verify_details, callback);
405 if (status == QUIC_PENDING) { 420 if (status == QUIC_PENDING) {
406 active_jobs_.insert(job.release()); 421 active_jobs_.insert(job.release());
407 } 422 }
408 return status; 423 return status;
409 } 424 }
410 425
411 void ProofVerifierChromium::OnJobComplete(Job* job) { 426 void ProofVerifierChromium::OnJobComplete(Job* job) {
412 active_jobs_.erase(job); 427 active_jobs_.erase(job);
413 delete job; 428 delete job;
414 } 429 }
415 430
416 } // namespace net 431 } // 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