Add simple cache backend experiment hidden behind a command line option.
[chromium-blink-merge.git] / net / ssl / default_server_bound_cert_store_unittest.cc
blobd52d28650e3165c6a7bd9a0cb890dda308c93fd3
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
3 // found in the LICENSE file.
5 #include "net/ssl/default_server_bound_cert_store.h"
7 #include <map>
8 #include <string>
9 #include <vector>
11 #include "base/bind.h"
12 #include "base/compiler_specific.h"
13 #include "base/logging.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/message_loop.h"
16 #include "testing/gtest/include/gtest/gtest.h"
18 namespace net {
20 namespace {
22 void CallCounter(int* counter) {
23 (*counter)++;
26 void NotCalled() {
27 ADD_FAILURE() << "Unexpected callback execution.";
30 void GetCertCallbackNotCalled(const std::string& server_identifier,
31 SSLClientCertType type,
32 base::Time expiration_time,
33 const std::string& private_key_result,
34 const std::string& cert_result) {
35 ADD_FAILURE() << "Unexpected callback execution.";
38 class AsyncGetCertHelper {
39 public:
40 AsyncGetCertHelper() : called_(false) {}
42 void Callback(const std::string& server_identifier,
43 SSLClientCertType type,
44 base::Time expiration_time,
45 const std::string& private_key_result,
46 const std::string& cert_result) {
47 server_identifier_ = server_identifier;
48 type_ = type;
49 expiration_time_ = expiration_time;
50 private_key_ = private_key_result;
51 cert_ = cert_result;
52 called_ = true;
55 std::string server_identifier_;
56 SSLClientCertType type_;
57 base::Time expiration_time_;
58 std::string private_key_;
59 std::string cert_;
60 bool called_;
63 void GetAllCallback(
64 ServerBoundCertStore::ServerBoundCertList* dest,
65 const ServerBoundCertStore::ServerBoundCertList& result) {
66 *dest = result;
69 class MockPersistentStore
70 : public DefaultServerBoundCertStore::PersistentStore {
71 public:
72 MockPersistentStore();
74 // DefaultServerBoundCertStore::PersistentStore implementation.
75 virtual void Load(const LoadedCallback& loaded_callback) OVERRIDE;
76 virtual void AddServerBoundCert(
77 const DefaultServerBoundCertStore::ServerBoundCert& cert) OVERRIDE;
78 virtual void DeleteServerBoundCert(
79 const DefaultServerBoundCertStore::ServerBoundCert& cert) OVERRIDE;
80 virtual void SetForceKeepSessionState() OVERRIDE;
82 protected:
83 virtual ~MockPersistentStore();
85 private:
86 typedef std::map<std::string, DefaultServerBoundCertStore::ServerBoundCert>
87 ServerBoundCertMap;
89 ServerBoundCertMap origin_certs_;
92 MockPersistentStore::MockPersistentStore() {}
94 void MockPersistentStore::Load(const LoadedCallback& loaded_callback) {
95 scoped_ptr<ScopedVector<DefaultServerBoundCertStore::ServerBoundCert> >
96 certs(new ScopedVector<DefaultServerBoundCertStore::ServerBoundCert>());
97 ServerBoundCertMap::iterator it;
99 for (it = origin_certs_.begin(); it != origin_certs_.end(); ++it) {
100 certs->push_back(
101 new DefaultServerBoundCertStore::ServerBoundCert(it->second));
104 MessageLoop::current()->PostTask(
105 FROM_HERE, base::Bind(loaded_callback, base::Passed(&certs)));
108 void MockPersistentStore::AddServerBoundCert(
109 const DefaultServerBoundCertStore::ServerBoundCert& cert) {
110 origin_certs_[cert.server_identifier()] = cert;
113 void MockPersistentStore::DeleteServerBoundCert(
114 const DefaultServerBoundCertStore::ServerBoundCert& cert) {
115 origin_certs_.erase(cert.server_identifier());
118 void MockPersistentStore::SetForceKeepSessionState() {}
120 MockPersistentStore::~MockPersistentStore() {}
122 } // namespace
124 TEST(DefaultServerBoundCertStoreTest, TestLoading) {
125 scoped_refptr<MockPersistentStore> persistent_store(new MockPersistentStore);
127 persistent_store->AddServerBoundCert(
128 DefaultServerBoundCertStore::ServerBoundCert(
129 "google.com",
130 CLIENT_CERT_RSA_SIGN,
131 base::Time(),
132 base::Time(),
133 "a", "b"));
134 persistent_store->AddServerBoundCert(
135 DefaultServerBoundCertStore::ServerBoundCert(
136 "verisign.com",
137 CLIENT_CERT_ECDSA_SIGN,
138 base::Time(),
139 base::Time(),
140 "c", "d"));
142 // Make sure certs load properly.
143 DefaultServerBoundCertStore store(persistent_store.get());
144 // Load has not occurred yet.
145 EXPECT_EQ(0, store.GetCertCount());
146 store.SetServerBoundCert(
147 "verisign.com",
148 CLIENT_CERT_RSA_SIGN,
149 base::Time(),
150 base::Time(),
151 "e", "f");
152 // Wait for load & queued set task.
153 MessageLoop::current()->RunUntilIdle();
154 EXPECT_EQ(2, store.GetCertCount());
155 store.SetServerBoundCert(
156 "twitter.com",
157 CLIENT_CERT_RSA_SIGN,
158 base::Time(),
159 base::Time(),
160 "g", "h");
161 // Set should be synchronous now that load is done.
162 EXPECT_EQ(3, store.GetCertCount());
165 //TODO(mattm): add more tests of without a persistent store?
166 TEST(DefaultServerBoundCertStoreTest, TestSettingAndGetting) {
167 // No persistent store, all calls will be synchronous.
168 DefaultServerBoundCertStore store(NULL);
169 SSLClientCertType type;
170 base::Time expiration_time;
171 std::string private_key, cert;
172 EXPECT_EQ(0, store.GetCertCount());
173 EXPECT_TRUE(store.GetServerBoundCert("verisign.com",
174 &type,
175 &expiration_time,
176 &private_key,
177 &cert,
178 base::Bind(&GetCertCallbackNotCalled)));
179 EXPECT_EQ(CLIENT_CERT_INVALID_TYPE, type);
180 EXPECT_TRUE(private_key.empty());
181 EXPECT_TRUE(cert.empty());
182 store.SetServerBoundCert(
183 "verisign.com",
184 CLIENT_CERT_RSA_SIGN,
185 base::Time::FromInternalValue(123),
186 base::Time::FromInternalValue(456),
187 "i", "j");
188 EXPECT_TRUE(store.GetServerBoundCert("verisign.com",
189 &type,
190 &expiration_time,
191 &private_key,
192 &cert,
193 base::Bind(&GetCertCallbackNotCalled)));
194 EXPECT_EQ(CLIENT_CERT_RSA_SIGN, type);
195 EXPECT_EQ(456, expiration_time.ToInternalValue());
196 EXPECT_EQ("i", private_key);
197 EXPECT_EQ("j", cert);
200 TEST(DefaultServerBoundCertStoreTest, TestDuplicateCerts) {
201 scoped_refptr<MockPersistentStore> persistent_store(new MockPersistentStore);
202 DefaultServerBoundCertStore store(persistent_store.get());
204 SSLClientCertType type;
205 base::Time expiration_time;
206 std::string private_key, cert;
207 EXPECT_EQ(0, store.GetCertCount());
208 store.SetServerBoundCert(
209 "verisign.com",
210 CLIENT_CERT_RSA_SIGN,
211 base::Time::FromInternalValue(123),
212 base::Time::FromInternalValue(1234),
213 "a", "b");
214 store.SetServerBoundCert(
215 "verisign.com",
216 CLIENT_CERT_ECDSA_SIGN,
217 base::Time::FromInternalValue(456),
218 base::Time::FromInternalValue(4567),
219 "c", "d");
221 // Wait for load & queued set tasks.
222 MessageLoop::current()->RunUntilIdle();
223 EXPECT_EQ(1, store.GetCertCount());
224 EXPECT_TRUE(store.GetServerBoundCert("verisign.com",
225 &type,
226 &expiration_time,
227 &private_key,
228 &cert,
229 base::Bind(&GetCertCallbackNotCalled)));
230 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type);
231 EXPECT_EQ(4567, expiration_time.ToInternalValue());
232 EXPECT_EQ("c", private_key);
233 EXPECT_EQ("d", cert);
236 TEST(DefaultServerBoundCertStoreTest, TestAsyncGet) {
237 scoped_refptr<MockPersistentStore> persistent_store(new MockPersistentStore);
238 persistent_store->AddServerBoundCert(ServerBoundCertStore::ServerBoundCert(
239 "verisign.com",
240 CLIENT_CERT_RSA_SIGN,
241 base::Time::FromInternalValue(123),
242 base::Time::FromInternalValue(1234),
243 "a", "b"));
245 DefaultServerBoundCertStore store(persistent_store.get());
246 AsyncGetCertHelper helper;
247 SSLClientCertType type;
248 base::Time expiration_time;
249 std::string private_key;
250 std::string cert = "not set";
251 EXPECT_EQ(0, store.GetCertCount());
252 EXPECT_FALSE(store.GetServerBoundCert(
253 "verisign.com", &type, &expiration_time, &private_key, &cert,
254 base::Bind(&AsyncGetCertHelper::Callback, base::Unretained(&helper))));
256 // Wait for load & queued get tasks.
257 MessageLoop::current()->RunUntilIdle();
258 EXPECT_EQ(1, store.GetCertCount());
259 EXPECT_EQ("not set", cert);
260 EXPECT_TRUE(helper.called_);
261 EXPECT_EQ("verisign.com", helper.server_identifier_);
262 EXPECT_EQ(CLIENT_CERT_RSA_SIGN, helper.type_);
263 EXPECT_EQ(1234, helper.expiration_time_.ToInternalValue());
264 EXPECT_EQ("a", helper.private_key_);
265 EXPECT_EQ("b", helper.cert_);
268 TEST(DefaultServerBoundCertStoreTest, TestDeleteAll) {
269 scoped_refptr<MockPersistentStore> persistent_store(new MockPersistentStore);
270 DefaultServerBoundCertStore store(persistent_store.get());
272 store.SetServerBoundCert(
273 "verisign.com",
274 CLIENT_CERT_RSA_SIGN,
275 base::Time(),
276 base::Time(),
277 "a", "b");
278 store.SetServerBoundCert(
279 "google.com",
280 CLIENT_CERT_RSA_SIGN,
281 base::Time(),
282 base::Time(),
283 "c", "d");
284 store.SetServerBoundCert(
285 "harvard.com",
286 CLIENT_CERT_RSA_SIGN,
287 base::Time(),
288 base::Time(),
289 "e", "f");
290 // Wait for load & queued set tasks.
291 MessageLoop::current()->RunUntilIdle();
293 EXPECT_EQ(3, store.GetCertCount());
294 int delete_finished = 0;
295 store.DeleteAll(base::Bind(&CallCounter, &delete_finished));
296 ASSERT_EQ(1, delete_finished);
297 EXPECT_EQ(0, store.GetCertCount());
300 TEST(DefaultServerBoundCertStoreTest, TestAsyncGetAndDeleteAll) {
301 scoped_refptr<MockPersistentStore> persistent_store(new MockPersistentStore);
302 persistent_store->AddServerBoundCert(ServerBoundCertStore::ServerBoundCert(
303 "verisign.com",
304 CLIENT_CERT_RSA_SIGN,
305 base::Time(),
306 base::Time(),
307 "a", "b"));
308 persistent_store->AddServerBoundCert(ServerBoundCertStore::ServerBoundCert(
309 "google.com",
310 CLIENT_CERT_RSA_SIGN,
311 base::Time(),
312 base::Time(),
313 "c", "d"));
315 ServerBoundCertStore::ServerBoundCertList pre_certs;
316 ServerBoundCertStore::ServerBoundCertList post_certs;
317 int delete_finished = 0;
318 DefaultServerBoundCertStore store(persistent_store.get());
320 store.GetAllServerBoundCerts(base::Bind(GetAllCallback, &pre_certs));
321 store.DeleteAll(base::Bind(&CallCounter, &delete_finished));
322 store.GetAllServerBoundCerts(base::Bind(GetAllCallback, &post_certs));
323 // Tasks have not run yet.
324 EXPECT_EQ(0u, pre_certs.size());
325 // Wait for load & queued tasks.
326 MessageLoop::current()->RunUntilIdle();
327 EXPECT_EQ(0, store.GetCertCount());
328 EXPECT_EQ(2u, pre_certs.size());
329 EXPECT_EQ(0u, post_certs.size());
332 TEST(DefaultServerBoundCertStoreTest, TestDelete) {
333 scoped_refptr<MockPersistentStore> persistent_store(new MockPersistentStore);
334 DefaultServerBoundCertStore store(persistent_store.get());
336 SSLClientCertType type;
337 base::Time expiration_time;
338 std::string private_key, cert;
339 EXPECT_EQ(0, store.GetCertCount());
340 store.SetServerBoundCert(
341 "verisign.com",
342 CLIENT_CERT_RSA_SIGN,
343 base::Time(),
344 base::Time(),
345 "a", "b");
346 // Wait for load & queued set task.
347 MessageLoop::current()->RunUntilIdle();
349 store.SetServerBoundCert(
350 "google.com",
351 CLIENT_CERT_ECDSA_SIGN,
352 base::Time(),
353 base::Time(),
354 "c", "d");
356 EXPECT_EQ(2, store.GetCertCount());
357 int delete_finished = 0;
358 store.DeleteServerBoundCert("verisign.com",
359 base::Bind(&CallCounter, &delete_finished));
360 ASSERT_EQ(1, delete_finished);
361 EXPECT_EQ(1, store.GetCertCount());
362 EXPECT_TRUE(store.GetServerBoundCert("verisign.com",
363 &type,
364 &expiration_time,
365 &private_key,
366 &cert,
367 base::Bind(&GetCertCallbackNotCalled)));
368 EXPECT_EQ(CLIENT_CERT_INVALID_TYPE, type);
369 EXPECT_TRUE(store.GetServerBoundCert("google.com",
370 &type,
371 &expiration_time,
372 &private_key,
373 &cert,
374 base::Bind(&GetCertCallbackNotCalled)));
375 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type);
376 int delete2_finished = 0;
377 store.DeleteServerBoundCert("google.com",
378 base::Bind(&CallCounter, &delete2_finished));
379 ASSERT_EQ(1, delete2_finished);
380 EXPECT_EQ(0, store.GetCertCount());
381 EXPECT_TRUE(store.GetServerBoundCert("google.com",
382 &type,
383 &expiration_time,
384 &private_key,
385 &cert,
386 base::Bind(&GetCertCallbackNotCalled)));
387 EXPECT_EQ(CLIENT_CERT_INVALID_TYPE, type);
390 TEST(DefaultServerBoundCertStoreTest, TestAsyncDelete) {
391 scoped_refptr<MockPersistentStore> persistent_store(new MockPersistentStore);
392 persistent_store->AddServerBoundCert(ServerBoundCertStore::ServerBoundCert(
393 "a.com",
394 CLIENT_CERT_RSA_SIGN,
395 base::Time::FromInternalValue(1),
396 base::Time::FromInternalValue(2),
397 "a", "b"));
398 persistent_store->AddServerBoundCert(ServerBoundCertStore::ServerBoundCert(
399 "b.com",
400 CLIENT_CERT_RSA_SIGN,
401 base::Time::FromInternalValue(3),
402 base::Time::FromInternalValue(4),
403 "c", "d"));
404 DefaultServerBoundCertStore store(persistent_store.get());
405 int delete_finished = 0;
406 store.DeleteServerBoundCert("a.com",
407 base::Bind(&CallCounter, &delete_finished));
409 AsyncGetCertHelper a_helper;
410 AsyncGetCertHelper b_helper;
411 SSLClientCertType type;
412 base::Time expiration_time;
413 std::string private_key;
414 std::string cert = "not set";
415 EXPECT_EQ(0, store.GetCertCount());
416 EXPECT_FALSE(store.GetServerBoundCert(
417 "a.com", &type, &expiration_time, &private_key, &cert,
418 base::Bind(&AsyncGetCertHelper::Callback, base::Unretained(&a_helper))));
419 EXPECT_FALSE(store.GetServerBoundCert(
420 "b.com", &type, &expiration_time, &private_key, &cert,
421 base::Bind(&AsyncGetCertHelper::Callback, base::Unretained(&b_helper))));
423 EXPECT_EQ(0, delete_finished);
424 EXPECT_FALSE(a_helper.called_);
425 EXPECT_FALSE(b_helper.called_);
426 // Wait for load & queued tasks.
427 MessageLoop::current()->RunUntilIdle();
428 EXPECT_EQ(1, delete_finished);
429 EXPECT_EQ(1, store.GetCertCount());
430 EXPECT_EQ("not set", cert);
431 EXPECT_TRUE(a_helper.called_);
432 EXPECT_EQ("a.com", a_helper.server_identifier_);
433 EXPECT_EQ(CLIENT_CERT_INVALID_TYPE, a_helper.type_);
434 EXPECT_EQ(0, a_helper.expiration_time_.ToInternalValue());
435 EXPECT_EQ("", a_helper.private_key_);
436 EXPECT_EQ("", a_helper.cert_);
437 EXPECT_TRUE(b_helper.called_);
438 EXPECT_EQ("b.com", b_helper.server_identifier_);
439 EXPECT_EQ(CLIENT_CERT_RSA_SIGN, b_helper.type_);
440 EXPECT_EQ(4, b_helper.expiration_time_.ToInternalValue());
441 EXPECT_EQ("c", b_helper.private_key_);
442 EXPECT_EQ("d", b_helper.cert_);
445 TEST(DefaultServerBoundCertStoreTest, TestGetAll) {
446 scoped_refptr<MockPersistentStore> persistent_store(new MockPersistentStore);
447 DefaultServerBoundCertStore store(persistent_store.get());
449 EXPECT_EQ(0, store.GetCertCount());
450 store.SetServerBoundCert(
451 "verisign.com",
452 CLIENT_CERT_RSA_SIGN,
453 base::Time(),
454 base::Time(),
455 "a", "b");
456 store.SetServerBoundCert(
457 "google.com",
458 CLIENT_CERT_ECDSA_SIGN,
459 base::Time(),
460 base::Time(),
461 "c", "d");
462 store.SetServerBoundCert(
463 "harvard.com",
464 CLIENT_CERT_RSA_SIGN,
465 base::Time(),
466 base::Time(),
467 "e", "f");
468 store.SetServerBoundCert(
469 "mit.com",
470 CLIENT_CERT_RSA_SIGN,
471 base::Time(),
472 base::Time(),
473 "g", "h");
474 // Wait for load & queued set tasks.
475 MessageLoop::current()->RunUntilIdle();
477 EXPECT_EQ(4, store.GetCertCount());
478 ServerBoundCertStore::ServerBoundCertList certs;
479 store.GetAllServerBoundCerts(base::Bind(GetAllCallback, &certs));
480 EXPECT_EQ(4u, certs.size());
483 TEST(DefaultServerBoundCertStoreTest, TestInitializeFrom) {
484 scoped_refptr<MockPersistentStore> persistent_store(new MockPersistentStore);
485 DefaultServerBoundCertStore store(persistent_store.get());
487 store.SetServerBoundCert(
488 "preexisting.com",
489 CLIENT_CERT_RSA_SIGN,
490 base::Time(),
491 base::Time(),
492 "a", "b");
493 store.SetServerBoundCert(
494 "both.com",
495 CLIENT_CERT_ECDSA_SIGN,
496 base::Time(),
497 base::Time(),
498 "c", "d");
499 // Wait for load & queued set tasks.
500 MessageLoop::current()->RunUntilIdle();
501 EXPECT_EQ(2, store.GetCertCount());
503 ServerBoundCertStore::ServerBoundCertList source_certs;
504 source_certs.push_back(ServerBoundCertStore::ServerBoundCert(
505 "both.com",
506 CLIENT_CERT_RSA_SIGN,
507 base::Time(),
508 base::Time(),
509 // Key differs from above to test that existing entries are overwritten.
510 "e", "f"));
511 source_certs.push_back(ServerBoundCertStore::ServerBoundCert(
512 "copied.com",
513 CLIENT_CERT_RSA_SIGN,
514 base::Time(),
515 base::Time(),
516 "g", "h"));
517 store.InitializeFrom(source_certs);
518 EXPECT_EQ(3, store.GetCertCount());
520 ServerBoundCertStore::ServerBoundCertList certs;
521 store.GetAllServerBoundCerts(base::Bind(GetAllCallback, &certs));
522 ASSERT_EQ(3u, certs.size());
524 ServerBoundCertStore::ServerBoundCertList::iterator cert = certs.begin();
525 EXPECT_EQ("both.com", cert->server_identifier());
526 EXPECT_EQ("e", cert->private_key());
528 ++cert;
529 EXPECT_EQ("copied.com", cert->server_identifier());
530 EXPECT_EQ("g", cert->private_key());
532 ++cert;
533 EXPECT_EQ("preexisting.com", cert->server_identifier());
534 EXPECT_EQ("a", cert->private_key());
537 TEST(DefaultServerBoundCertStoreTest, TestAsyncInitializeFrom) {
538 scoped_refptr<MockPersistentStore> persistent_store(new MockPersistentStore);
539 persistent_store->AddServerBoundCert(ServerBoundCertStore::ServerBoundCert(
540 "preexisting.com",
541 CLIENT_CERT_RSA_SIGN,
542 base::Time(),
543 base::Time(),
544 "a", "b"));
545 persistent_store->AddServerBoundCert(ServerBoundCertStore::ServerBoundCert(
546 "both.com",
547 CLIENT_CERT_RSA_SIGN,
548 base::Time(),
549 base::Time(),
550 "c", "d"));
552 DefaultServerBoundCertStore store(persistent_store.get());
553 ServerBoundCertStore::ServerBoundCertList source_certs;
554 source_certs.push_back(ServerBoundCertStore::ServerBoundCert(
555 "both.com",
556 CLIENT_CERT_RSA_SIGN,
557 base::Time(),
558 base::Time(),
559 // Key differs from above to test that existing entries are overwritten.
560 "e", "f"));
561 source_certs.push_back(ServerBoundCertStore::ServerBoundCert(
562 "copied.com",
563 CLIENT_CERT_RSA_SIGN,
564 base::Time(),
565 base::Time(),
566 "g", "h"));
567 store.InitializeFrom(source_certs);
568 EXPECT_EQ(0, store.GetCertCount());
569 // Wait for load & queued tasks.
570 MessageLoop::current()->RunUntilIdle();
571 EXPECT_EQ(3, store.GetCertCount());
573 ServerBoundCertStore::ServerBoundCertList certs;
574 store.GetAllServerBoundCerts(base::Bind(GetAllCallback, &certs));
575 ASSERT_EQ(3u, certs.size());
577 ServerBoundCertStore::ServerBoundCertList::iterator cert = certs.begin();
578 EXPECT_EQ("both.com", cert->server_identifier());
579 EXPECT_EQ("e", cert->private_key());
581 ++cert;
582 EXPECT_EQ("copied.com", cert->server_identifier());
583 EXPECT_EQ("g", cert->private_key());
585 ++cert;
586 EXPECT_EQ("preexisting.com", cert->server_identifier());
587 EXPECT_EQ("a", cert->private_key());
590 } // namespace net