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/task_runner.h"
     14 #include "base/threading/sequenced_worker_pool.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 class ServerBoundCertServiceTest : public testing::Test {
     32  public:
     33   ServerBoundCertServiceTest()
     34       : sequenced_worker_pool_(new base::SequencedWorkerPool(
     35             3, "ServerBoundCertServiceTest")),
     36         service_(new ServerBoundCertService(
     37             new DefaultServerBoundCertStore(NULL),
     38             sequenced_worker_pool_)) {
     39   }
     40 
     41   virtual ~ServerBoundCertServiceTest() {
     42     if (sequenced_worker_pool_.get())
     43       sequenced_worker_pool_->Shutdown();
     44   }
     45 
     46  protected:
     47   scoped_refptr<base::SequencedWorkerPool> sequenced_worker_pool_;
     48   scoped_ptr<ServerBoundCertService> service_;
     49 };
     50 
     51 class MockServerBoundCertStoreWithAsyncGet
     52     : public DefaultServerBoundCertStore {
     53  public:
     54   MockServerBoundCertStoreWithAsyncGet()
     55       : DefaultServerBoundCertStore(NULL), cert_count_(0) {}
     56 
     57   virtual int GetServerBoundCert(const std::string& server_identifier,
     58                                  base::Time* expiration_time,
     59                                  std::string* private_key_result,
     60                                  std::string* cert_result,
     61                                  const GetCertCallback& callback) OVERRIDE;
     62 
     63   virtual void SetServerBoundCert(const std::string& server_identifier,
     64                                   base::Time creation_time,
     65                                   base::Time expiration_time,
     66                                   const std::string& private_key,
     67                                   const std::string& cert) OVERRIDE {
     68     cert_count_ = 1;
     69   }
     70 
     71   virtual int GetCertCount() OVERRIDE { return cert_count_; }
     72 
     73   void CallGetServerBoundCertCallbackWithResult(int err,
     74                                                 base::Time expiration_time,
     75                                                 const std::string& private_key,
     76                                                 const std::string& cert);
     77 
     78  private:
     79   GetCertCallback callback_;
     80   std::string server_identifier_;
     81   int cert_count_;
     82 };
     83 
     84 int MockServerBoundCertStoreWithAsyncGet::GetServerBoundCert(
     85     const std::string& server_identifier,
     86     base::Time* expiration_time,
     87     std::string* private_key_result,
     88     std::string* cert_result,
     89     const GetCertCallback& callback) {
     90   server_identifier_ = server_identifier;
     91   callback_ = callback;
     92   // Reset the cert count, it'll get incremented in either SetServerBoundCert or
     93   // CallGetServerBoundCertCallbackWithResult.
     94   cert_count_ = 0;
     95   // Do nothing else: the results to be provided will be specified through
     96   // CallGetServerBoundCertCallbackWithResult.
     97   return ERR_IO_PENDING;
     98 }
     99 
    100 void
    101 MockServerBoundCertStoreWithAsyncGet::CallGetServerBoundCertCallbackWithResult(
    102     int err,
    103     base::Time expiration_time,
    104     const std::string& private_key,
    105     const std::string& cert) {
    106   if (err == OK)
    107     cert_count_ = 1;
    108   base::MessageLoop::current()->PostTask(FROM_HERE,
    109                                          base::Bind(callback_,
    110                                                     err,
    111                                                     server_identifier_,
    112                                                     expiration_time,
    113                                                     private_key,
    114                                                     cert));
    115 }
    116 
    117 TEST_F(ServerBoundCertServiceTest, GetDomainForHost) {
    118   EXPECT_EQ("google.com",
    119             ServerBoundCertService::GetDomainForHost("google.com"));
    120   EXPECT_EQ("google.com",
    121             ServerBoundCertService::GetDomainForHost("www.google.com"));
    122   EXPECT_EQ("foo.appspot.com",
    123             ServerBoundCertService::GetDomainForHost("foo.appspot.com"));
    124   EXPECT_EQ("bar.appspot.com",
    125             ServerBoundCertService::GetDomainForHost("foo.bar.appspot.com"));
    126   EXPECT_EQ("appspot.com",
    127             ServerBoundCertService::GetDomainForHost("appspot.com"));
    128   EXPECT_EQ("google.com",
    129             ServerBoundCertService::GetDomainForHost("www.mail.google.com"));
    130   EXPECT_EQ("goto",
    131             ServerBoundCertService::GetDomainForHost("goto"));
    132   EXPECT_EQ("127.0.0.1",
    133             ServerBoundCertService::GetDomainForHost("127.0.0.1"));
    134 }
    135 
    136 // See http://crbug.com/91512 - implement OpenSSL version of CreateSelfSigned.
    137 #if !defined(USE_OPENSSL)
    138 
    139 TEST_F(ServerBoundCertServiceTest, CacheHit) {
    140   std::string host("encrypted.google.com");
    141 
    142   int error;
    143   TestCompletionCallback callback;
    144   ServerBoundCertService::RequestHandle request_handle;
    145 
    146   // Asynchronous completion.
    147   std::string private_key_info1, der_cert1;
    148   EXPECT_EQ(0, service_->cert_count());
    149   error = service_->GetDomainBoundCert(
    150       host, &private_key_info1, &der_cert1,
    151       callback.callback(), &request_handle);
    152   EXPECT_EQ(ERR_IO_PENDING, error);
    153   EXPECT_TRUE(request_handle.is_active());
    154   error = callback.WaitForResult();
    155   EXPECT_EQ(OK, error);
    156   EXPECT_EQ(1, service_->cert_count());
    157   EXPECT_FALSE(private_key_info1.empty());
    158   EXPECT_FALSE(der_cert1.empty());
    159   EXPECT_FALSE(request_handle.is_active());
    160 
    161   // Synchronous completion.
    162   std::string private_key_info2, der_cert2;
    163   error = service_->GetDomainBoundCert(
    164       host, &private_key_info2, &der_cert2,
    165       callback.callback(), &request_handle);
    166   EXPECT_FALSE(request_handle.is_active());
    167   EXPECT_EQ(OK, error);
    168   EXPECT_EQ(1, service_->cert_count());
    169   EXPECT_EQ(private_key_info1, private_key_info2);
    170   EXPECT_EQ(der_cert1, der_cert2);
    171 
    172   EXPECT_EQ(2u, service_->requests());
    173   EXPECT_EQ(1u, service_->cert_store_hits());
    174   EXPECT_EQ(0u, service_->inflight_joins());
    175 }
    176 
    177 TEST_F(ServerBoundCertServiceTest, StoreCerts) {
    178   int error;
    179   TestCompletionCallback callback;
    180   ServerBoundCertService::RequestHandle request_handle;
    181 
    182   std::string host1("encrypted.google.com");
    183   std::string private_key_info1, der_cert1;
    184   EXPECT_EQ(0, service_->cert_count());
    185   error = service_->GetDomainBoundCert(
    186       host1, &private_key_info1, &der_cert1,
    187       callback.callback(), &request_handle);
    188   EXPECT_EQ(ERR_IO_PENDING, error);
    189   EXPECT_TRUE(request_handle.is_active());
    190   error = callback.WaitForResult();
    191   EXPECT_EQ(OK, error);
    192   EXPECT_EQ(1, service_->cert_count());
    193 
    194   std::string host2("www.verisign.com");
    195   std::string private_key_info2, der_cert2;
    196   error = service_->GetDomainBoundCert(
    197       host2, &private_key_info2, &der_cert2,
    198       callback.callback(), &request_handle);
    199   EXPECT_EQ(ERR_IO_PENDING, error);
    200   EXPECT_TRUE(request_handle.is_active());
    201   error = callback.WaitForResult();
    202   EXPECT_EQ(OK, error);
    203   EXPECT_EQ(2, service_->cert_count());
    204 
    205   std::string host3("www.twitter.com");
    206   std::string private_key_info3, der_cert3;
    207   error = service_->GetDomainBoundCert(
    208       host3, &private_key_info3, &der_cert3,
    209       callback.callback(), &request_handle);
    210   EXPECT_EQ(ERR_IO_PENDING, error);
    211   EXPECT_TRUE(request_handle.is_active());
    212   error = callback.WaitForResult();
    213   EXPECT_EQ(OK, error);
    214   EXPECT_EQ(3, service_->cert_count());
    215 
    216   EXPECT_NE(private_key_info1, private_key_info2);
    217   EXPECT_NE(der_cert1, der_cert2);
    218   EXPECT_NE(private_key_info1, private_key_info3);
    219   EXPECT_NE(der_cert1, der_cert3);
    220   EXPECT_NE(private_key_info2, private_key_info3);
    221   EXPECT_NE(der_cert2, der_cert3);
    222 }
    223 
    224 // Tests an inflight join.
    225 TEST_F(ServerBoundCertServiceTest, InflightJoin) {
    226   std::string host("encrypted.google.com");
    227   int error;
    228 
    229   std::string private_key_info1, der_cert1;
    230   TestCompletionCallback callback1;
    231   ServerBoundCertService::RequestHandle request_handle1;
    232 
    233   std::string private_key_info2, der_cert2;
    234   TestCompletionCallback callback2;
    235   ServerBoundCertService::RequestHandle request_handle2;
    236 
    237   error = service_->GetDomainBoundCert(
    238       host, &private_key_info1, &der_cert1,
    239       callback1.callback(), &request_handle1);
    240   EXPECT_EQ(ERR_IO_PENDING, error);
    241   EXPECT_TRUE(request_handle1.is_active());
    242   // Should join with the original request.
    243   error = service_->GetDomainBoundCert(
    244       host, &private_key_info2, &der_cert2,
    245       callback2.callback(), &request_handle2);
    246   EXPECT_EQ(ERR_IO_PENDING, error);
    247   EXPECT_TRUE(request_handle2.is_active());
    248 
    249   error = callback1.WaitForResult();
    250   EXPECT_EQ(OK, error);
    251   error = callback2.WaitForResult();
    252   EXPECT_EQ(OK, error);
    253 
    254   EXPECT_EQ(2u, service_->requests());
    255   EXPECT_EQ(0u, service_->cert_store_hits());
    256   EXPECT_EQ(1u, service_->inflight_joins());
    257 }
    258 
    259 TEST_F(ServerBoundCertServiceTest, ExtractValuesFromBytesEC) {
    260   std::string host("encrypted.google.com");
    261   std::string private_key_info, der_cert;
    262   int error;
    263   TestCompletionCallback callback;
    264   ServerBoundCertService::RequestHandle request_handle;
    265 
    266   error = service_->GetDomainBoundCert(
    267       host, &private_key_info, &der_cert, callback.callback(),
    268       &request_handle);
    269   EXPECT_EQ(ERR_IO_PENDING, error);
    270   EXPECT_TRUE(request_handle.is_active());
    271   error = callback.WaitForResult();
    272   EXPECT_EQ(OK, error);
    273 
    274   base::StringPiece spki_piece;
    275   ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(der_cert, &spki_piece));
    276   std::vector<uint8> spki(
    277       spki_piece.data(),
    278       spki_piece.data() + spki_piece.size());
    279 
    280   // Check that we can retrieve the key from the bytes.
    281   std::vector<uint8> key_vec(private_key_info.begin(), private_key_info.end());
    282   scoped_ptr<crypto::ECPrivateKey> private_key(
    283       crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo(
    284           ServerBoundCertService::kEPKIPassword, key_vec, spki));
    285   EXPECT_TRUE(private_key != NULL);
    286 
    287   // Check that we can retrieve the cert from the bytes.
    288   scoped_refptr<X509Certificate> x509cert(
    289       X509Certificate::CreateFromBytes(der_cert.data(), der_cert.size()));
    290   EXPECT_TRUE(x509cert.get() != NULL);
    291 }
    292 
    293 // Tests that the callback of a canceled request is never made.
    294 TEST_F(ServerBoundCertServiceTest, CancelRequest) {
    295   std::string host("encrypted.google.com");
    296   std::string private_key_info, der_cert;
    297   int error;
    298   ServerBoundCertService::RequestHandle request_handle;
    299 
    300   error = service_->GetDomainBoundCert(host,
    301                                       &private_key_info,
    302                                       &der_cert,
    303                                       base::Bind(&FailTest),
    304                                       &request_handle);
    305   EXPECT_EQ(ERR_IO_PENDING, error);
    306   EXPECT_TRUE(request_handle.is_active());
    307   request_handle.Cancel();
    308   EXPECT_FALSE(request_handle.is_active());
    309 
    310   // Wait for generation to finish.
    311   sequenced_worker_pool_->FlushForTesting();
    312   // Wait for reply from ServerBoundCertServiceWorker to be posted back to the
    313   // ServerBoundCertService.
    314   base::MessageLoop::current()->RunUntilIdle();
    315 
    316   // Even though the original request was cancelled, the service will still
    317   // store the result, it just doesn't call the callback.
    318   EXPECT_EQ(1, service_->cert_count());
    319 }
    320 
    321 // Tests that destructing the RequestHandle cancels the request.
    322 TEST_F(ServerBoundCertServiceTest, CancelRequestByHandleDestruction) {
    323   std::string host("encrypted.google.com");
    324   std::string private_key_info, der_cert;
    325   int error;
    326   {
    327     ServerBoundCertService::RequestHandle request_handle;
    328 
    329     error = service_->GetDomainBoundCert(host,
    330                                          &private_key_info,
    331                                          &der_cert,
    332                                          base::Bind(&FailTest),
    333                                          &request_handle);
    334     EXPECT_EQ(ERR_IO_PENDING, error);
    335     EXPECT_TRUE(request_handle.is_active());
    336   }
    337 
    338   // Wait for generation to finish.
    339   sequenced_worker_pool_->FlushForTesting();
    340   // Wait for reply from ServerBoundCertServiceWorker to be posted back to the
    341   // ServerBoundCertService.
    342   base::MessageLoop::current()->RunUntilIdle();
    343 
    344   // Even though the original request was cancelled, the service will still
    345   // store the result, it just doesn't call the callback.
    346   EXPECT_EQ(1, service_->cert_count());
    347 }
    348 
    349 TEST_F(ServerBoundCertServiceTest, DestructionWithPendingRequest) {
    350   std::string host("encrypted.google.com");
    351   std::string private_key_info, der_cert;
    352   int error;
    353   ServerBoundCertService::RequestHandle request_handle;
    354 
    355   error = service_->GetDomainBoundCert(host,
    356                                        &private_key_info,
    357                                        &der_cert,
    358                                        base::Bind(&FailTest),
    359                                        &request_handle);
    360   EXPECT_EQ(ERR_IO_PENDING, error);
    361   EXPECT_TRUE(request_handle.is_active());
    362 
    363   // Cancel request and destroy the ServerBoundCertService.
    364   request_handle.Cancel();
    365   service_.reset();
    366 
    367   // Wait for generation to finish.
    368   sequenced_worker_pool_->FlushForTesting();
    369   // ServerBoundCertServiceWorker should not post anything back to the
    370   // non-existant ServerBoundCertService, but run the loop just to be sure it
    371   // doesn't.
    372   base::MessageLoop::current()->RunUntilIdle();
    373 
    374   // If we got here without crashing or a valgrind error, it worked.
    375 }
    376 
    377 // Tests that shutting down the sequenced worker pool and then making new
    378 // requests gracefully fails.
    379 // This is a regression test for http://crbug.com/236387
    380 TEST_F(ServerBoundCertServiceTest, RequestAfterPoolShutdown) {
    381   // Shutdown the pool immediately.
    382   sequenced_worker_pool_->Shutdown();
    383   sequenced_worker_pool_ = NULL;
    384 
    385   // Ensure any shutdown code is processed.
    386   base::MessageLoop::current()->RunUntilIdle();
    387 
    388   // Make a request that will force synchronous completion.
    389   std::string host("encrypted.google.com");
    390   std::string private_key_info, der_cert;
    391   int error;
    392   ServerBoundCertService::RequestHandle request_handle;
    393 
    394   error = service_->GetDomainBoundCert(host,
    395                                        &private_key_info,
    396                                        &der_cert,
    397                                        base::Bind(&FailTest),
    398                                        &request_handle);
    399   // If we got here without crashing or a valgrind error, it worked.
    400   ASSERT_EQ(ERR_INSUFFICIENT_RESOURCES, error);
    401   EXPECT_FALSE(request_handle.is_active());
    402 }
    403 
    404 // Tests that simultaneous creation of different certs works.
    405 TEST_F(ServerBoundCertServiceTest, SimultaneousCreation) {
    406   int error;
    407 
    408   std::string host1("encrypted.google.com");
    409   std::string private_key_info1, der_cert1;
    410   TestCompletionCallback callback1;
    411   ServerBoundCertService::RequestHandle request_handle1;
    412 
    413   std::string host2("foo.com");
    414   std::string private_key_info2, der_cert2;
    415   TestCompletionCallback callback2;
    416   ServerBoundCertService::RequestHandle request_handle2;
    417 
    418   std::string host3("bar.com");
    419   std::string private_key_info3, der_cert3;
    420   TestCompletionCallback callback3;
    421   ServerBoundCertService::RequestHandle request_handle3;
    422 
    423   error = service_->GetDomainBoundCert(host1,
    424                                        &private_key_info1,
    425                                        &der_cert1,
    426                                        callback1.callback(),
    427                                        &request_handle1);
    428   EXPECT_EQ(ERR_IO_PENDING, error);
    429   EXPECT_TRUE(request_handle1.is_active());
    430 
    431   error = service_->GetDomainBoundCert(host2,
    432                                        &private_key_info2,
    433                                        &der_cert2,
    434                                        callback2.callback(),
    435                                        &request_handle2);
    436   EXPECT_EQ(ERR_IO_PENDING, error);
    437   EXPECT_TRUE(request_handle2.is_active());
    438 
    439   error = service_->GetDomainBoundCert(host3,
    440                                        &private_key_info3,
    441                                        &der_cert3,
    442                                        callback3.callback(),
    443                                        &request_handle3);
    444   EXPECT_EQ(ERR_IO_PENDING, error);
    445   EXPECT_TRUE(request_handle3.is_active());
    446 
    447   error = callback1.WaitForResult();
    448   EXPECT_EQ(OK, error);
    449   EXPECT_FALSE(private_key_info1.empty());
    450   EXPECT_FALSE(der_cert1.empty());
    451 
    452   error = callback2.WaitForResult();
    453   EXPECT_EQ(OK, error);
    454   EXPECT_FALSE(private_key_info2.empty());
    455   EXPECT_FALSE(der_cert2.empty());
    456 
    457   error = callback3.WaitForResult();
    458   EXPECT_EQ(OK, error);
    459   EXPECT_FALSE(private_key_info3.empty());
    460   EXPECT_FALSE(der_cert3.empty());
    461 
    462   EXPECT_NE(private_key_info1, private_key_info2);
    463   EXPECT_NE(der_cert1, der_cert2);
    464 
    465   EXPECT_NE(private_key_info1, private_key_info3);
    466   EXPECT_NE(der_cert1, der_cert3);
    467 
    468   EXPECT_NE(private_key_info2, private_key_info3);
    469   EXPECT_NE(der_cert2, der_cert3);
    470 
    471   EXPECT_EQ(3, service_->cert_count());
    472 }
    473 
    474 TEST_F(ServerBoundCertServiceTest, Expiration) {
    475   ServerBoundCertStore* store = service_->GetCertStore();
    476   base::Time now = base::Time::Now();
    477   store->SetServerBoundCert("good",
    478                             now,
    479                             now + base::TimeDelta::FromDays(1),
    480                             "a",
    481                             "b");
    482   store->SetServerBoundCert("expired",
    483                             now - base::TimeDelta::FromDays(2),
    484                             now - base::TimeDelta::FromDays(1),
    485                             "c",
    486                             "d");
    487   EXPECT_EQ(2, service_->cert_count());
    488 
    489   int error;
    490   TestCompletionCallback callback;
    491   ServerBoundCertService::RequestHandle request_handle;
    492 
    493   // Cert is valid - synchronous completion.
    494   std::string private_key_info1, der_cert1;
    495   error = service_->GetDomainBoundCert(
    496       "good", &private_key_info1, &der_cert1,
    497       callback.callback(), &request_handle);
    498   EXPECT_EQ(OK, error);
    499   EXPECT_FALSE(request_handle.is_active());
    500   EXPECT_EQ(2, service_->cert_count());
    501   EXPECT_STREQ("a", private_key_info1.c_str());
    502   EXPECT_STREQ("b", der_cert1.c_str());
    503 
    504   // Expired cert is valid as well - synchronous completion.
    505   std::string private_key_info2, der_cert2;
    506   error = service_->GetDomainBoundCert(
    507       "expired", &private_key_info2, &der_cert2,
    508       callback.callback(), &request_handle);
    509   EXPECT_EQ(OK, error);
    510   EXPECT_FALSE(request_handle.is_active());
    511   EXPECT_EQ(2, service_->cert_count());
    512   EXPECT_STREQ("c", private_key_info2.c_str());
    513   EXPECT_STREQ("d", der_cert2.c_str());
    514 }
    515 
    516 TEST_F(ServerBoundCertServiceTest, AsyncStoreGetNoCertsInStore) {
    517   MockServerBoundCertStoreWithAsyncGet* mock_store =
    518       new MockServerBoundCertStoreWithAsyncGet();
    519   service_ = scoped_ptr<ServerBoundCertService>(
    520       new ServerBoundCertService(mock_store, sequenced_worker_pool_));
    521 
    522   std::string host("encrypted.google.com");
    523 
    524   int error;
    525   TestCompletionCallback callback;
    526   ServerBoundCertService::RequestHandle request_handle;
    527 
    528   // Asynchronous completion with no certs in the store.
    529   std::string private_key_info, der_cert;
    530   EXPECT_EQ(0, service_->cert_count());
    531   error = service_->GetDomainBoundCert(
    532       host, &private_key_info, &der_cert, callback.callback(), &request_handle);
    533   EXPECT_EQ(ERR_IO_PENDING, error);
    534   EXPECT_TRUE(request_handle.is_active());
    535 
    536   mock_store->CallGetServerBoundCertCallbackWithResult(
    537       ERR_FILE_NOT_FOUND, base::Time(), std::string(), std::string());
    538 
    539   error = callback.WaitForResult();
    540   EXPECT_EQ(OK, error);
    541   EXPECT_EQ(1, service_->cert_count());
    542   EXPECT_FALSE(private_key_info.empty());
    543   EXPECT_FALSE(der_cert.empty());
    544   EXPECT_FALSE(request_handle.is_active());
    545 }
    546 
    547 TEST_F(ServerBoundCertServiceTest, AsyncStoreGetOneCertInStore) {
    548   MockServerBoundCertStoreWithAsyncGet* mock_store =
    549       new MockServerBoundCertStoreWithAsyncGet();
    550   service_ = scoped_ptr<ServerBoundCertService>(
    551       new ServerBoundCertService(mock_store, sequenced_worker_pool_));
    552 
    553   std::string host("encrypted.google.com");
    554 
    555   int error;
    556   TestCompletionCallback callback;
    557   ServerBoundCertService::RequestHandle request_handle;
    558 
    559   // Asynchronous completion with a cert in the store.
    560   std::string private_key_info, der_cert;
    561   EXPECT_EQ(0, service_->cert_count());
    562   error = service_->GetDomainBoundCert(
    563       host, &private_key_info, &der_cert, callback.callback(), &request_handle);
    564   EXPECT_EQ(ERR_IO_PENDING, error);
    565   EXPECT_TRUE(request_handle.is_active());
    566 
    567   mock_store->CallGetServerBoundCertCallbackWithResult(
    568       OK, base::Time(), "ab", "cd");
    569 
    570   error = callback.WaitForResult();
    571   EXPECT_EQ(OK, error);
    572   EXPECT_EQ(1, service_->cert_count());
    573   EXPECT_EQ(1u, service_->requests());
    574   EXPECT_EQ(1u, service_->cert_store_hits());
    575   // Because the cert was found in the store, no new workers should have been
    576   // created.
    577   EXPECT_EQ(0u, service_->workers_created());
    578   EXPECT_STREQ("ab", private_key_info.c_str());
    579   EXPECT_STREQ("cd", der_cert.c_str());
    580   EXPECT_FALSE(request_handle.is_active());
    581 }
    582 
    583 #endif  // !defined(USE_OPENSSL)
    584 
    585 }  // namespace
    586 
    587 }  // namespace net
    588