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
23namespace net {
24
25namespace {
26
27void 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.
34class 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
53class 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
86int 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
102void
103MockChannelIDStoreWithAsyncGet::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
119class 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
131TEST_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
150TEST_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
168TEST_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
217TEST_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.
265TEST_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.
301TEST_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
338TEST_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.
373TEST_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.
399TEST_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
424TEST_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
453TEST_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.
475TEST_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
544TEST_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
586TEST_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
617TEST_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
648TEST_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
684TEST_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
719TEST_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