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

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

Powered by Google App Engine
This is Rietveld 408576698