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 #include <memory> | 8 #include <memory> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
110 ++it) { | 110 ++it) { |
111 hashes->AppendString(it->ToString()); | 111 hashes->AppendString(it->ToString()); |
112 } | 112 } |
113 results->Set("public_key_hashes", std::move(hashes)); | 113 results->Set("public_key_hashes", std::move(hashes)); |
114 | 114 |
115 return std::move(results); | 115 return std::move(results); |
116 } | 116 } |
117 | 117 |
118 } // namespace | 118 } // namespace |
119 | 119 |
120 MultiThreadedCertVerifier::RequestParams::RequestParams( | |
121 const SHA1HashValue& cert_fingerprint_arg, | |
122 const SHA1HashValue& ca_fingerprint_arg, | |
123 const std::string& hostname_arg, | |
124 const std::string& ocsp_response_arg, | |
125 int flags_arg, | |
126 const CertificateList& additional_trust_anchors) | |
127 : hostname(hostname_arg), flags(flags_arg), start_time(base::Time::Now()) { | |
128 hash_values.reserve(3 + additional_trust_anchors.size()); | |
129 SHA1HashValue ocsp_hash; | |
130 base::SHA1HashBytes( | |
131 reinterpret_cast<const unsigned char*>(ocsp_response_arg.data()), | |
132 ocsp_response_arg.size(), ocsp_hash.data); | |
133 hash_values.push_back(ocsp_hash); | |
134 hash_values.push_back(cert_fingerprint_arg); | |
135 hash_values.push_back(ca_fingerprint_arg); | |
136 for (size_t i = 0; i < additional_trust_anchors.size(); ++i) | |
137 hash_values.push_back(additional_trust_anchors[i]->fingerprint()); | |
138 } | |
139 | |
140 MultiThreadedCertVerifier::RequestParams::RequestParams( | |
141 const RequestParams& other) = default; | |
142 | |
143 MultiThreadedCertVerifier::RequestParams::RequestParams( | |
144 const std::string& hostname_arg, | |
145 int flags_arg, | |
146 const std::vector<SHA1HashValue>& hash_values_arg, | |
147 const base::Time& start_time_arg) { | |
148 hostname = hostname_arg; | |
149 flags = flags_arg; | |
150 hash_values = std::move(hash_values_arg); | |
151 start_time = start_time_arg; | |
152 } | |
153 | |
154 MultiThreadedCertVerifier::RequestParams::~RequestParams() {} | |
155 | |
156 bool MultiThreadedCertVerifier::RequestParams::operator<( | |
157 const RequestParams& other) const { | |
158 // |flags| is compared before |cert_fingerprint|, |ca_fingerprint|, | |
159 // |hostname|, and |ocsp_response|, under assumption that integer comparisons | |
160 // are faster than memory and string comparisons. | |
161 if (flags != other.flags) | |
162 return flags < other.flags; | |
163 if (hostname != other.hostname) | |
164 return hostname < other.hostname; | |
165 return std::lexicographical_compare( | |
166 hash_values.begin(), hash_values.end(), other.hash_values.begin(), | |
167 other.hash_values.end(), SHA1HashValueLessThan()); | |
168 } | |
169 | |
120 MultiThreadedCertVerifier::CachedResult::CachedResult() : error(ERR_FAILED) {} | 170 MultiThreadedCertVerifier::CachedResult::CachedResult() : error(ERR_FAILED) {} |
121 | 171 |
172 MultiThreadedCertVerifier::CachedResult::CachedResult( | |
173 int error_arg, | |
174 CertVerifyResult result_arg) | |
175 : error(error_arg) { | |
176 result.CopyFrom(result_arg); | |
177 } | |
178 | |
122 MultiThreadedCertVerifier::CachedResult::~CachedResult() {} | 179 MultiThreadedCertVerifier::CachedResult::~CachedResult() {} |
123 | 180 |
124 MultiThreadedCertVerifier::CacheValidityPeriod::CacheValidityPeriod( | 181 MultiThreadedCertVerifier::CacheValidityPeriod::CacheValidityPeriod( |
125 const base::Time& now) | 182 const base::Time& now) |
126 : verification_time(now), | 183 : verification_time(now), |
127 expiration_time(now) { | 184 expiration_time(now) { |
128 } | 185 } |
129 | 186 |
130 MultiThreadedCertVerifier::CacheValidityPeriod::CacheValidityPeriod( | 187 MultiThreadedCertVerifier::CacheValidityPeriod::CacheValidityPeriod( |
131 const base::Time& now, | 188 const base::Time& now, |
(...skipping 30 matching lines...) Expand all Loading... | |
162 // This algorithm is only problematic if the user consistently keeps | 219 // This algorithm is only problematic if the user consistently keeps |
163 // adjusting their clock backwards in increments smaller than the expiration | 220 // adjusting their clock backwards in increments smaller than the expiration |
164 // TTL, in which case, cached elements continue to be added. However, | 221 // TTL, in which case, cached elements continue to be added. However, |
165 // because the cache has a fixed upper bound, if no entries are expired, a | 222 // because the cache has a fixed upper bound, if no entries are expired, a |
166 // 'random' entry will be, thus keeping the memory constraints bounded over | 223 // 'random' entry will be, thus keeping the memory constraints bounded over |
167 // time. | 224 // time. |
168 return now.verification_time >= expiration.verification_time && | 225 return now.verification_time >= expiration.verification_time && |
169 now.verification_time < expiration.expiration_time; | 226 now.verification_time < expiration.expiration_time; |
170 }; | 227 }; |
171 | 228 |
229 MultiThreadedCertVerifier::Iterator::Iterator( | |
230 const MultiThreadedCertVerifier& verifier) | |
231 : iterator_(verifier.cache_) {} | |
232 | |
233 MultiThreadedCertVerifier::Iterator::~Iterator() {} | |
234 | |
172 // Represents the output and result callback of a request. The | 235 // Represents the output and result callback of a request. The |
173 // CertVerifierRequest is owned by the caller that initiated the call to | 236 // CertVerifierRequest is owned by the caller that initiated the call to |
174 // CertVerifier::Verify(). | 237 // CertVerifier::Verify(). |
175 class CertVerifierRequest : public base::LinkNode<CertVerifierRequest>, | 238 class CertVerifierRequest : public base::LinkNode<CertVerifierRequest>, |
176 public CertVerifier::Request { | 239 public CertVerifier::Request { |
177 public: | 240 public: |
178 CertVerifierRequest(CertVerifierJob* job, | 241 CertVerifierRequest(CertVerifierJob* job, |
179 const CompletionCallback& callback, | 242 const CompletionCallback& callback, |
180 CertVerifyResult* verify_result, | 243 CertVerifyResult* verify_result, |
181 const BoundNetLog& net_log) | 244 const BoundNetLog& net_log) |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
476 std::unique_ptr<CertVerifierRequest> request = | 539 std::unique_ptr<CertVerifierRequest> request = |
477 job->CreateRequest(callback, verify_result, net_log); | 540 job->CreateRequest(callback, verify_result, net_log); |
478 *out_req = std::move(request); | 541 *out_req = std::move(request); |
479 return ERR_IO_PENDING; | 542 return ERR_IO_PENDING; |
480 } | 543 } |
481 | 544 |
482 bool MultiThreadedCertVerifier::SupportsOCSPStapling() { | 545 bool MultiThreadedCertVerifier::SupportsOCSPStapling() { |
483 return verify_proc_->SupportsOCSPStapling(); | 546 return verify_proc_->SupportsOCSPStapling(); |
484 } | 547 } |
485 | 548 |
486 MultiThreadedCertVerifier::RequestParams::RequestParams( | 549 bool MultiThreadedCertVerifier::AddCertResult( |
487 const SHA1HashValue& cert_fingerprint_arg, | 550 const std::string& hostname, |
488 const SHA1HashValue& ca_fingerprint_arg, | 551 int flags, |
489 const std::string& hostname_arg, | 552 const std::vector<SHA1HashValue>& hash_values, |
490 const std::string& ocsp_response_arg, | 553 const base::Time& start_time, |
491 int flags_arg, | 554 int error, |
492 const CertificateList& additional_trust_anchors) | 555 const CertVerifyResult& result, |
493 : hostname(hostname_arg), flags(flags_arg), start_time(base::Time::Now()) { | 556 const base::Time& verification_time, |
494 hash_values.reserve(3 + additional_trust_anchors.size()); | 557 const base::Time& expiration_time) { |
495 SHA1HashValue ocsp_hash; | 558 base::Time now = base::Time::Now(); |
496 base::SHA1HashBytes( | 559 if (hostname.empty() || hash_values.size() == 0 || |
Ryan Sleevi
2016/05/13 20:18:12
.empty()
| |
497 reinterpret_cast<const unsigned char*>(ocsp_response_arg.data()), | 560 start_time != verification_time || start_time >= now || |
498 ocsp_response_arg.size(), ocsp_hash.data); | 561 expiration_time <= now || |
499 hash_values.push_back(ocsp_hash); | 562 (expiration_time != |
500 hash_values.push_back(cert_fingerprint_arg); | 563 start_time + base::TimeDelta::FromSeconds(kTTLSecs))) { |
501 hash_values.push_back(ca_fingerprint_arg); | 564 DVLOG(1) << "Invalid data for: " << hostname; |
Ryan Sleevi
2016/05/13 20:18:13
Why DVLOG? Is it a programmer error? If so, why no
| |
502 for (size_t i = 0; i < additional_trust_anchors.size(); ++i) | 565 return false; |
503 hash_values.push_back(additional_trust_anchors[i]->fingerprint()); | 566 } |
504 } | |
505 | 567 |
506 MultiThreadedCertVerifier::RequestParams::RequestParams( | 568 // If cache is already full, then don't replace the current entries. |
507 const RequestParams& other) = default; | 569 if (cache_.size() >= kMaxCacheEntries) { |
570 DVLOG(1) << "Cache is full"; | |
Ryan Sleevi
2016/05/13 20:18:12
Necessary?
| |
571 return false; | |
572 } | |
508 | 573 |
509 MultiThreadedCertVerifier::RequestParams::~RequestParams() {} | 574 // Don't overwrite existing entry. |
575 RequestParams key(hostname, flags, hash_values, start_time); | |
576 CacheValidityPeriod expiration(now); | |
577 if (cache_.Get(key, expiration)) { | |
578 DVLOG(1) << "Already exists in the cache for " << key.hostname; | |
Ryan Sleevi
2016/05/13 20:18:13
Necessary?
| |
579 return false; | |
580 } | |
510 | 581 |
511 bool MultiThreadedCertVerifier::RequestParams::operator<( | 582 // Add a new entry. |
512 const RequestParams& other) const { | 583 CachedResult value(error, result); |
513 // |flags| is compared before |cert_fingerprint|, |ca_fingerprint|, | 584 cache_.Put(key, value, CacheValidityPeriod(verification_time), |
514 // |hostname|, and |ocsp_response|, under assumption that integer comparisons | 585 CacheValidityPeriod(verification_time, expiration_time)); |
515 // are faster than memory and string comparisons. | 586 return true; |
516 if (flags != other.flags) | |
517 return flags < other.flags; | |
518 if (hostname != other.hostname) | |
519 return hostname < other.hostname; | |
520 return std::lexicographical_compare( | |
521 hash_values.begin(), hash_values.end(), other.hash_values.begin(), | |
522 other.hash_values.end(), SHA1HashValueLessThan()); | |
523 } | 587 } |
524 | 588 |
525 bool MultiThreadedCertVerifier::JobComparator::operator()( | 589 bool MultiThreadedCertVerifier::JobComparator::operator()( |
526 const CertVerifierJob* job1, | 590 const CertVerifierJob* job1, |
527 const CertVerifierJob* job2) const { | 591 const CertVerifierJob* job2) const { |
528 return job1->key() < job2->key(); | 592 return job1->key() < job2->key(); |
529 } | 593 } |
530 | 594 |
531 void MultiThreadedCertVerifier::SaveResultToCache(const RequestParams& key, | 595 void MultiThreadedCertVerifier::SaveResultToCache(const RequestParams& key, |
532 const CachedResult& result) { | 596 const CachedResult& result) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
590 // The JobSet is kept in sorted order so items can be found using binary | 654 // The JobSet is kept in sorted order so items can be found using binary |
591 // search. | 655 // search. |
592 auto it = std::lower_bound(inflight_.begin(), inflight_.end(), key, | 656 auto it = std::lower_bound(inflight_.begin(), inflight_.end(), key, |
593 JobToRequestParamsComparator()); | 657 JobToRequestParamsComparator()); |
594 if (it != inflight_.end() && !(key < (*it)->key())) | 658 if (it != inflight_.end() && !(key < (*it)->key())) |
595 return *it; | 659 return *it; |
596 return nullptr; | 660 return nullptr; |
597 } | 661 } |
598 | 662 |
599 } // namespace net | 663 } // namespace net |
OLD | NEW |