Move pending tile priorities to active on tree activation
[chromium-blink-merge.git] / net / base / server_bound_cert_service_unittest.cc
blob9e505db81d9acbce5f069cc74ab38ec4c6469c42
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/base/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/asn1_util.h"
16 #include "net/base/default_server_bound_cert_store.h"
17 #include "net/base/net_errors.h"
18 #include "net/base/test_completion_callback.h"
19 #include "net/base/x509_certificate.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 protected:
32 virtual void SetUp() OVERRIDE {
33 sequenced_worker_pool_ = new base::SequencedWorkerPool(
34 3, "ServerBoundCertServiceTest");
35 service_.reset(new ServerBoundCertService(
36 new DefaultServerBoundCertStore(NULL), sequenced_worker_pool_));
39 virtual void TearDown() OVERRIDE {
40 sequenced_worker_pool_->Shutdown();
43 scoped_refptr<base::SequencedWorkerPool> sequenced_worker_pool_;
44 scoped_ptr<ServerBoundCertService> service_;
47 TEST_F(ServerBoundCertServiceTest, GetDomainForHost) {
48 EXPECT_EQ("google.com",
49 ServerBoundCertService::GetDomainForHost("google.com"));
50 EXPECT_EQ("google.com",
51 ServerBoundCertService::GetDomainForHost("www.google.com"));
52 // NOTE(rch): we would like to segregate cookies and certificates for
53 // *.appspot.com, but currently we can not do that becaues we want to
54 // allow direct navigation to appspot.com.
55 EXPECT_EQ("appspot.com",
56 ServerBoundCertService::GetDomainForHost("foo.appspot.com"));
57 EXPECT_EQ("google.com",
58 ServerBoundCertService::GetDomainForHost("www.mail.google.com"));
59 EXPECT_EQ("goto",
60 ServerBoundCertService::GetDomainForHost("goto"));
61 EXPECT_EQ("127.0.0.1",
62 ServerBoundCertService::GetDomainForHost("127.0.0.1"));
65 // See http://crbug.com/91512 - implement OpenSSL version of CreateSelfSigned.
66 #if !defined(USE_OPENSSL)
68 TEST_F(ServerBoundCertServiceTest, CacheHit) {
69 std::string origin("https://encrypted.google.com:443");
71 int error;
72 std::vector<uint8> types;
73 types.push_back(CLIENT_CERT_ECDSA_SIGN);
74 TestCompletionCallback callback;
75 ServerBoundCertService::RequestHandle request_handle;
77 // Asynchronous completion.
78 SSLClientCertType type1;
79 std::string private_key_info1, der_cert1;
80 EXPECT_EQ(0, service_->cert_count());
81 error = service_->GetDomainBoundCert(
82 origin, types, &type1, &private_key_info1, &der_cert1,
83 callback.callback(), &request_handle);
84 EXPECT_EQ(ERR_IO_PENDING, error);
85 EXPECT_TRUE(request_handle.is_active());
86 error = callback.WaitForResult();
87 EXPECT_EQ(OK, error);
88 EXPECT_EQ(1, service_->cert_count());
89 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1);
90 EXPECT_FALSE(private_key_info1.empty());
91 EXPECT_FALSE(der_cert1.empty());
92 EXPECT_FALSE(request_handle.is_active());
94 // Synchronous completion.
95 SSLClientCertType type2;
96 std::string private_key_info2, der_cert2;
97 error = service_->GetDomainBoundCert(
98 origin, types, &type2, &private_key_info2, &der_cert2,
99 callback.callback(), &request_handle);
100 EXPECT_FALSE(request_handle.is_active());
101 EXPECT_EQ(OK, error);
102 EXPECT_EQ(1, service_->cert_count());
103 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2);
104 EXPECT_EQ(private_key_info1, private_key_info2);
105 EXPECT_EQ(der_cert1, der_cert2);
107 EXPECT_EQ(2u, service_->requests());
108 EXPECT_EQ(1u, service_->cert_store_hits());
109 EXPECT_EQ(0u, service_->inflight_joins());
112 TEST_F(ServerBoundCertServiceTest, UnsupportedTypes) {
113 std::string origin("https://encrypted.google.com:443");
115 int error;
116 std::vector<uint8> types;
117 TestCompletionCallback callback;
118 ServerBoundCertService::RequestHandle request_handle;
120 // Empty requested_types.
121 SSLClientCertType type1;
122 std::string private_key_info1, der_cert1;
123 error = service_->GetDomainBoundCert(
124 origin, types, &type1, &private_key_info1, &der_cert1,
125 callback.callback(), &request_handle);
126 EXPECT_EQ(ERR_INVALID_ARGUMENT, error);
127 EXPECT_FALSE(request_handle.is_active());
129 // No supported types in requested_types.
130 types.push_back(CLIENT_CERT_RSA_SIGN);
131 types.push_back(2);
132 types.push_back(3);
133 error = service_->GetDomainBoundCert(
134 origin, types, &type1, &private_key_info1, &der_cert1,
135 callback.callback(), &request_handle);
136 EXPECT_EQ(ERR_CLIENT_AUTH_CERT_TYPE_UNSUPPORTED, error);
137 EXPECT_FALSE(request_handle.is_active());
139 // Supported types after unsupported ones in requested_types.
140 types.push_back(CLIENT_CERT_ECDSA_SIGN);
141 // Asynchronous completion.
142 EXPECT_EQ(0, service_->cert_count());
143 error = service_->GetDomainBoundCert(
144 origin, types, &type1, &private_key_info1, &der_cert1,
145 callback.callback(), &request_handle);
146 EXPECT_EQ(ERR_IO_PENDING, error);
147 EXPECT_TRUE(request_handle.is_active());
148 error = callback.WaitForResult();
149 EXPECT_EQ(OK, error);
150 EXPECT_EQ(1, service_->cert_count());
151 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1);
152 EXPECT_FALSE(private_key_info1.empty());
153 EXPECT_FALSE(der_cert1.empty());
155 // Now that the cert is created, doing requests for unsupported types
156 // shouldn't affect the created cert.
157 // Empty requested_types.
158 types.clear();
159 SSLClientCertType type2;
160 std::string private_key_info2, der_cert2;
161 error = service_->GetDomainBoundCert(
162 origin, types, &type2, &private_key_info2, &der_cert2,
163 callback.callback(), &request_handle);
164 EXPECT_EQ(ERR_INVALID_ARGUMENT, error);
165 EXPECT_FALSE(request_handle.is_active());
167 // No supported types in requested_types.
168 types.push_back(CLIENT_CERT_RSA_SIGN);
169 types.push_back(2);
170 types.push_back(3);
171 error = service_->GetDomainBoundCert(
172 origin, types, &type2, &private_key_info2, &der_cert2,
173 callback.callback(), &request_handle);
174 EXPECT_EQ(ERR_CLIENT_AUTH_CERT_TYPE_UNSUPPORTED, error);
175 EXPECT_FALSE(request_handle.is_active());
177 // If we request EC, the cert we created before should still be there.
178 types.push_back(CLIENT_CERT_ECDSA_SIGN);
179 error = service_->GetDomainBoundCert(
180 origin, types, &type2, &private_key_info2, &der_cert2,
181 callback.callback(), &request_handle);
182 EXPECT_FALSE(request_handle.is_active());
183 EXPECT_EQ(OK, error);
184 EXPECT_EQ(1, service_->cert_count());
185 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2);
186 EXPECT_EQ(private_key_info1, private_key_info2);
187 EXPECT_EQ(der_cert1, der_cert2);
190 TEST_F(ServerBoundCertServiceTest, StoreCerts) {
191 int error;
192 std::vector<uint8> types;
193 types.push_back(CLIENT_CERT_ECDSA_SIGN);
194 TestCompletionCallback callback;
195 ServerBoundCertService::RequestHandle request_handle;
197 std::string origin1("https://encrypted.google.com:443");
198 SSLClientCertType type1;
199 std::string private_key_info1, der_cert1;
200 EXPECT_EQ(0, service_->cert_count());
201 error = service_->GetDomainBoundCert(
202 origin1, types, &type1, &private_key_info1, &der_cert1,
203 callback.callback(), &request_handle);
204 EXPECT_EQ(ERR_IO_PENDING, error);
205 EXPECT_TRUE(request_handle.is_active());
206 error = callback.WaitForResult();
207 EXPECT_EQ(OK, error);
208 EXPECT_EQ(1, service_->cert_count());
210 std::string origin2("https://www.verisign.com:443");
211 SSLClientCertType type2;
212 std::string private_key_info2, der_cert2;
213 error = service_->GetDomainBoundCert(
214 origin2, types, &type2, &private_key_info2, &der_cert2,
215 callback.callback(), &request_handle);
216 EXPECT_EQ(ERR_IO_PENDING, error);
217 EXPECT_TRUE(request_handle.is_active());
218 error = callback.WaitForResult();
219 EXPECT_EQ(OK, error);
220 EXPECT_EQ(2, service_->cert_count());
222 std::string origin3("https://www.twitter.com:443");
223 SSLClientCertType type3;
224 std::string private_key_info3, der_cert3;
225 error = service_->GetDomainBoundCert(
226 origin3, types, &type3, &private_key_info3, &der_cert3,
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(3, service_->cert_count());
234 EXPECT_NE(private_key_info1, private_key_info2);
235 EXPECT_NE(der_cert1, der_cert2);
236 EXPECT_NE(private_key_info1, private_key_info3);
237 EXPECT_NE(der_cert1, der_cert3);
238 EXPECT_NE(private_key_info2, private_key_info3);
239 EXPECT_NE(der_cert2, der_cert3);
240 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1);
241 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2);
242 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type3);
245 // Tests an inflight join.
246 TEST_F(ServerBoundCertServiceTest, InflightJoin) {
247 std::string origin("https://encrypted.google.com:443");
248 int error;
249 std::vector<uint8> types;
250 types.push_back(CLIENT_CERT_ECDSA_SIGN);
252 SSLClientCertType type1;
253 std::string private_key_info1, der_cert1;
254 TestCompletionCallback callback1;
255 ServerBoundCertService::RequestHandle request_handle1;
257 SSLClientCertType type2;
258 std::string private_key_info2, der_cert2;
259 TestCompletionCallback callback2;
260 ServerBoundCertService::RequestHandle request_handle2;
262 error = service_->GetDomainBoundCert(
263 origin, types, &type1, &private_key_info1, &der_cert1,
264 callback1.callback(), &request_handle1);
265 EXPECT_EQ(ERR_IO_PENDING, error);
266 EXPECT_TRUE(request_handle1.is_active());
267 // If we request RSA and EC in the 2nd request, should still join with the
268 // original request.
269 types.insert(types.begin(), CLIENT_CERT_RSA_SIGN);
270 error = service_->GetDomainBoundCert(
271 origin, types, &type2, &private_key_info2, &der_cert2,
272 callback2.callback(), &request_handle2);
273 EXPECT_EQ(ERR_IO_PENDING, error);
274 EXPECT_TRUE(request_handle2.is_active());
276 error = callback1.WaitForResult();
277 EXPECT_EQ(OK, error);
278 error = callback2.WaitForResult();
279 EXPECT_EQ(OK, error);
281 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1);
282 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2);
283 EXPECT_EQ(2u, service_->requests());
284 EXPECT_EQ(0u, service_->cert_store_hits());
285 EXPECT_EQ(1u, service_->inflight_joins());
288 TEST_F(ServerBoundCertServiceTest, ExtractValuesFromBytesEC) {
289 std::string origin("https://encrypted.google.com:443");
290 SSLClientCertType type;
291 std::string private_key_info, der_cert;
292 int error;
293 std::vector<uint8> types;
294 types.push_back(CLIENT_CERT_ECDSA_SIGN);
295 TestCompletionCallback callback;
296 ServerBoundCertService::RequestHandle request_handle;
298 error = service_->GetDomainBoundCert(
299 origin, types, &type, &private_key_info, &der_cert, callback.callback(),
300 &request_handle);
301 EXPECT_EQ(ERR_IO_PENDING, error);
302 EXPECT_TRUE(request_handle.is_active());
303 error = callback.WaitForResult();
304 EXPECT_EQ(OK, error);
306 base::StringPiece spki_piece;
307 ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(der_cert, &spki_piece));
308 std::vector<uint8> spki(
309 spki_piece.data(),
310 spki_piece.data() + spki_piece.size());
312 // Check that we can retrieve the key from the bytes.
313 std::vector<uint8> key_vec(private_key_info.begin(), private_key_info.end());
314 scoped_ptr<crypto::ECPrivateKey> private_key(
315 crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo(
316 ServerBoundCertService::kEPKIPassword, key_vec, spki));
317 EXPECT_TRUE(private_key != NULL);
319 // Check that we can retrieve the cert from the bytes.
320 scoped_refptr<X509Certificate> x509cert(
321 X509Certificate::CreateFromBytes(der_cert.data(), der_cert.size()));
322 EXPECT_TRUE(x509cert != NULL);
325 // Tests that the callback of a canceled request is never made.
326 TEST_F(ServerBoundCertServiceTest, CancelRequest) {
327 std::string origin("https://encrypted.google.com:443");
328 SSLClientCertType type;
329 std::string private_key_info, der_cert;
330 int error;
331 std::vector<uint8> types;
332 types.push_back(CLIENT_CERT_ECDSA_SIGN);
333 ServerBoundCertService::RequestHandle request_handle;
335 error = service_->GetDomainBoundCert(origin,
336 types,
337 &type,
338 &private_key_info,
339 &der_cert,
340 base::Bind(&FailTest),
341 &request_handle);
342 EXPECT_EQ(ERR_IO_PENDING, error);
343 EXPECT_TRUE(request_handle.is_active());
344 request_handle.Cancel();
345 EXPECT_FALSE(request_handle.is_active());
347 // Wait for generation to finish.
348 sequenced_worker_pool_->FlushForTesting();
349 // Wait for reply from ServerBoundCertServiceWorker to be posted back to the
350 // ServerBoundCertService.
351 MessageLoop::current()->RunUntilIdle();
353 // Even though the original request was cancelled, the service will still
354 // store the result, it just doesn't call the callback.
355 EXPECT_EQ(1, service_->cert_count());
358 // Tests that destructing the RequestHandle cancels the request.
359 TEST_F(ServerBoundCertServiceTest, CancelRequestByHandleDestruction) {
360 std::string origin("https://encrypted.google.com:443");
361 SSLClientCertType type;
362 std::string private_key_info, der_cert;
363 int error;
364 std::vector<uint8> types;
365 types.push_back(CLIENT_CERT_ECDSA_SIGN);
367 ServerBoundCertService::RequestHandle request_handle;
369 error = service_->GetDomainBoundCert(origin,
370 types,
371 &type,
372 &private_key_info,
373 &der_cert,
374 base::Bind(&FailTest),
375 &request_handle);
376 EXPECT_EQ(ERR_IO_PENDING, error);
377 EXPECT_TRUE(request_handle.is_active());
380 // Wait for generation to finish.
381 sequenced_worker_pool_->FlushForTesting();
382 // Wait for reply from ServerBoundCertServiceWorker to be posted back to the
383 // ServerBoundCertService.
384 MessageLoop::current()->RunUntilIdle();
386 // Even though the original request was cancelled, the service will still
387 // store the result, it just doesn't call the callback.
388 EXPECT_EQ(1, service_->cert_count());
391 TEST_F(ServerBoundCertServiceTest, DestructionWithPendingRequest) {
392 std::string origin("https://encrypted.google.com:443");
393 SSLClientCertType type;
394 std::string private_key_info, der_cert;
395 int error;
396 std::vector<uint8> types;
397 types.push_back(CLIENT_CERT_ECDSA_SIGN);
398 ServerBoundCertService::RequestHandle request_handle;
400 error = service_->GetDomainBoundCert(origin,
401 types,
402 &type,
403 &private_key_info,
404 &der_cert,
405 base::Bind(&FailTest),
406 &request_handle);
407 EXPECT_EQ(ERR_IO_PENDING, error);
408 EXPECT_TRUE(request_handle.is_active());
410 // Cancel request and destroy the ServerBoundCertService.
411 request_handle.Cancel();
412 service_.reset();
414 // Wait for generation to finish.
415 sequenced_worker_pool_->FlushForTesting();
416 // ServerBoundCertServiceWorker should not post anything back to the
417 // non-existant ServerBoundCertService, but run the loop just to be sure it
418 // doesn't.
419 MessageLoop::current()->RunUntilIdle();
421 // If we got here without crashing or a valgrind error, it worked.
424 // Tests that simultaneous creation of different certs works.
425 TEST_F(ServerBoundCertServiceTest, SimultaneousCreation) {
426 int error;
427 std::vector<uint8> types;
428 types.push_back(CLIENT_CERT_ECDSA_SIGN);
430 std::string origin1("https://encrypted.google.com:443");
431 SSLClientCertType type1;
432 std::string private_key_info1, der_cert1;
433 TestCompletionCallback callback1;
434 ServerBoundCertService::RequestHandle request_handle1;
436 std::string origin2("https://foo.com:443");
437 SSLClientCertType type2;
438 std::string private_key_info2, der_cert2;
439 TestCompletionCallback callback2;
440 ServerBoundCertService::RequestHandle request_handle2;
442 std::string origin3("https://bar.com:443");
443 SSLClientCertType type3;
444 std::string private_key_info3, der_cert3;
445 TestCompletionCallback callback3;
446 ServerBoundCertService::RequestHandle request_handle3;
448 error = service_->GetDomainBoundCert(origin1,
449 types,
450 &type1,
451 &private_key_info1,
452 &der_cert1,
453 callback1.callback(),
454 &request_handle1);
455 EXPECT_EQ(ERR_IO_PENDING, error);
456 EXPECT_TRUE(request_handle1.is_active());
458 error = service_->GetDomainBoundCert(origin2,
459 types,
460 &type2,
461 &private_key_info2,
462 &der_cert2,
463 callback2.callback(),
464 &request_handle2);
465 EXPECT_EQ(ERR_IO_PENDING, error);
466 EXPECT_TRUE(request_handle2.is_active());
468 error = service_->GetDomainBoundCert(origin3,
469 types,
470 &type3,
471 &private_key_info3,
472 &der_cert3,
473 callback3.callback(),
474 &request_handle3);
475 EXPECT_EQ(ERR_IO_PENDING, error);
476 EXPECT_TRUE(request_handle3.is_active());
478 error = callback1.WaitForResult();
479 EXPECT_EQ(OK, error);
480 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1);
481 EXPECT_FALSE(private_key_info1.empty());
482 EXPECT_FALSE(der_cert1.empty());
484 error = callback2.WaitForResult();
485 EXPECT_EQ(OK, error);
486 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2);
487 EXPECT_FALSE(private_key_info2.empty());
488 EXPECT_FALSE(der_cert2.empty());
490 error = callback3.WaitForResult();
491 EXPECT_EQ(OK, error);
492 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type3);
493 EXPECT_FALSE(private_key_info3.empty());
494 EXPECT_FALSE(der_cert3.empty());
496 EXPECT_NE(private_key_info1, private_key_info2);
497 EXPECT_NE(der_cert1, der_cert2);
499 EXPECT_NE(private_key_info1, private_key_info3);
500 EXPECT_NE(der_cert1, der_cert3);
502 EXPECT_NE(private_key_info2, private_key_info3);
503 EXPECT_NE(der_cert2, der_cert3);
505 EXPECT_EQ(3, service_->cert_count());
508 TEST_F(ServerBoundCertServiceTest, Expiration) {
509 ServerBoundCertStore* store = service_->GetCertStore();
510 base::Time now = base::Time::Now();
511 store->SetServerBoundCert("good",
512 CLIENT_CERT_ECDSA_SIGN,
513 now,
514 now + base::TimeDelta::FromDays(1),
515 "a",
516 "b");
517 store->SetServerBoundCert("expired",
518 CLIENT_CERT_ECDSA_SIGN,
519 now - base::TimeDelta::FromDays(2),
520 now - base::TimeDelta::FromDays(1),
521 "c",
522 "d");
523 EXPECT_EQ(2, service_->cert_count());
525 int error;
526 std::vector<uint8> types;
527 types.push_back(CLIENT_CERT_ECDSA_SIGN);
528 TestCompletionCallback callback;
529 ServerBoundCertService::RequestHandle request_handle;
531 // Cert still valid - synchronous completion.
532 SSLClientCertType type1;
533 std::string private_key_info1, der_cert1;
534 error = service_->GetDomainBoundCert(
535 "https://good", types, &type1, &private_key_info1, &der_cert1,
536 callback.callback(), &request_handle);
537 EXPECT_EQ(OK, error);
538 EXPECT_FALSE(request_handle.is_active());
539 EXPECT_EQ(2, service_->cert_count());
540 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1);
541 EXPECT_STREQ("a", private_key_info1.c_str());
542 EXPECT_STREQ("b", der_cert1.c_str());
544 // Cert expired - New cert will be generated, asynchronous completion.
545 SSLClientCertType type2;
546 std::string private_key_info2, der_cert2;
547 error = service_->GetDomainBoundCert(
548 "https://expired", types, &type2, &private_key_info2, &der_cert2,
549 callback.callback(), &request_handle);
550 EXPECT_EQ(ERR_IO_PENDING, error);
551 EXPECT_TRUE(request_handle.is_active());
552 error = callback.WaitForResult();
553 EXPECT_EQ(OK, error);
554 EXPECT_EQ(2, service_->cert_count());
555 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2);
556 EXPECT_LT(1U, private_key_info2.size());
557 EXPECT_LT(1U, der_cert2.size());
560 #endif // !defined(USE_OPENSSL)
562 } // namespace
564 } // namespace net