Make touch-resizing windows to screen edge possible
[chromium-blink-merge.git] / net / ssl / server_bound_cert_service_unittest.cc
blob0c5105e4a8db1def4ba64810857261e96582fa8b
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.
5 #include "net/ssl/server_bound_cert_service.h"
7 #include <string>
8 #include <vector>
10 #include "base/bind.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/message_loop.h"
13 #include "base/threading/sequenced_worker_pool.h"
14 #include "crypto/ec_private_key.h"
15 #include "net/base/net_errors.h"
16 #include "net/base/test_completion_callback.h"
17 #include "net/cert/asn1_util.h"
18 #include "net/cert/x509_certificate.h"
19 #include "net/ssl/default_server_bound_cert_store.h"
20 #include "testing/gtest/include/gtest/gtest.h"
22 namespace net {
24 namespace {
26 void FailTest(int /* result */) {
27 FAIL();
30 class ServerBoundCertServiceTest : public testing::Test {
31 public:
32 ServerBoundCertServiceTest()
33 : sequenced_worker_pool_(new base::SequencedWorkerPool(
34 3, "ServerBoundCertServiceTest")),
35 service_(new ServerBoundCertService(
36 new DefaultServerBoundCertStore(NULL),
37 sequenced_worker_pool_)) {
40 virtual ~ServerBoundCertServiceTest() {
41 if (sequenced_worker_pool_.get())
42 sequenced_worker_pool_->Shutdown();
45 protected:
46 scoped_refptr<base::SequencedWorkerPool> sequenced_worker_pool_;
47 scoped_ptr<ServerBoundCertService> service_;
50 TEST_F(ServerBoundCertServiceTest, GetDomainForHost) {
51 EXPECT_EQ("google.com",
52 ServerBoundCertService::GetDomainForHost("google.com"));
53 EXPECT_EQ("google.com",
54 ServerBoundCertService::GetDomainForHost("www.google.com"));
55 EXPECT_EQ("foo.appspot.com",
56 ServerBoundCertService::GetDomainForHost("foo.appspot.com"));
57 EXPECT_EQ("bar.appspot.com",
58 ServerBoundCertService::GetDomainForHost("foo.bar.appspot.com"));
59 EXPECT_EQ("appspot.com",
60 ServerBoundCertService::GetDomainForHost("appspot.com"));
61 EXPECT_EQ("google.com",
62 ServerBoundCertService::GetDomainForHost("www.mail.google.com"));
63 EXPECT_EQ("goto",
64 ServerBoundCertService::GetDomainForHost("goto"));
65 EXPECT_EQ("127.0.0.1",
66 ServerBoundCertService::GetDomainForHost("127.0.0.1"));
69 // See http://crbug.com/91512 - implement OpenSSL version of CreateSelfSigned.
70 #if !defined(USE_OPENSSL)
72 TEST_F(ServerBoundCertServiceTest, CacheHit) {
73 std::string host("encrypted.google.com");
75 int error;
76 std::vector<uint8> types;
77 types.push_back(CLIENT_CERT_ECDSA_SIGN);
78 TestCompletionCallback callback;
79 ServerBoundCertService::RequestHandle request_handle;
81 // Asynchronous completion.
82 SSLClientCertType type1;
83 std::string private_key_info1, der_cert1;
84 EXPECT_EQ(0, service_->cert_count());
85 error = service_->GetDomainBoundCert(
86 host, types, &type1, &private_key_info1, &der_cert1,
87 callback.callback(), &request_handle);
88 EXPECT_EQ(ERR_IO_PENDING, error);
89 EXPECT_TRUE(request_handle.is_active());
90 error = callback.WaitForResult();
91 EXPECT_EQ(OK, error);
92 EXPECT_EQ(1, service_->cert_count());
93 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1);
94 EXPECT_FALSE(private_key_info1.empty());
95 EXPECT_FALSE(der_cert1.empty());
96 EXPECT_FALSE(request_handle.is_active());
98 // Synchronous completion.
99 SSLClientCertType type2;
100 std::string private_key_info2, der_cert2;
101 error = service_->GetDomainBoundCert(
102 host, types, &type2, &private_key_info2, &der_cert2,
103 callback.callback(), &request_handle);
104 EXPECT_FALSE(request_handle.is_active());
105 EXPECT_EQ(OK, error);
106 EXPECT_EQ(1, service_->cert_count());
107 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2);
108 EXPECT_EQ(private_key_info1, private_key_info2);
109 EXPECT_EQ(der_cert1, der_cert2);
111 EXPECT_EQ(2u, service_->requests());
112 EXPECT_EQ(1u, service_->cert_store_hits());
113 EXPECT_EQ(0u, service_->inflight_joins());
116 TEST_F(ServerBoundCertServiceTest, UnsupportedTypes) {
117 std::string host("encrypted.google.com");
119 int error;
120 std::vector<uint8> types;
121 TestCompletionCallback callback;
122 ServerBoundCertService::RequestHandle request_handle;
124 // Empty requested_types.
125 SSLClientCertType type1;
126 std::string private_key_info1, der_cert1;
127 error = service_->GetDomainBoundCert(
128 host, types, &type1, &private_key_info1, &der_cert1,
129 callback.callback(), &request_handle);
130 EXPECT_EQ(ERR_INVALID_ARGUMENT, error);
131 EXPECT_FALSE(request_handle.is_active());
133 // No supported types in requested_types.
134 types.push_back(CLIENT_CERT_RSA_SIGN);
135 types.push_back(2);
136 types.push_back(3);
137 error = service_->GetDomainBoundCert(
138 host, types, &type1, &private_key_info1, &der_cert1,
139 callback.callback(), &request_handle);
140 EXPECT_EQ(ERR_CLIENT_AUTH_CERT_TYPE_UNSUPPORTED, error);
141 EXPECT_FALSE(request_handle.is_active());
143 // Supported types after unsupported ones in requested_types.
144 types.push_back(CLIENT_CERT_ECDSA_SIGN);
145 // Asynchronous completion.
146 EXPECT_EQ(0, service_->cert_count());
147 error = service_->GetDomainBoundCert(
148 host, types, &type1, &private_key_info1, &der_cert1,
149 callback.callback(), &request_handle);
150 EXPECT_EQ(ERR_IO_PENDING, error);
151 EXPECT_TRUE(request_handle.is_active());
152 error = callback.WaitForResult();
153 EXPECT_EQ(OK, error);
154 EXPECT_EQ(1, service_->cert_count());
155 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1);
156 EXPECT_FALSE(private_key_info1.empty());
157 EXPECT_FALSE(der_cert1.empty());
159 // Now that the cert is created, doing requests for unsupported types
160 // shouldn't affect the created cert.
161 // Empty requested_types.
162 types.clear();
163 SSLClientCertType type2;
164 std::string private_key_info2, der_cert2;
165 error = service_->GetDomainBoundCert(
166 host, types, &type2, &private_key_info2, &der_cert2,
167 callback.callback(), &request_handle);
168 EXPECT_EQ(ERR_INVALID_ARGUMENT, error);
169 EXPECT_FALSE(request_handle.is_active());
171 // No supported types in requested_types.
172 types.push_back(CLIENT_CERT_RSA_SIGN);
173 types.push_back(2);
174 types.push_back(3);
175 error = service_->GetDomainBoundCert(
176 host, types, &type2, &private_key_info2, &der_cert2,
177 callback.callback(), &request_handle);
178 EXPECT_EQ(ERR_CLIENT_AUTH_CERT_TYPE_UNSUPPORTED, error);
179 EXPECT_FALSE(request_handle.is_active());
181 // If we request EC, the cert we created before should still be there.
182 types.push_back(CLIENT_CERT_ECDSA_SIGN);
183 error = service_->GetDomainBoundCert(
184 host, types, &type2, &private_key_info2, &der_cert2,
185 callback.callback(), &request_handle);
186 EXPECT_FALSE(request_handle.is_active());
187 EXPECT_EQ(OK, error);
188 EXPECT_EQ(1, service_->cert_count());
189 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2);
190 EXPECT_EQ(private_key_info1, private_key_info2);
191 EXPECT_EQ(der_cert1, der_cert2);
194 TEST_F(ServerBoundCertServiceTest, StoreCerts) {
195 int error;
196 std::vector<uint8> types;
197 types.push_back(CLIENT_CERT_ECDSA_SIGN);
198 TestCompletionCallback callback;
199 ServerBoundCertService::RequestHandle request_handle;
201 std::string host1("encrypted.google.com");
202 SSLClientCertType type1;
203 std::string private_key_info1, der_cert1;
204 EXPECT_EQ(0, service_->cert_count());
205 error = service_->GetDomainBoundCert(
206 host1, types, &type1, &private_key_info1, &der_cert1,
207 callback.callback(), &request_handle);
208 EXPECT_EQ(ERR_IO_PENDING, error);
209 EXPECT_TRUE(request_handle.is_active());
210 error = callback.WaitForResult();
211 EXPECT_EQ(OK, error);
212 EXPECT_EQ(1, service_->cert_count());
214 std::string host2("www.verisign.com");
215 SSLClientCertType type2;
216 std::string private_key_info2, der_cert2;
217 error = service_->GetDomainBoundCert(
218 host2, types, &type2, &private_key_info2, &der_cert2,
219 callback.callback(), &request_handle);
220 EXPECT_EQ(ERR_IO_PENDING, error);
221 EXPECT_TRUE(request_handle.is_active());
222 error = callback.WaitForResult();
223 EXPECT_EQ(OK, error);
224 EXPECT_EQ(2, service_->cert_count());
226 std::string host3("www.twitter.com");
227 SSLClientCertType type3;
228 std::string private_key_info3, der_cert3;
229 error = service_->GetDomainBoundCert(
230 host3, types, &type3, &private_key_info3, &der_cert3,
231 callback.callback(), &request_handle);
232 EXPECT_EQ(ERR_IO_PENDING, error);
233 EXPECT_TRUE(request_handle.is_active());
234 error = callback.WaitForResult();
235 EXPECT_EQ(OK, error);
236 EXPECT_EQ(3, service_->cert_count());
238 EXPECT_NE(private_key_info1, private_key_info2);
239 EXPECT_NE(der_cert1, der_cert2);
240 EXPECT_NE(private_key_info1, private_key_info3);
241 EXPECT_NE(der_cert1, der_cert3);
242 EXPECT_NE(private_key_info2, private_key_info3);
243 EXPECT_NE(der_cert2, der_cert3);
244 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1);
245 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2);
246 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type3);
249 // Tests an inflight join.
250 TEST_F(ServerBoundCertServiceTest, InflightJoin) {
251 std::string host("encrypted.google.com");
252 int error;
253 std::vector<uint8> types;
254 types.push_back(CLIENT_CERT_ECDSA_SIGN);
256 SSLClientCertType type1;
257 std::string private_key_info1, der_cert1;
258 TestCompletionCallback callback1;
259 ServerBoundCertService::RequestHandle request_handle1;
261 SSLClientCertType type2;
262 std::string private_key_info2, der_cert2;
263 TestCompletionCallback callback2;
264 ServerBoundCertService::RequestHandle request_handle2;
266 error = service_->GetDomainBoundCert(
267 host, types, &type1, &private_key_info1, &der_cert1,
268 callback1.callback(), &request_handle1);
269 EXPECT_EQ(ERR_IO_PENDING, error);
270 EXPECT_TRUE(request_handle1.is_active());
271 // If we request RSA and EC in the 2nd request, should still join with the
272 // original request.
273 types.insert(types.begin(), CLIENT_CERT_RSA_SIGN);
274 error = service_->GetDomainBoundCert(
275 host, types, &type2, &private_key_info2, &der_cert2,
276 callback2.callback(), &request_handle2);
277 EXPECT_EQ(ERR_IO_PENDING, error);
278 EXPECT_TRUE(request_handle2.is_active());
280 error = callback1.WaitForResult();
281 EXPECT_EQ(OK, error);
282 error = callback2.WaitForResult();
283 EXPECT_EQ(OK, error);
285 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1);
286 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2);
287 EXPECT_EQ(2u, service_->requests());
288 EXPECT_EQ(0u, service_->cert_store_hits());
289 EXPECT_EQ(1u, service_->inflight_joins());
292 TEST_F(ServerBoundCertServiceTest, ExtractValuesFromBytesEC) {
293 std::string host("encrypted.google.com");
294 SSLClientCertType type;
295 std::string private_key_info, der_cert;
296 int error;
297 std::vector<uint8> types;
298 types.push_back(CLIENT_CERT_ECDSA_SIGN);
299 TestCompletionCallback callback;
300 ServerBoundCertService::RequestHandle request_handle;
302 error = service_->GetDomainBoundCert(
303 host, types, &type, &private_key_info, &der_cert, callback.callback(),
304 &request_handle);
305 EXPECT_EQ(ERR_IO_PENDING, error);
306 EXPECT_TRUE(request_handle.is_active());
307 error = callback.WaitForResult();
308 EXPECT_EQ(OK, error);
310 base::StringPiece spki_piece;
311 ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(der_cert, &spki_piece));
312 std::vector<uint8> spki(
313 spki_piece.data(),
314 spki_piece.data() + spki_piece.size());
316 // Check that we can retrieve the key from the bytes.
317 std::vector<uint8> key_vec(private_key_info.begin(), private_key_info.end());
318 scoped_ptr<crypto::ECPrivateKey> private_key(
319 crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo(
320 ServerBoundCertService::kEPKIPassword, key_vec, spki));
321 EXPECT_TRUE(private_key != NULL);
323 // Check that we can retrieve the cert from the bytes.
324 scoped_refptr<X509Certificate> x509cert(
325 X509Certificate::CreateFromBytes(der_cert.data(), der_cert.size()));
326 EXPECT_TRUE(x509cert.get() != NULL);
329 // Tests that the callback of a canceled request is never made.
330 TEST_F(ServerBoundCertServiceTest, CancelRequest) {
331 std::string host("encrypted.google.com");
332 SSLClientCertType type;
333 std::string private_key_info, der_cert;
334 int error;
335 std::vector<uint8> types;
336 types.push_back(CLIENT_CERT_ECDSA_SIGN);
337 ServerBoundCertService::RequestHandle request_handle;
339 error = service_->GetDomainBoundCert(host,
340 types,
341 &type,
342 &private_key_info,
343 &der_cert,
344 base::Bind(&FailTest),
345 &request_handle);
346 EXPECT_EQ(ERR_IO_PENDING, error);
347 EXPECT_TRUE(request_handle.is_active());
348 request_handle.Cancel();
349 EXPECT_FALSE(request_handle.is_active());
351 // Wait for generation to finish.
352 sequenced_worker_pool_->FlushForTesting();
353 // Wait for reply from ServerBoundCertServiceWorker to be posted back to the
354 // ServerBoundCertService.
355 base::MessageLoop::current()->RunUntilIdle();
357 // Even though the original request was cancelled, the service will still
358 // store the result, it just doesn't call the callback.
359 EXPECT_EQ(1, service_->cert_count());
362 // Tests that destructing the RequestHandle cancels the request.
363 TEST_F(ServerBoundCertServiceTest, CancelRequestByHandleDestruction) {
364 std::string host("encrypted.google.com");
365 SSLClientCertType type;
366 std::string private_key_info, der_cert;
367 int error;
368 std::vector<uint8> types;
369 types.push_back(CLIENT_CERT_ECDSA_SIGN);
371 ServerBoundCertService::RequestHandle request_handle;
373 error = service_->GetDomainBoundCert(host,
374 types,
375 &type,
376 &private_key_info,
377 &der_cert,
378 base::Bind(&FailTest),
379 &request_handle);
380 EXPECT_EQ(ERR_IO_PENDING, error);
381 EXPECT_TRUE(request_handle.is_active());
384 // Wait for generation to finish.
385 sequenced_worker_pool_->FlushForTesting();
386 // Wait for reply from ServerBoundCertServiceWorker to be posted back to the
387 // ServerBoundCertService.
388 base::MessageLoop::current()->RunUntilIdle();
390 // Even though the original request was cancelled, the service will still
391 // store the result, it just doesn't call the callback.
392 EXPECT_EQ(1, service_->cert_count());
395 TEST_F(ServerBoundCertServiceTest, DestructionWithPendingRequest) {
396 std::string host("encrypted.google.com");
397 SSLClientCertType type;
398 std::string private_key_info, der_cert;
399 int error;
400 std::vector<uint8> types;
401 types.push_back(CLIENT_CERT_ECDSA_SIGN);
402 ServerBoundCertService::RequestHandle request_handle;
404 error = service_->GetDomainBoundCert(host,
405 types,
406 &type,
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());
414 // Cancel request and destroy the ServerBoundCertService.
415 request_handle.Cancel();
416 service_.reset();
418 // Wait for generation to finish.
419 sequenced_worker_pool_->FlushForTesting();
420 // ServerBoundCertServiceWorker should not post anything back to the
421 // non-existant ServerBoundCertService, but run the loop just to be sure it
422 // doesn't.
423 base::MessageLoop::current()->RunUntilIdle();
425 // If we got here without crashing or a valgrind error, it worked.
428 // Tests that shutting down the sequenced worker pool and then making new
429 // requests gracefully fails.
430 // This is a regression test for http://crbug.com/236387
431 TEST_F(ServerBoundCertServiceTest, RequestAfterPoolShutdown) {
432 // Shutdown the pool immediately.
433 sequenced_worker_pool_->Shutdown();
434 sequenced_worker_pool_ = NULL;
436 // Ensure any shutdown code is processed.
437 base::MessageLoop::current()->RunUntilIdle();
439 // Make a request that will force synchronous completion.
440 std::string host("encrypted.google.com");
441 SSLClientCertType type;
442 std::string private_key_info, der_cert;
443 int error;
444 std::vector<uint8> types;
445 types.push_back(CLIENT_CERT_ECDSA_SIGN);
446 ServerBoundCertService::RequestHandle request_handle;
448 error = service_->GetDomainBoundCert(host,
449 types,
450 &type,
451 &private_key_info,
452 &der_cert,
453 base::Bind(&FailTest),
454 &request_handle);
455 // If we got here without crashing or a valgrind error, it worked.
456 ASSERT_EQ(ERR_INSUFFICIENT_RESOURCES, error);
457 EXPECT_FALSE(request_handle.is_active());
460 // Tests that simultaneous creation of different certs works.
461 TEST_F(ServerBoundCertServiceTest, SimultaneousCreation) {
462 int error;
463 std::vector<uint8> types;
464 types.push_back(CLIENT_CERT_ECDSA_SIGN);
466 std::string host1("encrypted.google.com");
467 SSLClientCertType type1;
468 std::string private_key_info1, der_cert1;
469 TestCompletionCallback callback1;
470 ServerBoundCertService::RequestHandle request_handle1;
472 std::string host2("foo.com");
473 SSLClientCertType type2;
474 std::string private_key_info2, der_cert2;
475 TestCompletionCallback callback2;
476 ServerBoundCertService::RequestHandle request_handle2;
478 std::string host3("bar.com");
479 SSLClientCertType type3;
480 std::string private_key_info3, der_cert3;
481 TestCompletionCallback callback3;
482 ServerBoundCertService::RequestHandle request_handle3;
484 error = service_->GetDomainBoundCert(host1,
485 types,
486 &type1,
487 &private_key_info1,
488 &der_cert1,
489 callback1.callback(),
490 &request_handle1);
491 EXPECT_EQ(ERR_IO_PENDING, error);
492 EXPECT_TRUE(request_handle1.is_active());
494 error = service_->GetDomainBoundCert(host2,
495 types,
496 &type2,
497 &private_key_info2,
498 &der_cert2,
499 callback2.callback(),
500 &request_handle2);
501 EXPECT_EQ(ERR_IO_PENDING, error);
502 EXPECT_TRUE(request_handle2.is_active());
504 error = service_->GetDomainBoundCert(host3,
505 types,
506 &type3,
507 &private_key_info3,
508 &der_cert3,
509 callback3.callback(),
510 &request_handle3);
511 EXPECT_EQ(ERR_IO_PENDING, error);
512 EXPECT_TRUE(request_handle3.is_active());
514 error = callback1.WaitForResult();
515 EXPECT_EQ(OK, error);
516 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1);
517 EXPECT_FALSE(private_key_info1.empty());
518 EXPECT_FALSE(der_cert1.empty());
520 error = callback2.WaitForResult();
521 EXPECT_EQ(OK, error);
522 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2);
523 EXPECT_FALSE(private_key_info2.empty());
524 EXPECT_FALSE(der_cert2.empty());
526 error = callback3.WaitForResult();
527 EXPECT_EQ(OK, error);
528 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type3);
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(ServerBoundCertServiceTest, Expiration) {
545 ServerBoundCertStore* store = service_->GetCertStore();
546 base::Time now = base::Time::Now();
547 store->SetServerBoundCert("good",
548 CLIENT_CERT_ECDSA_SIGN,
549 now,
550 now + base::TimeDelta::FromDays(1),
551 "a",
552 "b");
553 store->SetServerBoundCert("expired",
554 CLIENT_CERT_ECDSA_SIGN,
555 now - base::TimeDelta::FromDays(2),
556 now - base::TimeDelta::FromDays(1),
557 "c",
558 "d");
559 EXPECT_EQ(2, service_->cert_count());
561 int error;
562 std::vector<uint8> types;
563 types.push_back(CLIENT_CERT_ECDSA_SIGN);
564 TestCompletionCallback callback;
565 ServerBoundCertService::RequestHandle request_handle;
567 // Cert is valid - synchronous completion.
568 SSLClientCertType type1;
569 std::string private_key_info1, der_cert1;
570 error = service_->GetDomainBoundCert(
571 "good", types, &type1, &private_key_info1, &der_cert1,
572 callback.callback(), &request_handle);
573 EXPECT_EQ(OK, error);
574 EXPECT_FALSE(request_handle.is_active());
575 EXPECT_EQ(2, service_->cert_count());
576 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1);
577 EXPECT_STREQ("a", private_key_info1.c_str());
578 EXPECT_STREQ("b", der_cert1.c_str());
580 // Expired cert is valid as well - synchronous completion.
581 SSLClientCertType type2;
582 std::string private_key_info2, der_cert2;
583 error = service_->GetDomainBoundCert(
584 "expired", types, &type2, &private_key_info2, &der_cert2,
585 callback.callback(), &request_handle);
586 EXPECT_EQ(OK, error);
587 EXPECT_FALSE(request_handle.is_active());
588 EXPECT_EQ(2, service_->cert_count());
589 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2);
590 EXPECT_STREQ("c", private_key_info2.c_str());
591 EXPECT_STREQ("d", der_cert2.c_str());
594 #endif // !defined(USE_OPENSSL)
596 } // namespace
598 } // namespace net