- add sources.
[platform/framework/web/crosswalk.git] / src / net / ssl / server_bound_cert_service_unittest.cc
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.
4
5 #include "net/ssl/server_bound_cert_service.h"
6
7 #include <string>
8 #include <vector>
9
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"
22
23 namespace net {
24
25 namespace {
26
27 void FailTest(int /* result */) {
28   FAIL();
29 }
30
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() {}
37
38   virtual bool PostDelayedTask(const tracked_objects::Location& from_here,
39                                const base::Closure& task,
40                                base::TimeDelta delay) OVERRIDE {
41     return false;
42   }
43
44   virtual bool RunsTasksOnCurrentThread() const OVERRIDE { return true; }
45
46  protected:
47   virtual ~FailingTaskRunner() {}
48
49  private:
50   DISALLOW_COPY_AND_ASSIGN(FailingTaskRunner);
51 };
52
53 class ServerBoundCertServiceTest : public testing::Test {
54  public:
55   ServerBoundCertServiceTest()
56       : service_(new ServerBoundCertService(
57             new DefaultServerBoundCertStore(NULL),
58             base::MessageLoopProxy::current())) {
59   }
60
61  protected:
62   scoped_ptr<ServerBoundCertService> service_;
63 };
64
65 class MockServerBoundCertStoreWithAsyncGet
66     : public DefaultServerBoundCertStore {
67  public:
68   MockServerBoundCertStoreWithAsyncGet()
69       : DefaultServerBoundCertStore(NULL), cert_count_(0) {}
70
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;
76
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 {
82     cert_count_ = 1;
83   }
84
85   virtual int GetCertCount() OVERRIDE { return cert_count_; }
86
87   void CallGetServerBoundCertCallbackWithResult(int err,
88                                                 base::Time expiration_time,
89                                                 const std::string& private_key,
90                                                 const std::string& cert);
91
92  private:
93   GetCertCallback callback_;
94   std::string server_identifier_;
95   int cert_count_;
96 };
97
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.
108   cert_count_ = 0;
109   // Do nothing else: the results to be provided will be specified through
110   // CallGetServerBoundCertCallbackWithResult.
111   return ERR_IO_PENDING;
112 }
113
114 void
115 MockServerBoundCertStoreWithAsyncGet::CallGetServerBoundCertCallbackWithResult(
116     int err,
117     base::Time expiration_time,
118     const std::string& private_key,
119     const std::string& cert) {
120   if (err == OK)
121     cert_count_ = 1;
122   base::MessageLoop::current()->PostTask(FROM_HERE,
123                                          base::Bind(callback_,
124                                                     err,
125                                                     server_identifier_,
126                                                     expiration_time,
127                                                     private_key,
128                                                     cert));
129 }
130
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"));
148 }
149
150 // See http://crbug.com/91512 - implement OpenSSL version of CreateSelfSigned.
151 #if !defined(USE_OPENSSL)
152
153 TEST_F(ServerBoundCertServiceTest, GetCacheMiss) {
154   std::string host("encrypted.google.com");
155
156   int error;
157   TestCompletionCallback callback;
158   ServerBoundCertService::RequestHandle request_handle;
159
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());
169 }
170
171 TEST_F(ServerBoundCertServiceTest, CacheHit) {
172   std::string host("encrypted.google.com");
173
174   int error;
175   TestCompletionCallback callback;
176   ServerBoundCertService::RequestHandle request_handle;
177
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());
192
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);
203
204   // Synchronous get.
205   std::string private_key_info3, der_cert3;
206   error = service_->GetDomainBoundCert(
207       host, &private_key_info3, &der_cert3, callback.callback(),
208       &request_handle);
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);
214
215   EXPECT_EQ(3u, service_->requests());
216   EXPECT_EQ(2u, service_->cert_store_hits());
217   EXPECT_EQ(0u, service_->inflight_joins());
218 }
219
220 TEST_F(ServerBoundCertServiceTest, StoreCerts) {
221   int error;
222   TestCompletionCallback callback;
223   ServerBoundCertService::RequestHandle request_handle;
224
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());
236
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());
247
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());
258
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);
265 }
266
267 // Tests an inflight join.
268 TEST_F(ServerBoundCertServiceTest, InflightJoin) {
269   std::string host("encrypted.google.com");
270   int error;
271
272   std::string private_key_info1, der_cert1;
273   TestCompletionCallback callback1;
274   ServerBoundCertService::RequestHandle request_handle1;
275
276   std::string private_key_info2, der_cert2;
277   TestCompletionCallback callback2;
278   ServerBoundCertService::RequestHandle request_handle2;
279
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());
291
292   error = callback1.WaitForResult();
293   EXPECT_EQ(OK, error);
294   error = callback2.WaitForResult();
295   EXPECT_EQ(OK, error);
296
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());
301 }
302
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");
306   int error;
307
308   std::string private_key_info1, der_cert1;
309   TestCompletionCallback callback1;
310   ServerBoundCertService::RequestHandle request_handle1;
311
312   std::string private_key_info2;
313   std::string der_cert2;
314   TestCompletionCallback callback2;
315   ServerBoundCertService::RequestHandle request_handle2;
316
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(),
325       &request_handle2);
326   EXPECT_EQ(ERR_IO_PENDING, error);
327   EXPECT_TRUE(request_handle2.is_active());
328
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);
334
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());
339 }
340
341 TEST_F(ServerBoundCertServiceTest, ExtractValuesFromBytesEC) {
342   std::string host("encrypted.google.com");
343   std::string private_key_info, der_cert;
344   int error;
345   TestCompletionCallback callback;
346   ServerBoundCertService::RequestHandle request_handle;
347
348   error = service_->GetOrCreateDomainBoundCert(
349       host, &private_key_info, &der_cert, callback.callback(),
350       &request_handle);
351   EXPECT_EQ(ERR_IO_PENDING, error);
352   EXPECT_TRUE(request_handle.is_active());
353   error = callback.WaitForResult();
354   EXPECT_EQ(OK, error);
355
356   base::StringPiece spki_piece;
357   ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(der_cert, &spki_piece));
358   std::vector<uint8> spki(
359       spki_piece.data(),
360       spki_piece.data() + spki_piece.size());
361
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);
368
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);
373 }
374
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;
379   int error;
380   ServerBoundCertService::RequestHandle request_handle;
381
382   error = service_->GetOrCreateDomainBoundCert(host,
383                                                &private_key_info,
384                                                &der_cert,
385                                                base::Bind(&FailTest),
386                                                &request_handle);
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());
391
392   // Wait for reply from ServerBoundCertServiceWorker to be posted back to the
393   // ServerBoundCertService.
394   base::MessageLoop::current()->RunUntilIdle();
395
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());
399 }
400
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;
405   int error;
406   {
407     ServerBoundCertService::RequestHandle request_handle;
408
409     error = service_->GetOrCreateDomainBoundCert(host,
410                                                  &private_key_info,
411                                                  &der_cert,
412                                                  base::Bind(&FailTest),
413                                                  &request_handle);
414     EXPECT_EQ(ERR_IO_PENDING, error);
415     EXPECT_TRUE(request_handle.is_active());
416   }
417
418   // Wait for reply from ServerBoundCertServiceWorker to be posted back to the
419   // ServerBoundCertService.
420   base::MessageLoop::current()->RunUntilIdle();
421
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());
425 }
426
427 TEST_F(ServerBoundCertServiceTest, DestructionWithPendingRequest) {
428   std::string host("encrypted.google.com");
429   std::string private_key_info, der_cert;
430   int error;
431   ServerBoundCertService::RequestHandle request_handle;
432
433   error = service_->GetOrCreateDomainBoundCert(host,
434                                                &private_key_info,
435                                                &der_cert,
436                                                base::Bind(&FailTest),
437                                                &request_handle);
438   EXPECT_EQ(ERR_IO_PENDING, error);
439   EXPECT_TRUE(request_handle.is_active());
440
441   // Cancel request and destroy the ServerBoundCertService.
442   request_handle.Cancel();
443   service_.reset();
444
445   // ServerBoundCertServiceWorker should not post anything back to the
446   // non-existent ServerBoundCertService, but run the loop just to be sure it
447   // doesn't.
448   base::MessageLoop::current()->RunUntilIdle();
449
450   // If we got here without crashing or a valgrind error, it worked.
451 }
452
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));
460
461   // Make a request that will force synchronous completion.
462   std::string host("encrypted.google.com");
463   std::string private_key_info, der_cert;
464   int error;
465   ServerBoundCertService::RequestHandle request_handle;
466
467   error = service_->GetOrCreateDomainBoundCert(host,
468                                                &private_key_info,
469                                                &der_cert,
470                                                base::Bind(&FailTest),
471                                                &request_handle);
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());
475 }
476
477 // Tests that simultaneous creation of different certs works.
478 TEST_F(ServerBoundCertServiceTest, SimultaneousCreation) {
479   int error;
480
481   std::string host1("encrypted.google.com");
482   std::string private_key_info1, der_cert1;
483   TestCompletionCallback callback1;
484   ServerBoundCertService::RequestHandle request_handle1;
485
486   std::string host2("foo.com");
487   std::string private_key_info2, der_cert2;
488   TestCompletionCallback callback2;
489   ServerBoundCertService::RequestHandle request_handle2;
490
491   std::string host3("bar.com");
492   std::string private_key_info3, der_cert3;
493   TestCompletionCallback callback3;
494   ServerBoundCertService::RequestHandle request_handle3;
495
496   error = service_->GetOrCreateDomainBoundCert(host1,
497                                                &private_key_info1,
498                                                &der_cert1,
499                                                callback1.callback(),
500                                                &request_handle1);
501   EXPECT_EQ(ERR_IO_PENDING, error);
502   EXPECT_TRUE(request_handle1.is_active());
503
504   error = service_->GetOrCreateDomainBoundCert(host2,
505                                                &private_key_info2,
506                                                &der_cert2,
507                                                callback2.callback(),
508                                                &request_handle2);
509   EXPECT_EQ(ERR_IO_PENDING, error);
510   EXPECT_TRUE(request_handle2.is_active());
511
512   error = service_->GetOrCreateDomainBoundCert(host3,
513                                                &private_key_info3,
514                                                &der_cert3,
515                                                callback3.callback(),
516                                                &request_handle3);
517   EXPECT_EQ(ERR_IO_PENDING, error);
518   EXPECT_TRUE(request_handle3.is_active());
519
520   error = callback1.WaitForResult();
521   EXPECT_EQ(OK, error);
522   EXPECT_FALSE(private_key_info1.empty());
523   EXPECT_FALSE(der_cert1.empty());
524
525   error = callback2.WaitForResult();
526   EXPECT_EQ(OK, error);
527   EXPECT_FALSE(private_key_info2.empty());
528   EXPECT_FALSE(der_cert2.empty());
529
530   error = callback3.WaitForResult();
531   EXPECT_EQ(OK, error);
532   EXPECT_FALSE(private_key_info3.empty());
533   EXPECT_FALSE(der_cert3.empty());
534
535   EXPECT_NE(private_key_info1, private_key_info2);
536   EXPECT_NE(der_cert1, der_cert2);
537
538   EXPECT_NE(private_key_info1, private_key_info3);
539   EXPECT_NE(der_cert1, der_cert3);
540
541   EXPECT_NE(private_key_info2, private_key_info3);
542   EXPECT_NE(der_cert2, der_cert3);
543
544   EXPECT_EQ(3, service_->cert_count());
545 }
546
547 TEST_F(ServerBoundCertServiceTest, Expiration) {
548   ServerBoundCertStore* store = service_->GetCertStore();
549   base::Time now = base::Time::Now();
550   store->SetServerBoundCert("good",
551                             now,
552                             now + base::TimeDelta::FromDays(1),
553                             "a",
554                             "b");
555   store->SetServerBoundCert("expired",
556                             now - base::TimeDelta::FromDays(2),
557                             now - base::TimeDelta::FromDays(1),
558                             "c",
559                             "d");
560   EXPECT_EQ(2, service_->cert_count());
561
562   int error;
563   TestCompletionCallback callback;
564   ServerBoundCertService::RequestHandle request_handle;
565
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());
576
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());
587 }
588
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()));
594
595   std::string host("encrypted.google.com");
596
597   int error;
598   TestCompletionCallback callback;
599   ServerBoundCertService::RequestHandle request_handle;
600
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());
608
609   mock_store->CallGetServerBoundCertCallbackWithResult(
610       ERR_FILE_NOT_FOUND, base::Time(), std::string(), std::string());
611
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());
618 }
619
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()));
625
626   std::string host("encrypted.google.com");
627
628   int error;
629   TestCompletionCallback callback;
630   ServerBoundCertService::RequestHandle request_handle;
631
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());
639
640   mock_store->CallGetServerBoundCertCallbackWithResult(
641       ERR_FILE_NOT_FOUND, base::Time(), std::string(), std::string());
642
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());
649 }
650
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()));
656
657   std::string host("encrypted.google.com");
658
659   int error;
660   TestCompletionCallback callback;
661   ServerBoundCertService::RequestHandle request_handle;
662
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());
670
671   mock_store->CallGetServerBoundCertCallbackWithResult(
672       OK, base::Time(), "ab", "cd");
673
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
680   // created.
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());
685 }
686
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()));
692
693   std::string host("encrypted.google.com");
694
695   int error;
696   TestCompletionCallback callback;
697   ServerBoundCertService::RequestHandle request_handle;
698
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());
706
707   mock_store->CallGetServerBoundCertCallbackWithResult(
708       OK, base::Time(), "ab", "cd");
709
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
716   // created.
717   EXPECT_EQ(0u, service_->workers_created());
718   EXPECT_STREQ("cd", der_cert.c_str());
719   EXPECT_FALSE(request_handle.is_active());
720 }
721
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()));
727
728   std::string host("encrypted.google.com");
729
730   int error;
731
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());
741
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());
751
752   mock_store->CallGetServerBoundCertCallbackWithResult(
753       ERR_FILE_NOT_FOUND, base::Time(), std::string(), std::string());
754
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);
761
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());
773 }
774
775 #endif  // !defined(USE_OPENSSL)
776
777 }  // namespace
778
779 }  // namespace net