| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/cert/multi_threaded_cert_verifier.h" | 5 #include "net/cert/multi_threaded_cert_verifier.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 namespace { | 73 namespace { |
| 74 | 74 |
| 75 // The default value of max_cache_entries_. | 75 // The default value of max_cache_entries_. |
| 76 const unsigned kMaxCacheEntries = 256; | 76 const unsigned kMaxCacheEntries = 256; |
| 77 | 77 |
| 78 // The number of seconds for which we'll cache a cache entry. | 78 // The number of seconds for which we'll cache a cache entry. |
| 79 const unsigned kTTLSecs = 1800; // 30 minutes. | 79 const unsigned kTTLSecs = 1800; // 30 minutes. |
| 80 | 80 |
| 81 } // namespace | 81 } // namespace |
| 82 | 82 |
| 83 MultiThreadedCertVerifier::CachedResult::CachedResult() : error(ERR_FAILED) {} | 83 MultiThreadedCertVerifier::CachedResult::CachedResult() : error(ERR_FAILED) { |
| 84 } |
| 84 | 85 |
| 85 MultiThreadedCertVerifier::CachedResult::~CachedResult() {} | 86 MultiThreadedCertVerifier::CachedResult::~CachedResult() { |
| 87 } |
| 86 | 88 |
| 87 MultiThreadedCertVerifier::CacheValidityPeriod::CacheValidityPeriod( | 89 MultiThreadedCertVerifier::CacheValidityPeriod::CacheValidityPeriod( |
| 88 const base::Time& now) | 90 const base::Time& now) |
| 89 : verification_time(now), | 91 : verification_time(now), expiration_time(now) { |
| 90 expiration_time(now) { | |
| 91 } | 92 } |
| 92 | 93 |
| 93 MultiThreadedCertVerifier::CacheValidityPeriod::CacheValidityPeriod( | 94 MultiThreadedCertVerifier::CacheValidityPeriod::CacheValidityPeriod( |
| 94 const base::Time& now, | 95 const base::Time& now, |
| 95 const base::Time& expiration) | 96 const base::Time& expiration) |
| 96 : verification_time(now), | 97 : verification_time(now), expiration_time(expiration) { |
| 97 expiration_time(expiration) { | |
| 98 } | 98 } |
| 99 | 99 |
| 100 bool MultiThreadedCertVerifier::CacheExpirationFunctor::operator()( | 100 bool MultiThreadedCertVerifier::CacheExpirationFunctor::operator()( |
| 101 const CacheValidityPeriod& now, | 101 const CacheValidityPeriod& now, |
| 102 const CacheValidityPeriod& expiration) const { | 102 const CacheValidityPeriod& expiration) const { |
| 103 // Ensure this functor is being used for expiration only, and not strict | 103 // Ensure this functor is being used for expiration only, and not strict |
| 104 // weak ordering/sorting. |now| should only ever contain a single | 104 // weak ordering/sorting. |now| should only ever contain a single |
| 105 // base::Time. | 105 // base::Time. |
| 106 // Note: DCHECK_EQ is not used due to operator<< overloading requirements. | 106 // Note: DCHECK_EQ is not used due to operator<< overloading requirements. |
| 107 DCHECK(now.verification_time == now.expiration_time); | 107 DCHECK(now.verification_time == now.expiration_time); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 125 // This algorithm is only problematic if the user consistently keeps | 125 // This algorithm is only problematic if the user consistently keeps |
| 126 // adjusting their clock backwards in increments smaller than the expiration | 126 // adjusting their clock backwards in increments smaller than the expiration |
| 127 // TTL, in which case, cached elements continue to be added. However, | 127 // TTL, in which case, cached elements continue to be added. However, |
| 128 // because the cache has a fixed upper bound, if no entries are expired, a | 128 // because the cache has a fixed upper bound, if no entries are expired, a |
| 129 // 'random' entry will be, thus keeping the memory constraints bounded over | 129 // 'random' entry will be, thus keeping the memory constraints bounded over |
| 130 // time. | 130 // time. |
| 131 return now.verification_time >= expiration.verification_time && | 131 return now.verification_time >= expiration.verification_time && |
| 132 now.verification_time < expiration.expiration_time; | 132 now.verification_time < expiration.expiration_time; |
| 133 }; | 133 }; |
| 134 | 134 |
| 135 | |
| 136 // Represents the output and result callback of a request. | 135 // Represents the output and result callback of a request. |
| 137 class CertVerifierRequest { | 136 class CertVerifierRequest { |
| 138 public: | 137 public: |
| 139 CertVerifierRequest(const CompletionCallback& callback, | 138 CertVerifierRequest(const CompletionCallback& callback, |
| 140 CertVerifyResult* verify_result, | 139 CertVerifyResult* verify_result, |
| 141 const BoundNetLog& net_log) | 140 const BoundNetLog& net_log) |
| 142 : callback_(callback), | 141 : callback_(callback), verify_result_(verify_result), net_log_(net_log) { |
| 143 verify_result_(verify_result), | |
| 144 net_log_(net_log) { | |
| 145 net_log_.BeginEvent(NetLog::TYPE_CERT_VERIFIER_REQUEST); | 142 net_log_.BeginEvent(NetLog::TYPE_CERT_VERIFIER_REQUEST); |
| 146 } | 143 } |
| 147 | 144 |
| 148 ~CertVerifierRequest() { | 145 ~CertVerifierRequest() {} |
| 149 } | |
| 150 | 146 |
| 151 // Ensures that the result callback will never be made. | 147 // Ensures that the result callback will never be made. |
| 152 void Cancel() { | 148 void Cancel() { |
| 153 callback_.Reset(); | 149 callback_.Reset(); |
| 154 verify_result_ = NULL; | 150 verify_result_ = NULL; |
| 155 net_log_.AddEvent(NetLog::TYPE_CANCELLED); | 151 net_log_.AddEvent(NetLog::TYPE_CANCELLED); |
| 156 net_log_.EndEvent(NetLog::TYPE_CERT_VERIFIER_REQUEST); | 152 net_log_.EndEvent(NetLog::TYPE_CERT_VERIFIER_REQUEST); |
| 157 } | 153 } |
| 158 | 154 |
| 159 // Copies the contents of |verify_result| to the caller's | 155 // Copies the contents of |verify_result| to the caller's |
| (...skipping 10 matching lines...) Expand all Loading... |
| 170 bool canceled() const { return callback_.is_null(); } | 166 bool canceled() const { return callback_.is_null(); } |
| 171 | 167 |
| 172 const BoundNetLog& net_log() const { return net_log_; } | 168 const BoundNetLog& net_log() const { return net_log_; } |
| 173 | 169 |
| 174 private: | 170 private: |
| 175 CompletionCallback callback_; | 171 CompletionCallback callback_; |
| 176 CertVerifyResult* verify_result_; | 172 CertVerifyResult* verify_result_; |
| 177 const BoundNetLog net_log_; | 173 const BoundNetLog net_log_; |
| 178 }; | 174 }; |
| 179 | 175 |
| 180 | |
| 181 // CertVerifierWorker runs on a worker thread and takes care of the blocking | 176 // CertVerifierWorker runs on a worker thread and takes care of the blocking |
| 182 // process of performing the certificate verification. Deletes itself | 177 // process of performing the certificate verification. Deletes itself |
| 183 // eventually if Start() succeeds. | 178 // eventually if Start() succeeds. |
| 184 class CertVerifierWorker { | 179 class CertVerifierWorker { |
| 185 public: | 180 public: |
| 186 CertVerifierWorker(CertVerifyProc* verify_proc, | 181 CertVerifierWorker(CertVerifyProc* verify_proc, |
| 187 X509Certificate* cert, | 182 X509Certificate* cert, |
| 188 const std::string& hostname, | 183 const std::string& hostname, |
| 189 int flags, | 184 int flags, |
| 190 CRLSet* crl_set, | 185 CRLSet* crl_set, |
| 191 const CertificateList& additional_trust_anchors, | 186 const CertificateList& additional_trust_anchors, |
| 192 MultiThreadedCertVerifier* cert_verifier) | 187 MultiThreadedCertVerifier* cert_verifier) |
| 193 : verify_proc_(verify_proc), | 188 : verify_proc_(verify_proc), |
| 194 cert_(cert), | 189 cert_(cert), |
| 195 hostname_(hostname), | 190 hostname_(hostname), |
| 196 flags_(flags), | 191 flags_(flags), |
| 197 crl_set_(crl_set), | 192 crl_set_(crl_set), |
| 198 additional_trust_anchors_(additional_trust_anchors), | 193 additional_trust_anchors_(additional_trust_anchors), |
| 199 origin_loop_(base::MessageLoop::current()), | 194 origin_loop_(base::MessageLoop::current()), |
| 200 cert_verifier_(cert_verifier), | 195 cert_verifier_(cert_verifier), |
| 201 canceled_(false), | 196 canceled_(false), |
| 202 error_(ERR_FAILED) { | 197 error_(ERR_FAILED) {} |
| 203 } | |
| 204 | 198 |
| 205 // Returns the certificate being verified. May only be called /before/ | 199 // Returns the certificate being verified. May only be called /before/ |
| 206 // Start() is called. | 200 // Start() is called. |
| 207 X509Certificate* certificate() const { return cert_.get(); } | 201 X509Certificate* certificate() const { return cert_.get(); } |
| 208 | 202 |
| 209 bool Start() { | 203 bool Start() { |
| 210 DCHECK_EQ(base::MessageLoop::current(), origin_loop_); | 204 DCHECK_EQ(base::MessageLoop::current(), origin_loop_); |
| 211 | 205 |
| 212 return base::WorkerPool::PostTask( | 206 return base::WorkerPool::PostTask( |
| 213 FROM_HERE, base::Bind(&CertVerifierWorker::Run, base::Unretained(this)), | 207 FROM_HERE, |
| 208 base::Bind(&CertVerifierWorker::Run, base::Unretained(this)), |
| 214 true /* task is slow */); | 209 true /* task is slow */); |
| 215 } | 210 } |
| 216 | 211 |
| 217 // Cancel is called from the origin loop when the MultiThreadedCertVerifier is | 212 // Cancel is called from the origin loop when the MultiThreadedCertVerifier is |
| 218 // getting deleted. | 213 // getting deleted. |
| 219 void Cancel() { | 214 void Cancel() { |
| 220 DCHECK_EQ(base::MessageLoop::current(), origin_loop_); | 215 DCHECK_EQ(base::MessageLoop::current(), origin_loop_); |
| 221 base::AutoLock locked(lock_); | 216 base::AutoLock locked(lock_); |
| 222 canceled_ = true; | 217 canceled_ = true; |
| 223 } | 218 } |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 // If it does so after this function, we assume that the MessageLoop will | 271 // If it does so after this function, we assume that the MessageLoop will |
| 277 // process pending tasks. In which case we'll notice the |canceled_| flag | 272 // process pending tasks. In which case we'll notice the |canceled_| flag |
| 278 // in DoReply. | 273 // in DoReply. |
| 279 | 274 |
| 280 bool canceled; | 275 bool canceled; |
| 281 { | 276 { |
| 282 base::AutoLock locked(lock_); | 277 base::AutoLock locked(lock_); |
| 283 canceled = canceled_; | 278 canceled = canceled_; |
| 284 if (!canceled) { | 279 if (!canceled) { |
| 285 origin_loop_->PostTask( | 280 origin_loop_->PostTask( |
| 286 FROM_HERE, base::Bind( | 281 FROM_HERE, |
| 287 &CertVerifierWorker::DoReply, base::Unretained(this))); | 282 base::Bind(&CertVerifierWorker::DoReply, base::Unretained(this))); |
| 288 } | 283 } |
| 289 } | 284 } |
| 290 | 285 |
| 291 if (canceled) | 286 if (canceled) |
| 292 delete this; | 287 delete this; |
| 293 } | 288 } |
| 294 | 289 |
| 295 scoped_refptr<CertVerifyProc> verify_proc_; | 290 scoped_refptr<CertVerifyProc> verify_proc_; |
| 296 scoped_refptr<X509Certificate> cert_; | 291 scoped_refptr<X509Certificate> cert_; |
| 297 const std::string hostname_; | 292 const std::string hostname_; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 312 int error_; | 307 int error_; |
| 313 CertVerifyResult verify_result_; | 308 CertVerifyResult verify_result_; |
| 314 | 309 |
| 315 DISALLOW_COPY_AND_ASSIGN(CertVerifierWorker); | 310 DISALLOW_COPY_AND_ASSIGN(CertVerifierWorker); |
| 316 }; | 311 }; |
| 317 | 312 |
| 318 // A CertVerifierJob is a one-to-one counterpart of a CertVerifierWorker. It | 313 // A CertVerifierJob is a one-to-one counterpart of a CertVerifierWorker. It |
| 319 // lives only on the CertVerifier's origin message loop. | 314 // lives only on the CertVerifier's origin message loop. |
| 320 class CertVerifierJob { | 315 class CertVerifierJob { |
| 321 public: | 316 public: |
| 322 CertVerifierJob(CertVerifierWorker* worker, | 317 CertVerifierJob(CertVerifierWorker* worker, const BoundNetLog& net_log) |
| 323 const BoundNetLog& net_log) | |
| 324 : start_time_(base::TimeTicks::Now()), | 318 : start_time_(base::TimeTicks::Now()), |
| 325 worker_(worker), | 319 worker_(worker), |
| 326 net_log_(net_log) { | 320 net_log_(net_log) { |
| 327 net_log_.BeginEvent( | 321 net_log_.BeginEvent(NetLog::TYPE_CERT_VERIFIER_JOB, |
| 328 NetLog::TYPE_CERT_VERIFIER_JOB, | 322 base::Bind(&NetLogX509CertificateCallback, |
| 329 base::Bind(&NetLogX509CertificateCallback, | 323 base::Unretained(worker_->certificate()))); |
| 330 base::Unretained(worker_->certificate()))); | |
| 331 } | 324 } |
| 332 | 325 |
| 333 ~CertVerifierJob() { | 326 ~CertVerifierJob() { |
| 334 if (worker_) { | 327 if (worker_) { |
| 335 net_log_.AddEvent(NetLog::TYPE_CANCELLED); | 328 net_log_.AddEvent(NetLog::TYPE_CANCELLED); |
| 336 net_log_.EndEvent(NetLog::TYPE_CERT_VERIFIER_JOB); | 329 net_log_.EndEvent(NetLog::TYPE_CERT_VERIFIER_JOB); |
| 337 worker_->Cancel(); | 330 worker_->Cancel(); |
| 338 DeleteAllCanceled(); | 331 DeleteAllCanceled(); |
| 339 } | 332 } |
| 340 } | 333 } |
| 341 | 334 |
| 342 void AddRequest(CertVerifierRequest* request) { | 335 void AddRequest(CertVerifierRequest* request) { |
| 343 request->net_log().AddEvent( | 336 request->net_log().AddEvent(NetLog::TYPE_CERT_VERIFIER_REQUEST_BOUND_TO_JOB, |
| 344 NetLog::TYPE_CERT_VERIFIER_REQUEST_BOUND_TO_JOB, | 337 net_log_.source().ToEventParametersCallback()); |
| 345 net_log_.source().ToEventParametersCallback()); | |
| 346 | 338 |
| 347 requests_.push_back(request); | 339 requests_.push_back(request); |
| 348 } | 340 } |
| 349 | 341 |
| 350 void HandleResult( | 342 void HandleResult( |
| 351 const MultiThreadedCertVerifier::CachedResult& verify_result, | 343 const MultiThreadedCertVerifier::CachedResult& verify_result, |
| 352 bool is_first_job) { | 344 bool is_first_job) { |
| 353 worker_ = NULL; | 345 worker_ = NULL; |
| 354 net_log_.EndEvent(NetLog::TYPE_CERT_VERIFIER_JOB); | 346 net_log_.EndEvent(NetLog::TYPE_CERT_VERIFIER_JOB); |
| 355 base::TimeDelta latency = base::TimeTicks::Now() - start_time_; | 347 base::TimeDelta latency = base::TimeTicks::Now() - start_time_; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 366 100); | 358 100); |
| 367 } | 359 } |
| 368 PostAll(verify_result); | 360 PostAll(verify_result); |
| 369 } | 361 } |
| 370 | 362 |
| 371 private: | 363 private: |
| 372 void PostAll(const MultiThreadedCertVerifier::CachedResult& verify_result) { | 364 void PostAll(const MultiThreadedCertVerifier::CachedResult& verify_result) { |
| 373 std::vector<CertVerifierRequest*> requests; | 365 std::vector<CertVerifierRequest*> requests; |
| 374 requests_.swap(requests); | 366 requests_.swap(requests); |
| 375 | 367 |
| 376 for (std::vector<CertVerifierRequest*>::iterator | 368 for (std::vector<CertVerifierRequest*>::iterator i = requests.begin(); |
| 377 i = requests.begin(); i != requests.end(); i++) { | 369 i != requests.end(); |
| 370 i++) { |
| 378 (*i)->Post(verify_result); | 371 (*i)->Post(verify_result); |
| 379 // Post() causes the CertVerifierRequest to delete itself. | 372 // Post() causes the CertVerifierRequest to delete itself. |
| 380 } | 373 } |
| 381 } | 374 } |
| 382 | 375 |
| 383 void DeleteAllCanceled() { | 376 void DeleteAllCanceled() { |
| 384 for (std::vector<CertVerifierRequest*>::iterator | 377 for (std::vector<CertVerifierRequest*>::iterator i = requests_.begin(); |
| 385 i = requests_.begin(); i != requests_.end(); i++) { | 378 i != requests_.end(); |
| 379 i++) { |
| 386 if ((*i)->canceled()) { | 380 if ((*i)->canceled()) { |
| 387 delete *i; | 381 delete *i; |
| 388 } else { | 382 } else { |
| 389 LOG(DFATAL) << "CertVerifierRequest leaked!"; | 383 LOG(DFATAL) << "CertVerifierRequest leaked!"; |
| 390 } | 384 } |
| 391 } | 385 } |
| 392 } | 386 } |
| 393 | 387 |
| 394 const base::TimeTicks start_time_; | 388 const base::TimeTicks start_time_; |
| 395 std::vector<CertVerifierRequest*> requests_; | 389 std::vector<CertVerifierRequest*> requests_; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 432 | 426 |
| 433 if (callback.is_null() || !verify_result || hostname.empty()) { | 427 if (callback.is_null() || !verify_result || hostname.empty()) { |
| 434 *out_req = NULL; | 428 *out_req = NULL; |
| 435 return ERR_INVALID_ARGUMENT; | 429 return ERR_INVALID_ARGUMENT; |
| 436 } | 430 } |
| 437 | 431 |
| 438 requests_++; | 432 requests_++; |
| 439 | 433 |
| 440 const CertificateList empty_cert_list; | 434 const CertificateList empty_cert_list; |
| 441 const CertificateList& additional_trust_anchors = | 435 const CertificateList& additional_trust_anchors = |
| 442 trust_anchor_provider_ ? | 436 trust_anchor_provider_ |
| 443 trust_anchor_provider_->GetAdditionalTrustAnchors() : empty_cert_list; | 437 ? trust_anchor_provider_->GetAdditionalTrustAnchors() |
| 438 : empty_cert_list; |
| 444 | 439 |
| 445 const RequestParams key(cert->fingerprint(), cert->ca_fingerprint(), | 440 const RequestParams key(cert->fingerprint(), |
| 446 hostname, flags, additional_trust_anchors); | 441 cert->ca_fingerprint(), |
| 442 hostname, |
| 443 flags, |
| 444 additional_trust_anchors); |
| 447 const CertVerifierCache::value_type* cached_entry = | 445 const CertVerifierCache::value_type* cached_entry = |
| 448 cache_.Get(key, CacheValidityPeriod(base::Time::Now())); | 446 cache_.Get(key, CacheValidityPeriod(base::Time::Now())); |
| 449 if (cached_entry) { | 447 if (cached_entry) { |
| 450 ++cache_hits_; | 448 ++cache_hits_; |
| 451 *out_req = NULL; | 449 *out_req = NULL; |
| 452 *verify_result = cached_entry->result; | 450 *verify_result = cached_entry->result; |
| 453 return cached_entry->error; | 451 return cached_entry->error; |
| 454 } | 452 } |
| 455 | 453 |
| 456 // No cache hit. See if an identical request is currently in flight. | 454 // No cache hit. See if an identical request is currently in flight. |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 502 CertVerifierRequest* request = reinterpret_cast<CertVerifierRequest*>(req); | 500 CertVerifierRequest* request = reinterpret_cast<CertVerifierRequest*>(req); |
| 503 request->Cancel(); | 501 request->Cancel(); |
| 504 } | 502 } |
| 505 | 503 |
| 506 MultiThreadedCertVerifier::RequestParams::RequestParams( | 504 MultiThreadedCertVerifier::RequestParams::RequestParams( |
| 507 const SHA1HashValue& cert_fingerprint_arg, | 505 const SHA1HashValue& cert_fingerprint_arg, |
| 508 const SHA1HashValue& ca_fingerprint_arg, | 506 const SHA1HashValue& ca_fingerprint_arg, |
| 509 const std::string& hostname_arg, | 507 const std::string& hostname_arg, |
| 510 int flags_arg, | 508 int flags_arg, |
| 511 const CertificateList& additional_trust_anchors) | 509 const CertificateList& additional_trust_anchors) |
| 512 : hostname(hostname_arg), | 510 : hostname(hostname_arg), flags(flags_arg) { |
| 513 flags(flags_arg) { | |
| 514 hash_values.reserve(2 + additional_trust_anchors.size()); | 511 hash_values.reserve(2 + additional_trust_anchors.size()); |
| 515 hash_values.push_back(cert_fingerprint_arg); | 512 hash_values.push_back(cert_fingerprint_arg); |
| 516 hash_values.push_back(ca_fingerprint_arg); | 513 hash_values.push_back(ca_fingerprint_arg); |
| 517 for (size_t i = 0; i < additional_trust_anchors.size(); ++i) | 514 for (size_t i = 0; i < additional_trust_anchors.size(); ++i) |
| 518 hash_values.push_back(additional_trust_anchors[i]->fingerprint()); | 515 hash_values.push_back(additional_trust_anchors[i]->fingerprint()); |
| 519 } | 516 } |
| 520 | 517 |
| 521 MultiThreadedCertVerifier::RequestParams::~RequestParams() {} | 518 MultiThreadedCertVerifier::RequestParams::~RequestParams() { |
| 519 } |
| 522 | 520 |
| 523 bool MultiThreadedCertVerifier::RequestParams::operator<( | 521 bool MultiThreadedCertVerifier::RequestParams::operator<( |
| 524 const RequestParams& other) const { | 522 const RequestParams& other) const { |
| 525 // |flags| is compared before |cert_fingerprint|, |ca_fingerprint|, and | 523 // |flags| is compared before |cert_fingerprint|, |ca_fingerprint|, and |
| 526 // |hostname| under assumption that integer comparisons are faster than | 524 // |hostname| under assumption that integer comparisons are faster than |
| 527 // memory and string comparisons. | 525 // memory and string comparisons. |
| 528 if (flags != other.flags) | 526 if (flags != other.flags) |
| 529 return flags < other.flags; | 527 return flags < other.flags; |
| 530 if (hostname != other.hostname) | 528 if (hostname != other.hostname) |
| 531 return hostname < other.hostname; | 529 return hostname < other.hostname; |
| 532 return std::lexicographical_compare( | 530 return std::lexicographical_compare(hash_values.begin(), |
| 533 hash_values.begin(), hash_values.end(), | 531 hash_values.end(), |
| 534 other.hash_values.begin(), other.hash_values.end(), | 532 other.hash_values.begin(), |
| 535 net::SHA1HashValueLessThan()); | 533 other.hash_values.end(), |
| 534 net::SHA1HashValueLessThan()); |
| 536 } | 535 } |
| 537 | 536 |
| 538 // HandleResult is called by CertVerifierWorker on the origin message loop. | 537 // HandleResult is called by CertVerifierWorker on the origin message loop. |
| 539 // It deletes CertVerifierJob. | 538 // It deletes CertVerifierJob. |
| 540 void MultiThreadedCertVerifier::HandleResult( | 539 void MultiThreadedCertVerifier::HandleResult( |
| 541 X509Certificate* cert, | 540 X509Certificate* cert, |
| 542 const std::string& hostname, | 541 const std::string& hostname, |
| 543 int flags, | 542 int flags, |
| 544 const CertificateList& additional_trust_anchors, | 543 const CertificateList& additional_trust_anchors, |
| 545 int error, | 544 int error, |
| 546 const CertVerifyResult& verify_result) { | 545 const CertVerifyResult& verify_result) { |
| 547 DCHECK(CalledOnValidThread()); | 546 DCHECK(CalledOnValidThread()); |
| 548 | 547 |
| 549 const RequestParams key(cert->fingerprint(), cert->ca_fingerprint(), | 548 const RequestParams key(cert->fingerprint(), |
| 550 hostname, flags, additional_trust_anchors); | 549 cert->ca_fingerprint(), |
| 550 hostname, |
| 551 flags, |
| 552 additional_trust_anchors); |
| 551 | 553 |
| 552 CachedResult cached_result; | 554 CachedResult cached_result; |
| 553 cached_result.error = error; | 555 cached_result.error = error; |
| 554 cached_result.result = verify_result; | 556 cached_result.result = verify_result; |
| 555 base::Time now = base::Time::Now(); | 557 base::Time now = base::Time::Now(); |
| 556 cache_.Put( | 558 cache_.Put( |
| 557 key, cached_result, CacheValidityPeriod(now), | 559 key, |
| 560 cached_result, |
| 561 CacheValidityPeriod(now), |
| 558 CacheValidityPeriod(now, now + base::TimeDelta::FromSeconds(kTTLSecs))); | 562 CacheValidityPeriod(now, now + base::TimeDelta::FromSeconds(kTTLSecs))); |
| 559 | 563 |
| 560 std::map<RequestParams, CertVerifierJob*>::iterator j; | 564 std::map<RequestParams, CertVerifierJob*>::iterator j; |
| 561 j = inflight_.find(key); | 565 j = inflight_.find(key); |
| 562 if (j == inflight_.end()) { | 566 if (j == inflight_.end()) { |
| 563 NOTREACHED(); | 567 NOTREACHED(); |
| 564 return; | 568 return; |
| 565 } | 569 } |
| 566 CertVerifierJob* job = j->second; | 570 CertVerifierJob* job = j->second; |
| 567 inflight_.erase(j); | 571 inflight_.erase(j); |
| 568 bool is_first_job = false; | 572 bool is_first_job = false; |
| 569 if (first_job_ == job) { | 573 if (first_job_ == job) { |
| 570 is_first_job = true; | 574 is_first_job = true; |
| 571 first_job_ = NULL; | 575 first_job_ = NULL; |
| 572 } | 576 } |
| 573 | 577 |
| 574 job->HandleResult(cached_result, is_first_job); | 578 job->HandleResult(cached_result, is_first_job); |
| 575 delete job; | 579 delete job; |
| 576 } | 580 } |
| 577 | 581 |
| 578 void MultiThreadedCertVerifier::OnCACertChanged( | 582 void MultiThreadedCertVerifier::OnCACertChanged(const X509Certificate* cert) { |
| 579 const X509Certificate* cert) { | |
| 580 DCHECK(CalledOnValidThread()); | 583 DCHECK(CalledOnValidThread()); |
| 581 | 584 |
| 582 ClearCache(); | 585 ClearCache(); |
| 583 } | 586 } |
| 584 | 587 |
| 585 } // namespace net | 588 } // namespace net |
| OLD | NEW |