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 #ifndef NET_CERT_MULTI_THREADED_CERT_VERIFIER_H_ | 5 #ifndef NET_CERT_MULTI_THREADED_CERT_VERIFIER_H_ |
6 #define NET_CERT_MULTI_THREADED_CERT_VERIFIER_H_ | 6 #define NET_CERT_MULTI_THREADED_CERT_VERIFIER_H_ |
7 | 7 |
8 #include <stddef.h> | 8 #include <stddef.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 | 10 |
11 #include <memory> | 11 #include <memory> |
12 #include <set> | 12 #include <set> |
13 #include <string> | 13 #include <string> |
14 #include <vector> | 14 #include <vector> |
15 | 15 |
16 #include "base/gtest_prod_util.h" | 16 #include "base/gtest_prod_util.h" |
17 #include "base/macros.h" | 17 #include "base/macros.h" |
18 #include "base/memory/ref_counted.h" | 18 #include "base/memory/ref_counted.h" |
19 #include "base/threading/non_thread_safe.h" | 19 #include "base/threading/non_thread_safe.h" |
20 #include "net/base/completion_callback.h" | 20 #include "net/base/completion_callback.h" |
21 #include "net/base/expiring_cache.h" | |
22 #include "net/base/hash_value.h" | |
23 #include "net/base/net_export.h" | 21 #include "net/base/net_export.h" |
24 #include "net/cert/cert_database.h" | |
25 #include "net/cert/cert_verifier.h" | 22 #include "net/cert/cert_verifier.h" |
26 #include "net/cert/cert_verify_result.h" | |
27 #include "net/cert/x509_cert_types.h" | |
28 | 23 |
29 namespace net { | 24 namespace net { |
30 | 25 |
31 class CertTrustAnchorProvider; | |
32 class CertVerifierJob; | 26 class CertVerifierJob; |
33 class CertVerifierRequest; | 27 class CertVerifierRequest; |
34 class CertVerifierWorker; | 28 class CertVerifierWorker; |
35 class CertVerifyProc; | 29 class CertVerifyProc; |
36 | 30 |
37 // MultiThreadedCertVerifier is a CertVerifier implementation that runs | 31 // MultiThreadedCertVerifier is a CertVerifier implementation that runs |
38 // synchronous CertVerifier implementations on worker threads. | 32 // synchronous CertVerifier implementations on worker threads. |
39 class NET_EXPORT_PRIVATE MultiThreadedCertVerifier | 33 class NET_EXPORT_PRIVATE MultiThreadedCertVerifier |
40 : public CertVerifier, | 34 : public CertVerifier, |
41 NON_EXPORTED_BASE(public base::NonThreadSafe), | 35 NON_EXPORTED_BASE(public base::NonThreadSafe) { |
42 public CertDatabase::Observer { | |
43 public: | 36 public: |
44 explicit MultiThreadedCertVerifier(CertVerifyProc* verify_proc); | 37 explicit MultiThreadedCertVerifier(CertVerifyProc* verify_proc); |
45 | 38 |
46 // When the verifier is destroyed, all certificate verifications requests are | 39 // When the verifier is destroyed, all certificate verifications requests are |
47 // canceled, and their completion callbacks will not be called. | 40 // canceled, and their completion callbacks will not be called. |
48 ~MultiThreadedCertVerifier() override; | 41 ~MultiThreadedCertVerifier() override; |
49 | 42 |
50 // Configures a source of additional certificates that should be treated as | |
51 // trust anchors during verification, provided that the underlying | |
52 // CertVerifyProc supports additional trust beyond the default implementation. | |
53 // The CertTrustAnchorProvider will only be accessed on the same | |
54 // thread that Verify() is called on; that is, it will not be | |
55 // accessed from worker threads. | |
56 // It must outlive the MultiThreadedCertVerifier. | |
57 void SetCertTrustAnchorProvider( | |
58 CertTrustAnchorProvider* trust_anchor_provider); | |
59 | |
60 // CertVerifier implementation | 43 // CertVerifier implementation |
61 int Verify(const RequestParams& params, | 44 int Verify(const RequestParams& params, |
62 CRLSet* crl_set, | 45 CRLSet* crl_set, |
63 CertVerifyResult* verify_result, | 46 CertVerifyResult* verify_result, |
64 const CompletionCallback& callback, | 47 const CompletionCallback& callback, |
65 std::unique_ptr<Request>* out_req, | 48 std::unique_ptr<Request>* out_req, |
66 const BoundNetLog& net_log) override; | 49 const BoundNetLog& net_log) override; |
67 | 50 |
68 bool SupportsOCSPStapling() override; | 51 bool SupportsOCSPStapling() override; |
69 | 52 |
70 private: | 53 private: |
71 struct JobToRequestParamsComparator; | 54 struct JobToRequestParamsComparator; |
72 friend class CertVerifierRequest; | 55 friend class CertVerifierRequest; |
73 friend class CertVerifierJob; | 56 friend class CertVerifierJob; |
74 friend class MultiThreadedCertVerifierTest; | 57 friend class MultiThreadedCertVerifierTest; |
75 FRIEND_TEST_ALL_PREFIXES(MultiThreadedCertVerifierTest, CacheHit); | |
76 FRIEND_TEST_ALL_PREFIXES(MultiThreadedCertVerifierTest, DifferentCACerts); | |
77 FRIEND_TEST_ALL_PREFIXES(MultiThreadedCertVerifierTest, InflightJoin); | 58 FRIEND_TEST_ALL_PREFIXES(MultiThreadedCertVerifierTest, InflightJoin); |
78 FRIEND_TEST_ALL_PREFIXES(MultiThreadedCertVerifierTest, MultipleInflightJoin); | 59 FRIEND_TEST_ALL_PREFIXES(MultiThreadedCertVerifierTest, MultipleInflightJoin); |
79 FRIEND_TEST_ALL_PREFIXES(MultiThreadedCertVerifierTest, CancelRequest); | 60 FRIEND_TEST_ALL_PREFIXES(MultiThreadedCertVerifierTest, CancelRequest); |
80 FRIEND_TEST_ALL_PREFIXES(MultiThreadedCertVerifierTest, | 61 FRIEND_TEST_ALL_PREFIXES(MultiThreadedCertVerifierTest, |
81 RequestParamsComparators); | 62 RequestParamsComparators); |
82 FRIEND_TEST_ALL_PREFIXES(MultiThreadedCertVerifierTest, | 63 FRIEND_TEST_ALL_PREFIXES(MultiThreadedCertVerifierTest, |
83 CertTrustAnchorProvider); | 64 CertTrustAnchorProvider); |
84 | 65 |
85 // CachedResult contains the result of a certificate verification. | |
86 struct NET_EXPORT_PRIVATE CachedResult { | |
87 CachedResult(); | |
88 ~CachedResult(); | |
89 | |
90 int error; // The return value of CertVerifier::Verify. | |
91 CertVerifyResult result; // The output of CertVerifier::Verify. | |
92 }; | |
93 | |
94 // Rather than having a single validity point along a monotonically increasing | |
95 // timeline, certificate verification is based on falling within a range of | |
96 // the certificate's NotBefore and NotAfter and based on what the current | |
97 // system clock says (which may advance forwards or backwards as users correct | |
98 // clock skew). CacheValidityPeriod and CacheExpirationFunctor are helpers to | |
99 // ensure that expiration is measured both by the 'general' case (now + cache | |
100 // TTL) and by whether or not significant enough clock skew was introduced | |
101 // since the last verification. | |
102 struct CacheValidityPeriod { | |
103 explicit CacheValidityPeriod(const base::Time& now); | |
104 CacheValidityPeriod(const base::Time& now, const base::Time& expiration); | |
105 | |
106 base::Time verification_time; | |
107 base::Time expiration_time; | |
108 }; | |
109 | |
110 struct CacheExpirationFunctor { | |
111 // Returns true iff |now| is within the validity period of |expiration|. | |
112 bool operator()(const CacheValidityPeriod& now, | |
113 const CacheValidityPeriod& expiration) const; | |
114 }; | |
115 | |
116 struct JobComparator { | 66 struct JobComparator { |
117 bool operator()(const CertVerifierJob* job1, | 67 bool operator()(const CertVerifierJob* job1, |
118 const CertVerifierJob* job2) const; | 68 const CertVerifierJob* job2) const; |
119 }; | 69 }; |
120 | 70 |
121 using JobSet = std::set<CertVerifierJob*, JobComparator>; | 71 using JobSet = std::set<CertVerifierJob*, JobComparator>; |
122 using CertVerifierCache = ExpiringCache<RequestParams, | |
123 CachedResult, | |
124 CacheValidityPeriod, | |
125 CacheExpirationFunctor>; | |
126 | |
127 // Saves |result| into the cache, keyed by |key|, which began validation at | |
128 // |start_time|. | |
129 void SaveResultToCache(const RequestParams& key, | |
130 const base::Time& start_time, | |
131 const CachedResult& result); | |
132 | |
133 // CertDatabase::Observer methods: | |
134 void OnCACertChanged(const X509Certificate* cert) override; | |
135 | 72 |
136 // Returns an inflight job for |key|. If there is no such job then returns | 73 // Returns an inflight job for |key|. If there is no such job then returns |
137 // null. | 74 // null. |
138 CertVerifierJob* FindJob(const RequestParams& key); | 75 CertVerifierJob* FindJob(const RequestParams& key); |
139 | 76 |
140 // Removes |job| from the inflight set, and passes ownership back to the | 77 // Removes |job| from the inflight set, and passes ownership back to the |
141 // caller. |job| must already be |inflight_|. | 78 // caller. |job| must already be |inflight_|. |
142 std::unique_ptr<CertVerifierJob> RemoveJob(CertVerifierJob* job); | 79 std::unique_ptr<CertVerifierJob> RemoveJob(CertVerifierJob* job); |
143 | 80 |
144 // For unit testing. | 81 // For unit testing. |
145 void ClearCache() { cache_.Clear(); } | |
146 size_t GetCacheSize() const { return cache_.size(); } | |
147 uint64_t cache_hits() const { return cache_hits_; } | |
148 uint64_t requests() const { return requests_; } | 82 uint64_t requests() const { return requests_; } |
149 uint64_t inflight_joins() const { return inflight_joins_; } | 83 uint64_t inflight_joins() const { return inflight_joins_; } |
150 | 84 |
151 // cache_ maps from a request to a cached result. | |
152 CertVerifierCache cache_; | |
153 | |
154 // inflight_ holds the jobs for which an active verification is taking place. | 85 // inflight_ holds the jobs for which an active verification is taking place. |
155 JobSet inflight_; | 86 JobSet inflight_; |
156 | 87 |
157 uint64_t requests_; | 88 uint64_t requests_; |
158 uint64_t cache_hits_; | |
159 uint64_t inflight_joins_; | 89 uint64_t inflight_joins_; |
160 | 90 |
161 scoped_refptr<CertVerifyProc> verify_proc_; | 91 scoped_refptr<CertVerifyProc> verify_proc_; |
162 | 92 |
163 CertTrustAnchorProvider* trust_anchor_provider_; | |
164 | |
165 DISALLOW_COPY_AND_ASSIGN(MultiThreadedCertVerifier); | 93 DISALLOW_COPY_AND_ASSIGN(MultiThreadedCertVerifier); |
166 }; | 94 }; |
167 | 95 |
168 } // namespace net | 96 } // namespace net |
169 | 97 |
170 #endif // NET_CERT_MULTI_THREADED_CERT_VERIFIER_H_ | 98 #endif // NET_CERT_MULTI_THREADED_CERT_VERIFIER_H_ |
OLD | NEW |