• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
FailTest(int)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:
FailingTaskRunner()36   FailingTaskRunner() {}
37 
PostDelayedTask(const tracked_objects::Location & from_here,const base::Closure & task,base::TimeDelta delay)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 
RunsTasksOnCurrentThread() const44   virtual bool RunsTasksOnCurrentThread() const OVERRIDE { return true; }
45 
46  protected:
~FailingTaskRunner()47   virtual ~FailingTaskRunner() {}
48 
49  private:
50   DISALLOW_COPY_AND_ASSIGN(FailingTaskRunner);
51 };
52 
53 class MockChannelIDStoreWithAsyncGet
54     : public DefaultChannelIDStore {
55  public:
MockChannelIDStoreWithAsyncGet()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 
SetChannelID(const std::string & server_identifier,base::Time creation_time,base::Time expiration_time,const std::string & private_key,const std::string & cert)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 
GetChannelIDCount()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 
GetChannelID(const std::string & server_identifier,base::Time * expiration_time,std::string * private_key_result,std::string * cert_result,const GetChannelIDCallback & callback)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
CallGetChannelIDCallbackWithResult(int err,base::Time expiration_time,const std::string & private_key,const std::string & cert)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:
ChannelIDServiceTest()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 
TEST_F(ChannelIDServiceTest,GetDomainForHost)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 
TEST_F(ChannelIDServiceTest,GetCacheMiss)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 
TEST_F(ChannelIDServiceTest,CacheHit)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 
TEST_F(ChannelIDServiceTest,StoreChannelIDs)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.
TEST_F(ChannelIDServiceTest,InflightJoin)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.
TEST_F(ChannelIDServiceTest,InflightJoinGetOrCreateAndGet)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 
TEST_F(ChannelIDServiceTest,ExtractValuesFromBytesEC)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.
TEST_F(ChannelIDServiceTest,CancelRequest)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.
TEST_F(ChannelIDServiceTest,CancelRequestByHandleDestruction)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 
TEST_F(ChannelIDServiceTest,DestructionWithPendingRequest)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
TEST_F(ChannelIDServiceTest,RequestAfterPoolShutdown)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.
TEST_F(ChannelIDServiceTest,SimultaneousCreation)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 
TEST_F(ChannelIDServiceTest,Expiration)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 
TEST_F(ChannelIDServiceTest,AsyncStoreGetOrCreateNoChannelIDsInStore)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 
TEST_F(ChannelIDServiceTest,AsyncStoreGetNoChannelIDsInStore)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 
TEST_F(ChannelIDServiceTest,AsyncStoreGetOrCreateOneCertInStore)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 
TEST_F(ChannelIDServiceTest,AsyncStoreGetOneCertInStore)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 
TEST_F(ChannelIDServiceTest,AsyncStoreGetThenCreateNoCertsInStore)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