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"
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"
27 void FailTest(int /* result */) {
31 // Simple task runner that refuses to actually post any tasks. This simulates
32 // a TaskRunner that has been shutdown, by returning false for any attempt to
34 class FailingTaskRunner : public base::TaskRunner {
36 FailingTaskRunner() {}
38 virtual bool PostDelayedTask(const tracked_objects::Location& from_here,
39 const base::Closure& task,
40 base::TimeDelta delay) OVERRIDE {
44 virtual bool RunsTasksOnCurrentThread() const OVERRIDE { return true; }
47 virtual ~FailingTaskRunner() {}
50 DISALLOW_COPY_AND_ASSIGN(FailingTaskRunner);
53 class ServerBoundCertServiceTest : public testing::Test {
55 ServerBoundCertServiceTest()
56 : service_(new ServerBoundCertService(
57 new DefaultServerBoundCertStore(NULL),
58 base::MessageLoopProxy::current())) {
62 scoped_ptr<ServerBoundCertService> service_;
65 class MockServerBoundCertStoreWithAsyncGet
66 : public DefaultServerBoundCertStore {
68 MockServerBoundCertStoreWithAsyncGet()
69 : DefaultServerBoundCertStore(NULL), cert_count_(0) {}
71 virtual int GetServerBoundCert(const std::string& server_identifier,
72 base::Time* expiration_time,
73 std::string* private_key_result,
74 std::string* cert_result,
75 const GetCertCallback& callback) OVERRIDE;
77 virtual void SetServerBoundCert(const std::string& server_identifier,
78 base::Time creation_time,
79 base::Time expiration_time,
80 const std::string& private_key,
81 const std::string& cert) OVERRIDE {
85 virtual int GetCertCount() OVERRIDE { return cert_count_; }
87 void CallGetServerBoundCertCallbackWithResult(int err,
88 base::Time expiration_time,
89 const std::string& private_key,
90 const std::string& cert);
93 GetCertCallback callback_;
94 std::string server_identifier_;
98 int MockServerBoundCertStoreWithAsyncGet::GetServerBoundCert(
99 const std::string& server_identifier,
100 base::Time* expiration_time,
101 std::string* private_key_result,
102 std::string* cert_result,
103 const GetCertCallback& callback) {
104 server_identifier_ = server_identifier;
105 callback_ = callback;
106 // Reset the cert count, it'll get incremented in either SetServerBoundCert or
107 // CallGetServerBoundCertCallbackWithResult.
109 // Do nothing else: the results to be provided will be specified through
110 // CallGetServerBoundCertCallbackWithResult.
111 return ERR_IO_PENDING;
115 MockServerBoundCertStoreWithAsyncGet::CallGetServerBoundCertCallbackWithResult(
117 base::Time expiration_time,
118 const std::string& private_key,
119 const std::string& cert) {
122 base::MessageLoop::current()->PostTask(FROM_HERE,
123 base::Bind(callback_,
131 TEST_F(ServerBoundCertServiceTest, GetDomainForHost) {
132 EXPECT_EQ("google.com",
133 ServerBoundCertService::GetDomainForHost("google.com"));
134 EXPECT_EQ("google.com",
135 ServerBoundCertService::GetDomainForHost("www.google.com"));
136 EXPECT_EQ("foo.appspot.com",
137 ServerBoundCertService::GetDomainForHost("foo.appspot.com"));
138 EXPECT_EQ("bar.appspot.com",
139 ServerBoundCertService::GetDomainForHost("foo.bar.appspot.com"));
140 EXPECT_EQ("appspot.com",
141 ServerBoundCertService::GetDomainForHost("appspot.com"));
142 EXPECT_EQ("google.com",
143 ServerBoundCertService::GetDomainForHost("www.mail.google.com"));
145 ServerBoundCertService::GetDomainForHost("goto"));
146 EXPECT_EQ("127.0.0.1",
147 ServerBoundCertService::GetDomainForHost("127.0.0.1"));
150 // See http://crbug.com/91512 - implement OpenSSL version of CreateSelfSigned.
151 #if !defined(USE_OPENSSL)
153 TEST_F(ServerBoundCertServiceTest, GetCacheMiss) {
154 std::string host("encrypted.google.com");
157 TestCompletionCallback callback;
158 ServerBoundCertService::RequestHandle request_handle;
160 // Synchronous completion, because the store is initialized.
161 std::string private_key, der_cert;
162 EXPECT_EQ(0, service_->cert_count());
163 error = service_->GetDomainBoundCert(
164 host, &private_key, &der_cert, callback.callback(), &request_handle);
165 EXPECT_EQ(ERR_FILE_NOT_FOUND, error);
166 EXPECT_FALSE(request_handle.is_active());
167 EXPECT_EQ(0, service_->cert_count());
168 EXPECT_TRUE(der_cert.empty());
171 TEST_F(ServerBoundCertServiceTest, CacheHit) {
172 std::string host("encrypted.google.com");
175 TestCompletionCallback callback;
176 ServerBoundCertService::RequestHandle request_handle;
178 // Asynchronous completion.
179 std::string private_key_info1, der_cert1;
180 EXPECT_EQ(0, service_->cert_count());
181 error = service_->GetOrCreateDomainBoundCert(
182 host, &private_key_info1, &der_cert1,
183 callback.callback(), &request_handle);
184 EXPECT_EQ(ERR_IO_PENDING, error);
185 EXPECT_TRUE(request_handle.is_active());
186 error = callback.WaitForResult();
187 EXPECT_EQ(OK, error);
188 EXPECT_EQ(1, service_->cert_count());
189 EXPECT_FALSE(private_key_info1.empty());
190 EXPECT_FALSE(der_cert1.empty());
191 EXPECT_FALSE(request_handle.is_active());
193 // Synchronous completion.
194 std::string private_key_info2, der_cert2;
195 error = service_->GetOrCreateDomainBoundCert(
196 host, &private_key_info2, &der_cert2,
197 callback.callback(), &request_handle);
198 EXPECT_FALSE(request_handle.is_active());
199 EXPECT_EQ(OK, error);
200 EXPECT_EQ(1, service_->cert_count());
201 EXPECT_EQ(private_key_info1, private_key_info2);
202 EXPECT_EQ(der_cert1, der_cert2);
205 std::string private_key_info3, der_cert3;
206 error = service_->GetDomainBoundCert(
207 host, &private_key_info3, &der_cert3, callback.callback(),
209 EXPECT_FALSE(request_handle.is_active());
210 EXPECT_EQ(OK, error);
211 EXPECT_EQ(1, service_->cert_count());
212 EXPECT_EQ(der_cert1, der_cert3);
213 EXPECT_EQ(private_key_info1, private_key_info3);
215 EXPECT_EQ(3u, service_->requests());
216 EXPECT_EQ(2u, service_->cert_store_hits());
217 EXPECT_EQ(0u, service_->inflight_joins());
220 TEST_F(ServerBoundCertServiceTest, StoreCerts) {
222 TestCompletionCallback callback;
223 ServerBoundCertService::RequestHandle request_handle;
225 std::string host1("encrypted.google.com");
226 std::string private_key_info1, der_cert1;
227 EXPECT_EQ(0, service_->cert_count());
228 error = service_->GetOrCreateDomainBoundCert(
229 host1, &private_key_info1, &der_cert1,
230 callback.callback(), &request_handle);
231 EXPECT_EQ(ERR_IO_PENDING, error);
232 EXPECT_TRUE(request_handle.is_active());
233 error = callback.WaitForResult();
234 EXPECT_EQ(OK, error);
235 EXPECT_EQ(1, service_->cert_count());
237 std::string host2("www.verisign.com");
238 std::string private_key_info2, der_cert2;
239 error = service_->GetOrCreateDomainBoundCert(
240 host2, &private_key_info2, &der_cert2,
241 callback.callback(), &request_handle);
242 EXPECT_EQ(ERR_IO_PENDING, error);
243 EXPECT_TRUE(request_handle.is_active());
244 error = callback.WaitForResult();
245 EXPECT_EQ(OK, error);
246 EXPECT_EQ(2, service_->cert_count());
248 std::string host3("www.twitter.com");
249 std::string private_key_info3, der_cert3;
250 error = service_->GetOrCreateDomainBoundCert(
251 host3, &private_key_info3, &der_cert3,
252 callback.callback(), &request_handle);
253 EXPECT_EQ(ERR_IO_PENDING, error);
254 EXPECT_TRUE(request_handle.is_active());
255 error = callback.WaitForResult();
256 EXPECT_EQ(OK, error);
257 EXPECT_EQ(3, service_->cert_count());
259 EXPECT_NE(private_key_info1, private_key_info2);
260 EXPECT_NE(der_cert1, der_cert2);
261 EXPECT_NE(private_key_info1, private_key_info3);
262 EXPECT_NE(der_cert1, der_cert3);
263 EXPECT_NE(private_key_info2, private_key_info3);
264 EXPECT_NE(der_cert2, der_cert3);
267 // Tests an inflight join.
268 TEST_F(ServerBoundCertServiceTest, InflightJoin) {
269 std::string host("encrypted.google.com");
272 std::string private_key_info1, der_cert1;
273 TestCompletionCallback callback1;
274 ServerBoundCertService::RequestHandle request_handle1;
276 std::string private_key_info2, der_cert2;
277 TestCompletionCallback callback2;
278 ServerBoundCertService::RequestHandle request_handle2;
280 error = service_->GetOrCreateDomainBoundCert(
281 host, &private_key_info1, &der_cert1,
282 callback1.callback(), &request_handle1);
283 EXPECT_EQ(ERR_IO_PENDING, error);
284 EXPECT_TRUE(request_handle1.is_active());
285 // Should join with the original request.
286 error = service_->GetOrCreateDomainBoundCert(
287 host, &private_key_info2, &der_cert2,
288 callback2.callback(), &request_handle2);
289 EXPECT_EQ(ERR_IO_PENDING, error);
290 EXPECT_TRUE(request_handle2.is_active());
292 error = callback1.WaitForResult();
293 EXPECT_EQ(OK, error);
294 error = callback2.WaitForResult();
295 EXPECT_EQ(OK, error);
297 EXPECT_EQ(2u, service_->requests());
298 EXPECT_EQ(0u, service_->cert_store_hits());
299 EXPECT_EQ(1u, service_->inflight_joins());
300 EXPECT_EQ(1u, service_->workers_created());
303 // Tests an inflight join of a Get request to a GetOrCreate request.
304 TEST_F(ServerBoundCertServiceTest, InflightJoinGetOrCreateAndGet) {
305 std::string host("encrypted.google.com");
308 std::string private_key_info1, der_cert1;
309 TestCompletionCallback callback1;
310 ServerBoundCertService::RequestHandle request_handle1;
312 std::string private_key_info2;
313 std::string der_cert2;
314 TestCompletionCallback callback2;
315 ServerBoundCertService::RequestHandle request_handle2;
317 error = service_->GetOrCreateDomainBoundCert(
318 host, &private_key_info1, &der_cert1,
319 callback1.callback(), &request_handle1);
320 EXPECT_EQ(ERR_IO_PENDING, error);
321 EXPECT_TRUE(request_handle1.is_active());
322 // Should join with the original request.
323 error = service_->GetDomainBoundCert(
324 host, &private_key_info2, &der_cert2, callback2.callback(),
326 EXPECT_EQ(ERR_IO_PENDING, error);
327 EXPECT_TRUE(request_handle2.is_active());
329 error = callback1.WaitForResult();
330 EXPECT_EQ(OK, error);
331 error = callback2.WaitForResult();
332 EXPECT_EQ(OK, error);
333 EXPECT_EQ(der_cert1, der_cert2);
335 EXPECT_EQ(2u, service_->requests());
336 EXPECT_EQ(0u, service_->cert_store_hits());
337 EXPECT_EQ(1u, service_->inflight_joins());
338 EXPECT_EQ(1u, service_->workers_created());
341 TEST_F(ServerBoundCertServiceTest, ExtractValuesFromBytesEC) {
342 std::string host("encrypted.google.com");
343 std::string private_key_info, der_cert;
345 TestCompletionCallback callback;
346 ServerBoundCertService::RequestHandle request_handle;
348 error = service_->GetOrCreateDomainBoundCert(
349 host, &private_key_info, &der_cert, callback.callback(),
351 EXPECT_EQ(ERR_IO_PENDING, error);
352 EXPECT_TRUE(request_handle.is_active());
353 error = callback.WaitForResult();
354 EXPECT_EQ(OK, error);
356 base::StringPiece spki_piece;
357 ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(der_cert, &spki_piece));
358 std::vector<uint8> spki(
360 spki_piece.data() + spki_piece.size());
362 // Check that we can retrieve the key from the bytes.
363 std::vector<uint8> key_vec(private_key_info.begin(), private_key_info.end());
364 scoped_ptr<crypto::ECPrivateKey> private_key(
365 crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo(
366 ServerBoundCertService::kEPKIPassword, key_vec, spki));
367 EXPECT_TRUE(private_key != NULL);
369 // Check that we can retrieve the cert from the bytes.
370 scoped_refptr<X509Certificate> x509cert(
371 X509Certificate::CreateFromBytes(der_cert.data(), der_cert.size()));
372 EXPECT_TRUE(x509cert.get() != NULL);
375 // Tests that the callback of a canceled request is never made.
376 TEST_F(ServerBoundCertServiceTest, CancelRequest) {
377 std::string host("encrypted.google.com");
378 std::string private_key_info, der_cert;
380 ServerBoundCertService::RequestHandle request_handle;
382 error = service_->GetOrCreateDomainBoundCert(host,
385 base::Bind(&FailTest),
387 EXPECT_EQ(ERR_IO_PENDING, error);
388 EXPECT_TRUE(request_handle.is_active());
389 request_handle.Cancel();
390 EXPECT_FALSE(request_handle.is_active());
392 // Wait for reply from ServerBoundCertServiceWorker to be posted back to the
393 // ServerBoundCertService.
394 base::MessageLoop::current()->RunUntilIdle();
396 // Even though the original request was cancelled, the service will still
397 // store the result, it just doesn't call the callback.
398 EXPECT_EQ(1, service_->cert_count());
401 // Tests that destructing the RequestHandle cancels the request.
402 TEST_F(ServerBoundCertServiceTest, CancelRequestByHandleDestruction) {
403 std::string host("encrypted.google.com");
404 std::string private_key_info, der_cert;
407 ServerBoundCertService::RequestHandle request_handle;
409 error = service_->GetOrCreateDomainBoundCert(host,
412 base::Bind(&FailTest),
414 EXPECT_EQ(ERR_IO_PENDING, error);
415 EXPECT_TRUE(request_handle.is_active());
418 // Wait for reply from ServerBoundCertServiceWorker to be posted back to the
419 // ServerBoundCertService.
420 base::MessageLoop::current()->RunUntilIdle();
422 // Even though the original request was cancelled, the service will still
423 // store the result, it just doesn't call the callback.
424 EXPECT_EQ(1, service_->cert_count());
427 TEST_F(ServerBoundCertServiceTest, DestructionWithPendingRequest) {
428 std::string host("encrypted.google.com");
429 std::string private_key_info, der_cert;
431 ServerBoundCertService::RequestHandle request_handle;
433 error = service_->GetOrCreateDomainBoundCert(host,
436 base::Bind(&FailTest),
438 EXPECT_EQ(ERR_IO_PENDING, error);
439 EXPECT_TRUE(request_handle.is_active());
441 // Cancel request and destroy the ServerBoundCertService.
442 request_handle.Cancel();
445 // ServerBoundCertServiceWorker should not post anything back to the
446 // non-existent ServerBoundCertService, but run the loop just to be sure it
448 base::MessageLoop::current()->RunUntilIdle();
450 // If we got here without crashing or a valgrind error, it worked.
453 // Tests that shutting down the sequenced worker pool and then making new
454 // requests gracefully fails.
455 // This is a regression test for http://crbug.com/236387
456 TEST_F(ServerBoundCertServiceTest, RequestAfterPoolShutdown) {
457 scoped_refptr<FailingTaskRunner> task_runner(new FailingTaskRunner);
458 service_.reset(new ServerBoundCertService(
459 new DefaultServerBoundCertStore(NULL), task_runner));
461 // Make a request that will force synchronous completion.
462 std::string host("encrypted.google.com");
463 std::string private_key_info, der_cert;
465 ServerBoundCertService::RequestHandle request_handle;
467 error = service_->GetOrCreateDomainBoundCert(host,
470 base::Bind(&FailTest),
472 // If we got here without crashing or a valgrind error, it worked.
473 ASSERT_EQ(ERR_INSUFFICIENT_RESOURCES, error);
474 EXPECT_FALSE(request_handle.is_active());
477 // Tests that simultaneous creation of different certs works.
478 TEST_F(ServerBoundCertServiceTest, SimultaneousCreation) {
481 std::string host1("encrypted.google.com");
482 std::string private_key_info1, der_cert1;
483 TestCompletionCallback callback1;
484 ServerBoundCertService::RequestHandle request_handle1;
486 std::string host2("foo.com");
487 std::string private_key_info2, der_cert2;
488 TestCompletionCallback callback2;
489 ServerBoundCertService::RequestHandle request_handle2;
491 std::string host3("bar.com");
492 std::string private_key_info3, der_cert3;
493 TestCompletionCallback callback3;
494 ServerBoundCertService::RequestHandle request_handle3;
496 error = service_->GetOrCreateDomainBoundCert(host1,
499 callback1.callback(),
501 EXPECT_EQ(ERR_IO_PENDING, error);
502 EXPECT_TRUE(request_handle1.is_active());
504 error = service_->GetOrCreateDomainBoundCert(host2,
507 callback2.callback(),
509 EXPECT_EQ(ERR_IO_PENDING, error);
510 EXPECT_TRUE(request_handle2.is_active());
512 error = service_->GetOrCreateDomainBoundCert(host3,
515 callback3.callback(),
517 EXPECT_EQ(ERR_IO_PENDING, error);
518 EXPECT_TRUE(request_handle3.is_active());
520 error = callback1.WaitForResult();
521 EXPECT_EQ(OK, error);
522 EXPECT_FALSE(private_key_info1.empty());
523 EXPECT_FALSE(der_cert1.empty());
525 error = callback2.WaitForResult();
526 EXPECT_EQ(OK, error);
527 EXPECT_FALSE(private_key_info2.empty());
528 EXPECT_FALSE(der_cert2.empty());
530 error = callback3.WaitForResult();
531 EXPECT_EQ(OK, error);
532 EXPECT_FALSE(private_key_info3.empty());
533 EXPECT_FALSE(der_cert3.empty());
535 EXPECT_NE(private_key_info1, private_key_info2);
536 EXPECT_NE(der_cert1, der_cert2);
538 EXPECT_NE(private_key_info1, private_key_info3);
539 EXPECT_NE(der_cert1, der_cert3);
541 EXPECT_NE(private_key_info2, private_key_info3);
542 EXPECT_NE(der_cert2, der_cert3);
544 EXPECT_EQ(3, service_->cert_count());
547 TEST_F(ServerBoundCertServiceTest, Expiration) {
548 ServerBoundCertStore* store = service_->GetCertStore();
549 base::Time now = base::Time::Now();
550 store->SetServerBoundCert("good",
552 now + base::TimeDelta::FromDays(1),
555 store->SetServerBoundCert("expired",
556 now - base::TimeDelta::FromDays(2),
557 now - base::TimeDelta::FromDays(1),
560 EXPECT_EQ(2, service_->cert_count());
563 TestCompletionCallback callback;
564 ServerBoundCertService::RequestHandle request_handle;
566 // Cert is valid - synchronous completion.
567 std::string private_key_info1, der_cert1;
568 error = service_->GetOrCreateDomainBoundCert(
569 "good", &private_key_info1, &der_cert1,
570 callback.callback(), &request_handle);
571 EXPECT_EQ(OK, error);
572 EXPECT_FALSE(request_handle.is_active());
573 EXPECT_EQ(2, service_->cert_count());
574 EXPECT_STREQ("a", private_key_info1.c_str());
575 EXPECT_STREQ("b", der_cert1.c_str());
577 // Expired cert is valid as well - synchronous completion.
578 std::string private_key_info2, der_cert2;
579 error = service_->GetOrCreateDomainBoundCert(
580 "expired", &private_key_info2, &der_cert2,
581 callback.callback(), &request_handle);
582 EXPECT_EQ(OK, error);
583 EXPECT_FALSE(request_handle.is_active());
584 EXPECT_EQ(2, service_->cert_count());
585 EXPECT_STREQ("c", private_key_info2.c_str());
586 EXPECT_STREQ("d", der_cert2.c_str());
589 TEST_F(ServerBoundCertServiceTest, AsyncStoreGetOrCreateNoCertsInStore) {
590 MockServerBoundCertStoreWithAsyncGet* mock_store =
591 new MockServerBoundCertStoreWithAsyncGet();
592 service_ = scoped_ptr<ServerBoundCertService>(new ServerBoundCertService(
593 mock_store, base::MessageLoopProxy::current()));
595 std::string host("encrypted.google.com");
598 TestCompletionCallback callback;
599 ServerBoundCertService::RequestHandle request_handle;
601 // Asynchronous completion with no certs in the store.
602 std::string private_key_info, der_cert;
603 EXPECT_EQ(0, service_->cert_count());
604 error = service_->GetOrCreateDomainBoundCert(
605 host, &private_key_info, &der_cert, callback.callback(), &request_handle);
606 EXPECT_EQ(ERR_IO_PENDING, error);
607 EXPECT_TRUE(request_handle.is_active());
609 mock_store->CallGetServerBoundCertCallbackWithResult(
610 ERR_FILE_NOT_FOUND, base::Time(), std::string(), std::string());
612 error = callback.WaitForResult();
613 EXPECT_EQ(OK, error);
614 EXPECT_EQ(1, service_->cert_count());
615 EXPECT_FALSE(private_key_info.empty());
616 EXPECT_FALSE(der_cert.empty());
617 EXPECT_FALSE(request_handle.is_active());
620 TEST_F(ServerBoundCertServiceTest, AsyncStoreGetNoCertsInStore) {
621 MockServerBoundCertStoreWithAsyncGet* mock_store =
622 new MockServerBoundCertStoreWithAsyncGet();
623 service_ = scoped_ptr<ServerBoundCertService>(new ServerBoundCertService(
624 mock_store, base::MessageLoopProxy::current()));
626 std::string host("encrypted.google.com");
629 TestCompletionCallback callback;
630 ServerBoundCertService::RequestHandle request_handle;
632 // Asynchronous completion with no certs in the store.
633 std::string private_key, der_cert;
634 EXPECT_EQ(0, service_->cert_count());
635 error = service_->GetDomainBoundCert(
636 host, &private_key, &der_cert, callback.callback(), &request_handle);
637 EXPECT_EQ(ERR_IO_PENDING, error);
638 EXPECT_TRUE(request_handle.is_active());
640 mock_store->CallGetServerBoundCertCallbackWithResult(
641 ERR_FILE_NOT_FOUND, base::Time(), std::string(), std::string());
643 error = callback.WaitForResult();
644 EXPECT_EQ(ERR_FILE_NOT_FOUND, error);
645 EXPECT_EQ(0, service_->cert_count());
646 EXPECT_EQ(0u, service_->workers_created());
647 EXPECT_TRUE(der_cert.empty());
648 EXPECT_FALSE(request_handle.is_active());
651 TEST_F(ServerBoundCertServiceTest, AsyncStoreGetOrCreateOneCertInStore) {
652 MockServerBoundCertStoreWithAsyncGet* mock_store =
653 new MockServerBoundCertStoreWithAsyncGet();
654 service_ = scoped_ptr<ServerBoundCertService>(new ServerBoundCertService(
655 mock_store, base::MessageLoopProxy::current()));
657 std::string host("encrypted.google.com");
660 TestCompletionCallback callback;
661 ServerBoundCertService::RequestHandle request_handle;
663 // Asynchronous completion with a cert in the store.
664 std::string private_key_info, der_cert;
665 EXPECT_EQ(0, service_->cert_count());
666 error = service_->GetOrCreateDomainBoundCert(
667 host, &private_key_info, &der_cert, callback.callback(), &request_handle);
668 EXPECT_EQ(ERR_IO_PENDING, error);
669 EXPECT_TRUE(request_handle.is_active());
671 mock_store->CallGetServerBoundCertCallbackWithResult(
672 OK, base::Time(), "ab", "cd");
674 error = callback.WaitForResult();
675 EXPECT_EQ(OK, error);
676 EXPECT_EQ(1, service_->cert_count());
677 EXPECT_EQ(1u, service_->requests());
678 EXPECT_EQ(1u, service_->cert_store_hits());
679 // Because the cert was found in the store, no new workers should have been
681 EXPECT_EQ(0u, service_->workers_created());
682 EXPECT_STREQ("ab", private_key_info.c_str());
683 EXPECT_STREQ("cd", der_cert.c_str());
684 EXPECT_FALSE(request_handle.is_active());
687 TEST_F(ServerBoundCertServiceTest, AsyncStoreGetOneCertInStore) {
688 MockServerBoundCertStoreWithAsyncGet* mock_store =
689 new MockServerBoundCertStoreWithAsyncGet();
690 service_ = scoped_ptr<ServerBoundCertService>(new ServerBoundCertService(
691 mock_store, base::MessageLoopProxy::current()));
693 std::string host("encrypted.google.com");
696 TestCompletionCallback callback;
697 ServerBoundCertService::RequestHandle request_handle;
699 // Asynchronous completion with a cert in the store.
700 std::string private_key, der_cert;
701 EXPECT_EQ(0, service_->cert_count());
702 error = service_->GetDomainBoundCert(
703 host, &private_key, &der_cert, callback.callback(), &request_handle);
704 EXPECT_EQ(ERR_IO_PENDING, error);
705 EXPECT_TRUE(request_handle.is_active());
707 mock_store->CallGetServerBoundCertCallbackWithResult(
708 OK, base::Time(), "ab", "cd");
710 error = callback.WaitForResult();
711 EXPECT_EQ(OK, error);
712 EXPECT_EQ(1, service_->cert_count());
713 EXPECT_EQ(1u, service_->requests());
714 EXPECT_EQ(1u, service_->cert_store_hits());
715 // Because the cert was found in the store, no new workers should have been
717 EXPECT_EQ(0u, service_->workers_created());
718 EXPECT_STREQ("cd", der_cert.c_str());
719 EXPECT_FALSE(request_handle.is_active());
722 TEST_F(ServerBoundCertServiceTest, AsyncStoreGetThenCreateNoCertsInStore) {
723 MockServerBoundCertStoreWithAsyncGet* mock_store =
724 new MockServerBoundCertStoreWithAsyncGet();
725 service_ = scoped_ptr<ServerBoundCertService>(new ServerBoundCertService(
726 mock_store, base::MessageLoopProxy::current()));
728 std::string host("encrypted.google.com");
732 // Asynchronous get with no certs in the store.
733 TestCompletionCallback callback1;
734 ServerBoundCertService::RequestHandle request_handle1;
735 std::string private_key1, der_cert1;
736 EXPECT_EQ(0, service_->cert_count());
737 error = service_->GetDomainBoundCert(
738 host, &private_key1, &der_cert1, callback1.callback(), &request_handle1);
739 EXPECT_EQ(ERR_IO_PENDING, error);
740 EXPECT_TRUE(request_handle1.is_active());
742 // Asynchronous get/create with no certs in the store.
743 TestCompletionCallback callback2;
744 ServerBoundCertService::RequestHandle request_handle2;
745 std::string private_key2, der_cert2;
746 EXPECT_EQ(0, service_->cert_count());
747 error = service_->GetOrCreateDomainBoundCert(
748 host, &private_key2, &der_cert2, callback2.callback(), &request_handle2);
749 EXPECT_EQ(ERR_IO_PENDING, error);
750 EXPECT_TRUE(request_handle2.is_active());
752 mock_store->CallGetServerBoundCertCallbackWithResult(
753 ERR_FILE_NOT_FOUND, base::Time(), std::string(), std::string());
755 // Even though the first request didn't ask to create a cert, it gets joined
756 // by the second, which does, so both succeed.
757 error = callback1.WaitForResult();
758 EXPECT_EQ(OK, error);
759 error = callback2.WaitForResult();
760 EXPECT_EQ(OK, error);
762 // One cert is created, one request is joined.
763 EXPECT_EQ(2U, service_->requests());
764 EXPECT_EQ(1, service_->cert_count());
765 EXPECT_EQ(1u, service_->workers_created());
766 EXPECT_EQ(1u, service_->inflight_joins());
767 EXPECT_FALSE(der_cert1.empty());
768 EXPECT_EQ(der_cert1, der_cert2);
769 EXPECT_FALSE(private_key1.empty());
770 EXPECT_EQ(private_key1, private_key2);
771 EXPECT_FALSE(request_handle1.is_active());
772 EXPECT_FALSE(request_handle2.is_active());
775 #endif // !defined(USE_OPENSSL)