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.
5 #include "net/ssl/channel_id_service.h"
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"
27 void FailTest(int /* result */) {
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
34 class FailingTaskRunner
: public base::TaskRunner
{
36 FailingTaskRunner() {}
38 bool PostDelayedTask(const tracked_objects::Location
& from_here
,
39 const base::Closure
& task
,
40 base::TimeDelta delay
) override
{
44 bool RunsTasksOnCurrentThread() const override
{ return true; }
47 ~FailingTaskRunner() override
{}
50 DISALLOW_COPY_AND_ASSIGN(FailingTaskRunner
);
53 class MockChannelIDStoreWithAsyncGet
54 : public DefaultChannelIDStore
{
56 MockChannelIDStoreWithAsyncGet()
57 : DefaultChannelIDStore(NULL
), channel_id_count_(0) {}
59 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
;
65 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;
73 int GetChannelIDCount() override
{ return channel_id_count_
; }
75 void CallGetChannelIDCallbackWithResult(int err
,
76 base::Time expiration_time
,
77 const std::string
& private_key
,
78 const std::string
& cert
);
81 GetChannelIDCallback callback_
;
82 std::string server_identifier_
;
83 int channel_id_count_
;
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
;
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
;
103 MockChannelIDStoreWithAsyncGet::CallGetChannelIDCallbackWithResult(
105 base::Time expiration_time
,
106 const std::string
& private_key
,
107 const std::string
& cert
) {
109 channel_id_count_
= 1;
110 base::MessageLoop::current()->PostTask(FROM_HERE
,
111 base::Bind(callback_
,
119 class ChannelIDServiceTest
: public testing::Test
{
121 ChannelIDServiceTest()
122 : service_(new ChannelIDService(
123 new DefaultChannelIDStore(NULL
),
124 base::MessageLoopProxy::current())) {
128 scoped_ptr
<ChannelIDService
> service_
;
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"));
145 ChannelIDService::GetDomainForHost("goto"));
146 EXPECT_EQ("127.0.0.1",
147 ChannelIDService::GetDomainForHost("127.0.0.1"));
150 TEST_F(ChannelIDServiceTest
, GetCacheMiss
) {
151 std::string
host("encrypted.google.com");
154 TestCompletionCallback callback
;
155 ChannelIDService::RequestHandle request_handle
;
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());
168 TEST_F(ChannelIDServiceTest
, CacheHit
) {
169 std::string
host("encrypted.google.com");
172 TestCompletionCallback callback
;
173 ChannelIDService::RequestHandle request_handle
;
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());
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
);
202 std::string private_key_info3
, der_cert3
;
203 error
= service_
->GetChannelID(
204 host
, &private_key_info3
, &der_cert3
, callback
.callback(),
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
);
212 EXPECT_EQ(3u, service_
->requests());
213 EXPECT_EQ(2u, service_
->cert_store_hits());
214 EXPECT_EQ(0u, service_
->inflight_joins());
217 TEST_F(ChannelIDServiceTest
, StoreChannelIDs
) {
219 TestCompletionCallback callback
;
220 ChannelIDService::RequestHandle request_handle
;
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());
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());
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());
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
);
264 // Tests an inflight join.
265 TEST_F(ChannelIDServiceTest
, InflightJoin
) {
266 std::string
host("encrypted.google.com");
269 std::string private_key_info1
, der_cert1
;
270 TestCompletionCallback callback1
;
271 ChannelIDService::RequestHandle request_handle1
;
273 std::string private_key_info2
, der_cert2
;
274 TestCompletionCallback callback2
;
275 ChannelIDService::RequestHandle request_handle2
;
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());
289 error
= callback1
.WaitForResult();
290 EXPECT_EQ(OK
, error
);
291 error
= callback2
.WaitForResult();
292 EXPECT_EQ(OK
, error
);
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());
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");
305 std::string private_key_info1
, der_cert1
;
306 TestCompletionCallback callback1
;
307 ChannelIDService::RequestHandle request_handle1
;
309 std::string private_key_info2
;
310 std::string der_cert2
;
311 TestCompletionCallback callback2
;
312 ChannelIDService::RequestHandle request_handle2
;
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(),
323 EXPECT_EQ(ERR_IO_PENDING
, error
);
324 EXPECT_TRUE(request_handle2
.is_active());
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
);
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());
338 TEST_F(ChannelIDServiceTest
, ExtractValuesFromBytesEC
) {
339 std::string
host("encrypted.google.com");
340 std::string private_key_info
, der_cert
;
342 TestCompletionCallback callback
;
343 ChannelIDService::RequestHandle request_handle
;
345 error
= service_
->GetOrCreateChannelID(
346 host
, &private_key_info
, &der_cert
, callback
.callback(),
348 EXPECT_EQ(ERR_IO_PENDING
, error
);
349 EXPECT_TRUE(request_handle
.is_active());
350 error
= callback
.WaitForResult();
351 EXPECT_EQ(OK
, error
);
353 base::StringPiece spki_piece
;
354 ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(der_cert
, &spki_piece
));
355 std::vector
<uint8
> spki(
357 spki_piece
.data() + spki_piece
.size());
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
);
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
);
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
;
377 ChannelIDService::RequestHandle request_handle
;
379 error
= service_
->GetOrCreateChannelID(host
,
382 base::Bind(&FailTest
),
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());
389 // Wait for reply from ChannelIDServiceWorker to be posted back to the
391 base::MessageLoop::current()->RunUntilIdle();
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());
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
;
404 ChannelIDService::RequestHandle request_handle
;
406 error
= service_
->GetOrCreateChannelID(host
,
409 base::Bind(&FailTest
),
411 EXPECT_EQ(ERR_IO_PENDING
, error
);
412 EXPECT_TRUE(request_handle
.is_active());
415 // Wait for reply from ChannelIDServiceWorker to be posted back to the
417 base::MessageLoop::current()->RunUntilIdle();
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());
424 TEST_F(ChannelIDServiceTest
, DestructionWithPendingRequest
) {
425 std::string
host("encrypted.google.com");
426 std::string private_key_info
, der_cert
;
428 ChannelIDService::RequestHandle request_handle
;
430 error
= service_
->GetOrCreateChannelID(host
,
433 base::Bind(&FailTest
),
435 EXPECT_EQ(ERR_IO_PENDING
, error
);
436 EXPECT_TRUE(request_handle
.is_active());
438 // Cancel request and destroy the ChannelIDService.
439 request_handle
.Cancel();
442 // ChannelIDServiceWorker should not post anything back to the
443 // non-existent ChannelIDService, but run the loop just to be sure it
445 base::MessageLoop::current()->RunUntilIdle();
447 // If we got here without crashing or a valgrind error, it worked.
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
));
458 // Make a request that will force synchronous completion.
459 std::string
host("encrypted.google.com");
460 std::string private_key_info
, der_cert
;
462 ChannelIDService::RequestHandle request_handle
;
464 error
= service_
->GetOrCreateChannelID(host
,
467 base::Bind(&FailTest
),
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());
474 // Tests that simultaneous creation of different certs works.
475 TEST_F(ChannelIDServiceTest
, SimultaneousCreation
) {
478 std::string
host1("encrypted.google.com");
479 std::string private_key_info1
, der_cert1
;
480 TestCompletionCallback callback1
;
481 ChannelIDService::RequestHandle request_handle1
;
483 std::string
host2("foo.com");
484 std::string private_key_info2
, der_cert2
;
485 TestCompletionCallback callback2
;
486 ChannelIDService::RequestHandle request_handle2
;
488 std::string
host3("bar.com");
489 std::string private_key_info3
, der_cert3
;
490 TestCompletionCallback callback3
;
491 ChannelIDService::RequestHandle request_handle3
;
493 error
= service_
->GetOrCreateChannelID(host1
,
496 callback1
.callback(),
498 EXPECT_EQ(ERR_IO_PENDING
, error
);
499 EXPECT_TRUE(request_handle1
.is_active());
501 error
= service_
->GetOrCreateChannelID(host2
,
504 callback2
.callback(),
506 EXPECT_EQ(ERR_IO_PENDING
, error
);
507 EXPECT_TRUE(request_handle2
.is_active());
509 error
= service_
->GetOrCreateChannelID(host3
,
512 callback3
.callback(),
514 EXPECT_EQ(ERR_IO_PENDING
, error
);
515 EXPECT_TRUE(request_handle3
.is_active());
517 error
= callback1
.WaitForResult();
518 EXPECT_EQ(OK
, error
);
519 EXPECT_FALSE(private_key_info1
.empty());
520 EXPECT_FALSE(der_cert1
.empty());
522 error
= callback2
.WaitForResult();
523 EXPECT_EQ(OK
, error
);
524 EXPECT_FALSE(private_key_info2
.empty());
525 EXPECT_FALSE(der_cert2
.empty());
527 error
= callback3
.WaitForResult();
528 EXPECT_EQ(OK
, error
);
529 EXPECT_FALSE(private_key_info3
.empty());
530 EXPECT_FALSE(der_cert3
.empty());
532 EXPECT_NE(private_key_info1
, private_key_info2
);
533 EXPECT_NE(der_cert1
, der_cert2
);
535 EXPECT_NE(private_key_info1
, private_key_info3
);
536 EXPECT_NE(der_cert1
, der_cert3
);
538 EXPECT_NE(private_key_info2
, private_key_info3
);
539 EXPECT_NE(der_cert2
, der_cert3
);
541 EXPECT_EQ(3, service_
->cert_count());
544 TEST_F(ChannelIDServiceTest
, Expiration
) {
545 ChannelIDStore
* store
= service_
->GetChannelIDStore();
546 base::Time now
= base::Time::Now();
547 store
->SetChannelID("good",
549 now
+ base::TimeDelta::FromDays(1),
552 store
->SetChannelID("expired",
553 now
- base::TimeDelta::FromDays(2),
554 now
- base::TimeDelta::FromDays(1),
557 EXPECT_EQ(2, service_
->cert_count());
560 TestCompletionCallback callback
;
561 ChannelIDService::RequestHandle request_handle
;
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());
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());
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()));
592 std::string
host("encrypted.google.com");
595 TestCompletionCallback callback
;
596 ChannelIDService::RequestHandle request_handle
;
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());
606 mock_store
->CallGetChannelIDCallbackWithResult(
607 ERR_FILE_NOT_FOUND
, base::Time(), std::string(), std::string());
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());
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()));
623 std::string
host("encrypted.google.com");
626 TestCompletionCallback callback
;
627 ChannelIDService::RequestHandle request_handle
;
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());
637 mock_store
->CallGetChannelIDCallbackWithResult(
638 ERR_FILE_NOT_FOUND
, base::Time(), std::string(), std::string());
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());
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()));
654 std::string
host("encrypted.google.com");
657 TestCompletionCallback callback
;
658 ChannelIDService::RequestHandle request_handle
;
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());
668 mock_store
->CallGetChannelIDCallbackWithResult(
669 OK
, base::Time(), "ab", "cd");
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
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());
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()));
690 std::string
host("encrypted.google.com");
693 TestCompletionCallback callback
;
694 ChannelIDService::RequestHandle request_handle
;
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());
704 mock_store
->CallGetChannelIDCallbackWithResult(
705 OK
, base::Time(), "ab", "cd");
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
714 EXPECT_EQ(0u, service_
->workers_created());
715 EXPECT_STREQ("cd", der_cert
.c_str());
716 EXPECT_FALSE(request_handle
.is_active());
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()));
725 std::string
host("encrypted.google.com");
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());
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());
749 mock_store
->CallGetChannelIDCallbackWithResult(
750 ERR_FILE_NOT_FOUND
, base::Time(), std::string(), std::string());
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
);
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());