OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "net/http/disk_based_cert_cache.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/callback_helpers.h" | |
9 #include "net/base/completion_callback.h" | |
10 #include "net/base/net_errors.h" | |
11 #include "net/base/test_completion_callback.h" | |
12 #include "net/base/test_data_directory.h" | |
13 #include "net/disk_cache/memory/mem_backend_impl.h" | |
14 #include "net/http/mock_http_cache.h" | |
15 #include "net/test/cert_test_util.h" | |
16 #include "testing/gtest/include/gtest/gtest.h" | |
17 | |
18 namespace net { | |
19 | |
20 namespace { | |
21 | |
22 // MockTransactions are required to use the MockDiskCache backend. | |
23 | |
24 // This transaction corresponds to "root_ca_cert.pem" in | |
25 // GetTestCertsDirectory(). | |
26 const MockTransaction kCertTransaction1 = { | |
27 "cert:4C005EF1CF45F80D4A5A2BCFB00D4F198121E8D4", | |
Ryan Sleevi
2014/06/23 22:43:58
Since you end up repeating these cert: strings, yo
| |
28 "", | |
29 base::Time(), | |
30 "", | |
31 LOAD_NORMAL, | |
32 "", | |
33 "", | |
34 base::Time(), | |
35 "", | |
36 TEST_MODE_NORMAL, | |
37 NULL, | |
38 0, | |
39 OK | |
40 }; | |
41 | |
42 // This transaction corresponds to "ok_cert.pem" in GetTestCertsDirectory(). | |
43 const MockTransaction kCertTransaction2 = { | |
44 "cert:9174C7CB9E4919604E7B1BFC430E4929DA45F65F", | |
45 "", | |
46 base::Time(), | |
47 "", | |
48 LOAD_NORMAL, | |
49 "", | |
50 "", | |
51 base::Time(), | |
52 "", | |
53 TEST_MODE_NORMAL, | |
54 NULL, | |
55 0, | |
56 OK | |
57 }; | |
58 | |
59 // MockCertCache is used so that results from the DiskBasedCertCache can be | |
60 // received using TestCompletionCallback::GetResult. | |
61 class MockCertCache { | |
62 public: | |
63 MockCertCache() | |
64 : backend(new MockDiskCache()), | |
65 cert_cache_(new DiskBasedCertCache(backend.get())) {} | |
66 | |
67 int Set(X509Certificate::OSCertHandle cert_handle, | |
68 std::string* key, | |
69 const CompletionCallback& callback) { | |
Ryan Sleevi
2014/06/23 22:43:58
indentation is wrong for all of these methods
| |
70 cert_cache_->Set(cert_handle, | |
71 base::Bind(&MockCertCache::OnSetComplete, | |
72 base::Unretained(this), | |
73 key, | |
74 callback)); | |
75 return ERR_IO_PENDING; | |
76 } | |
77 | |
78 int Get(const std::string& key, | |
79 X509Certificate::OSCertHandle* cert_handle, | |
80 const CompletionCallback& callback) { | |
81 cert_cache_->Get(key, | |
82 base::Bind(&MockCertCache::OnGetComplete, | |
83 base::Unretained(this), | |
84 cert_handle, | |
85 callback)); | |
86 return ERR_IO_PENDING; | |
87 } | |
88 | |
89 void OnSetComplete(std::string* key_return, | |
90 CompletionCallback callback, | |
91 const std::string& key_retrieved) { | |
92 *key_return = key_retrieved; | |
93 callback.Run(OK); | |
94 } | |
95 | |
96 void OnGetComplete(X509Certificate::OSCertHandle* handle_return, | |
97 CompletionCallback callback, | |
98 const X509Certificate::OSCertHandle handle_retrieved) { | |
99 *handle_return = handle_retrieved; | |
100 callback.Run(OK); | |
101 } | |
102 | |
103 void DeleteCertCache() { cert_cache_.reset(); } | |
104 | |
105 private: | |
106 scoped_ptr<disk_cache::Backend> backend; | |
107 scoped_ptr<DiskBasedCertCache> cert_cache_; | |
108 }; | |
109 | |
110 } // namespace | |
111 | |
112 // ---------------------------------------------------------------------------- | |
113 | |
114 // Tests that a certificate can be stored in the cache. | |
115 TEST(DiskBasedCertCache, SetCert) { | |
116 AddMockTransaction(&kCertTransaction1); | |
117 MockCertCache user; | |
118 scoped_refptr<X509Certificate> cert( | |
119 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem")); | |
120 ASSERT_TRUE(cert.get()); | |
121 | |
122 TestCompletionCallback set_callback; | |
123 std::string key; | |
124 | |
125 int rv = | |
126 user.Set(cert.get()->os_cert_handle(), &key, set_callback.callback()); | |
127 rv = set_callback.GetResult(rv); | |
128 EXPECT_EQ(OK, rv); | |
129 EXPECT_FALSE(key.empty()); | |
130 } | |
131 | |
132 // Tests that attempting to retrieve a cert that is not in the cache will | |
133 // return NULL. | |
134 TEST(DiskBasedCertCache, GetUncachedCert) { | |
135 AddMockTransaction(&kCertTransaction1); | |
136 MockCertCache user; | |
137 TestCompletionCallback get_callback; | |
138 X509Certificate::OSCertHandle cert_handle = NULL; | |
139 | |
140 int rv = user.Get("cert:4C005EF1CF45F80D4A5A2BCFB00D4F198121E8D4", | |
141 &cert_handle, | |
142 get_callback.callback()); | |
143 rv = get_callback.GetResult(rv); | |
144 EXPECT_EQ(OK, rv); | |
145 EXPECT_EQ(NULL, cert_handle); | |
146 } | |
147 | |
148 // Issues two requests to store a certificate in the cache | |
149 // (simultaneously), and checks that the DiskBasedCertCache stores the | |
150 // certificate to the cache (in one write rather than two). | |
151 TEST(DiskBasedCertCache, SetMultiple) { | |
152 AddMockTransaction(&kCertTransaction1); | |
153 MockCertCache user; | |
154 | |
155 scoped_refptr<X509Certificate> cert( | |
156 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem")); | |
157 ASSERT_TRUE(cert.get()); | |
158 | |
159 TestCompletionCallback set_callback1; | |
160 TestCompletionCallback set_callback2; | |
161 | |
162 std::string key1, key2; | |
163 | |
164 int rv1 = | |
165 user.Set(cert.get()->os_cert_handle(), &key1, set_callback1.callback()); | |
166 int rv2 = | |
167 user.Set(cert.get()->os_cert_handle(), &key2, set_callback2.callback()); | |
168 | |
169 rv1 = set_callback1.GetResult(rv1); | |
170 EXPECT_EQ(OK, rv1); | |
171 rv2 = set_callback2.GetResult(rv2); | |
172 EXPECT_EQ(OK, rv2); | |
173 EXPECT_EQ(key1, key2); | |
174 } | |
175 | |
176 // Stores a certificate in the DiskBasedCertCache, then retrieves it | |
177 // and makes sure it was retrieved successfully. | |
178 TEST(DiskBasedCertCache, SimpleSetAndGet) { | |
179 AddMockTransaction(&kCertTransaction1); | |
180 MockCertCache user; | |
181 | |
182 scoped_refptr<X509Certificate> cert( | |
183 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem")); | |
184 ASSERT_TRUE(cert.get()); | |
185 | |
186 TestCompletionCallback set_callback; | |
187 TestCompletionCallback get_callback; | |
188 std::string key; | |
189 | |
190 X509Certificate::OSCertHandle retrieved_cert_handle = NULL; | |
191 int rv = | |
192 user.Set(cert.get()->os_cert_handle(), &key, set_callback.callback()); | |
193 rv = set_callback.GetResult(rv); | |
194 EXPECT_EQ(OK, rv); | |
195 rv = user.Get(key, &retrieved_cert_handle, get_callback.callback()); | |
196 rv = get_callback.GetResult(rv); | |
197 EXPECT_EQ(OK, rv); | |
198 EXPECT_TRUE(X509Certificate::IsSameOSCert(retrieved_cert_handle, | |
199 cert.get()->os_cert_handle())); | |
200 } | |
201 | |
202 // Tests some basic functionality of the DiskBasedCertCache, with multiple | |
203 // set and get operations. | |
204 TEST(DiskBasedCertCache, BasicUsage) { | |
205 AddMockTransaction(&kCertTransaction1); | |
206 AddMockTransaction(&kCertTransaction2); | |
207 MockCertCache user; | |
208 | |
209 scoped_refptr<X509Certificate> cert1( | |
210 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem")); | |
211 scoped_refptr<X509Certificate> cert2( | |
212 ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem")); | |
213 ASSERT_TRUE(cert1.get()); | |
214 ASSERT_TRUE(cert2.get()); | |
215 ASSERT_FALSE(X509Certificate::IsSameOSCert(cert1->os_cert_handle(), | |
216 cert2->os_cert_handle())); | |
217 TestCompletionCallback set_callback1, set_callback2; | |
218 std::string key1, key2; | |
219 | |
220 int rv1 = | |
221 user.Set(cert1.get()->os_cert_handle(), &key1, set_callback1.callback()); | |
222 int rv2 = | |
223 user.Set(cert2.get()->os_cert_handle(), &key2, set_callback2.callback()); | |
224 | |
225 rv1 = set_callback1.GetResult(rv1); | |
226 EXPECT_EQ(OK, rv1); | |
227 rv2 = set_callback2.GetResult(rv2); | |
228 EXPECT_EQ(OK, rv2); | |
229 | |
230 TestCompletionCallback get_callback1, get_callback2; | |
231 X509Certificate::OSCertHandle cert_handle1, cert_handle2; | |
232 | |
233 rv1 = user.Get(key1, &cert_handle1, get_callback1.callback()); | |
234 rv2 = user.Get(key2, &cert_handle2, get_callback2.callback()); | |
235 | |
236 rv1 = get_callback1.GetResult(rv1); | |
237 EXPECT_EQ(OK, rv1); | |
238 rv2 = get_callback2.GetResult(rv2); | |
239 EXPECT_EQ(OK, rv2); | |
240 | |
241 EXPECT_TRUE( | |
242 X509Certificate::IsSameOSCert(cert1->os_cert_handle(), cert_handle1)); | |
243 EXPECT_TRUE( | |
244 X509Certificate::IsSameOSCert(cert2->os_cert_handle(), cert_handle2)); | |
245 } | |
246 | |
247 // Test the result of simultaneous requests to store and retrieve a | |
248 // certificate from the cache. Since it is unknown whether the set or get | |
249 // operation will complete first, this test is just to make sure that it | |
250 // does not crash. | |
Ryan Sleevi
2014/06/23 22:43:58
We should make this test deterministic, and handle
| |
251 TEST(DiskBasedCertCache, SimultaneousSetGet) { | |
252 AddMockTransaction(&kCertTransaction1); | |
253 MockCertCache user; | |
254 TestCompletionCallback set_callback, get_callback; | |
255 X509Certificate::OSCertHandle cert_handle; | |
256 std::string key("cert:4C005EF1CF45F80D4A5A2BCFB00D4F198121E8D4"); | |
257 | |
258 scoped_refptr<X509Certificate> cert( | |
259 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem")); | |
260 ASSERT_TRUE(cert.get()); | |
261 | |
262 int rv1 = | |
263 user.Set(cert.get()->os_cert_handle(), &key, set_callback.callback()); | |
264 int rv2 = user.Get(key, &cert_handle, get_callback.callback()); | |
265 rv1 = get_callback.GetResult(rv1); | |
266 EXPECT_EQ(OK, rv1); | |
267 rv2 = set_callback.GetResult(rv2); | |
268 EXPECT_EQ(OK, rv2); | |
269 } | |
270 | |
271 | |
272 // Tests that the DiskBasedCertCache can be deleted without issues when | |
273 // there are pending operations in the disk cache. | |
274 TEST(DiskBasedCertCache, DeletedCertCache) { | |
275 AddMockTransaction(&kCertTransaction1); | |
276 MockCertCache user; | |
277 std::string key; | |
278 scoped_refptr<X509Certificate> cert( | |
279 ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem")); | |
280 ASSERT_TRUE(cert.get()); | |
281 | |
282 TestCompletionCallback set_callback; | |
283 int rv = | |
284 user.Set(cert.get()->os_cert_handle(), &key, set_callback.callback()); | |
285 | |
286 user.DeleteCertCache(); | |
287 rv = set_callback.GetResult(rv); | |
288 EXPECT_EQ(OK, rv); | |
289 EXPECT_EQ(std::string(), key); | |
290 } | |
291 | |
292 } // namespace net | |
OLD | NEW |