Lots of random cleanups, mostly for native_theme_win.cc:
[chromium-blink-merge.git] / net / ssl / server_bound_cert_service_unittest.cc
blob2be073bb16c3b930dda083c631a3116970eab6b8
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 void FailTest(int /* result */) {
28 FAIL();
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
33 // add new tasks.
34 class FailingTaskRunner : public base::TaskRunner {
35 public:
36 FailingTaskRunner() {}
38 virtual bool PostDelayedTask(const tracked_objects::Location& from_here,
39 const base::Closure& task,
40 base::TimeDelta delay) OVERRIDE {
41 return false;
44 virtual bool RunsTasksOnCurrentThread() const OVERRIDE { return true; }
46 protected:
47 virtual ~FailingTaskRunner() {}
49 private:
50 DISALLOW_COPY_AND_ASSIGN(FailingTaskRunner);
53 class MockServerBoundCertStoreWithAsyncGet
54 : public DefaultServerBoundCertStore {
55 public:
56 MockServerBoundCertStoreWithAsyncGet()
57 : DefaultServerBoundCertStore(NULL), cert_count_(0) {}
59 virtual int GetServerBoundCert(const std::string& server_identifier,
60 base::Time* expiration_time,
61 std::string* private_key_result,
62 std::string* cert_result,
63 const GetCertCallback& callback) OVERRIDE;
65 virtual void SetServerBoundCert(const std::string& server_identifier,
66 base::Time creation_time,
67 base::Time expiration_time,
68 const std::string& private_key,
69 const std::string& cert) OVERRIDE {
70 cert_count_ = 1;
73 virtual int GetCertCount() OVERRIDE { return cert_count_; }
75 void CallGetServerBoundCertCallbackWithResult(int err,
76 base::Time expiration_time,
77 const std::string& private_key,
78 const std::string& cert);
80 private:
81 GetCertCallback callback_;
82 std::string server_identifier_;
83 int cert_count_;
86 int MockServerBoundCertStoreWithAsyncGet::GetServerBoundCert(
87 const std::string& server_identifier,
88 base::Time* expiration_time,
89 std::string* private_key_result,
90 std::string* cert_result,
91 const GetCertCallback& callback) {
92 server_identifier_ = server_identifier;
93 callback_ = callback;
94 // Reset the cert count, it'll get incremented in either SetServerBoundCert or
95 // CallGetServerBoundCertCallbackWithResult.
96 cert_count_ = 0;
97 // Do nothing else: the results to be provided will be specified through
98 // CallGetServerBoundCertCallbackWithResult.
99 return ERR_IO_PENDING;
102 void
103 MockServerBoundCertStoreWithAsyncGet::CallGetServerBoundCertCallbackWithResult(
104 int err,
105 base::Time expiration_time,
106 const std::string& private_key,
107 const std::string& cert) {
108 if (err == OK)
109 cert_count_ = 1;
110 base::MessageLoop::current()->PostTask(FROM_HERE,
111 base::Bind(callback_,
112 err,
113 server_identifier_,
114 expiration_time,
115 private_key,
116 cert));
119 class ServerBoundCertServiceTest : public testing::Test {
120 public:
121 ServerBoundCertServiceTest()
122 : service_(new ServerBoundCertService(
123 new DefaultServerBoundCertStore(NULL),
124 base::MessageLoopProxy::current())) {
127 protected:
128 scoped_ptr<ServerBoundCertService> service_;
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"));
144 EXPECT_EQ("goto",
145 ServerBoundCertService::GetDomainForHost("goto"));
146 EXPECT_EQ("127.0.0.1",
147 ServerBoundCertService::GetDomainForHost("127.0.0.1"));
150 TEST_F(ServerBoundCertServiceTest, GetCacheMiss) {
151 std::string host("encrypted.google.com");
153 int error;
154 TestCompletionCallback callback;
155 ServerBoundCertService::RequestHandle request_handle;
157 // Synchronous completion, because the store is initialized.
158 std::string private_key, der_cert;
159 EXPECT_EQ(0, service_->cert_count());
160 error = service_->GetDomainBoundCert(
161 host, &private_key, &der_cert, callback.callback(), &request_handle);
162 EXPECT_EQ(ERR_FILE_NOT_FOUND, error);
163 EXPECT_FALSE(request_handle.is_active());
164 EXPECT_EQ(0, service_->cert_count());
165 EXPECT_TRUE(der_cert.empty());
168 TEST_F(ServerBoundCertServiceTest, CacheHit) {
169 std::string host("encrypted.google.com");
171 int error;
172 TestCompletionCallback callback;
173 ServerBoundCertService::RequestHandle request_handle;
175 // Asynchronous completion.
176 std::string private_key_info1, der_cert1;
177 EXPECT_EQ(0, service_->cert_count());
178 error = service_->GetOrCreateDomainBoundCert(
179 host, &private_key_info1, &der_cert1,
180 callback.callback(), &request_handle);
181 EXPECT_EQ(ERR_IO_PENDING, error);
182 EXPECT_TRUE(request_handle.is_active());
183 error = callback.WaitForResult();
184 EXPECT_EQ(OK, error);
185 EXPECT_EQ(1, service_->cert_count());
186 EXPECT_FALSE(private_key_info1.empty());
187 EXPECT_FALSE(der_cert1.empty());
188 EXPECT_FALSE(request_handle.is_active());
190 // Synchronous completion.
191 std::string private_key_info2, der_cert2;
192 error = service_->GetOrCreateDomainBoundCert(
193 host, &private_key_info2, &der_cert2,
194 callback.callback(), &request_handle);
195 EXPECT_FALSE(request_handle.is_active());
196 EXPECT_EQ(OK, error);
197 EXPECT_EQ(1, service_->cert_count());
198 EXPECT_EQ(private_key_info1, private_key_info2);
199 EXPECT_EQ(der_cert1, der_cert2);
201 // Synchronous get.
202 std::string private_key_info3, der_cert3;
203 error = service_->GetDomainBoundCert(
204 host, &private_key_info3, &der_cert3, callback.callback(),
205 &request_handle);
206 EXPECT_FALSE(request_handle.is_active());
207 EXPECT_EQ(OK, error);
208 EXPECT_EQ(1, service_->cert_count());
209 EXPECT_EQ(der_cert1, der_cert3);
210 EXPECT_EQ(private_key_info1, private_key_info3);
212 EXPECT_EQ(3u, service_->requests());
213 EXPECT_EQ(2u, service_->cert_store_hits());
214 EXPECT_EQ(0u, service_->inflight_joins());
217 TEST_F(ServerBoundCertServiceTest, StoreCerts) {
218 int error;
219 TestCompletionCallback callback;
220 ServerBoundCertService::RequestHandle request_handle;
222 std::string host1("encrypted.google.com");
223 std::string private_key_info1, der_cert1;
224 EXPECT_EQ(0, service_->cert_count());
225 error = service_->GetOrCreateDomainBoundCert(
226 host1, &private_key_info1, &der_cert1,
227 callback.callback(), &request_handle);
228 EXPECT_EQ(ERR_IO_PENDING, error);
229 EXPECT_TRUE(request_handle.is_active());
230 error = callback.WaitForResult();
231 EXPECT_EQ(OK, error);
232 EXPECT_EQ(1, service_->cert_count());
234 std::string host2("www.verisign.com");
235 std::string private_key_info2, der_cert2;
236 error = service_->GetOrCreateDomainBoundCert(
237 host2, &private_key_info2, &der_cert2,
238 callback.callback(), &request_handle);
239 EXPECT_EQ(ERR_IO_PENDING, error);
240 EXPECT_TRUE(request_handle.is_active());
241 error = callback.WaitForResult();
242 EXPECT_EQ(OK, error);
243 EXPECT_EQ(2, service_->cert_count());
245 std::string host3("www.twitter.com");
246 std::string private_key_info3, der_cert3;
247 error = service_->GetOrCreateDomainBoundCert(
248 host3, &private_key_info3, &der_cert3,
249 callback.callback(), &request_handle);
250 EXPECT_EQ(ERR_IO_PENDING, error);
251 EXPECT_TRUE(request_handle.is_active());
252 error = callback.WaitForResult();
253 EXPECT_EQ(OK, error);
254 EXPECT_EQ(3, service_->cert_count());
256 EXPECT_NE(private_key_info1, private_key_info2);
257 EXPECT_NE(der_cert1, der_cert2);
258 EXPECT_NE(private_key_info1, private_key_info3);
259 EXPECT_NE(der_cert1, der_cert3);
260 EXPECT_NE(private_key_info2, private_key_info3);
261 EXPECT_NE(der_cert2, der_cert3);
264 // Tests an inflight join.
265 TEST_F(ServerBoundCertServiceTest, InflightJoin) {
266 std::string host("encrypted.google.com");
267 int error;
269 std::string private_key_info1, der_cert1;
270 TestCompletionCallback callback1;
271 ServerBoundCertService::RequestHandle request_handle1;
273 std::string private_key_info2, der_cert2;
274 TestCompletionCallback callback2;
275 ServerBoundCertService::RequestHandle request_handle2;
277 error = service_->GetOrCreateDomainBoundCert(
278 host, &private_key_info1, &der_cert1,
279 callback1.callback(), &request_handle1);
280 EXPECT_EQ(ERR_IO_PENDING, error);
281 EXPECT_TRUE(request_handle1.is_active());
282 // Should join with the original request.
283 error = service_->GetOrCreateDomainBoundCert(
284 host, &private_key_info2, &der_cert2,
285 callback2.callback(), &request_handle2);
286 EXPECT_EQ(ERR_IO_PENDING, error);
287 EXPECT_TRUE(request_handle2.is_active());
289 error = callback1.WaitForResult();
290 EXPECT_EQ(OK, error);
291 error = callback2.WaitForResult();
292 EXPECT_EQ(OK, error);
294 EXPECT_EQ(2u, service_->requests());
295 EXPECT_EQ(0u, service_->cert_store_hits());
296 EXPECT_EQ(1u, service_->inflight_joins());
297 EXPECT_EQ(1u, service_->workers_created());
300 // Tests an inflight join of a Get request to a GetOrCreate request.
301 TEST_F(ServerBoundCertServiceTest, InflightJoinGetOrCreateAndGet) {
302 std::string host("encrypted.google.com");
303 int error;
305 std::string private_key_info1, der_cert1;
306 TestCompletionCallback callback1;
307 ServerBoundCertService::RequestHandle request_handle1;
309 std::string private_key_info2;
310 std::string der_cert2;
311 TestCompletionCallback callback2;
312 ServerBoundCertService::RequestHandle request_handle2;
314 error = service_->GetOrCreateDomainBoundCert(
315 host, &private_key_info1, &der_cert1,
316 callback1.callback(), &request_handle1);
317 EXPECT_EQ(ERR_IO_PENDING, error);
318 EXPECT_TRUE(request_handle1.is_active());
319 // Should join with the original request.
320 error = service_->GetDomainBoundCert(
321 host, &private_key_info2, &der_cert2, callback2.callback(),
322 &request_handle2);
323 EXPECT_EQ(ERR_IO_PENDING, error);
324 EXPECT_TRUE(request_handle2.is_active());
326 error = callback1.WaitForResult();
327 EXPECT_EQ(OK, error);
328 error = callback2.WaitForResult();
329 EXPECT_EQ(OK, error);
330 EXPECT_EQ(der_cert1, der_cert2);
332 EXPECT_EQ(2u, service_->requests());
333 EXPECT_EQ(0u, service_->cert_store_hits());
334 EXPECT_EQ(1u, service_->inflight_joins());
335 EXPECT_EQ(1u, service_->workers_created());
338 TEST_F(ServerBoundCertServiceTest, ExtractValuesFromBytesEC) {
339 std::string host("encrypted.google.com");
340 std::string private_key_info, der_cert;
341 int error;
342 TestCompletionCallback callback;
343 ServerBoundCertService::RequestHandle request_handle;
345 error = service_->GetOrCreateDomainBoundCert(
346 host, &private_key_info, &der_cert, callback.callback(),
347 &request_handle);
348 EXPECT_EQ(ERR_IO_PENDING, error);
349 EXPECT_TRUE(request_handle.is_active());
350 error = callback.WaitForResult();
351 EXPECT_EQ(OK, error);
353 base::StringPiece spki_piece;
354 ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(der_cert, &spki_piece));
355 std::vector<uint8> spki(
356 spki_piece.data(),
357 spki_piece.data() + spki_piece.size());
359 // Check that we can retrieve the key from the bytes.
360 std::vector<uint8> key_vec(private_key_info.begin(), private_key_info.end());
361 scoped_ptr<crypto::ECPrivateKey> private_key(
362 crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo(
363 ServerBoundCertService::kEPKIPassword, key_vec, spki));
364 EXPECT_TRUE(private_key != NULL);
366 // Check that we can retrieve the cert from the bytes.
367 scoped_refptr<X509Certificate> x509cert(
368 X509Certificate::CreateFromBytes(der_cert.data(), der_cert.size()));
369 EXPECT_TRUE(x509cert.get() != NULL);
372 // Tests that the callback of a canceled request is never made.
373 TEST_F(ServerBoundCertServiceTest, CancelRequest) {
374 std::string host("encrypted.google.com");
375 std::string private_key_info, der_cert;
376 int error;
377 ServerBoundCertService::RequestHandle request_handle;
379 error = service_->GetOrCreateDomainBoundCert(host,
380 &private_key_info,
381 &der_cert,
382 base::Bind(&FailTest),
383 &request_handle);
384 EXPECT_EQ(ERR_IO_PENDING, error);
385 EXPECT_TRUE(request_handle.is_active());
386 request_handle.Cancel();
387 EXPECT_FALSE(request_handle.is_active());
389 // Wait for reply from ServerBoundCertServiceWorker to be posted back to the
390 // ServerBoundCertService.
391 base::MessageLoop::current()->RunUntilIdle();
393 // Even though the original request was cancelled, the service will still
394 // store the result, it just doesn't call the callback.
395 EXPECT_EQ(1, service_->cert_count());
398 // Tests that destructing the RequestHandle cancels the request.
399 TEST_F(ServerBoundCertServiceTest, CancelRequestByHandleDestruction) {
400 std::string host("encrypted.google.com");
401 std::string private_key_info, der_cert;
402 int error;
404 ServerBoundCertService::RequestHandle request_handle;
406 error = service_->GetOrCreateDomainBoundCert(host,
407 &private_key_info,
408 &der_cert,
409 base::Bind(&FailTest),
410 &request_handle);
411 EXPECT_EQ(ERR_IO_PENDING, error);
412 EXPECT_TRUE(request_handle.is_active());
415 // Wait for reply from ServerBoundCertServiceWorker to be posted back to the
416 // ServerBoundCertService.
417 base::MessageLoop::current()->RunUntilIdle();
419 // Even though the original request was cancelled, the service will still
420 // store the result, it just doesn't call the callback.
421 EXPECT_EQ(1, service_->cert_count());
424 TEST_F(ServerBoundCertServiceTest, DestructionWithPendingRequest) {
425 std::string host("encrypted.google.com");
426 std::string private_key_info, der_cert;
427 int error;
428 ServerBoundCertService::RequestHandle request_handle;
430 error = service_->GetOrCreateDomainBoundCert(host,
431 &private_key_info,
432 &der_cert,
433 base::Bind(&FailTest),
434 &request_handle);
435 EXPECT_EQ(ERR_IO_PENDING, error);
436 EXPECT_TRUE(request_handle.is_active());
438 // Cancel request and destroy the ServerBoundCertService.
439 request_handle.Cancel();
440 service_.reset();
442 // ServerBoundCertServiceWorker should not post anything back to the
443 // non-existent ServerBoundCertService, but run the loop just to be sure it
444 // doesn't.
445 base::MessageLoop::current()->RunUntilIdle();
447 // If we got here without crashing or a valgrind error, it worked.
450 // Tests that shutting down the sequenced worker pool and then making new
451 // requests gracefully fails.
452 // This is a regression test for http://crbug.com/236387
453 TEST_F(ServerBoundCertServiceTest, RequestAfterPoolShutdown) {
454 scoped_refptr<FailingTaskRunner> task_runner(new FailingTaskRunner);
455 service_.reset(new ServerBoundCertService(
456 new DefaultServerBoundCertStore(NULL), task_runner));
458 // Make a request that will force synchronous completion.
459 std::string host("encrypted.google.com");
460 std::string private_key_info, der_cert;
461 int error;
462 ServerBoundCertService::RequestHandle request_handle;
464 error = service_->GetOrCreateDomainBoundCert(host,
465 &private_key_info,
466 &der_cert,
467 base::Bind(&FailTest),
468 &request_handle);
469 // If we got here without crashing or a valgrind error, it worked.
470 ASSERT_EQ(ERR_INSUFFICIENT_RESOURCES, error);
471 EXPECT_FALSE(request_handle.is_active());
474 // Tests that simultaneous creation of different certs works.
475 TEST_F(ServerBoundCertServiceTest, SimultaneousCreation) {
476 int error;
478 std::string host1("encrypted.google.com");
479 std::string private_key_info1, der_cert1;
480 TestCompletionCallback callback1;
481 ServerBoundCertService::RequestHandle request_handle1;
483 std::string host2("foo.com");
484 std::string private_key_info2, der_cert2;
485 TestCompletionCallback callback2;
486 ServerBoundCertService::RequestHandle request_handle2;
488 std::string host3("bar.com");
489 std::string private_key_info3, der_cert3;
490 TestCompletionCallback callback3;
491 ServerBoundCertService::RequestHandle request_handle3;
493 error = service_->GetOrCreateDomainBoundCert(host1,
494 &private_key_info1,
495 &der_cert1,
496 callback1.callback(),
497 &request_handle1);
498 EXPECT_EQ(ERR_IO_PENDING, error);
499 EXPECT_TRUE(request_handle1.is_active());
501 error = service_->GetOrCreateDomainBoundCert(host2,
502 &private_key_info2,
503 &der_cert2,
504 callback2.callback(),
505 &request_handle2);
506 EXPECT_EQ(ERR_IO_PENDING, error);
507 EXPECT_TRUE(request_handle2.is_active());
509 error = service_->GetOrCreateDomainBoundCert(host3,
510 &private_key_info3,
511 &der_cert3,
512 callback3.callback(),
513 &request_handle3);
514 EXPECT_EQ(ERR_IO_PENDING, error);
515 EXPECT_TRUE(request_handle3.is_active());
517 error = callback1.WaitForResult();
518 EXPECT_EQ(OK, error);
519 EXPECT_FALSE(private_key_info1.empty());
520 EXPECT_FALSE(der_cert1.empty());
522 error = callback2.WaitForResult();
523 EXPECT_EQ(OK, error);
524 EXPECT_FALSE(private_key_info2.empty());
525 EXPECT_FALSE(der_cert2.empty());
527 error = callback3.WaitForResult();
528 EXPECT_EQ(OK, error);
529 EXPECT_FALSE(private_key_info3.empty());
530 EXPECT_FALSE(der_cert3.empty());
532 EXPECT_NE(private_key_info1, private_key_info2);
533 EXPECT_NE(der_cert1, der_cert2);
535 EXPECT_NE(private_key_info1, private_key_info3);
536 EXPECT_NE(der_cert1, der_cert3);
538 EXPECT_NE(private_key_info2, private_key_info3);
539 EXPECT_NE(der_cert2, der_cert3);
541 EXPECT_EQ(3, service_->cert_count());
544 TEST_F(ServerBoundCertServiceTest, Expiration) {
545 ServerBoundCertStore* store = service_->GetCertStore();
546 base::Time now = base::Time::Now();
547 store->SetServerBoundCert("good",
548 now,
549 now + base::TimeDelta::FromDays(1),
550 "a",
551 "b");
552 store->SetServerBoundCert("expired",
553 now - base::TimeDelta::FromDays(2),
554 now - base::TimeDelta::FromDays(1),
555 "c",
556 "d");
557 EXPECT_EQ(2, service_->cert_count());
559 int error;
560 TestCompletionCallback callback;
561 ServerBoundCertService::RequestHandle request_handle;
563 // Cert is valid - synchronous completion.
564 std::string private_key_info1, der_cert1;
565 error = service_->GetOrCreateDomainBoundCert(
566 "good", &private_key_info1, &der_cert1,
567 callback.callback(), &request_handle);
568 EXPECT_EQ(OK, error);
569 EXPECT_FALSE(request_handle.is_active());
570 EXPECT_EQ(2, service_->cert_count());
571 EXPECT_STREQ("a", private_key_info1.c_str());
572 EXPECT_STREQ("b", der_cert1.c_str());
574 // Expired cert is valid as well - synchronous completion.
575 std::string private_key_info2, der_cert2;
576 error = service_->GetOrCreateDomainBoundCert(
577 "expired", &private_key_info2, &der_cert2,
578 callback.callback(), &request_handle);
579 EXPECT_EQ(OK, error);
580 EXPECT_FALSE(request_handle.is_active());
581 EXPECT_EQ(2, service_->cert_count());
582 EXPECT_STREQ("c", private_key_info2.c_str());
583 EXPECT_STREQ("d", der_cert2.c_str());
586 TEST_F(ServerBoundCertServiceTest, AsyncStoreGetOrCreateNoCertsInStore) {
587 MockServerBoundCertStoreWithAsyncGet* mock_store =
588 new MockServerBoundCertStoreWithAsyncGet();
589 service_ = scoped_ptr<ServerBoundCertService>(new ServerBoundCertService(
590 mock_store, base::MessageLoopProxy::current()));
592 std::string host("encrypted.google.com");
594 int error;
595 TestCompletionCallback callback;
596 ServerBoundCertService::RequestHandle request_handle;
598 // Asynchronous completion with no certs in the store.
599 std::string private_key_info, der_cert;
600 EXPECT_EQ(0, service_->cert_count());
601 error = service_->GetOrCreateDomainBoundCert(
602 host, &private_key_info, &der_cert, callback.callback(), &request_handle);
603 EXPECT_EQ(ERR_IO_PENDING, error);
604 EXPECT_TRUE(request_handle.is_active());
606 mock_store->CallGetServerBoundCertCallbackWithResult(
607 ERR_FILE_NOT_FOUND, base::Time(), std::string(), std::string());
609 error = callback.WaitForResult();
610 EXPECT_EQ(OK, error);
611 EXPECT_EQ(1, service_->cert_count());
612 EXPECT_FALSE(private_key_info.empty());
613 EXPECT_FALSE(der_cert.empty());
614 EXPECT_FALSE(request_handle.is_active());
617 TEST_F(ServerBoundCertServiceTest, AsyncStoreGetNoCertsInStore) {
618 MockServerBoundCertStoreWithAsyncGet* mock_store =
619 new MockServerBoundCertStoreWithAsyncGet();
620 service_ = scoped_ptr<ServerBoundCertService>(new ServerBoundCertService(
621 mock_store, base::MessageLoopProxy::current()));
623 std::string host("encrypted.google.com");
625 int error;
626 TestCompletionCallback callback;
627 ServerBoundCertService::RequestHandle request_handle;
629 // Asynchronous completion with no certs in the store.
630 std::string private_key, der_cert;
631 EXPECT_EQ(0, service_->cert_count());
632 error = service_->GetDomainBoundCert(
633 host, &private_key, &der_cert, callback.callback(), &request_handle);
634 EXPECT_EQ(ERR_IO_PENDING, error);
635 EXPECT_TRUE(request_handle.is_active());
637 mock_store->CallGetServerBoundCertCallbackWithResult(
638 ERR_FILE_NOT_FOUND, base::Time(), std::string(), std::string());
640 error = callback.WaitForResult();
641 EXPECT_EQ(ERR_FILE_NOT_FOUND, error);
642 EXPECT_EQ(0, service_->cert_count());
643 EXPECT_EQ(0u, service_->workers_created());
644 EXPECT_TRUE(der_cert.empty());
645 EXPECT_FALSE(request_handle.is_active());
648 TEST_F(ServerBoundCertServiceTest, AsyncStoreGetOrCreateOneCertInStore) {
649 MockServerBoundCertStoreWithAsyncGet* mock_store =
650 new MockServerBoundCertStoreWithAsyncGet();
651 service_ = scoped_ptr<ServerBoundCertService>(new ServerBoundCertService(
652 mock_store, base::MessageLoopProxy::current()));
654 std::string host("encrypted.google.com");
656 int error;
657 TestCompletionCallback callback;
658 ServerBoundCertService::RequestHandle request_handle;
660 // Asynchronous completion with a cert in the store.
661 std::string private_key_info, der_cert;
662 EXPECT_EQ(0, service_->cert_count());
663 error = service_->GetOrCreateDomainBoundCert(
664 host, &private_key_info, &der_cert, callback.callback(), &request_handle);
665 EXPECT_EQ(ERR_IO_PENDING, error);
666 EXPECT_TRUE(request_handle.is_active());
668 mock_store->CallGetServerBoundCertCallbackWithResult(
669 OK, base::Time(), "ab", "cd");
671 error = callback.WaitForResult();
672 EXPECT_EQ(OK, error);
673 EXPECT_EQ(1, service_->cert_count());
674 EXPECT_EQ(1u, service_->requests());
675 EXPECT_EQ(1u, service_->cert_store_hits());
676 // Because the cert was found in the store, no new workers should have been
677 // created.
678 EXPECT_EQ(0u, service_->workers_created());
679 EXPECT_STREQ("ab", private_key_info.c_str());
680 EXPECT_STREQ("cd", der_cert.c_str());
681 EXPECT_FALSE(request_handle.is_active());
684 TEST_F(ServerBoundCertServiceTest, AsyncStoreGetOneCertInStore) {
685 MockServerBoundCertStoreWithAsyncGet* mock_store =
686 new MockServerBoundCertStoreWithAsyncGet();
687 service_ = scoped_ptr<ServerBoundCertService>(new ServerBoundCertService(
688 mock_store, base::MessageLoopProxy::current()));
690 std::string host("encrypted.google.com");
692 int error;
693 TestCompletionCallback callback;
694 ServerBoundCertService::RequestHandle request_handle;
696 // Asynchronous completion with a cert in the store.
697 std::string private_key, der_cert;
698 EXPECT_EQ(0, service_->cert_count());
699 error = service_->GetDomainBoundCert(
700 host, &private_key, &der_cert, callback.callback(), &request_handle);
701 EXPECT_EQ(ERR_IO_PENDING, error);
702 EXPECT_TRUE(request_handle.is_active());
704 mock_store->CallGetServerBoundCertCallbackWithResult(
705 OK, base::Time(), "ab", "cd");
707 error = callback.WaitForResult();
708 EXPECT_EQ(OK, error);
709 EXPECT_EQ(1, service_->cert_count());
710 EXPECT_EQ(1u, service_->requests());
711 EXPECT_EQ(1u, service_->cert_store_hits());
712 // Because the cert was found in the store, no new workers should have been
713 // created.
714 EXPECT_EQ(0u, service_->workers_created());
715 EXPECT_STREQ("cd", der_cert.c_str());
716 EXPECT_FALSE(request_handle.is_active());
719 TEST_F(ServerBoundCertServiceTest, AsyncStoreGetThenCreateNoCertsInStore) {
720 MockServerBoundCertStoreWithAsyncGet* mock_store =
721 new MockServerBoundCertStoreWithAsyncGet();
722 service_ = scoped_ptr<ServerBoundCertService>(new ServerBoundCertService(
723 mock_store, base::MessageLoopProxy::current()));
725 std::string host("encrypted.google.com");
727 int error;
729 // Asynchronous get with no certs in the store.
730 TestCompletionCallback callback1;
731 ServerBoundCertService::RequestHandle request_handle1;
732 std::string private_key1, der_cert1;
733 EXPECT_EQ(0, service_->cert_count());
734 error = service_->GetDomainBoundCert(
735 host, &private_key1, &der_cert1, callback1.callback(), &request_handle1);
736 EXPECT_EQ(ERR_IO_PENDING, error);
737 EXPECT_TRUE(request_handle1.is_active());
739 // Asynchronous get/create with no certs in the store.
740 TestCompletionCallback callback2;
741 ServerBoundCertService::RequestHandle request_handle2;
742 std::string private_key2, der_cert2;
743 EXPECT_EQ(0, service_->cert_count());
744 error = service_->GetOrCreateDomainBoundCert(
745 host, &private_key2, &der_cert2, callback2.callback(), &request_handle2);
746 EXPECT_EQ(ERR_IO_PENDING, error);
747 EXPECT_TRUE(request_handle2.is_active());
749 mock_store->CallGetServerBoundCertCallbackWithResult(
750 ERR_FILE_NOT_FOUND, base::Time(), std::string(), std::string());
752 // Even though the first request didn't ask to create a cert, it gets joined
753 // by the second, which does, so both succeed.
754 error = callback1.WaitForResult();
755 EXPECT_EQ(OK, error);
756 error = callback2.WaitForResult();
757 EXPECT_EQ(OK, error);
759 // One cert is created, one request is joined.
760 EXPECT_EQ(2U, service_->requests());
761 EXPECT_EQ(1, service_->cert_count());
762 EXPECT_EQ(1u, service_->workers_created());
763 EXPECT_EQ(1u, service_->inflight_joins());
764 EXPECT_FALSE(der_cert1.empty());
765 EXPECT_EQ(der_cert1, der_cert2);
766 EXPECT_FALSE(private_key1.empty());
767 EXPECT_EQ(private_key1, private_key2);
768 EXPECT_FALSE(request_handle1.is_active());
769 EXPECT_FALSE(request_handle2.is_active());
772 } // namespace
774 } // namespace net