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 <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 TransportSecurityState* transport_security_state, | 57 TransportSecurityState* transport_security_state, |
58 CTVerifier* cert_transparency_verifier, | 58 CTVerifier* cert_transparency_verifier, |
59 int cert_verify_flags, | 59 int cert_verify_flags, |
60 const BoundNetLog& net_log); | 60 const BoundNetLog& net_log); |
61 ~Job(); | 61 ~Job(); |
62 | 62 |
63 // Starts the proof verification. If |QUIC_PENDING| is returned, then | 63 // Starts the proof verification. If |QUIC_PENDING| is returned, then |
64 // |callback| will be invoked asynchronously when the verification completes. | 64 // |callback| will be invoked asynchronously when the verification completes. |
65 QuicAsyncStatus VerifyProof(const std::string& hostname, | 65 QuicAsyncStatus VerifyProof(const std::string& hostname, |
66 const std::string& server_config, | 66 const std::string& server_config, |
| 67 QuicVersion quic_version, |
| 68 base::StringPiece chlo_hash, |
67 const std::vector<std::string>& certs, | 69 const std::vector<std::string>& certs, |
68 const std::string& cert_sct, | 70 const std::string& cert_sct, |
69 const std::string& signature, | 71 const std::string& signature, |
70 std::string* error_details, | 72 std::string* error_details, |
71 scoped_ptr<ProofVerifyDetails>* verify_details, | 73 scoped_ptr<ProofVerifyDetails>* verify_details, |
72 ProofVerifierCallback* callback); | 74 ProofVerifierCallback* callback); |
73 | 75 |
74 private: | 76 private: |
75 enum State { | 77 enum State { |
76 STATE_NONE, | 78 STATE_NONE, |
77 STATE_VERIFY_CERT, | 79 STATE_VERIFY_CERT, |
78 STATE_VERIFY_CERT_COMPLETE, | 80 STATE_VERIFY_CERT_COMPLETE, |
79 }; | 81 }; |
80 | 82 |
81 int DoLoop(int last_io_result); | 83 int DoLoop(int last_io_result); |
82 void OnIOComplete(int result); | 84 void OnIOComplete(int result); |
83 int DoVerifyCert(int result); | 85 int DoVerifyCert(int result); |
84 int DoVerifyCertComplete(int result); | 86 int DoVerifyCertComplete(int result); |
85 | 87 |
86 bool VerifySignature(const std::string& signed_data, | 88 bool VerifySignature(const std::string& signed_data, |
| 89 QuicVersion quic_version, |
| 90 StringPiece chlo_hash, |
87 const std::string& signature, | 91 const std::string& signature, |
88 const std::string& cert); | 92 const std::string& cert); |
89 | 93 |
90 // Proof verifier to notify when this jobs completes. | 94 // Proof verifier to notify when this jobs completes. |
91 ProofVerifierChromium* proof_verifier_; | 95 ProofVerifierChromium* proof_verifier_; |
92 | 96 |
93 // The underlying verifier used for verifying certificates. | 97 // The underlying verifier used for verifying certificates. |
94 CertVerifier* verifier_; | 98 CertVerifier* verifier_; |
95 scoped_ptr<CertVerifier::Request> cert_verifier_request_; | 99 scoped_ptr<CertVerifier::Request> cert_verifier_request_; |
96 | 100 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 // |hostname_| will always be canonicalized to lowercase. | 152 // |hostname_| will always be canonicalized to lowercase. |
149 if (hostname_.compare("www.google.com") == 0) { | 153 if (hostname_.compare("www.google.com") == 0) { |
150 UMA_HISTOGRAM_TIMES("Net.QuicSession.VerifyProofTime.google", | 154 UMA_HISTOGRAM_TIMES("Net.QuicSession.VerifyProofTime.google", |
151 end_time - start_time_); | 155 end_time - start_time_); |
152 } | 156 } |
153 } | 157 } |
154 | 158 |
155 QuicAsyncStatus ProofVerifierChromium::Job::VerifyProof( | 159 QuicAsyncStatus ProofVerifierChromium::Job::VerifyProof( |
156 const string& hostname, | 160 const string& hostname, |
157 const string& server_config, | 161 const string& server_config, |
| 162 QuicVersion quic_version, |
| 163 StringPiece chlo_hash, |
158 const vector<string>& certs, | 164 const vector<string>& certs, |
159 const std::string& cert_sct, | 165 const std::string& cert_sct, |
160 const string& signature, | 166 const string& signature, |
161 std::string* error_details, | 167 std::string* error_details, |
162 scoped_ptr<ProofVerifyDetails>* verify_details, | 168 scoped_ptr<ProofVerifyDetails>* verify_details, |
163 ProofVerifierCallback* callback) { | 169 ProofVerifierCallback* callback) { |
164 DCHECK(error_details); | 170 DCHECK(error_details); |
165 DCHECK(verify_details); | 171 DCHECK(verify_details); |
166 DCHECK(callback); | 172 DCHECK(callback); |
167 | 173 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 // Note that this is a completely synchronous operation: The CT Log Verifier | 207 // Note that this is a completely synchronous operation: The CT Log Verifier |
202 // gets all the data it needs for SCT verification and does not do any | 208 // gets all the data it needs for SCT verification and does not do any |
203 // external communication. | 209 // external communication. |
204 cert_transparency_verifier_->Verify(cert_.get(), std::string(), cert_sct, | 210 cert_transparency_verifier_->Verify(cert_.get(), std::string(), cert_sct, |
205 &verify_details_->ct_verify_result, | 211 &verify_details_->ct_verify_result, |
206 net_log_); | 212 net_log_); |
207 } | 213 } |
208 | 214 |
209 // We call VerifySignature first to avoid copying of server_config and | 215 // We call VerifySignature first to avoid copying of server_config and |
210 // signature. | 216 // signature. |
211 if (!VerifySignature(server_config, signature, certs[0])) { | 217 if (!VerifySignature(server_config, quic_version, chlo_hash, signature, |
| 218 certs[0])) { |
212 *error_details = "Failed to verify signature of server config"; | 219 *error_details = "Failed to verify signature of server config"; |
213 DLOG(WARNING) << *error_details; | 220 DLOG(WARNING) << *error_details; |
214 verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID; | 221 verify_details_->cert_verify_result.cert_status = CERT_STATUS_INVALID; |
215 *verify_details = std::move(verify_details_); | 222 *verify_details = std::move(verify_details_); |
216 return QUIC_FAILURE; | 223 return QUIC_FAILURE; |
217 } | 224 } |
218 | 225 |
219 hostname_ = hostname; | 226 hostname_ = hostname; |
220 | 227 |
221 next_state_ = STATE_VERIFY_CERT; | 228 next_state_ = STATE_VERIFY_CERT; |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 error_string.c_str()); | 343 error_string.c_str()); |
337 DLOG(WARNING) << error_details_; | 344 DLOG(WARNING) << error_details_; |
338 } | 345 } |
339 | 346 |
340 // Exit DoLoop and return the result to the caller to VerifyProof. | 347 // Exit DoLoop and return the result to the caller to VerifyProof. |
341 DCHECK_EQ(STATE_NONE, next_state_); | 348 DCHECK_EQ(STATE_NONE, next_state_); |
342 return result; | 349 return result; |
343 } | 350 } |
344 | 351 |
345 bool ProofVerifierChromium::Job::VerifySignature(const string& signed_data, | 352 bool ProofVerifierChromium::Job::VerifySignature(const string& signed_data, |
| 353 QuicVersion quic_version, |
| 354 StringPiece chlo_hash, |
346 const string& signature, | 355 const string& signature, |
347 const string& cert) { | 356 const string& cert) { |
348 StringPiece spki; | 357 StringPiece spki; |
349 if (!asn1::ExtractSPKIFromDERCert(cert, &spki)) { | 358 if (!asn1::ExtractSPKIFromDERCert(cert, &spki)) { |
350 DLOG(WARNING) << "ExtractSPKIFromDERCert failed"; | 359 DLOG(WARNING) << "ExtractSPKIFromDERCert failed"; |
351 return false; | 360 return false; |
352 } | 361 } |
353 | 362 |
354 crypto::SignatureVerifier verifier; | 363 crypto::SignatureVerifier verifier; |
355 | 364 |
(...skipping 21 matching lines...) Expand all Loading... |
377 reinterpret_cast<const uint8_t*>(spki.data()), | 386 reinterpret_cast<const uint8_t*>(spki.data()), |
378 spki.size())) { | 387 spki.size())) { |
379 DLOG(WARNING) << "VerifyInit failed"; | 388 DLOG(WARNING) << "VerifyInit failed"; |
380 return false; | 389 return false; |
381 } | 390 } |
382 } else { | 391 } else { |
383 LOG(ERROR) << "Unsupported public key type " << type; | 392 LOG(ERROR) << "Unsupported public key type " << type; |
384 return false; | 393 return false; |
385 } | 394 } |
386 | 395 |
387 verifier.VerifyUpdate(reinterpret_cast<const uint8_t*>(kProofSignatureLabel), | 396 if (quic_version <= QUIC_VERSION_30) { |
388 sizeof(kProofSignatureLabel)); | 397 verifier.VerifyUpdate( |
| 398 reinterpret_cast<const uint8_t*>(kProofSignatureLabelOld), |
| 399 sizeof(kProofSignatureLabelOld)); |
| 400 } else { |
| 401 verifier.VerifyUpdate( |
| 402 reinterpret_cast<const uint8_t*>(kProofSignatureLabel), |
| 403 sizeof(kProofSignatureLabel)); |
| 404 uint32_t len = chlo_hash.length(); |
| 405 verifier.VerifyUpdate(reinterpret_cast<const uint8_t*>(&len), sizeof(len)); |
| 406 verifier.VerifyUpdate(reinterpret_cast<const uint8_t*>(chlo_hash.data()), |
| 407 len); |
| 408 } |
| 409 |
389 verifier.VerifyUpdate(reinterpret_cast<const uint8_t*>(signed_data.data()), | 410 verifier.VerifyUpdate(reinterpret_cast<const uint8_t*>(signed_data.data()), |
390 signed_data.size()); | 411 signed_data.size()); |
391 | 412 |
392 if (!verifier.VerifyFinal()) { | 413 if (!verifier.VerifyFinal()) { |
393 DLOG(WARNING) << "VerifyFinal failed"; | 414 DLOG(WARNING) << "VerifyFinal failed"; |
394 return false; | 415 return false; |
395 } | 416 } |
396 | 417 |
397 DVLOG(1) << "VerifyFinal success"; | 418 DVLOG(1) << "VerifyFinal success"; |
398 return true; | 419 return true; |
399 } | 420 } |
400 | 421 |
401 ProofVerifierChromium::ProofVerifierChromium( | 422 ProofVerifierChromium::ProofVerifierChromium( |
402 CertVerifier* cert_verifier, | 423 CertVerifier* cert_verifier, |
403 CTPolicyEnforcer* ct_policy_enforcer, | 424 CTPolicyEnforcer* ct_policy_enforcer, |
404 TransportSecurityState* transport_security_state, | 425 TransportSecurityState* transport_security_state, |
405 CTVerifier* cert_transparency_verifier) | 426 CTVerifier* cert_transparency_verifier) |
406 : cert_verifier_(cert_verifier), | 427 : cert_verifier_(cert_verifier), |
407 ct_policy_enforcer_(ct_policy_enforcer), | 428 ct_policy_enforcer_(ct_policy_enforcer), |
408 transport_security_state_(transport_security_state), | 429 transport_security_state_(transport_security_state), |
409 cert_transparency_verifier_(cert_transparency_verifier) {} | 430 cert_transparency_verifier_(cert_transparency_verifier) {} |
410 | 431 |
411 ProofVerifierChromium::~ProofVerifierChromium() { | 432 ProofVerifierChromium::~ProofVerifierChromium() { |
412 STLDeleteElements(&active_jobs_); | 433 STLDeleteElements(&active_jobs_); |
413 } | 434 } |
414 | 435 |
415 QuicAsyncStatus ProofVerifierChromium::VerifyProof( | 436 QuicAsyncStatus ProofVerifierChromium::VerifyProof( |
416 const std::string& hostname, | 437 const std::string& hostname, |
417 const std::string& server_config, | 438 const std::string& server_config, |
| 439 QuicVersion quic_version, |
| 440 base::StringPiece chlo_hash, |
418 const std::vector<std::string>& certs, | 441 const std::vector<std::string>& certs, |
419 const std::string& cert_sct, | 442 const std::string& cert_sct, |
420 const std::string& signature, | 443 const std::string& signature, |
421 const ProofVerifyContext* verify_context, | 444 const ProofVerifyContext* verify_context, |
422 std::string* error_details, | 445 std::string* error_details, |
423 scoped_ptr<ProofVerifyDetails>* verify_details, | 446 scoped_ptr<ProofVerifyDetails>* verify_details, |
424 ProofVerifierCallback* callback) { | 447 ProofVerifierCallback* callback) { |
425 if (!verify_context) { | 448 if (!verify_context) { |
426 *error_details = "Missing context"; | 449 *error_details = "Missing context"; |
427 return QUIC_FAILURE; | 450 return QUIC_FAILURE; |
428 } | 451 } |
429 const ProofVerifyContextChromium* chromium_context = | 452 const ProofVerifyContextChromium* chromium_context = |
430 reinterpret_cast<const ProofVerifyContextChromium*>(verify_context); | 453 reinterpret_cast<const ProofVerifyContextChromium*>(verify_context); |
431 scoped_ptr<Job> job( | 454 scoped_ptr<Job> job( |
432 new Job(this, cert_verifier_, ct_policy_enforcer_, | 455 new Job(this, cert_verifier_, ct_policy_enforcer_, |
433 transport_security_state_, cert_transparency_verifier_, | 456 transport_security_state_, cert_transparency_verifier_, |
434 chromium_context->cert_verify_flags, chromium_context->net_log)); | 457 chromium_context->cert_verify_flags, chromium_context->net_log)); |
435 QuicAsyncStatus status = | 458 QuicAsyncStatus status = job->VerifyProof( |
436 job->VerifyProof(hostname, server_config, certs, cert_sct, signature, | 459 hostname, server_config, quic_version, chlo_hash, certs, cert_sct, |
437 error_details, verify_details, callback); | 460 signature, error_details, verify_details, callback); |
438 if (status == QUIC_PENDING) { | 461 if (status == QUIC_PENDING) { |
439 active_jobs_.insert(job.release()); | 462 active_jobs_.insert(job.release()); |
440 } | 463 } |
441 return status; | 464 return status; |
442 } | 465 } |
443 | 466 |
444 void ProofVerifierChromium::OnJobComplete(Job* job) { | 467 void ProofVerifierChromium::OnJobComplete(Job* job) { |
445 active_jobs_.erase(job); | 468 active_jobs_.erase(job); |
446 delete job; | 469 delete job; |
447 } | 470 } |
448 | 471 |
449 } // namespace net | 472 } // namespace net |
OLD | NEW |