Add explicit |forceOnlineSignin| to user pod status
[chromium-blink-merge.git] / net / ssl / server_bound_cert_service_unittest.cc
blob4df003913aa0b74d96558ca05d8a6d5de9e069b6
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/server_bound_cert_service.h"
7 #include <string>
8 #include <vector>
10 #include "base/bind.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/message_loop/message_loop_proxy.h"
14 #include "base/task_runner.h"
15 #include "crypto/ec_private_key.h"
16 #include "net/base/net_errors.h"
17 #include "net/base/test_completion_callback.h"
18 #include "net/cert/asn1_util.h"
19 #include "net/cert/x509_certificate.h"
20 #include "net/ssl/default_server_bound_cert_store.h"
21 #include "testing/gtest/include/gtest/gtest.h"
23 namespace net {
25 namespace {
27 #if !defined(USE_OPENSSL)
28 void FailTest(int /* result */) {
29 FAIL();
32 // Simple task runner that refuses to actually post any tasks. This simulates
33 // a TaskRunner that has been shutdown, by returning false for any attempt to
34 // add new tasks.
35 class FailingTaskRunner : public base::TaskRunner {
36 public:
37 FailingTaskRunner() {}
39 virtual bool PostDelayedTask(const tracked_objects::Location& from_here,
40 const base::Closure& task,
41 base::TimeDelta delay) OVERRIDE {
42 return false;
45 virtual bool RunsTasksOnCurrentThread() const OVERRIDE { return true; }
47 protected:
48 virtual ~FailingTaskRunner() {}
50 private:
51 DISALLOW_COPY_AND_ASSIGN(FailingTaskRunner);
54 class MockServerBoundCertStoreWithAsyncGet
55 : public DefaultServerBoundCertStore {
56 public:
57 MockServerBoundCertStoreWithAsyncGet()
58 : DefaultServerBoundCertStore(NULL), cert_count_(0) {}
60 virtual int GetServerBoundCert(const std::string& server_identifier,
61 base::Time* expiration_time,
62 std::string* private_key_result,
63 std::string* cert_result,
64 const GetCertCallback& callback) OVERRIDE;
66 virtual void SetServerBoundCert(const std::string& server_identifier,
67 base::Time creation_time,
68 base::Time expiration_time,
69 const std::string& private_key,
70 const std::string& cert) OVERRIDE {
71 cert_count_ = 1;
74 virtual int GetCertCount() OVERRIDE { return cert_count_; }
76 void CallGetServerBoundCertCallbackWithResult(int err,
77 base::Time expiration_time,
78 const std::string& private_key,
79 const std::string& cert);
81 private:
82 GetCertCallback callback_;
83 std::string server_identifier_;
84 int cert_count_;
87 int MockServerBoundCertStoreWithAsyncGet::GetServerBoundCert(
88 const std::string& server_identifier,
89 base::Time* expiration_time,
90 std::string* private_key_result,
91 std::string* cert_result,
92 const GetCertCallback& callback) {
93 server_identifier_ = server_identifier;
94 callback_ = callback;
95 // Reset the cert count, it'll get incremented in either SetServerBoundCert or
96 // CallGetServerBoundCertCallbackWithResult.
97 cert_count_ = 0;
98 // Do nothing else: the results to be provided will be specified through
99 // CallGetServerBoundCertCallbackWithResult.
100 return ERR_IO_PENDING;
103 void
104 MockServerBoundCertStoreWithAsyncGet::CallGetServerBoundCertCallbackWithResult(
105 int err,
106 base::Time expiration_time,
107 const std::string& private_key,
108 const std::string& cert) {
109 if (err == OK)
110 cert_count_ = 1;
111 base::MessageLoop::current()->PostTask(FROM_HERE,
112 base::Bind(callback_,
113 err,
114 server_identifier_,
115 expiration_time,
116 private_key,
117 cert));
120 #endif // !defined(USE_OPENSSL)
122 class ServerBoundCertServiceTest : public testing::Test {
123 public:
124 ServerBoundCertServiceTest()
125 : service_(new ServerBoundCertService(
126 new DefaultServerBoundCertStore(NULL),
127 base::MessageLoopProxy::current())) {
130 protected:
131 scoped_ptr<ServerBoundCertService> service_;
134 TEST_F(ServerBoundCertServiceTest, GetDomainForHost) {
135 EXPECT_EQ("google.com",
136 ServerBoundCertService::GetDomainForHost("google.com"));
137 EXPECT_EQ("google.com",
138 ServerBoundCertService::GetDomainForHost("www.google.com"));
139 EXPECT_EQ("foo.appspot.com",
140 ServerBoundCertService::GetDomainForHost("foo.appspot.com"));
141 EXPECT_EQ("bar.appspot.com",
142 ServerBoundCertService::GetDomainForHost("foo.bar.appspot.com"));
143 EXPECT_EQ("appspot.com",
144 ServerBoundCertService::GetDomainForHost("appspot.com"));
145 EXPECT_EQ("google.com",
146 ServerBoundCertService::GetDomainForHost("www.mail.google.com"));
147 EXPECT_EQ("goto",
148 ServerBoundCertService::GetDomainForHost("goto"));
149 EXPECT_EQ("127.0.0.1",
150 ServerBoundCertService::GetDomainForHost("127.0.0.1"));
153 // See http://crbug.com/91512 - implement OpenSSL version of CreateSelfSigned.
154 #if !defined(USE_OPENSSL)
156 TEST_F(ServerBoundCertServiceTest, GetCacheMiss) {
157 std::string host("encrypted.google.com");
159 int error;
160 TestCompletionCallback callback;
161 ServerBoundCertService::RequestHandle request_handle;
163 // Synchronous completion, because the store is initialized.
164 std::string private_key, der_cert;
165 EXPECT_EQ(0, service_->cert_count());
166 error = service_->GetDomainBoundCert(
167 host, &private_key, &der_cert, callback.callback(), &request_handle);
168 EXPECT_EQ(ERR_FILE_NOT_FOUND, error);
169 EXPECT_FALSE(request_handle.is_active());
170 EXPECT_EQ(0, service_->cert_count());
171 EXPECT_TRUE(der_cert.empty());
174 TEST_F(ServerBoundCertServiceTest, CacheHit) {
175 std::string host("encrypted.google.com");
177 int error;
178 TestCompletionCallback callback;
179 ServerBoundCertService::RequestHandle request_handle;
181 // Asynchronous completion.
182 std::string private_key_info1, der_cert1;
183 EXPECT_EQ(0, service_->cert_count());
184 error = service_->GetOrCreateDomainBoundCert(
185 host, &private_key_info1, &der_cert1,
186 callback.callback(), &request_handle);
187 EXPECT_EQ(ERR_IO_PENDING, error);
188 EXPECT_TRUE(request_handle.is_active());
189 error = callback.WaitForResult();
190 EXPECT_EQ(OK, error);
191 EXPECT_EQ(1, service_->cert_count());
192 EXPECT_FALSE(private_key_info1.empty());
193 EXPECT_FALSE(der_cert1.empty());
194 EXPECT_FALSE(request_handle.is_active());
196 // Synchronous completion.
197 std::string private_key_info2, der_cert2;
198 error = service_->GetOrCreateDomainBoundCert(
199 host, &private_key_info2, &der_cert2,
200 callback.callback(), &request_handle);
201 EXPECT_FALSE(request_handle.is_active());
202 EXPECT_EQ(OK, error);
203 EXPECT_EQ(1, service_->cert_count());
204 EXPECT_EQ(private_key_info1, private_key_info2);
205 EXPECT_EQ(der_cert1, der_cert2);
207 // Synchronous get.
208 std::string private_key_info3, der_cert3;
209 error = service_->GetDomainBoundCert(
210 host, &private_key_info3, &der_cert3, callback.callback(),
211 &request_handle);
212 EXPECT_FALSE(request_handle.is_active());
213 EXPECT_EQ(OK, error);
214 EXPECT_EQ(1, service_->cert_count());
215 EXPECT_EQ(der_cert1, der_cert3);
216 EXPECT_EQ(private_key_info1, private_key_info3);
218 EXPECT_EQ(3u, service_->requests());
219 EXPECT_EQ(2u, service_->cert_store_hits());
220 EXPECT_EQ(0u, service_->inflight_joins());
223 TEST_F(ServerBoundCertServiceTest, StoreCerts) {
224 int error;
225 TestCompletionCallback callback;
226 ServerBoundCertService::RequestHandle request_handle;
228 std::string host1("encrypted.google.com");
229 std::string private_key_info1, der_cert1;
230 EXPECT_EQ(0, service_->cert_count());
231 error = service_->GetOrCreateDomainBoundCert(
232 host1, &private_key_info1, &der_cert1,
233 callback.callback(), &request_handle);
234 EXPECT_EQ(ERR_IO_PENDING, error);
235 EXPECT_TRUE(request_handle.is_active());
236 error = callback.WaitForResult();
237 EXPECT_EQ(OK, error);
238 EXPECT_EQ(1, service_->cert_count());
240 std::string host2("www.verisign.com");
241 std::string private_key_info2, der_cert2;
242 error = service_->GetOrCreateDomainBoundCert(
243 host2, &private_key_info2, &der_cert2,
244 callback.callback(), &request_handle);
245 EXPECT_EQ(ERR_IO_PENDING, error);
246 EXPECT_TRUE(request_handle.is_active());
247 error = callback.WaitForResult();
248 EXPECT_EQ(OK, error);
249 EXPECT_EQ(2, service_->cert_count());
251 std::string host3("www.twitter.com");
252 std::string private_key_info3, der_cert3;
253 error = service_->GetOrCreateDomainBoundCert(
254 host3, &private_key_info3, &der_cert3,
255 callback.callback(), &request_handle);
256 EXPECT_EQ(ERR_IO_PENDING, error);
257 EXPECT_TRUE(request_handle.is_active());
258 error = callback.WaitForResult();
259 EXPECT_EQ(OK, error);
260 EXPECT_EQ(3, service_->cert_count());
262 EXPECT_NE(private_key_info1, private_key_info2);
263 EXPECT_NE(der_cert1, der_cert2);
264 EXPECT_NE(private_key_info1, private_key_info3);
265 EXPECT_NE(der_cert1, der_cert3);
266 EXPECT_NE(private_key_info2, private_key_info3);
267 EXPECT_NE(der_cert2, der_cert3);
270 // Tests an inflight join.
271 TEST_F(ServerBoundCertServiceTest, InflightJoin) {
272 std::string host("encrypted.google.com");
273 int error;
275 std::string private_key_info1, der_cert1;
276 TestCompletionCallback callback1;
277 ServerBoundCertService::RequestHandle request_handle1;
279 std::string private_key_info2, der_cert2;
280 TestCompletionCallback callback2;
281 ServerBoundCertService::RequestHandle request_handle2;
283 error = service_->GetOrCreateDomainBoundCert(
284 host, &private_key_info1, &der_cert1,
285 callback1.callback(), &request_handle1);
286 EXPECT_EQ(ERR_IO_PENDING, error);
287 EXPECT_TRUE(request_handle1.is_active());
288 // Should join with the original request.
289 error = service_->GetOrCreateDomainBoundCert(
290 host, &private_key_info2, &der_cert2,
291 callback2.callback(), &request_handle2);
292 EXPECT_EQ(ERR_IO_PENDING, error);
293 EXPECT_TRUE(request_handle2.is_active());
295 error = callback1.WaitForResult();
296 EXPECT_EQ(OK, error);
297 error = callback2.WaitForResult();
298 EXPECT_EQ(OK, error);
300 EXPECT_EQ(2u, service_->requests());
301 EXPECT_EQ(0u, service_->cert_store_hits());
302 EXPECT_EQ(1u, service_->inflight_joins());
303 EXPECT_EQ(1u, service_->workers_created());
306 // Tests an inflight join of a Get request to a GetOrCreate request.
307 TEST_F(ServerBoundCertServiceTest, InflightJoinGetOrCreateAndGet) {
308 std::string host("encrypted.google.com");
309 int error;
311 std::string private_key_info1, der_cert1;
312 TestCompletionCallback callback1;
313 ServerBoundCertService::RequestHandle request_handle1;
315 std::string private_key_info2;
316 std::string der_cert2;
317 TestCompletionCallback callback2;
318 ServerBoundCertService::RequestHandle request_handle2;
320 error = service_->GetOrCreateDomainBoundCert(
321 host, &private_key_info1, &der_cert1,
322 callback1.callback(), &request_handle1);
323 EXPECT_EQ(ERR_IO_PENDING, error);
324 EXPECT_TRUE(request_handle1.is_active());
325 // Should join with the original request.
326 error = service_->GetDomainBoundCert(
327 host, &private_key_info2, &der_cert2, callback2.callback(),
328 &request_handle2);
329 EXPECT_EQ(ERR_IO_PENDING, error);
330 EXPECT_TRUE(request_handle2.is_active());
332 error = callback1.WaitForResult();
333 EXPECT_EQ(OK, error);
334 error = callback2.WaitForResult();
335 EXPECT_EQ(OK, error);
336 EXPECT_EQ(der_cert1, der_cert2);
338 EXPECT_EQ(2u, service_->requests());
339 EXPECT_EQ(0u, service_->cert_store_hits());
340 EXPECT_EQ(1u, service_->inflight_joins());
341 EXPECT_EQ(1u, service_->workers_created());
344 TEST_F(ServerBoundCertServiceTest, ExtractValuesFromBytesEC) {
345 std::string host("encrypted.google.com");
346 std::string private_key_info, der_cert;
347 int error;
348 TestCompletionCallback callback;
349 ServerBoundCertService::RequestHandle request_handle;
351 error = service_->GetOrCreateDomainBoundCert(
352 host, &private_key_info, &der_cert, callback.callback(),
353 &request_handle);
354 EXPECT_EQ(ERR_IO_PENDING, error);
355 EXPECT_TRUE(request_handle.is_active());
356 error = callback.WaitForResult();
357 EXPECT_EQ(OK, error);
359 base::StringPiece spki_piece;
360 ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(der_cert, &spki_piece));
361 std::vector<uint8> spki(
362 spki_piece.data(),
363 spki_piece.data() + spki_piece.size());
365 // Check that we can retrieve the key from the bytes.
366 std::vector<uint8> key_vec(private_key_info.begin(), private_key_info.end());
367 scoped_ptr<crypto::ECPrivateKey> private_key(
368 crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo(
369 ServerBoundCertService::kEPKIPassword, key_vec, spki));
370 EXPECT_TRUE(private_key != NULL);
372 // Check that we can retrieve the cert from the bytes.
373 scoped_refptr<X509Certificate> x509cert(
374 X509Certificate::CreateFromBytes(der_cert.data(), der_cert.size()));
375 EXPECT_TRUE(x509cert.get() != NULL);
378 // Tests that the callback of a canceled request is never made.
379 TEST_F(ServerBoundCertServiceTest, CancelRequest) {
380 std::string host("encrypted.google.com");
381 std::string private_key_info, der_cert;
382 int error;
383 ServerBoundCertService::RequestHandle request_handle;
385 error = service_->GetOrCreateDomainBoundCert(host,
386 &private_key_info,
387 &der_cert,
388 base::Bind(&FailTest),
389 &request_handle);
390 EXPECT_EQ(ERR_IO_PENDING, error);
391 EXPECT_TRUE(request_handle.is_active());
392 request_handle.Cancel();
393 EXPECT_FALSE(request_handle.is_active());
395 // Wait for reply from ServerBoundCertServiceWorker to be posted back to the
396 // ServerBoundCertService.
397 base::MessageLoop::current()->RunUntilIdle();
399 // Even though the original request was cancelled, the service will still
400 // store the result, it just doesn't call the callback.
401 EXPECT_EQ(1, service_->cert_count());
404 // Tests that destructing the RequestHandle cancels the request.
405 TEST_F(ServerBoundCertServiceTest, CancelRequestByHandleDestruction) {
406 std::string host("encrypted.google.com");
407 std::string private_key_info, der_cert;
408 int error;
410 ServerBoundCertService::RequestHandle request_handle;
412 error = service_->GetOrCreateDomainBoundCert(host,
413 &private_key_info,
414 &der_cert,
415 base::Bind(&FailTest),
416 &request_handle);
417 EXPECT_EQ(ERR_IO_PENDING, error);
418 EXPECT_TRUE(request_handle.is_active());
421 // Wait for reply from ServerBoundCertServiceWorker to be posted back to the
422 // ServerBoundCertService.
423 base::MessageLoop::current()->RunUntilIdle();
425 // Even though the original request was cancelled, the service will still
426 // store the result, it just doesn't call the callback.
427 EXPECT_EQ(1, service_->cert_count());
430 TEST_F(ServerBoundCertServiceTest, DestructionWithPendingRequest) {
431 std::string host("encrypted.google.com");
432 std::string private_key_info, der_cert;
433 int error;
434 ServerBoundCertService::RequestHandle request_handle;
436 error = service_->GetOrCreateDomainBoundCert(host,
437 &private_key_info,
438 &der_cert,
439 base::Bind(&FailTest),
440 &request_handle);
441 EXPECT_EQ(ERR_IO_PENDING, error);
442 EXPECT_TRUE(request_handle.is_active());
444 // Cancel request and destroy the ServerBoundCertService.
445 request_handle.Cancel();
446 service_.reset();
448 // ServerBoundCertServiceWorker should not post anything back to the
449 // non-existent ServerBoundCertService, but run the loop just to be sure it
450 // doesn't.
451 base::MessageLoop::current()->RunUntilIdle();
453 // If we got here without crashing or a valgrind error, it worked.
456 // Tests that shutting down the sequenced worker pool and then making new
457 // requests gracefully fails.
458 // This is a regression test for http://crbug.com/236387
459 TEST_F(ServerBoundCertServiceTest, RequestAfterPoolShutdown) {
460 scoped_refptr<FailingTaskRunner> task_runner(new FailingTaskRunner);
461 service_.reset(new ServerBoundCertService(
462 new DefaultServerBoundCertStore(NULL), task_runner));
464 // Make a request that will force synchronous completion.
465 std::string host("encrypted.google.com");
466 std::string private_key_info, der_cert;
467 int error;
468 ServerBoundCertService::RequestHandle request_handle;
470 error = service_->GetOrCreateDomainBoundCert(host,
471 &private_key_info,
472 &der_cert,
473 base::Bind(&FailTest),
474 &request_handle);
475 // If we got here without crashing or a valgrind error, it worked.
476 ASSERT_EQ(ERR_INSUFFICIENT_RESOURCES, error);
477 EXPECT_FALSE(request_handle.is_active());
480 // Tests that simultaneous creation of different certs works.
481 TEST_F(ServerBoundCertServiceTest, SimultaneousCreation) {
482 int error;
484 std::string host1("encrypted.google.com");
485 std::string private_key_info1, der_cert1;
486 TestCompletionCallback callback1;
487 ServerBoundCertService::RequestHandle request_handle1;
489 std::string host2("foo.com");
490 std::string private_key_info2, der_cert2;
491 TestCompletionCallback callback2;
492 ServerBoundCertService::RequestHandle request_handle2;
494 std::string host3("bar.com");
495 std::string private_key_info3, der_cert3;
496 TestCompletionCallback callback3;
497 ServerBoundCertService::RequestHandle request_handle3;
499 error = service_->GetOrCreateDomainBoundCert(host1,
500 &private_key_info1,
501 &der_cert1,
502 callback1.callback(),
503 &request_handle1);
504 EXPECT_EQ(ERR_IO_PENDING, error);
505 EXPECT_TRUE(request_handle1.is_active());
507 error = service_->GetOrCreateDomainBoundCert(host2,
508 &private_key_info2,
509 &der_cert2,
510 callback2.callback(),
511 &request_handle2);
512 EXPECT_EQ(ERR_IO_PENDING, error);
513 EXPECT_TRUE(request_handle2.is_active());
515 error = service_->GetOrCreateDomainBoundCert(host3,
516 &private_key_info3,
517 &der_cert3,
518 callback3.callback(),
519 &request_handle3);
520 EXPECT_EQ(ERR_IO_PENDING, error);
521 EXPECT_TRUE(request_handle3.is_active());
523 error = callback1.WaitForResult();
524 EXPECT_EQ(OK, error);
525 EXPECT_FALSE(private_key_info1.empty());
526 EXPECT_FALSE(der_cert1.empty());
528 error = callback2.WaitForResult();
529 EXPECT_EQ(OK, error);
530 EXPECT_FALSE(private_key_info2.empty());
531 EXPECT_FALSE(der_cert2.empty());
533 error = callback3.WaitForResult();
534 EXPECT_EQ(OK, error);
535 EXPECT_FALSE(private_key_info3.empty());
536 EXPECT_FALSE(der_cert3.empty());
538 EXPECT_NE(private_key_info1, private_key_info2);
539 EXPECT_NE(der_cert1, der_cert2);
541 EXPECT_NE(private_key_info1, private_key_info3);
542 EXPECT_NE(der_cert1, der_cert3);
544 EXPECT_NE(private_key_info2, private_key_info3);
545 EXPECT_NE(der_cert2, der_cert3);
547 EXPECT_EQ(3, service_->cert_count());
550 TEST_F(ServerBoundCertServiceTest, Expiration) {
551 ServerBoundCertStore* store = service_->GetCertStore();
552 base::Time now = base::Time::Now();
553 store->SetServerBoundCert("good",
554 now,
555 now + base::TimeDelta::FromDays(1),
556 "a",
557 "b");
558 store->SetServerBoundCert("expired",
559 now - base::TimeDelta::FromDays(2),
560 now - base::TimeDelta::FromDays(1),
561 "c",
562 "d");
563 EXPECT_EQ(2, service_->cert_count());
565 int error;
566 TestCompletionCallback callback;
567 ServerBoundCertService::RequestHandle request_handle;
569 // Cert is valid - synchronous completion.
570 std::string private_key_info1, der_cert1;
571 error = service_->GetOrCreateDomainBoundCert(
572 "good", &private_key_info1, &der_cert1,
573 callback.callback(), &request_handle);
574 EXPECT_EQ(OK, error);
575 EXPECT_FALSE(request_handle.is_active());
576 EXPECT_EQ(2, service_->cert_count());
577 EXPECT_STREQ("a", private_key_info1.c_str());
578 EXPECT_STREQ("b", der_cert1.c_str());
580 // Expired cert is valid as well - synchronous completion.
581 std::string private_key_info2, der_cert2;
582 error = service_->GetOrCreateDomainBoundCert(
583 "expired", &private_key_info2, &der_cert2,
584 callback.callback(), &request_handle);
585 EXPECT_EQ(OK, error);
586 EXPECT_FALSE(request_handle.is_active());
587 EXPECT_EQ(2, service_->cert_count());
588 EXPECT_STREQ("c", private_key_info2.c_str());
589 EXPECT_STREQ("d", der_cert2.c_str());
592 TEST_F(ServerBoundCertServiceTest, AsyncStoreGetOrCreateNoCertsInStore) {
593 MockServerBoundCertStoreWithAsyncGet* mock_store =
594 new MockServerBoundCertStoreWithAsyncGet();
595 service_ = scoped_ptr<ServerBoundCertService>(new ServerBoundCertService(
596 mock_store, base::MessageLoopProxy::current()));
598 std::string host("encrypted.google.com");
600 int error;
601 TestCompletionCallback callback;
602 ServerBoundCertService::RequestHandle request_handle;
604 // Asynchronous completion with no certs in the store.
605 std::string private_key_info, der_cert;
606 EXPECT_EQ(0, service_->cert_count());
607 error = service_->GetOrCreateDomainBoundCert(
608 host, &private_key_info, &der_cert, callback.callback(), &request_handle);
609 EXPECT_EQ(ERR_IO_PENDING, error);
610 EXPECT_TRUE(request_handle.is_active());
612 mock_store->CallGetServerBoundCertCallbackWithResult(
613 ERR_FILE_NOT_FOUND, base::Time(), std::string(), std::string());
615 error = callback.WaitForResult();
616 EXPECT_EQ(OK, error);
617 EXPECT_EQ(1, service_->cert_count());
618 EXPECT_FALSE(private_key_info.empty());
619 EXPECT_FALSE(der_cert.empty());
620 EXPECT_FALSE(request_handle.is_active());
623 TEST_F(ServerBoundCertServiceTest, AsyncStoreGetNoCertsInStore) {
624 MockServerBoundCertStoreWithAsyncGet* mock_store =
625 new MockServerBoundCertStoreWithAsyncGet();
626 service_ = scoped_ptr<ServerBoundCertService>(new ServerBoundCertService(
627 mock_store, base::MessageLoopProxy::current()));
629 std::string host("encrypted.google.com");
631 int error;
632 TestCompletionCallback callback;
633 ServerBoundCertService::RequestHandle request_handle;
635 // Asynchronous completion with no certs in the store.
636 std::string private_key, der_cert;
637 EXPECT_EQ(0, service_->cert_count());
638 error = service_->GetDomainBoundCert(
639 host, &private_key, &der_cert, callback.callback(), &request_handle);
640 EXPECT_EQ(ERR_IO_PENDING, error);
641 EXPECT_TRUE(request_handle.is_active());
643 mock_store->CallGetServerBoundCertCallbackWithResult(
644 ERR_FILE_NOT_FOUND, base::Time(), std::string(), std::string());
646 error = callback.WaitForResult();
647 EXPECT_EQ(ERR_FILE_NOT_FOUND, error);
648 EXPECT_EQ(0, service_->cert_count());
649 EXPECT_EQ(0u, service_->workers_created());
650 EXPECT_TRUE(der_cert.empty());
651 EXPECT_FALSE(request_handle.is_active());
654 TEST_F(ServerBoundCertServiceTest, AsyncStoreGetOrCreateOneCertInStore) {
655 MockServerBoundCertStoreWithAsyncGet* mock_store =
656 new MockServerBoundCertStoreWithAsyncGet();
657 service_ = scoped_ptr<ServerBoundCertService>(new ServerBoundCertService(
658 mock_store, base::MessageLoopProxy::current()));
660 std::string host("encrypted.google.com");
662 int error;
663 TestCompletionCallback callback;
664 ServerBoundCertService::RequestHandle request_handle;
666 // Asynchronous completion with a cert in the store.
667 std::string private_key_info, der_cert;
668 EXPECT_EQ(0, service_->cert_count());
669 error = service_->GetOrCreateDomainBoundCert(
670 host, &private_key_info, &der_cert, callback.callback(), &request_handle);
671 EXPECT_EQ(ERR_IO_PENDING, error);
672 EXPECT_TRUE(request_handle.is_active());
674 mock_store->CallGetServerBoundCertCallbackWithResult(
675 OK, base::Time(), "ab", "cd");
677 error = callback.WaitForResult();
678 EXPECT_EQ(OK, error);
679 EXPECT_EQ(1, service_->cert_count());
680 EXPECT_EQ(1u, service_->requests());
681 EXPECT_EQ(1u, service_->cert_store_hits());
682 // Because the cert was found in the store, no new workers should have been
683 // created.
684 EXPECT_EQ(0u, service_->workers_created());
685 EXPECT_STREQ("ab", private_key_info.c_str());
686 EXPECT_STREQ("cd", der_cert.c_str());
687 EXPECT_FALSE(request_handle.is_active());
690 TEST_F(ServerBoundCertServiceTest, AsyncStoreGetOneCertInStore) {
691 MockServerBoundCertStoreWithAsyncGet* mock_store =
692 new MockServerBoundCertStoreWithAsyncGet();
693 service_ = scoped_ptr<ServerBoundCertService>(new ServerBoundCertService(
694 mock_store, base::MessageLoopProxy::current()));
696 std::string host("encrypted.google.com");
698 int error;
699 TestCompletionCallback callback;
700 ServerBoundCertService::RequestHandle request_handle;
702 // Asynchronous completion with a cert in the store.
703 std::string private_key, der_cert;
704 EXPECT_EQ(0, service_->cert_count());
705 error = service_->GetDomainBoundCert(
706 host, &private_key, &der_cert, callback.callback(), &request_handle);
707 EXPECT_EQ(ERR_IO_PENDING, error);
708 EXPECT_TRUE(request_handle.is_active());
710 mock_store->CallGetServerBoundCertCallbackWithResult(
711 OK, base::Time(), "ab", "cd");
713 error = callback.WaitForResult();
714 EXPECT_EQ(OK, error);
715 EXPECT_EQ(1, service_->cert_count());
716 EXPECT_EQ(1u, service_->requests());
717 EXPECT_EQ(1u, service_->cert_store_hits());
718 // Because the cert was found in the store, no new workers should have been
719 // created.
720 EXPECT_EQ(0u, service_->workers_created());
721 EXPECT_STREQ("cd", der_cert.c_str());
722 EXPECT_FALSE(request_handle.is_active());
725 TEST_F(ServerBoundCertServiceTest, AsyncStoreGetThenCreateNoCertsInStore) {
726 MockServerBoundCertStoreWithAsyncGet* mock_store =
727 new MockServerBoundCertStoreWithAsyncGet();
728 service_ = scoped_ptr<ServerBoundCertService>(new ServerBoundCertService(
729 mock_store, base::MessageLoopProxy::current()));
731 std::string host("encrypted.google.com");
733 int error;
735 // Asynchronous get with no certs in the store.
736 TestCompletionCallback callback1;
737 ServerBoundCertService::RequestHandle request_handle1;
738 std::string private_key1, der_cert1;
739 EXPECT_EQ(0, service_->cert_count());
740 error = service_->GetDomainBoundCert(
741 host, &private_key1, &der_cert1, callback1.callback(), &request_handle1);
742 EXPECT_EQ(ERR_IO_PENDING, error);
743 EXPECT_TRUE(request_handle1.is_active());
745 // Asynchronous get/create with no certs in the store.
746 TestCompletionCallback callback2;
747 ServerBoundCertService::RequestHandle request_handle2;
748 std::string private_key2, der_cert2;
749 EXPECT_EQ(0, service_->cert_count());
750 error = service_->GetOrCreateDomainBoundCert(
751 host, &private_key2, &der_cert2, callback2.callback(), &request_handle2);
752 EXPECT_EQ(ERR_IO_PENDING, error);
753 EXPECT_TRUE(request_handle2.is_active());
755 mock_store->CallGetServerBoundCertCallbackWithResult(
756 ERR_FILE_NOT_FOUND, base::Time(), std::string(), std::string());
758 // Even though the first request didn't ask to create a cert, it gets joined
759 // by the second, which does, so both succeed.
760 error = callback1.WaitForResult();
761 EXPECT_EQ(OK, error);
762 error = callback2.WaitForResult();
763 EXPECT_EQ(OK, error);
765 // One cert is created, one request is joined.
766 EXPECT_EQ(2U, service_->requests());
767 EXPECT_EQ(1, service_->cert_count());
768 EXPECT_EQ(1u, service_->workers_created());
769 EXPECT_EQ(1u, service_->inflight_joins());
770 EXPECT_FALSE(der_cert1.empty());
771 EXPECT_EQ(der_cert1, der_cert2);
772 EXPECT_FALSE(private_key1.empty());
773 EXPECT_EQ(private_key1, private_key2);
774 EXPECT_FALSE(request_handle1.is_active());
775 EXPECT_FALSE(request_handle2.is_active());
778 #endif // !defined(USE_OPENSSL)
780 } // namespace
782 } // namespace net