| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |