Home | History | Annotate | Download | only in ssl
      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 #if !defined(USE_OPENSSL)
     28 void FailTest(int /* result */) {
     29   FAIL();
     30 }
     31 
     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() {}
     38 
     39   virtual bool PostDelayedTask(const tracked_objects::Location& from_here,
     40                                const base::Closure& task,
     41                                base::TimeDelta delay) OVERRIDE {
     42     return false;
     43   }
     44 
     45   virtual bool RunsTasksOnCurrentThread() const OVERRIDE { return true; }
     46 
     47  protected:
     48   virtual ~FailingTaskRunner() {}
     49 
     50  private:
     51   DISALLOW_COPY_AND_ASSIGN(FailingTaskRunner);
     52 };
     53 
     54 class MockServerBoundCertStoreWithAsyncGet
     55     : public DefaultServerBoundCertStore {
     56  public:
     57   MockServerBoundCertStoreWithAsyncGet()
     58       : DefaultServerBoundCertStore(NULL), cert_count_(0) {}
     59 
     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;
     65 
     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;
     72   }
     73 
     74   virtual int GetCertCount() OVERRIDE { return cert_count_; }
     75 
     76   void CallGetServerBoundCertCallbackWithResult(int err,
     77                                                 base::Time expiration_time,
     78                                                 const std::string& private_key,
     79                                                 const std::string& cert);
     80 
     81  private:
     82   GetCertCallback callback_;
     83   std::string server_identifier_;
     84   int cert_count_;
     85 };
     86 
     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;
    101 }
    102 
    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));
    118 }
    119 
    120 #endif  // !defined(USE_OPENSSL)
    121 
    122 class ServerBoundCertServiceTest : public testing::Test {
    123  public:
    124   ServerBoundCertServiceTest()
    125       : service_(new ServerBoundCertService(
    126             new DefaultServerBoundCertStore(NULL),
    127             base::MessageLoopProxy::current())) {
    128   }
    129 
    130  protected:
    131   scoped_ptr<ServerBoundCertService> service_;
    132 };
    133 
    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"));
    151 }
    152 
    153 // See http://crbug.com/91512 - implement OpenSSL version of CreateSelfSigned.
    154 #if !defined(USE_OPENSSL)
    155 
    156 TEST_F(ServerBoundCertServiceTest, GetCacheMiss) {
    157   std::string host("encrypted.google.com");
    158 
    159   int error;
    160   TestCompletionCallback callback;
    161   ServerBoundCertService::RequestHandle request_handle;
    162 
    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());
    172 }
    173 
    174 TEST_F(ServerBoundCertServiceTest, CacheHit) {
    175   std::string host("encrypted.google.com");
    176 
    177   int error;
    178   TestCompletionCallback callback;
    179   ServerBoundCertService::RequestHandle request_handle;
    180 
    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());
    195 
    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);
    206 
    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);
    217 
    218   EXPECT_EQ(3u, service_->requests());
    219   EXPECT_EQ(2u, service_->cert_store_hits());
    220   EXPECT_EQ(0u, service_->inflight_joins());
    221 }
    222 
    223 TEST_F(ServerBoundCertServiceTest, StoreCerts) {
    224   int error;
    225   TestCompletionCallback callback;
    226   ServerBoundCertService::RequestHandle request_handle;
    227 
    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());
    239 
    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());
    250 
    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());
    261 
    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);
    268 }
    269 
    270 // Tests an inflight join.
    271 TEST_F(ServerBoundCertServiceTest, InflightJoin) {
    272   std::string host("encrypted.google.com");
    273   int error;
    274 
    275   std::string private_key_info1, der_cert1;
    276   TestCompletionCallback callback1;
    277   ServerBoundCertService::RequestHandle request_handle1;
    278 
    279   std::string private_key_info2, der_cert2;
    280   TestCompletionCallback callback2;
    281   ServerBoundCertService::RequestHandle request_handle2;
    282 
    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());
    294 
    295   error = callback1.WaitForResult();
    296   EXPECT_EQ(OK, error);
    297   error = callback2.WaitForResult();
    298   EXPECT_EQ(OK, error);
    299 
    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());
    304 }
    305 
    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;
    310 
    311   std::string private_key_info1, der_cert1;
    312   TestCompletionCallback callback1;
    313   ServerBoundCertService::RequestHandle request_handle1;
    314 
    315   std::string private_key_info2;
    316   std::string der_cert2;
    317   TestCompletionCallback callback2;
    318   ServerBoundCertService::RequestHandle request_handle2;
    319 
    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());
    331 
    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);
    337 
    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());
    342 }
    343 
    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;
    350 
    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);
    358 
    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());
    364 
    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);
    371 
    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);
    376 }
    377 
    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;
    384 
    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());
    394 
    395   // Wait for reply from ServerBoundCertServiceWorker to be posted back to the
    396   // ServerBoundCertService.
    397   base::MessageLoop::current()->RunUntilIdle();
    398 
    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());
    402 }
    403 
    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;
    409   {
    410     ServerBoundCertService::RequestHandle request_handle;
    411 
    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());
    419   }
    420 
    421   // Wait for reply from ServerBoundCertServiceWorker to be posted back to the
    422   // ServerBoundCertService.
    423   base::MessageLoop::current()->RunUntilIdle();
    424 
    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());
    428 }
    429 
    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;
    435 
    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());
    443 
    444   // Cancel request and destroy the ServerBoundCertService.
    445   request_handle.Cancel();
    446   service_.reset();
    447 
    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();
    452 
    453   // If we got here without crashing or a valgrind error, it worked.
    454 }
    455 
    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));
    463 
    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;
    469 
    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());
    478 }
    479 
    480 // Tests that simultaneous creation of different certs works.
    481 TEST_F(ServerBoundCertServiceTest, SimultaneousCreation) {
    482   int error;
    483 
    484   std::string host1("encrypted.google.com");
    485   std::string private_key_info1, der_cert1;
    486   TestCompletionCallback callback1;
    487   ServerBoundCertService::RequestHandle request_handle1;
    488 
    489   std::string host2("foo.com");
    490   std::string private_key_info2, der_cert2;
    491   TestCompletionCallback callback2;
    492   ServerBoundCertService::RequestHandle request_handle2;
    493 
    494   std::string host3("bar.com");
    495   std::string private_key_info3, der_cert3;
    496   TestCompletionCallback callback3;
    497   ServerBoundCertService::RequestHandle request_handle3;
    498 
    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());
    506 
    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());
    514 
    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());
    522 
    523   error = callback1.WaitForResult();
    524   EXPECT_EQ(OK, error);
    525   EXPECT_FALSE(private_key_info1.empty());
    526   EXPECT_FALSE(der_cert1.empty());
    527 
    528   error = callback2.WaitForResult();
    529   EXPECT_EQ(OK, error);
    530   EXPECT_FALSE(private_key_info2.empty());
    531   EXPECT_FALSE(der_cert2.empty());
    532 
    533   error = callback3.WaitForResult();
    534   EXPECT_EQ(OK, error);
    535   EXPECT_FALSE(private_key_info3.empty());
    536   EXPECT_FALSE(der_cert3.empty());
    537 
    538   EXPECT_NE(private_key_info1, private_key_info2);
    539   EXPECT_NE(der_cert1, der_cert2);
    540 
    541   EXPECT_NE(private_key_info1, private_key_info3);
    542   EXPECT_NE(der_cert1, der_cert3);
    543 
    544   EXPECT_NE(private_key_info2, private_key_info3);
    545   EXPECT_NE(der_cert2, der_cert3);
    546 
    547   EXPECT_EQ(3, service_->cert_count());
    548 }
    549 
    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());
    564 
    565   int error;
    566   TestCompletionCallback callback;
    567   ServerBoundCertService::RequestHandle request_handle;
    568 
    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());
    579 
    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());
    590 }
    591 
    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()));
    597 
    598   std::string host("encrypted.google.com");
    599 
    600   int error;
    601   TestCompletionCallback callback;
    602   ServerBoundCertService::RequestHandle request_handle;
    603 
    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());
    611 
    612   mock_store->CallGetServerBoundCertCallbackWithResult(
    613       ERR_FILE_NOT_FOUND, base::Time(), std::string(), std::string());
    614 
    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());
    621 }
    622 
    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()));
    628 
    629   std::string host("encrypted.google.com");
    630 
    631   int error;
    632   TestCompletionCallback callback;
    633   ServerBoundCertService::RequestHandle request_handle;
    634 
    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());
    642 
    643   mock_store->CallGetServerBoundCertCallbackWithResult(
    644       ERR_FILE_NOT_FOUND, base::Time(), std::string(), std::string());
    645 
    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());
    652 }
    653 
    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()));
    659 
    660   std::string host("encrypted.google.com");
    661 
    662   int error;
    663   TestCompletionCallback callback;
    664   ServerBoundCertService::RequestHandle request_handle;
    665 
    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());
    673 
    674   mock_store->CallGetServerBoundCertCallbackWithResult(
    675       OK, base::Time(), "ab", "cd");
    676 
    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());
    688 }
    689 
    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()));
    695 
    696   std::string host("encrypted.google.com");
    697 
    698   int error;
    699   TestCompletionCallback callback;
    700   ServerBoundCertService::RequestHandle request_handle;
    701 
    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());
    709 
    710   mock_store->CallGetServerBoundCertCallbackWithResult(
    711       OK, base::Time(), "ab", "cd");
    712 
    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());
    723 }
    724 
    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()));
    730 
    731   std::string host("encrypted.google.com");
    732 
    733   int error;
    734 
    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());
    744 
    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());
    754 
    755   mock_store->CallGetServerBoundCertCallbackWithResult(
    756       ERR_FILE_NOT_FOUND, base::Time(), std::string(), std::string());
    757 
    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);
    764 
    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());
    776 }
    777 
    778 #endif  // !defined(USE_OPENSSL)
    779 
    780 }  // namespace
    781 
    782 }  // namespace net
    783