blob: f09b47c2cdb4648312f0155c2b9baa602f6ecfc4 [file] [log] [blame]
[email protected]eb7974c2012-01-25 17:38:481// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]97301cd2011-07-29 02:32:392// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]32cb7fb2012-03-22 22:41:115#include "net/base/server_bound_cert_service.h"
[email protected]97301cd2011-07-29 02:32:396
7#include <string>
8#include <vector>
9
[email protected]0f7804ec2011-10-07 20:04:1810#include "base/bind.h"
[email protected]fc58ffa82011-08-10 22:31:5511#include "base/memory/scoped_ptr.h"
[email protected]5bab49ec2012-05-04 21:13:1912#include "base/message_loop.h"
13#include "base/threading/sequenced_worker_pool.h"
[email protected]550cee92011-12-06 04:21:0914#include "crypto/ec_private_key.h"
[email protected]550cee92011-12-06 04:21:0915#include "net/base/asn1_util.h"
[email protected]32cb7fb2012-03-22 22:41:1116#include "net/base/default_server_bound_cert_store.h"
[email protected]fc58ffa82011-08-10 22:31:5517#include "net/base/net_errors.h"
18#include "net/base/test_completion_callback.h"
[email protected]97301cd2011-07-29 02:32:3919#include "net/base/x509_certificate.h"
20#include "testing/gtest/include/gtest/gtest.h"
21
22namespace net {
23
[email protected]0f7804ec2011-10-07 20:04:1824namespace {
[email protected]fc58ffa82011-08-10 22:31:5525
[email protected]0f7804ec2011-10-07 20:04:1826void FailTest(int /* result */) {
27 FAIL();
28}
[email protected]fc58ffa82011-08-10 22:31:5529
[email protected]5bab49ec2012-05-04 21:13:1930class 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
47TEST_F(ServerBoundCertServiceTest, GetDomainForHost) {
[email protected]fbda95d82012-02-29 05:42:0948 EXPECT_EQ("google.com",
[email protected]9c4eff22012-03-20 22:42:2949 ServerBoundCertService::GetDomainForHost("google.com"));
[email protected]fbda95d82012-02-29 05:42:0950 EXPECT_EQ("google.com",
[email protected]9c4eff22012-03-20 22:42:2951 ServerBoundCertService::GetDomainForHost("www.google.com"));
[email protected]fbda95d82012-02-29 05:42:0952 // 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",
[email protected]9c4eff22012-03-20 22:42:2956 ServerBoundCertService::GetDomainForHost("foo.appspot.com"));
[email protected]fbda95d82012-02-29 05:42:0957 EXPECT_EQ("google.com",
[email protected]9c4eff22012-03-20 22:42:2958 ServerBoundCertService::GetDomainForHost("www.mail.google.com"));
[email protected]fbda95d82012-02-29 05:42:0959 EXPECT_EQ("goto",
[email protected]9c4eff22012-03-20 22:42:2960 ServerBoundCertService::GetDomainForHost("goto"));
[email protected]fbda95d82012-02-29 05:42:0961 EXPECT_EQ("127.0.0.1",
[email protected]9c4eff22012-03-20 22:42:2962 ServerBoundCertService::GetDomainForHost("127.0.0.1"));
[email protected]fbda95d82012-02-29 05:42:0963}
64
[email protected]f687f1a2011-08-03 19:34:1165// See http://crbug.com/91512 - implement OpenSSL version of CreateSelfSigned.
66#if !defined(USE_OPENSSL)
67
[email protected]5bab49ec2012-05-04 21:13:1968TEST_F(ServerBoundCertServiceTest, CacheHit) {
[email protected]fc58ffa82011-08-10 22:31:5569 std::string origin("https://encrypted.google.com:443");
[email protected]97301cd2011-07-29 02:32:3970
[email protected]fc58ffa82011-08-10 22:31:5571 int error;
[email protected]550cee92011-12-06 04:21:0972 std::vector<uint8> types;
[email protected]515face42012-02-29 05:43:1573 types.push_back(CLIENT_CERT_ECDSA_SIGN);
[email protected]0f7804ec2011-10-07 20:04:1874 TestCompletionCallback callback;
[email protected]9c4eff22012-03-20 22:42:2975 ServerBoundCertService::RequestHandle request_handle;
[email protected]97301cd2011-07-29 02:32:3976
[email protected]fc58ffa82011-08-10 22:31:5577 // Asynchronous completion.
[email protected]550cee92011-12-06 04:21:0978 SSLClientCertType type1;
[email protected]fc58ffa82011-08-10 22:31:5579 std::string private_key_info1, der_cert1;
[email protected]5bab49ec2012-05-04 21:13:1980 EXPECT_EQ(0, service_->cert_count());
81 error = service_->GetDomainBoundCert(
[email protected]550cee92011-12-06 04:21:0982 origin, types, &type1, &private_key_info1, &der_cert1,
83 callback.callback(), &request_handle);
[email protected]fc58ffa82011-08-10 22:31:5584 EXPECT_EQ(ERR_IO_PENDING, error);
85 EXPECT_TRUE(request_handle != NULL);
86 error = callback.WaitForResult();
87 EXPECT_EQ(OK, error);
[email protected]5bab49ec2012-05-04 21:13:1988 EXPECT_EQ(1, service_->cert_count());
[email protected]515face42012-02-29 05:43:1589 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1);
[email protected]fc58ffa82011-08-10 22:31:5590 EXPECT_FALSE(private_key_info1.empty());
91 EXPECT_FALSE(der_cert1.empty());
[email protected]97301cd2011-07-29 02:32:3992
[email protected]fc58ffa82011-08-10 22:31:5593 // Synchronous completion.
[email protected]550cee92011-12-06 04:21:0994 SSLClientCertType type2;
[email protected]fc58ffa82011-08-10 22:31:5595 std::string private_key_info2, der_cert2;
[email protected]5bab49ec2012-05-04 21:13:1996 error = service_->GetDomainBoundCert(
[email protected]550cee92011-12-06 04:21:0997 origin, types, &type2, &private_key_info2, &der_cert2,
98 callback.callback(), &request_handle);
[email protected]fc58ffa82011-08-10 22:31:5599 EXPECT_TRUE(request_handle == NULL);
100 EXPECT_EQ(OK, error);
[email protected]5bab49ec2012-05-04 21:13:19101 EXPECT_EQ(1, service_->cert_count());
[email protected]515face42012-02-29 05:43:15102 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2);
[email protected]fc58ffa82011-08-10 22:31:55103 EXPECT_EQ(private_key_info1, private_key_info2);
104 EXPECT_EQ(der_cert1, der_cert2);
105
[email protected]5bab49ec2012-05-04 21:13:19106 EXPECT_EQ(2u, service_->requests());
107 EXPECT_EQ(1u, service_->cert_store_hits());
108 EXPECT_EQ(0u, service_->inflight_joins());
[email protected]97301cd2011-07-29 02:32:39109}
110
[email protected]5bab49ec2012-05-04 21:13:19111TEST_F(ServerBoundCertServiceTest, UnsupportedTypes) {
[email protected]550cee92011-12-06 04:21:09112 std::string origin("https://encrypted.google.com:443");
113
114 int error;
115 std::vector<uint8> types;
116 TestCompletionCallback callback;
[email protected]9c4eff22012-03-20 22:42:29117 ServerBoundCertService::RequestHandle request_handle;
[email protected]550cee92011-12-06 04:21:09118
119 // Empty requested_types.
120 SSLClientCertType type1;
121 std::string private_key_info1, der_cert1;
[email protected]5bab49ec2012-05-04 21:13:19122 error = service_->GetDomainBoundCert(
[email protected]550cee92011-12-06 04:21:09123 origin, types, &type1, &private_key_info1, &der_cert1,
124 callback.callback(), &request_handle);
125 EXPECT_EQ(ERR_INVALID_ARGUMENT, error);
126 EXPECT_TRUE(request_handle == NULL);
127
128 // No supported types in requested_types.
[email protected]515face42012-02-29 05:43:15129 types.push_back(CLIENT_CERT_RSA_SIGN);
[email protected]550cee92011-12-06 04:21:09130 types.push_back(2);
131 types.push_back(3);
[email protected]5bab49ec2012-05-04 21:13:19132 error = service_->GetDomainBoundCert(
[email protected]550cee92011-12-06 04:21:09133 origin, types, &type1, &private_key_info1, &der_cert1,
134 callback.callback(), &request_handle);
135 EXPECT_EQ(ERR_CLIENT_AUTH_CERT_TYPE_UNSUPPORTED, error);
136 EXPECT_TRUE(request_handle == NULL);
137
138 // Supported types after unsupported ones in requested_types.
139 types.push_back(CLIENT_CERT_ECDSA_SIGN);
[email protected]550cee92011-12-06 04:21:09140 // Asynchronous completion.
[email protected]5bab49ec2012-05-04 21:13:19141 EXPECT_EQ(0, service_->cert_count());
142 error = service_->GetDomainBoundCert(
[email protected]550cee92011-12-06 04:21:09143 origin, types, &type1, &private_key_info1, &der_cert1,
144 callback.callback(), &request_handle);
145 EXPECT_EQ(ERR_IO_PENDING, error);
146 EXPECT_TRUE(request_handle != NULL);
147 error = callback.WaitForResult();
148 EXPECT_EQ(OK, error);
[email protected]5bab49ec2012-05-04 21:13:19149 EXPECT_EQ(1, service_->cert_count());
[email protected]550cee92011-12-06 04:21:09150 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1);
151 EXPECT_FALSE(private_key_info1.empty());
152 EXPECT_FALSE(der_cert1.empty());
153
154 // Now that the cert is created, doing requests for unsupported types
155 // shouldn't affect the created cert.
156 // Empty requested_types.
157 types.clear();
158 SSLClientCertType type2;
159 std::string private_key_info2, der_cert2;
[email protected]5bab49ec2012-05-04 21:13:19160 error = service_->GetDomainBoundCert(
[email protected]550cee92011-12-06 04:21:09161 origin, types, &type2, &private_key_info2, &der_cert2,
162 callback.callback(), &request_handle);
163 EXPECT_EQ(ERR_INVALID_ARGUMENT, error);
164 EXPECT_TRUE(request_handle == NULL);
165
166 // No supported types in requested_types.
[email protected]515face42012-02-29 05:43:15167 types.push_back(CLIENT_CERT_RSA_SIGN);
[email protected]550cee92011-12-06 04:21:09168 types.push_back(2);
169 types.push_back(3);
[email protected]5bab49ec2012-05-04 21:13:19170 error = service_->GetDomainBoundCert(
[email protected]550cee92011-12-06 04:21:09171 origin, types, &type2, &private_key_info2, &der_cert2,
172 callback.callback(), &request_handle);
173 EXPECT_EQ(ERR_CLIENT_AUTH_CERT_TYPE_UNSUPPORTED, error);
174 EXPECT_TRUE(request_handle == NULL);
175
176 // If we request EC, the cert we created before should still be there.
[email protected]550cee92011-12-06 04:21:09177 types.push_back(CLIENT_CERT_ECDSA_SIGN);
[email protected]5bab49ec2012-05-04 21:13:19178 error = service_->GetDomainBoundCert(
[email protected]550cee92011-12-06 04:21:09179 origin, types, &type2, &private_key_info2, &der_cert2,
180 callback.callback(), &request_handle);
181 EXPECT_TRUE(request_handle == NULL);
182 EXPECT_EQ(OK, error);
[email protected]5bab49ec2012-05-04 21:13:19183 EXPECT_EQ(1, service_->cert_count());
[email protected]550cee92011-12-06 04:21:09184 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2);
185 EXPECT_EQ(private_key_info1, private_key_info2);
186 EXPECT_EQ(der_cert1, der_cert2);
187}
188
[email protected]5bab49ec2012-05-04 21:13:19189TEST_F(ServerBoundCertServiceTest, StoreCerts) {
[email protected]fc58ffa82011-08-10 22:31:55190 int error;
[email protected]550cee92011-12-06 04:21:09191 std::vector<uint8> types;
[email protected]515face42012-02-29 05:43:15192 types.push_back(CLIENT_CERT_ECDSA_SIGN);
[email protected]0f7804ec2011-10-07 20:04:18193 TestCompletionCallback callback;
[email protected]9c4eff22012-03-20 22:42:29194 ServerBoundCertService::RequestHandle request_handle;
[email protected]97301cd2011-07-29 02:32:39195
[email protected]fc58ffa82011-08-10 22:31:55196 std::string origin1("https://encrypted.google.com:443");
[email protected]550cee92011-12-06 04:21:09197 SSLClientCertType type1;
[email protected]fc58ffa82011-08-10 22:31:55198 std::string private_key_info1, der_cert1;
[email protected]5bab49ec2012-05-04 21:13:19199 EXPECT_EQ(0, service_->cert_count());
200 error = service_->GetDomainBoundCert(
[email protected]550cee92011-12-06 04:21:09201 origin1, types, &type1, &private_key_info1, &der_cert1,
202 callback.callback(), &request_handle);
[email protected]fc58ffa82011-08-10 22:31:55203 EXPECT_EQ(ERR_IO_PENDING, error);
204 EXPECT_TRUE(request_handle != NULL);
205 error = callback.WaitForResult();
206 EXPECT_EQ(OK, error);
[email protected]5bab49ec2012-05-04 21:13:19207 EXPECT_EQ(1, service_->cert_count());
[email protected]fc58ffa82011-08-10 22:31:55208
209 std::string origin2("https://www.verisign.com:443");
[email protected]550cee92011-12-06 04:21:09210 SSLClientCertType type2;
[email protected]fc58ffa82011-08-10 22:31:55211 std::string private_key_info2, der_cert2;
[email protected]5bab49ec2012-05-04 21:13:19212 error = service_->GetDomainBoundCert(
[email protected]550cee92011-12-06 04:21:09213 origin2, types, &type2, &private_key_info2, &der_cert2,
214 callback.callback(), &request_handle);
[email protected]fc58ffa82011-08-10 22:31:55215 EXPECT_EQ(ERR_IO_PENDING, error);
216 EXPECT_TRUE(request_handle != NULL);
217 error = callback.WaitForResult();
218 EXPECT_EQ(OK, error);
[email protected]5bab49ec2012-05-04 21:13:19219 EXPECT_EQ(2, service_->cert_count());
[email protected]fc58ffa82011-08-10 22:31:55220
221 std::string origin3("https://www.twitter.com:443");
[email protected]550cee92011-12-06 04:21:09222 SSLClientCertType type3;
[email protected]fc58ffa82011-08-10 22:31:55223 std::string private_key_info3, der_cert3;
[email protected]5bab49ec2012-05-04 21:13:19224 error = service_->GetDomainBoundCert(
[email protected]550cee92011-12-06 04:21:09225 origin3, types, &type3, &private_key_info3, &der_cert3,
226 callback.callback(), &request_handle);
[email protected]fc58ffa82011-08-10 22:31:55227 EXPECT_EQ(ERR_IO_PENDING, error);
228 EXPECT_TRUE(request_handle != NULL);
229 error = callback.WaitForResult();
230 EXPECT_EQ(OK, error);
[email protected]5bab49ec2012-05-04 21:13:19231 EXPECT_EQ(3, service_->cert_count());
[email protected]fc58ffa82011-08-10 22:31:55232
233 EXPECT_NE(private_key_info1, private_key_info2);
234 EXPECT_NE(der_cert1, der_cert2);
235 EXPECT_NE(private_key_info1, private_key_info3);
236 EXPECT_NE(der_cert1, der_cert3);
237 EXPECT_NE(private_key_info2, private_key_info3);
238 EXPECT_NE(der_cert2, der_cert3);
[email protected]515face42012-02-29 05:43:15239 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1);
240 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2);
[email protected]550cee92011-12-06 04:21:09241 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type3);
[email protected]fc58ffa82011-08-10 22:31:55242}
243
244// Tests an inflight join.
[email protected]5bab49ec2012-05-04 21:13:19245TEST_F(ServerBoundCertServiceTest, InflightJoin) {
[email protected]fc58ffa82011-08-10 22:31:55246 std::string origin("https://encrypted.google.com:443");
247 int error;
[email protected]550cee92011-12-06 04:21:09248 std::vector<uint8> types;
[email protected]515face42012-02-29 05:43:15249 types.push_back(CLIENT_CERT_ECDSA_SIGN);
[email protected]fc58ffa82011-08-10 22:31:55250
[email protected]550cee92011-12-06 04:21:09251 SSLClientCertType type1;
[email protected]fc58ffa82011-08-10 22:31:55252 std::string private_key_info1, der_cert1;
[email protected]0f7804ec2011-10-07 20:04:18253 TestCompletionCallback callback1;
[email protected]9c4eff22012-03-20 22:42:29254 ServerBoundCertService::RequestHandle request_handle1;
[email protected]fc58ffa82011-08-10 22:31:55255
[email protected]550cee92011-12-06 04:21:09256 SSLClientCertType type2;
[email protected]fc58ffa82011-08-10 22:31:55257 std::string private_key_info2, der_cert2;
[email protected]0f7804ec2011-10-07 20:04:18258 TestCompletionCallback callback2;
[email protected]9c4eff22012-03-20 22:42:29259 ServerBoundCertService::RequestHandle request_handle2;
[email protected]fc58ffa82011-08-10 22:31:55260
[email protected]5bab49ec2012-05-04 21:13:19261 error = service_->GetDomainBoundCert(
[email protected]550cee92011-12-06 04:21:09262 origin, types, &type1, &private_key_info1, &der_cert1,
263 callback1.callback(), &request_handle1);
[email protected]fc58ffa82011-08-10 22:31:55264 EXPECT_EQ(ERR_IO_PENDING, error);
265 EXPECT_TRUE(request_handle1 != NULL);
[email protected]515face42012-02-29 05:43:15266 // If we request RSA and EC in the 2nd request, should still join with the
[email protected]550cee92011-12-06 04:21:09267 // original request.
[email protected]515face42012-02-29 05:43:15268 types.insert(types.begin(), CLIENT_CERT_RSA_SIGN);
[email protected]5bab49ec2012-05-04 21:13:19269 error = service_->GetDomainBoundCert(
[email protected]550cee92011-12-06 04:21:09270 origin, types, &type2, &private_key_info2, &der_cert2,
271 callback2.callback(), &request_handle2);
[email protected]fc58ffa82011-08-10 22:31:55272 EXPECT_EQ(ERR_IO_PENDING, error);
273 EXPECT_TRUE(request_handle2 != NULL);
274
275 error = callback1.WaitForResult();
276 EXPECT_EQ(OK, error);
277 error = callback2.WaitForResult();
278 EXPECT_EQ(OK, error);
279
[email protected]515face42012-02-29 05:43:15280 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1);
281 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2);
[email protected]5bab49ec2012-05-04 21:13:19282 EXPECT_EQ(2u, service_->requests());
283 EXPECT_EQ(0u, service_->cert_store_hits());
284 EXPECT_EQ(1u, service_->inflight_joins());
[email protected]fc58ffa82011-08-10 22:31:55285}
286
[email protected]5bab49ec2012-05-04 21:13:19287TEST_F(ServerBoundCertServiceTest, ExtractValuesFromBytesEC) {
[email protected]550cee92011-12-06 04:21:09288 std::string origin("https://encrypted.google.com:443");
289 SSLClientCertType type;
290 std::string private_key_info, der_cert;
291 int error;
292 std::vector<uint8> types;
293 types.push_back(CLIENT_CERT_ECDSA_SIGN);
294 TestCompletionCallback callback;
[email protected]9c4eff22012-03-20 22:42:29295 ServerBoundCertService::RequestHandle request_handle;
[email protected]550cee92011-12-06 04:21:09296
[email protected]5bab49ec2012-05-04 21:13:19297 error = service_->GetDomainBoundCert(
[email protected]550cee92011-12-06 04:21:09298 origin, types, &type, &private_key_info, &der_cert, callback.callback(),
299 &request_handle);
300 EXPECT_EQ(ERR_IO_PENDING, error);
301 EXPECT_TRUE(request_handle != NULL);
302 error = callback.WaitForResult();
303 EXPECT_EQ(OK, error);
304
305 base::StringPiece spki_piece;
306 ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(der_cert, &spki_piece));
307 std::vector<uint8> spki(
308 spki_piece.data(),
309 spki_piece.data() + spki_piece.size());
310
311 // Check that we can retrieve the key from the bytes.
312 std::vector<uint8> key_vec(private_key_info.begin(), private_key_info.end());
313 scoped_ptr<crypto::ECPrivateKey> private_key(
314 crypto::ECPrivateKey::CreateFromEncryptedPrivateKeyInfo(
[email protected]9c4eff22012-03-20 22:42:29315 ServerBoundCertService::kEPKIPassword, key_vec, spki));
[email protected]550cee92011-12-06 04:21:09316 EXPECT_TRUE(private_key != NULL);
317
318 // Check that we can retrieve the cert from the bytes.
319 scoped_refptr<X509Certificate> x509cert(
320 X509Certificate::CreateFromBytes(der_cert.data(), der_cert.size()));
321 EXPECT_TRUE(x509cert != NULL);
322}
323
[email protected]fc58ffa82011-08-10 22:31:55324// Tests that the callback of a canceled request is never made.
[email protected]5bab49ec2012-05-04 21:13:19325TEST_F(ServerBoundCertServiceTest, CancelRequest) {
[email protected]fc58ffa82011-08-10 22:31:55326 std::string origin("https://encrypted.google.com:443");
[email protected]550cee92011-12-06 04:21:09327 SSLClientCertType type;
[email protected]fc58ffa82011-08-10 22:31:55328 std::string private_key_info, der_cert;
329 int error;
[email protected]550cee92011-12-06 04:21:09330 std::vector<uint8> types;
[email protected]515face42012-02-29 05:43:15331 types.push_back(CLIENT_CERT_ECDSA_SIGN);
[email protected]9c4eff22012-03-20 22:42:29332 ServerBoundCertService::RequestHandle request_handle;
[email protected]fc58ffa82011-08-10 22:31:55333
[email protected]5bab49ec2012-05-04 21:13:19334 error = service_->GetDomainBoundCert(origin,
[email protected]550cee92011-12-06 04:21:09335 types,
336 &type,
[email protected]fc58ffa82011-08-10 22:31:55337 &private_key_info,
338 &der_cert,
[email protected]0f7804ec2011-10-07 20:04:18339 base::Bind(&FailTest),
[email protected]fc58ffa82011-08-10 22:31:55340 &request_handle);
341 EXPECT_EQ(ERR_IO_PENDING, error);
342 EXPECT_TRUE(request_handle != NULL);
[email protected]5bab49ec2012-05-04 21:13:19343 service_->CancelRequest(request_handle);
[email protected]fc58ffa82011-08-10 22:31:55344
[email protected]5bab49ec2012-05-04 21:13:19345 // Wait for generation to finish.
346 sequenced_worker_pool_->FlushForTesting();
347 // Wait for reply from ServerBoundCertServiceWorker to be posted back to the
348 // ServerBoundCertService.
349 MessageLoop::current()->RunAllPending();
[email protected]550cee92011-12-06 04:21:09350
351 // Even though the original request was cancelled, the service will still
352 // store the result, it just doesn't call the callback.
[email protected]5bab49ec2012-05-04 21:13:19353 EXPECT_EQ(1, service_->cert_count());
[email protected]fc58ffa82011-08-10 22:31:55354}
355
[email protected]5bab49ec2012-05-04 21:13:19356TEST_F(ServerBoundCertServiceTest, DestructionWithPendingRequest) {
357 std::string origin("https://encrypted.google.com:443");
358 SSLClientCertType type;
359 std::string private_key_info, der_cert;
360 int error;
361 std::vector<uint8> types;
362 types.push_back(CLIENT_CERT_ECDSA_SIGN);
363 ServerBoundCertService::RequestHandle request_handle;
364
365 error = service_->GetDomainBoundCert(origin,
366 types,
367 &type,
368 &private_key_info,
369 &der_cert,
370 base::Bind(&FailTest),
371 &request_handle);
372 EXPECT_EQ(ERR_IO_PENDING, error);
373 EXPECT_TRUE(request_handle != NULL);
374
375 // Cancel request and destroy the ServerBoundCertService.
376 service_->CancelRequest(request_handle);
377 service_.reset();
378
379 // Wait for generation to finish.
380 sequenced_worker_pool_->FlushForTesting();
381 // ServerBoundCertServiceWorker should not post anything back to the
382 // non-existant ServerBoundCertService, but run the loop just to be sure it
383 // doesn't.
384 MessageLoop::current()->RunAllPending();
385
386 // If we got here without crashing or a valgrind error, it worked.
387}
388
389// Tests that simultaneous creation of different certs works.
390TEST_F(ServerBoundCertServiceTest, SimultaneousCreation) {
391 int error;
392 std::vector<uint8> types;
393 types.push_back(CLIENT_CERT_ECDSA_SIGN);
394 ServerBoundCertService::RequestHandle request_handle;
395
396 std::string origin1("https://encrypted.google.com:443");
397 SSLClientCertType type1;
398 std::string private_key_info1, der_cert1;
399 TestCompletionCallback callback1;
400
401 std::string origin2("https://foo.com:443");
402 SSLClientCertType type2;
403 std::string private_key_info2, der_cert2;
404 TestCompletionCallback callback2;
405
406 std::string origin3("https://bar.com:443");
407 SSLClientCertType type3;
408 std::string private_key_info3, der_cert3;
409 TestCompletionCallback callback3;
410
411 error = service_->GetDomainBoundCert(origin1,
412 types,
413 &type1,
414 &private_key_info1,
415 &der_cert1,
416 callback1.callback(),
417 &request_handle);
418 EXPECT_EQ(ERR_IO_PENDING, error);
419 EXPECT_TRUE(request_handle != NULL);
420
421 error = service_->GetDomainBoundCert(origin2,
422 types,
423 &type2,
424 &private_key_info2,
425 &der_cert2,
426 callback2.callback(),
427 &request_handle);
428 EXPECT_EQ(ERR_IO_PENDING, error);
429 EXPECT_TRUE(request_handle != NULL);
430
431 error = service_->GetDomainBoundCert(origin3,
432 types,
433 &type3,
434 &private_key_info3,
435 &der_cert3,
436 callback3.callback(),
437 &request_handle);
438 EXPECT_EQ(ERR_IO_PENDING, error);
439 EXPECT_TRUE(request_handle != NULL);
440
441 error = callback1.WaitForResult();
442 EXPECT_EQ(OK, error);
443 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1);
444 EXPECT_FALSE(private_key_info1.empty());
445 EXPECT_FALSE(der_cert1.empty());
446
447 error = callback2.WaitForResult();
448 EXPECT_EQ(OK, error);
449 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2);
450 EXPECT_FALSE(private_key_info2.empty());
451 EXPECT_FALSE(der_cert2.empty());
452
453 error = callback3.WaitForResult();
454 EXPECT_EQ(OK, error);
455 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type3);
456 EXPECT_FALSE(private_key_info3.empty());
457 EXPECT_FALSE(der_cert3.empty());
458
459 EXPECT_NE(private_key_info1, private_key_info2);
460 EXPECT_NE(der_cert1, der_cert2);
461
462 EXPECT_NE(private_key_info1, private_key_info3);
463 EXPECT_NE(der_cert1, der_cert3);
464
465 EXPECT_NE(private_key_info2, private_key_info3);
466 EXPECT_NE(der_cert2, der_cert3);
467
468 EXPECT_EQ(3, service_->cert_count());
469}
470
471TEST_F(ServerBoundCertServiceTest, Expiration) {
472 ServerBoundCertStore* store = service_->GetCertStore();
[email protected]eb7974c2012-01-25 17:38:48473 base::Time now = base::Time::Now();
[email protected]9c4eff22012-03-20 22:42:29474 store->SetServerBoundCert("good",
[email protected]515face42012-02-29 05:43:15475 CLIENT_CERT_ECDSA_SIGN,
[email protected]eb7974c2012-01-25 17:38:48476 now,
477 now + base::TimeDelta::FromDays(1),
[email protected]4082fa22011-12-22 01:46:19478 "a",
479 "b");
[email protected]9c4eff22012-03-20 22:42:29480 store->SetServerBoundCert("expired",
[email protected]515face42012-02-29 05:43:15481 CLIENT_CERT_ECDSA_SIGN,
[email protected]eb7974c2012-01-25 17:38:48482 now - base::TimeDelta::FromDays(2),
483 now - base::TimeDelta::FromDays(1),
[email protected]4082fa22011-12-22 01:46:19484 "c",
485 "d");
[email protected]5bab49ec2012-05-04 21:13:19486 EXPECT_EQ(2, service_->cert_count());
[email protected]4082fa22011-12-22 01:46:19487
488 int error;
489 std::vector<uint8> types;
[email protected]515face42012-02-29 05:43:15490 types.push_back(CLIENT_CERT_ECDSA_SIGN);
[email protected]4082fa22011-12-22 01:46:19491 TestCompletionCallback callback;
[email protected]9c4eff22012-03-20 22:42:29492 ServerBoundCertService::RequestHandle request_handle;
[email protected]4082fa22011-12-22 01:46:19493
494 // Cert still valid - synchronous completion.
495 SSLClientCertType type1;
496 std::string private_key_info1, der_cert1;
[email protected]5bab49ec2012-05-04 21:13:19497 error = service_->GetDomainBoundCert(
[email protected]4082fa22011-12-22 01:46:19498 "https://good", types, &type1, &private_key_info1, &der_cert1,
499 callback.callback(), &request_handle);
500 EXPECT_EQ(OK, error);
501 EXPECT_TRUE(request_handle == NULL);
[email protected]5bab49ec2012-05-04 21:13:19502 EXPECT_EQ(2, service_->cert_count());
[email protected]515face42012-02-29 05:43:15503 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1);
[email protected]4082fa22011-12-22 01:46:19504 EXPECT_STREQ("a", private_key_info1.c_str());
505 EXPECT_STREQ("b", der_cert1.c_str());
506
507 // Cert expired - New cert will be generated, asynchronous completion.
508 SSLClientCertType type2;
509 std::string private_key_info2, der_cert2;
[email protected]5bab49ec2012-05-04 21:13:19510 error = service_->GetDomainBoundCert(
[email protected]4082fa22011-12-22 01:46:19511 "https://expired", types, &type2, &private_key_info2, &der_cert2,
512 callback.callback(), &request_handle);
513 EXPECT_EQ(ERR_IO_PENDING, error);
514 EXPECT_TRUE(request_handle != NULL);
515 error = callback.WaitForResult();
516 EXPECT_EQ(OK, error);
[email protected]5bab49ec2012-05-04 21:13:19517 EXPECT_EQ(2, service_->cert_count());
[email protected]515face42012-02-29 05:43:15518 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2);
[email protected]4082fa22011-12-22 01:46:19519 EXPECT_LT(1U, private_key_info2.size());
520 EXPECT_LT(1U, der_cert2.size());
521}
522
[email protected]f687f1a2011-08-03 19:34:11523#endif // !defined(USE_OPENSSL)
524
[email protected]0f7804ec2011-10-07 20:04:18525} // namespace
526
[email protected]97301cd2011-07-29 02:32:39527} // namespace net