Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Side by Side Diff: net/base/cert_verifier.h

Issue 5386001: Cache certificate verification results in memory. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Add unit tests. Ready for review. Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2008-2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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_BASE_CERT_VERIFIER_H_ 5 #ifndef NET_BASE_CERT_VERIFIER_H_
6 #define NET_BASE_CERT_VERIFIER_H_ 6 #define NET_BASE_CERT_VERIFIER_H_
7 #pragma once 7 #pragma once
8 8
9 #include <map>
9 #include <string> 10 #include <string>
10 11
11 #include "base/basictypes.h" 12 #include "base/basictypes.h"
12 #include "base/ref_counted.h" 13 #include "base/non_thread_safe.h"
14 #include "base/scoped_ptr.h"
15 #include "base/time.h"
16 #include "net/base/cert_verify_result.h"
13 #include "net/base/completion_callback.h" 17 #include "net/base/completion_callback.h"
18 #include "net/base/x509_cert_types.h"
14 19
15 namespace net { 20 namespace net {
16 21
17 class CertVerifyResult; 22 class CertVerifierJob;
23 class CertVerifierWorker;
18 class X509Certificate; 24 class X509Certificate;
19 25
20 // This class represents the task of verifying a certificate. It can only 26 // CachedCertVerifyResult contains the result of a certificate verification.
21 // verify a single certificate at a time, so if you need to verify multiple 27 class CachedCertVerifyResult {
willchan no longer on Chromium 2010/12/13 09:30:53 I think this should be a struct. Otherwise, pleas
22 // certificates at the same time, you will need to allocate a CertVerifier 28 public:
23 // object for each certificate. 29 CachedCertVerifyResult();
30 ~CachedCertVerifyResult();
31
32 int error; // The return value of CertVerifier::Verify.
33 CertVerifyResult result; // The output of CertVerifier::Verify.
34
35 // The time at which the certificate verification result expires.
36 base::Time expiry;
37
38 // Returns true if |current_time| is greater than or equal to |expiry|.
39 bool HasExpired(base::Time current_time) const;
40 };
41
42 // CertVerifier represents a service for verifying certificates.
24 // 43 //
25 class CertVerifier { 44 // CertVerifier can handle multiple requests at a time, so when cancelling a
45 // request the RequestHandle that was returned by Verify() needs to be
46 // given. A simpler alternative for consumers that only have 1 outstanding
47 // request at a time is to create a SingleRequestCertVerifier wrapper around
48 // CertVerifier (which will automatically cancel the single request when it
49 // goes out of scope).
50 class CertVerifier : public NonThreadSafe {
willchan no longer on Chromium 2010/12/13 09:30:53 Have you thought about monitoring the NetworkChang
agl 2010/12/13 16:25:04 I can imagine that OCSP/CRL/AIA requests get guill
26 public: 51 public:
52 // Opaque type used to cancel a request.
53 typedef void* RequestHandle;
54
55 // CertVerifier must not call base::Time::Now() directly. It must call
56 // time_service_->Now(). This allows unit tests to mock the current time.
57 class TimeService {
58 public:
59 virtual ~TimeService() {}
60
61 virtual base::Time Now() = 0;
62 };
63
27 CertVerifier(); 64 CertVerifier();
28 65
29 // If a completion callback is pending when the verifier is destroyed, the 66 // Used by unit tests to mock the current time. Takes ownership of
30 // certificate verification is cancelled, and the completion callback will 67 // |time_service|.
31 // not be called. 68 explicit CertVerifier(TimeService* time_service);
69
70 // When the verifier is destroyed, all certificate verifications requests are
71 // cancelled, and their completion callbacks will not be called.
32 ~CertVerifier(); 72 ~CertVerifier();
33 73
34 // Verifies the given certificate against the given hostname. Returns OK if 74 // Verifies the given certificate against the given hostname. Returns OK if
35 // successful or an error code upon failure. 75 // successful or an error code upon failure.
36 // 76 //
37 // The |*verify_result| structure, including the |verify_result->cert_status| 77 // The |*verify_result| structure, including the |verify_result->cert_status|
38 // bitmask, is always filled out regardless of the return value. If the 78 // bitmask, is always filled out regardless of the return value. If the
39 // certificate has multiple errors, the corresponding status flags are set in 79 // certificate has multiple errors, the corresponding status flags are set in
40 // |verify_result->cert_status|, and the error code for the most serious 80 // |verify_result->cert_status|, and the error code for the most serious
41 // error is returned. 81 // error is returned.
42 // 82 //
43 // |flags| is bitwise OR'd of X509Certificate::VerifyFlags. 83 // |flags| is bitwise OR'd of X509Certificate::VerifyFlags.
44 // If VERIFY_REV_CHECKING_ENABLED is set in |flags|, certificate revocation 84 // If VERIFY_REV_CHECKING_ENABLED is set in |flags|, certificate revocation
45 // checking is performed. 85 // checking is performed.
46 // 86 //
47 // If VERIFY_EV_CERT is set in |flags| too, EV certificate verification is 87 // If VERIFY_EV_CERT is set in |flags| too, EV certificate verification is
48 // performed. If |flags| is VERIFY_EV_CERT (that is, 88 // performed. If |flags| is VERIFY_EV_CERT (that is,
49 // VERIFY_REV_CHECKING_ENABLED is not set), EV certificate verification will 89 // VERIFY_REV_CHECKING_ENABLED is not set), EV certificate verification will
50 // not be performed. 90 // not be performed.
51 // 91 //
52 // When callback is null, the operation completes synchronously. 92 // |callback| must not be null. ERR_IO_PENDING is returned if the operation
53 //
54 // When callback is non-null, ERR_IO_PENDING is returned if the operation
55 // could not be completed synchronously, in which case the result code will 93 // could not be completed synchronously, in which case the result code will
56 // be passed to the callback when available. 94 // be passed to the callback when available.
57 // 95 //
58 int Verify(X509Certificate* cert, const std::string& hostname, 96 // If |out_req| is non-NULL, then |*out_req| will be filled with a handle to
59 int flags, CertVerifyResult* verify_result, 97 // the async request. This handle is not valid after the request has
98 // completed.
99 int Verify(X509Certificate* cert,
willchan no longer on Chromium 2010/12/13 09:30:53 I don't know enough about this area, but it seems
100 const std::string& hostname,
101 int flags,
102 CertVerifyResult* verify_result,
103 CompletionCallback* callback,
104 RequestHandle* out_req);
willchan no longer on Chromium 2010/12/13 09:30:53 I think you should be passing in a BoundNetLog for
105
106 // Cancels the specified request. |req| is the handle returned by Verify().
107 // After a request is cancelled, its completion callback will not be called.
108 void CancelRequest(RequestHandle req);
109
110 // Clears the verification result cache.
111 void ClearCache();
112
113 int GetCacheSize() const;
114
115 uint64 requests() const { return requests_; }
116 uint64 cache_hits() const { return cache_hits_; }
117 uint64 inflight_joins() const { return inflight_joins_; }
118
119 private:
120 friend class CertVerifierWorker; // Calls HandleResult.
121
122 // Input parameters of a certificate verification request.
123 struct RequestParams {
124 bool operator==(const RequestParams& other) const {
125 // |flags| is compared before |cert_fingerprint| and |hostname| under
126 // assumption that integer comparisons are faster than memory and string
127 // comparisons.
128 return (flags == other.flags &&
129 memcmp(cert_fingerprint.data, other.cert_fingerprint.data,
130 sizeof(cert_fingerprint.data)) == 0 &&
willchan no longer on Chromium 2010/12/13 09:30:53 arraysize
131 hostname == other.hostname);
132 }
133
134 bool operator<(const RequestParams& other) const {
135 // |flags| is compared before |cert_fingerprint| and |hostname| under
136 // assumption that integer comparisons are faster than memory and string
137 // comparisons.
138 if (flags != other.flags)
139 return flags < other.flags;
140 int rv = memcmp(cert_fingerprint.data, other.cert_fingerprint.data,
141 sizeof(cert_fingerprint.data));
willchan no longer on Chromium 2010/12/13 09:30:53 arraysize
142 if (rv != 0)
143 return rv < 0;
144 return hostname < other.hostname;
145 }
146
147 SHA1Fingerprint cert_fingerprint;
148 std::string hostname;
149 int flags;
150 };
151
152 void HandleResult(X509Certificate* cert,
153 const std::string& hostname,
154 int flags,
155 int error,
156 const CertVerifyResult& verify_result);
157
158 // cache_ maps from a request to a cached result. The cached result may
159 // have expired and the size of |cache_| must be <= kMaxCacheEntries.
160 std::map<RequestParams, CachedCertVerifyResult> cache_;
161
162 // inflight_ maps from a request to an active verification which is taking
163 // place.
164 std::map<RequestParams, CertVerifierJob*> inflight_;
165
166 scoped_ptr<TimeService> time_service_;
167
168 uint64 requests_;
169 uint64 cache_hits_;
170 uint64 inflight_joins_;
171
172 DISALLOW_COPY_AND_ASSIGN(CertVerifier);
173 };
174
175 // This class represents the task of verifying a certificate. It wraps
176 // CertVerifier to verify only a single certificate at a time and cancels this
177 // request when going out of scope.
178 class SingleRequestCertVerifier {
179 public:
180 // |cert_verifier| must remain valid for the lifetime of |this|.
181 explicit SingleRequestCertVerifier(CertVerifier* cert_verifier);
182
183 // If a completion callback is pending when the verifier is destroyed, the
184 // certificate verification is cancelled, and the completion callback will
willchan no longer on Chromium 2010/12/13 09:30:53 Cancelled is the British spelling. American Engli
185 // not be called.
186 ~SingleRequestCertVerifier();
187
188 // Verifies the given certificate, filling out the |verify_result| object
189 // upon success. See CertVerifier::Verify() for details.
190 int Verify(X509Certificate* cert,
191 const std::string& hostname,
192 int flags,
193 CertVerifyResult* verify_result,
60 CompletionCallback* callback); 194 CompletionCallback* callback);
61 195
62 private: 196 private:
63 class Request; 197 // Callback for when the request to |cert_verifier_| completes, so we
64 friend class Request; 198 // dispatch to the user's callback.
65 scoped_refptr<Request> request_; 199 void OnVerifyCompletion(int result);
66 DISALLOW_COPY_AND_ASSIGN(CertVerifier); 200
201 // The actual certificate verifier that will handle the request.
202 CertVerifier* const cert_verifier_;
203
204 // The current request (if any).
205 CertVerifier::RequestHandle cur_request_;
206 CompletionCallback* cur_request_callback_;
207
208 // Completion callback for when request to |cert_verifier_| completes.
209 net::CompletionCallbackImpl<SingleRequestCertVerifier> callback_;
210
211 DISALLOW_COPY_AND_ASSIGN(SingleRequestCertVerifier);
67 }; 212 };
68 213
69 } // namespace net 214 } // namespace net
70 215
71 #endif // NET_BASE_CERT_VERIFIER_H_ 216 #endif // NET_BASE_CERT_VERIFIER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698