Home | History | Annotate | Download | only in ssl
      1 // Copyright 2014 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/channel_id_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_channel_id_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 MockChannelIDStoreWithAsyncGet
     54     : public DefaultChannelIDStore {
     55  public:
     56   MockChannelIDStoreWithAsyncGet()
     57       : DefaultChannelIDStore(NULL), channel_id_count_(0) {}
     58 
     59   virtual int GetChannelID(const std::string& server_identifier,
     60                            base::Time* expiration_time,
     61                            std::string* private_key_result,
     62                            std::string* cert_result,
     63                            const GetChannelIDCallback& callback) OVERRIDE;
     64 
     65   virtual void SetChannelID(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     channel_id_count_ = 1;
     71   }
     72 
     73   virtual int GetChannelIDCount() OVERRIDE { return channel_id_count_; }
     74 
     75   void CallGetChannelIDCallbackWithResult(int err,
     76                                           base::Time expiration_time,
     77                                           const std::string& private_key,
     78                                           const std::string& cert);
     79 
     80  private:
     81   GetChannelIDCallback callback_;
     82   std::string server_identifier_;
     83   int channel_id_count_;
     84 };
     85 
     86 int MockChannelIDStoreWithAsyncGet::GetChannelID(
     87     const std::string& server_identifier,
     88     base::Time* expiration_time,
     89     std::string* private_key_result,
     90     std::string* cert_result,
     91     const GetChannelIDCallback& callback) {
     92   server_identifier_ = server_identifier;
     93   callback_ = callback;
     94   // Reset the cert count, it'll get incremented in either SetChannelID or
     95   // CallGetChannelIDCallbackWithResult.
     96   channel_id_count_ = 0;
     97   // Do nothing else: the results to be provided will be specified through
     98   // CallGetChannelIDCallbackWithResult.
     99   return ERR_IO_PENDING;
    100 }
    101 
    102 void
    103 MockChannelIDStoreWithAsyncGet::CallGetChannelIDCallbackWithResult(
    104     int err,
    105     base::Time expiration_time,
    106     const std::string& private_key,
    107     const std::string& cert) {
    108   if (err == OK)
    109     channel_id_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));
    117 }
    118 
    119 class ChannelIDServiceTest : public testing::Test {
    120  public:
    121   ChannelIDServiceTest()
    122       : service_(new ChannelIDService(
    123             new DefaultChannelIDStore(NULL),
    124             base::MessageLoopProxy::current())) {
    125   }
    126 
    127  protected:
    128   scoped_ptr<ChannelIDService> service_;
    129 };
    130 
    131 TEST_F(ChannelIDServiceTest, GetDomainForHost) {
    132   EXPECT_EQ("google.com",
    133             ChannelIDService::GetDomainForHost("google.com"));
    134   EXPECT_EQ("google.com",
    135             ChannelIDService::GetDomainForHost("www.google.com"));
    136   EXPECT_EQ("foo.appspot.com",
    137             ChannelIDService::GetDomainForHost("foo.appspot.com"));
    138   EXPECT_EQ("bar.appspot.com",
    139             ChannelIDService::GetDomainForHost("foo.bar.appspot.com"));
    140   EXPECT_EQ("appspot.com",
    141             ChannelIDService::GetDomainForHost("appspot.com"));
    142   EXPECT_EQ("google.com",
    143             ChannelIDService::GetDomainForHost("www.mail.google.com"));
    144   EXPECT_EQ("goto",
    145             ChannelIDService::GetDomainForHost("goto"));
    146   EXPECT_EQ("127.0.0.1",
    147             ChannelIDService::GetDomainForHost("127.0.0.1"));
    148 }
    149 
    150 TEST_F(ChannelIDServiceTest, GetCacheMiss) {
    151   std::string host("encrypted.google.com");
    152 
    153   int error;
    154   TestCompletionCallback callback;
    155   ChannelIDService::RequestHandle request_handle;
    156 
    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_->GetChannelID(
    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());
    166 }
    167 
    168 TEST_F(ChannelIDServiceTest, CacheHit) {
    169   std::string host("encrypted.google.com");
    170 
    171   int error;
    172   TestCompletionCallback callback;
    173   ChannelIDService::RequestHandle request_handle;
    174 
    175   // Asynchronous completion.
    176   std::string private_key_info1, der_cert1;
    177   EXPECT_EQ(0, service_->cert_count());
    178   error = service_->GetOrCreateChannelID(
    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());
    189 
    190   // Synchronous completion.
    191   std::string private_key_info2, der_cert2;
    192   error = service_->GetOrCreateChannelID(
    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);
    200 
    201   // Synchronous get.
    202   std::string private_key_info3, der_cert3;
    203   error = service_->GetChannelID(
    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);
    211 
    212   EXPECT_EQ(3u, service_->requests());
    213   EXPECT_EQ(2u, service_->cert_store_hits());
    214   EXPECT_EQ(0u, service_->inflight_joins());
    215 }
    216 
    217 TEST_F(ChannelIDServiceTest, StoreChannelIDs) {
    218   int error;
    219   TestCompletionCallback callback;
    220   ChannelIDService::RequestHandle request_handle;
    221 
    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_->GetOrCreateChannelID(
    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());
    233 
    234   std::string host2("www.verisign.com");
    235   std::string private_key_info2, der_cert2;
    236   error = service_->GetOrCreateChannelID(
    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());
    244 
    245   std::string host3("www.twitter.com");
    246   std::string private_key_info3, der_cert3;
    247   error = service_->GetOrCreateChannelID(
    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());
    255 
    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);
    262 }
    263 
    264 // Tests an inflight join.
    265 TEST_F(ChannelIDServiceTest, InflightJoin) {
    266   std::string host("encrypted.google.com");
    267   int error;
    268 
    269   std::string private_key_info1, der_cert1;
    270   TestCompletionCallback callback1;
    271   ChannelIDService::RequestHandle request_handle1;
    272 
    273   std::string private_key_info2, der_cert2;
    274   TestCompletionCallback callback2;
    275   ChannelIDService::RequestHandle request_handle2;
    276 
    277   error = service_->GetOrCreateChannelID(
    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_->GetOrCreateChannelID(
    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());
    288 
    289   error = callback1.WaitForResult();
    290   EXPECT_EQ(OK, error);
    291   error = callback2.WaitForResult();
    292   EXPECT_EQ(OK, error);
    293 
    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());
    298 }
    299 
    300 // Tests an inflight join of a Get request to a GetOrCreate request.
    301 TEST_F(ChannelIDServiceTest, InflightJoinGetOrCreateAndGet) {
    302   std::string host("encrypted.google.com");
    303   int error;
    304 
    305   std::string private_key_info1, der_cert1;
    306   TestCompletionCallback callback1;
    307   ChannelIDService::RequestHandle request_handle1;
    308 
    309   std::string private_key_info2;
    310   std::string der_cert2;
    311   TestCompletionCallback callback2;
    312   ChannelIDService::RequestHandle request_handle2;
    313 
    314   error = service_->GetOrCreateChannelID(
    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_->GetChannelID(
    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());
    325 
    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);
    331 
    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());
    336 }
    337 
    338 TEST_F(ChannelIDServiceTest, ExtractValuesFromBytesEC) {
    339   std::string host("encrypted.google.com");
    340   std::string private_key_info, der_cert;
    341   int error;
    342   TestCompletionCallback callback;
    343   ChannelIDService::RequestHandle request_handle;
    344 
    345   error = service_->GetOrCreateChannelID(
    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);
    352 
    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());
    358 
    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           ChannelIDService::kEPKIPassword, key_vec, spki));
    364   EXPECT_TRUE(private_key != NULL);
    365 
    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);
    370 }
    371 
    372 // Tests that the callback of a canceled request is never made.
    373 TEST_F(ChannelIDServiceTest, CancelRequest) {
    374   std::string host("encrypted.google.com");
    375   std::string private_key_info, der_cert;
    376   int error;
    377   ChannelIDService::RequestHandle request_handle;
    378 
    379   error = service_->GetOrCreateChannelID(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());
    388 
    389   // Wait for reply from ChannelIDServiceWorker to be posted back to the
    390   // ChannelIDService.
    391   base::MessageLoop::current()->RunUntilIdle();
    392 
    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());
    396 }
    397 
    398 // Tests that destructing the RequestHandle cancels the request.
    399 TEST_F(ChannelIDServiceTest, CancelRequestByHandleDestruction) {
    400   std::string host("encrypted.google.com");
    401   std::string private_key_info, der_cert;
    402   int error;
    403   {
    404     ChannelIDService::RequestHandle request_handle;
    405 
    406     error = service_->GetOrCreateChannelID(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());
    413   }
    414 
    415   // Wait for reply from ChannelIDServiceWorker to be posted back to the
    416   // ChannelIDService.
    417   base::MessageLoop::current()->RunUntilIdle();
    418 
    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());
    422 }
    423 
    424 TEST_F(ChannelIDServiceTest, DestructionWithPendingRequest) {
    425   std::string host("encrypted.google.com");
    426   std::string private_key_info, der_cert;
    427   int error;
    428   ChannelIDService::RequestHandle request_handle;
    429 
    430   error = service_->GetOrCreateChannelID(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());
    437 
    438   // Cancel request and destroy the ChannelIDService.
    439   request_handle.Cancel();
    440   service_.reset();
    441 
    442   // ChannelIDServiceWorker should not post anything back to the
    443   // non-existent ChannelIDService, but run the loop just to be sure it
    444   // doesn't.
    445   base::MessageLoop::current()->RunUntilIdle();
    446 
    447   // If we got here without crashing or a valgrind error, it worked.
    448 }
    449 
    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(ChannelIDServiceTest, RequestAfterPoolShutdown) {
    454   scoped_refptr<FailingTaskRunner> task_runner(new FailingTaskRunner);
    455   service_.reset(new ChannelIDService(
    456       new DefaultChannelIDStore(NULL), task_runner));
    457 
    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   ChannelIDService::RequestHandle request_handle;
    463 
    464   error = service_->GetOrCreateChannelID(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());
    472 }
    473 
    474 // Tests that simultaneous creation of different certs works.
    475 TEST_F(ChannelIDServiceTest, SimultaneousCreation) {
    476   int error;
    477 
    478   std::string host1("encrypted.google.com");
    479   std::string private_key_info1, der_cert1;
    480   TestCompletionCallback callback1;
    481   ChannelIDService::RequestHandle request_handle1;
    482 
    483   std::string host2("foo.com");
    484   std::string private_key_info2, der_cert2;
    485   TestCompletionCallback callback2;
    486   ChannelIDService::RequestHandle request_handle2;
    487 
    488   std::string host3("bar.com");
    489   std::string private_key_info3, der_cert3;
    490   TestCompletionCallback callback3;
    491   ChannelIDService::RequestHandle request_handle3;
    492 
    493   error = service_->GetOrCreateChannelID(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());
    500 
    501   error = service_->GetOrCreateChannelID(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());
    508 
    509   error = service_->GetOrCreateChannelID(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());
    516 
    517   error = callback1.WaitForResult();
    518   EXPECT_EQ(OK, error);
    519   EXPECT_FALSE(private_key_info1.empty());
    520   EXPECT_FALSE(der_cert1.empty());
    521 
    522   error = callback2.WaitForResult();
    523   EXPECT_EQ(OK, error);
    524   EXPECT_FALSE(private_key_info2.empty());
    525   EXPECT_FALSE(der_cert2.empty());
    526 
    527   error = callback3.WaitForResult();
    528   EXPECT_EQ(OK, error);
    529   EXPECT_FALSE(private_key_info3.empty());
    530   EXPECT_FALSE(der_cert3.empty());
    531 
    532   EXPECT_NE(private_key_info1, private_key_info2);
    533   EXPECT_NE(der_cert1, der_cert2);
    534 
    535   EXPECT_NE(private_key_info1, private_key_info3);
    536   EXPECT_NE(der_cert1, der_cert3);
    537 
    538   EXPECT_NE(private_key_info2, private_key_info3);
    539   EXPECT_NE(der_cert2, der_cert3);
    540 
    541   EXPECT_EQ(3, service_->cert_count());
    542 }
    543 
    544 TEST_F(ChannelIDServiceTest, Expiration) {
    545   ChannelIDStore* store = service_->GetChannelIDStore();
    546   base::Time now = base::Time::Now();
    547   store->SetChannelID("good",
    548                       now,
    549                       now + base::TimeDelta::FromDays(1),
    550                       "a",
    551                       "b");
    552   store->SetChannelID("expired",
    553                       now - base::TimeDelta::FromDays(2),
    554                       now - base::TimeDelta::FromDays(1),
    555                       "c",
    556                       "d");
    557   EXPECT_EQ(2, service_->cert_count());
    558 
    559   int error;
    560   TestCompletionCallback callback;
    561   ChannelIDService::RequestHandle request_handle;
    562 
    563   // Cert is valid - synchronous completion.
    564   std::string private_key_info1, der_cert1;
    565   error = service_->GetOrCreateChannelID(
    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());
    573 
    574   // Expired cert is valid as well - synchronous completion.
    575   std::string private_key_info2, der_cert2;
    576   error = service_->GetOrCreateChannelID(
    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());
    584 }
    585 
    586 TEST_F(ChannelIDServiceTest, AsyncStoreGetOrCreateNoChannelIDsInStore) {
    587   MockChannelIDStoreWithAsyncGet* mock_store =
    588       new MockChannelIDStoreWithAsyncGet();
    589   service_ = scoped_ptr<ChannelIDService>(new ChannelIDService(
    590       mock_store, base::MessageLoopProxy::current()));
    591 
    592   std::string host("encrypted.google.com");
    593 
    594   int error;
    595   TestCompletionCallback callback;
    596   ChannelIDService::RequestHandle request_handle;
    597 
    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_->GetOrCreateChannelID(
    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());
    605 
    606   mock_store->CallGetChannelIDCallbackWithResult(
    607       ERR_FILE_NOT_FOUND, base::Time(), std::string(), std::string());
    608 
    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());
    615 }
    616 
    617 TEST_F(ChannelIDServiceTest, AsyncStoreGetNoChannelIDsInStore) {
    618   MockChannelIDStoreWithAsyncGet* mock_store =
    619       new MockChannelIDStoreWithAsyncGet();
    620   service_ = scoped_ptr<ChannelIDService>(new ChannelIDService(
    621       mock_store, base::MessageLoopProxy::current()));
    622 
    623   std::string host("encrypted.google.com");
    624 
    625   int error;
    626   TestCompletionCallback callback;
    627   ChannelIDService::RequestHandle request_handle;
    628 
    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_->GetChannelID(
    633       host, &private_key, &der_cert, callback.callback(), &request_handle);
    634   EXPECT_EQ(ERR_IO_PENDING, error);
    635   EXPECT_TRUE(request_handle.is_active());
    636 
    637   mock_store->CallGetChannelIDCallbackWithResult(
    638       ERR_FILE_NOT_FOUND, base::Time(), std::string(), std::string());
    639 
    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());
    646 }
    647 
    648 TEST_F(ChannelIDServiceTest, AsyncStoreGetOrCreateOneCertInStore) {
    649   MockChannelIDStoreWithAsyncGet* mock_store =
    650       new MockChannelIDStoreWithAsyncGet();
    651   service_ = scoped_ptr<ChannelIDService>(new ChannelIDService(
    652       mock_store, base::MessageLoopProxy::current()));
    653 
    654   std::string host("encrypted.google.com");
    655 
    656   int error;
    657   TestCompletionCallback callback;
    658   ChannelIDService::RequestHandle request_handle;
    659 
    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_->GetOrCreateChannelID(
    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());
    667 
    668   mock_store->CallGetChannelIDCallbackWithResult(
    669       OK, base::Time(), "ab", "cd");
    670 
    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());
    682 }
    683 
    684 TEST_F(ChannelIDServiceTest, AsyncStoreGetOneCertInStore) {
    685   MockChannelIDStoreWithAsyncGet* mock_store =
    686       new MockChannelIDStoreWithAsyncGet();
    687   service_ = scoped_ptr<ChannelIDService>(new ChannelIDService(
    688       mock_store, base::MessageLoopProxy::current()));
    689 
    690   std::string host("encrypted.google.com");
    691 
    692   int error;
    693   TestCompletionCallback callback;
    694   ChannelIDService::RequestHandle request_handle;
    695 
    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_->GetChannelID(
    700       host, &private_key, &der_cert, callback.callback(), &request_handle);
    701   EXPECT_EQ(ERR_IO_PENDING, error);
    702   EXPECT_TRUE(request_handle.is_active());
    703 
    704   mock_store->CallGetChannelIDCallbackWithResult(
    705       OK, base::Time(), "ab", "cd");
    706 
    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());
    717 }
    718 
    719 TEST_F(ChannelIDServiceTest, AsyncStoreGetThenCreateNoCertsInStore) {
    720   MockChannelIDStoreWithAsyncGet* mock_store =
    721       new MockChannelIDStoreWithAsyncGet();
    722   service_ = scoped_ptr<ChannelIDService>(new ChannelIDService(
    723       mock_store, base::MessageLoopProxy::current()));
    724 
    725   std::string host("encrypted.google.com");
    726 
    727   int error;
    728 
    729   // Asynchronous get with no certs in the store.
    730   TestCompletionCallback callback1;
    731   ChannelIDService::RequestHandle request_handle1;
    732   std::string private_key1, der_cert1;
    733   EXPECT_EQ(0, service_->cert_count());
    734   error = service_->GetChannelID(
    735       host, &private_key1, &der_cert1, callback1.callback(), &request_handle1);
    736   EXPECT_EQ(ERR_IO_PENDING, error);
    737   EXPECT_TRUE(request_handle1.is_active());
    738 
    739   // Asynchronous get/create with no certs in the store.
    740   TestCompletionCallback callback2;
    741   ChannelIDService::RequestHandle request_handle2;
    742   std::string private_key2, der_cert2;
    743   EXPECT_EQ(0, service_->cert_count());
    744   error = service_->GetOrCreateChannelID(
    745       host, &private_key2, &der_cert2, callback2.callback(), &request_handle2);
    746   EXPECT_EQ(ERR_IO_PENDING, error);
    747   EXPECT_TRUE(request_handle2.is_active());
    748 
    749   mock_store->CallGetChannelIDCallbackWithResult(
    750       ERR_FILE_NOT_FOUND, base::Time(), std::string(), std::string());
    751 
    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);
    758 
    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());
    770 }
    771 
    772 }  // namespace
    773 
    774 }  // namespace net
    775