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