OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "net/base/server_bound_cert_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.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" | |
21 | |
22 namespace net { | |
23 | |
24 namespace { | |
25 | |
26 void FailTest(int /* result */) { | |
27 FAIL(); | |
28 } | |
29 | |
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_)); | |
37 } | |
38 | |
39 virtual void TearDown() OVERRIDE { | |
40 sequenced_worker_pool_->Shutdown(); | |
41 } | |
42 | |
43 scoped_refptr<base::SequencedWorkerPool> sequenced_worker_pool_; | |
44 scoped_ptr<ServerBoundCertService> service_; | |
45 }; | |
46 | |
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")); | |
63 } | |
64 | |
65 // See http://crbug.com/91512 - implement OpenSSL version of CreateSelfSigned. | |
66 #if !defined(USE_OPENSSL) | |
67 | |
68 TEST_F(ServerBoundCertServiceTest, CacheHit) { | |
69 std::string origin("https://encrypted.google.com:443"); | |
70 | |
71 int error; | |
72 std::vector<uint8> types; | |
73 types.push_back(CLIENT_CERT_ECDSA_SIGN); | |
74 TestCompletionCallback callback; | |
75 ServerBoundCertService::RequestHandle request_handle; | |
76 | |
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()); | |
93 | |
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); | |
106 | |
107 EXPECT_EQ(2u, service_->requests()); | |
108 EXPECT_EQ(1u, service_->cert_store_hits()); | |
109 EXPECT_EQ(0u, service_->inflight_joins()); | |
110 } | |
111 | |
112 TEST_F(ServerBoundCertServiceTest, UnsupportedTypes) { | |
113 std::string origin("https://encrypted.google.com:443"); | |
114 | |
115 int error; | |
116 std::vector<uint8> types; | |
117 TestCompletionCallback callback; | |
118 ServerBoundCertService::RequestHandle request_handle; | |
119 | |
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()); | |
128 | |
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()); | |
138 | |
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()); | |
154 | |
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()); | |
166 | |
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()); | |
176 | |
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); | |
188 } | |
189 | |
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; | |
196 | |
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()); | |
209 | |
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()); | |
221 | |
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()); | |
233 | |
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); | |
243 } | |
244 | |
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); | |
251 | |
252 SSLClientCertType type1; | |
253 std::string private_key_info1, der_cert1; | |
254 TestCompletionCallback callback1; | |
255 ServerBoundCertService::RequestHandle request_handle1; | |
256 | |
257 SSLClientCertType type2; | |
258 std::string private_key_info2, der_cert2; | |
259 TestCompletionCallback callback2; | |
260 ServerBoundCertService::RequestHandle request_handle2; | |
261 | |
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()); | |
275 | |
276 error = callback1.WaitForResult(); | |
277 EXPECT_EQ(OK, error); | |
278 error = callback2.WaitForResult(); | |
279 EXPECT_EQ(OK, error); | |
280 | |
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()); | |
286 } | |
287 | |
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; | |
297 | |
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); | |
305 | |
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()); | |
311 | |
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); | |
318 | |
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); | |
323 } | |
324 | |
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; | |
334 | |
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()); | |
346 | |
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(); | |
352 | |
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()); | |
356 } | |
357 | |
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); | |
366 { | |
367 ServerBoundCertService::RequestHandle request_handle; | |
368 | |
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()); | |
378 } | |
379 | |
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(); | |
385 | |
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()); | |
389 } | |
390 | |
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; | |
399 | |
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()); | |
409 | |
410 // Cancel request and destroy the ServerBoundCertService. | |
411 request_handle.Cancel(); | |
412 service_.reset(); | |
413 | |
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(); | |
420 | |
421 // If we got here without crashing or a valgrind error, it worked. | |
422 } | |
423 | |
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); | |
429 | |
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; | |
435 | |
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; | |
441 | |
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; | |
447 | |
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()); | |
457 | |
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()); | |
467 | |
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()); | |
477 | |
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()); | |
483 | |
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()); | |
489 | |
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()); | |
495 | |
496 EXPECT_NE(private_key_info1, private_key_info2); | |
497 EXPECT_NE(der_cert1, der_cert2); | |
498 | |
499 EXPECT_NE(private_key_info1, private_key_info3); | |
500 EXPECT_NE(der_cert1, der_cert3); | |
501 | |
502 EXPECT_NE(private_key_info2, private_key_info3); | |
503 EXPECT_NE(der_cert2, der_cert3); | |
504 | |
505 EXPECT_EQ(3, service_->cert_count()); | |
506 } | |
507 | |
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()); | |
524 | |
525 int error; | |
526 std::vector<uint8> types; | |
527 types.push_back(CLIENT_CERT_ECDSA_SIGN); | |
528 TestCompletionCallback callback; | |
529 ServerBoundCertService::RequestHandle request_handle; | |
530 | |
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()); | |
543 | |
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()); | |
558 } | |
559 | |
560 #endif // !defined(USE_OPENSSL) | |
561 | |
562 } // namespace | |
563 | |
564 } // namespace net | |
OLD | NEW |