blob: 9e505db81d9acbce5f069cc74ab38ec4c6469c42 [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);
[email protected]2d07fa962013-01-09 22:13:3185 EXPECT_TRUE(request_handle.is_active());
[email protected]fc58ffa82011-08-10 22:31:5586 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]2d07fa962013-01-09 22:13:3192 EXPECT_FALSE(request_handle.is_active());
[email protected]97301cd2011-07-29 02:32:3993
[email protected]fc58ffa82011-08-10 22:31:5594 // Synchronous completion.
[email protected]550cee92011-12-06 04:21:0995 SSLClientCertType type2;
[email protected]fc58ffa82011-08-10 22:31:5596 std::string private_key_info2, der_cert2;
[email protected]5bab49ec2012-05-04 21:13:1997 error = service_->GetDomainBoundCert(
[email protected]550cee92011-12-06 04:21:0998 origin, types, &type2, &private_key_info2, &der_cert2,
99 callback.callback(), &request_handle);
[email protected]2d07fa962013-01-09 22:13:31100 EXPECT_FALSE(request_handle.is_active());
[email protected]fc58ffa82011-08-10 22:31:55101 EXPECT_EQ(OK, error);
[email protected]5bab49ec2012-05-04 21:13:19102 EXPECT_EQ(1, service_->cert_count());
[email protected]515face42012-02-29 05:43:15103 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2);
[email protected]fc58ffa82011-08-10 22:31:55104 EXPECT_EQ(private_key_info1, private_key_info2);
105 EXPECT_EQ(der_cert1, der_cert2);
106
[email protected]5bab49ec2012-05-04 21:13:19107 EXPECT_EQ(2u, service_->requests());
108 EXPECT_EQ(1u, service_->cert_store_hits());
109 EXPECT_EQ(0u, service_->inflight_joins());
[email protected]97301cd2011-07-29 02:32:39110}
111
[email protected]5bab49ec2012-05-04 21:13:19112TEST_F(ServerBoundCertServiceTest, UnsupportedTypes) {
[email protected]550cee92011-12-06 04:21:09113 std::string origin("https://encrypted.google.com:443");
114
115 int error;
116 std::vector<uint8> types;
117 TestCompletionCallback callback;
[email protected]9c4eff22012-03-20 22:42:29118 ServerBoundCertService::RequestHandle request_handle;
[email protected]550cee92011-12-06 04:21:09119
120 // Empty requested_types.
121 SSLClientCertType type1;
122 std::string private_key_info1, der_cert1;
[email protected]5bab49ec2012-05-04 21:13:19123 error = service_->GetDomainBoundCert(
[email protected]550cee92011-12-06 04:21:09124 origin, types, &type1, &private_key_info1, &der_cert1,
125 callback.callback(), &request_handle);
126 EXPECT_EQ(ERR_INVALID_ARGUMENT, error);
[email protected]2d07fa962013-01-09 22:13:31127 EXPECT_FALSE(request_handle.is_active());
[email protected]550cee92011-12-06 04:21:09128
129 // No supported types in requested_types.
[email protected]515face42012-02-29 05:43:15130 types.push_back(CLIENT_CERT_RSA_SIGN);
[email protected]550cee92011-12-06 04:21:09131 types.push_back(2);
132 types.push_back(3);
[email protected]5bab49ec2012-05-04 21:13:19133 error = service_->GetDomainBoundCert(
[email protected]550cee92011-12-06 04:21:09134 origin, types, &type1, &private_key_info1, &der_cert1,
135 callback.callback(), &request_handle);
136 EXPECT_EQ(ERR_CLIENT_AUTH_CERT_TYPE_UNSUPPORTED, error);
[email protected]2d07fa962013-01-09 22:13:31137 EXPECT_FALSE(request_handle.is_active());
[email protected]550cee92011-12-06 04:21:09138
139 // Supported types after unsupported ones in requested_types.
140 types.push_back(CLIENT_CERT_ECDSA_SIGN);
[email protected]550cee92011-12-06 04:21:09141 // Asynchronous completion.
[email protected]5bab49ec2012-05-04 21:13:19142 EXPECT_EQ(0, service_->cert_count());
143 error = service_->GetDomainBoundCert(
[email protected]550cee92011-12-06 04:21:09144 origin, types, &type1, &private_key_info1, &der_cert1,
145 callback.callback(), &request_handle);
146 EXPECT_EQ(ERR_IO_PENDING, error);
[email protected]2d07fa962013-01-09 22:13:31147 EXPECT_TRUE(request_handle.is_active());
[email protected]550cee92011-12-06 04:21:09148 error = callback.WaitForResult();
149 EXPECT_EQ(OK, error);
[email protected]5bab49ec2012-05-04 21:13:19150 EXPECT_EQ(1, service_->cert_count());
[email protected]550cee92011-12-06 04:21:09151 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;
[email protected]5bab49ec2012-05-04 21:13:19161 error = service_->GetDomainBoundCert(
[email protected]550cee92011-12-06 04:21:09162 origin, types, &type2, &private_key_info2, &der_cert2,
163 callback.callback(), &request_handle);
164 EXPECT_EQ(ERR_INVALID_ARGUMENT, error);
[email protected]2d07fa962013-01-09 22:13:31165 EXPECT_FALSE(request_handle.is_active());
[email protected]550cee92011-12-06 04:21:09166
167 // No supported types in requested_types.
[email protected]515face42012-02-29 05:43:15168 types.push_back(CLIENT_CERT_RSA_SIGN);
[email protected]550cee92011-12-06 04:21:09169 types.push_back(2);
170 types.push_back(3);
[email protected]5bab49ec2012-05-04 21:13:19171 error = service_->GetDomainBoundCert(
[email protected]550cee92011-12-06 04:21:09172 origin, types, &type2, &private_key_info2, &der_cert2,
173 callback.callback(), &request_handle);
174 EXPECT_EQ(ERR_CLIENT_AUTH_CERT_TYPE_UNSUPPORTED, error);
[email protected]2d07fa962013-01-09 22:13:31175 EXPECT_FALSE(request_handle.is_active());
[email protected]550cee92011-12-06 04:21:09176
177 // If we request EC, the cert we created before should still be there.
[email protected]550cee92011-12-06 04:21:09178 types.push_back(CLIENT_CERT_ECDSA_SIGN);
[email protected]5bab49ec2012-05-04 21:13:19179 error = service_->GetDomainBoundCert(
[email protected]550cee92011-12-06 04:21:09180 origin, types, &type2, &private_key_info2, &der_cert2,
181 callback.callback(), &request_handle);
[email protected]2d07fa962013-01-09 22:13:31182 EXPECT_FALSE(request_handle.is_active());
[email protected]550cee92011-12-06 04:21:09183 EXPECT_EQ(OK, error);
[email protected]5bab49ec2012-05-04 21:13:19184 EXPECT_EQ(1, service_->cert_count());
[email protected]550cee92011-12-06 04:21:09185 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
[email protected]5bab49ec2012-05-04 21:13:19190TEST_F(ServerBoundCertServiceTest, StoreCerts) {
[email protected]fc58ffa82011-08-10 22:31:55191 int error;
[email protected]550cee92011-12-06 04:21:09192 std::vector<uint8> types;
[email protected]515face42012-02-29 05:43:15193 types.push_back(CLIENT_CERT_ECDSA_SIGN);
[email protected]0f7804ec2011-10-07 20:04:18194 TestCompletionCallback callback;
[email protected]9c4eff22012-03-20 22:42:29195 ServerBoundCertService::RequestHandle request_handle;
[email protected]97301cd2011-07-29 02:32:39196
[email protected]fc58ffa82011-08-10 22:31:55197 std::string origin1("https://encrypted.google.com:443");
[email protected]550cee92011-12-06 04:21:09198 SSLClientCertType type1;
[email protected]fc58ffa82011-08-10 22:31:55199 std::string private_key_info1, der_cert1;
[email protected]5bab49ec2012-05-04 21:13:19200 EXPECT_EQ(0, service_->cert_count());
201 error = service_->GetDomainBoundCert(
[email protected]550cee92011-12-06 04:21:09202 origin1, types, &type1, &private_key_info1, &der_cert1,
203 callback.callback(), &request_handle);
[email protected]fc58ffa82011-08-10 22:31:55204 EXPECT_EQ(ERR_IO_PENDING, error);
[email protected]2d07fa962013-01-09 22:13:31205 EXPECT_TRUE(request_handle.is_active());
[email protected]fc58ffa82011-08-10 22:31:55206 error = callback.WaitForResult();
207 EXPECT_EQ(OK, error);
[email protected]5bab49ec2012-05-04 21:13:19208 EXPECT_EQ(1, service_->cert_count());
[email protected]fc58ffa82011-08-10 22:31:55209
210 std::string origin2("https://www.verisign.com:443");
[email protected]550cee92011-12-06 04:21:09211 SSLClientCertType type2;
[email protected]fc58ffa82011-08-10 22:31:55212 std::string private_key_info2, der_cert2;
[email protected]5bab49ec2012-05-04 21:13:19213 error = service_->GetDomainBoundCert(
[email protected]550cee92011-12-06 04:21:09214 origin2, types, &type2, &private_key_info2, &der_cert2,
215 callback.callback(), &request_handle);
[email protected]fc58ffa82011-08-10 22:31:55216 EXPECT_EQ(ERR_IO_PENDING, error);
[email protected]2d07fa962013-01-09 22:13:31217 EXPECT_TRUE(request_handle.is_active());
[email protected]fc58ffa82011-08-10 22:31:55218 error = callback.WaitForResult();
219 EXPECT_EQ(OK, error);
[email protected]5bab49ec2012-05-04 21:13:19220 EXPECT_EQ(2, service_->cert_count());
[email protected]fc58ffa82011-08-10 22:31:55221
222 std::string origin3("https://www.twitter.com:443");
[email protected]550cee92011-12-06 04:21:09223 SSLClientCertType type3;
[email protected]fc58ffa82011-08-10 22:31:55224 std::string private_key_info3, der_cert3;
[email protected]5bab49ec2012-05-04 21:13:19225 error = service_->GetDomainBoundCert(
[email protected]550cee92011-12-06 04:21:09226 origin3, types, &type3, &private_key_info3, &der_cert3,
227 callback.callback(), &request_handle);
[email protected]fc58ffa82011-08-10 22:31:55228 EXPECT_EQ(ERR_IO_PENDING, error);
[email protected]2d07fa962013-01-09 22:13:31229 EXPECT_TRUE(request_handle.is_active());
[email protected]fc58ffa82011-08-10 22:31:55230 error = callback.WaitForResult();
231 EXPECT_EQ(OK, error);
[email protected]5bab49ec2012-05-04 21:13:19232 EXPECT_EQ(3, service_->cert_count());
[email protected]fc58ffa82011-08-10 22:31:55233
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);
[email protected]515face42012-02-29 05:43:15240 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1);
241 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2);
[email protected]550cee92011-12-06 04:21:09242 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type3);
[email protected]fc58ffa82011-08-10 22:31:55243}
244
245// Tests an inflight join.
[email protected]5bab49ec2012-05-04 21:13:19246TEST_F(ServerBoundCertServiceTest, InflightJoin) {
[email protected]fc58ffa82011-08-10 22:31:55247 std::string origin("https://encrypted.google.com:443");
248 int error;
[email protected]550cee92011-12-06 04:21:09249 std::vector<uint8> types;
[email protected]515face42012-02-29 05:43:15250 types.push_back(CLIENT_CERT_ECDSA_SIGN);
[email protected]fc58ffa82011-08-10 22:31:55251
[email protected]550cee92011-12-06 04:21:09252 SSLClientCertType type1;
[email protected]fc58ffa82011-08-10 22:31:55253 std::string private_key_info1, der_cert1;
[email protected]0f7804ec2011-10-07 20:04:18254 TestCompletionCallback callback1;
[email protected]9c4eff22012-03-20 22:42:29255 ServerBoundCertService::RequestHandle request_handle1;
[email protected]fc58ffa82011-08-10 22:31:55256
[email protected]550cee92011-12-06 04:21:09257 SSLClientCertType type2;
[email protected]fc58ffa82011-08-10 22:31:55258 std::string private_key_info2, der_cert2;
[email protected]0f7804ec2011-10-07 20:04:18259 TestCompletionCallback callback2;
[email protected]9c4eff22012-03-20 22:42:29260 ServerBoundCertService::RequestHandle request_handle2;
[email protected]fc58ffa82011-08-10 22:31:55261
[email protected]5bab49ec2012-05-04 21:13:19262 error = service_->GetDomainBoundCert(
[email protected]550cee92011-12-06 04:21:09263 origin, types, &type1, &private_key_info1, &der_cert1,
264 callback1.callback(), &request_handle1);
[email protected]fc58ffa82011-08-10 22:31:55265 EXPECT_EQ(ERR_IO_PENDING, error);
[email protected]2d07fa962013-01-09 22:13:31266 EXPECT_TRUE(request_handle1.is_active());
[email protected]515face42012-02-29 05:43:15267 // If we request RSA and EC in the 2nd request, should still join with the
[email protected]550cee92011-12-06 04:21:09268 // original request.
[email protected]515face42012-02-29 05:43:15269 types.insert(types.begin(), CLIENT_CERT_RSA_SIGN);
[email protected]5bab49ec2012-05-04 21:13:19270 error = service_->GetDomainBoundCert(
[email protected]550cee92011-12-06 04:21:09271 origin, types, &type2, &private_key_info2, &der_cert2,
272 callback2.callback(), &request_handle2);
[email protected]fc58ffa82011-08-10 22:31:55273 EXPECT_EQ(ERR_IO_PENDING, error);
[email protected]2d07fa962013-01-09 22:13:31274 EXPECT_TRUE(request_handle2.is_active());
[email protected]fc58ffa82011-08-10 22:31:55275
276 error = callback1.WaitForResult();
277 EXPECT_EQ(OK, error);
278 error = callback2.WaitForResult();
279 EXPECT_EQ(OK, error);
280
[email protected]515face42012-02-29 05:43:15281 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1);
282 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2);
[email protected]5bab49ec2012-05-04 21:13:19283 EXPECT_EQ(2u, service_->requests());
284 EXPECT_EQ(0u, service_->cert_store_hits());
285 EXPECT_EQ(1u, service_->inflight_joins());
[email protected]fc58ffa82011-08-10 22:31:55286}
287
[email protected]5bab49ec2012-05-04 21:13:19288TEST_F(ServerBoundCertServiceTest, ExtractValuesFromBytesEC) {
[email protected]550cee92011-12-06 04:21:09289 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;
[email protected]9c4eff22012-03-20 22:42:29296 ServerBoundCertService::RequestHandle request_handle;
[email protected]550cee92011-12-06 04:21:09297
[email protected]5bab49ec2012-05-04 21:13:19298 error = service_->GetDomainBoundCert(
[email protected]550cee92011-12-06 04:21:09299 origin, types, &type, &private_key_info, &der_cert, callback.callback(),
300 &request_handle);
301 EXPECT_EQ(ERR_IO_PENDING, error);
[email protected]2d07fa962013-01-09 22:13:31302 EXPECT_TRUE(request_handle.is_active());
[email protected]550cee92011-12-06 04:21:09303 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(
[email protected]9c4eff22012-03-20 22:42:29316 ServerBoundCertService::kEPKIPassword, key_vec, spki));
[email protected]550cee92011-12-06 04:21:09317 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
[email protected]fc58ffa82011-08-10 22:31:55325// Tests that the callback of a canceled request is never made.
[email protected]5bab49ec2012-05-04 21:13:19326TEST_F(ServerBoundCertServiceTest, CancelRequest) {
[email protected]fc58ffa82011-08-10 22:31:55327 std::string origin("https://encrypted.google.com:443");
[email protected]550cee92011-12-06 04:21:09328 SSLClientCertType type;
[email protected]fc58ffa82011-08-10 22:31:55329 std::string private_key_info, der_cert;
330 int error;
[email protected]550cee92011-12-06 04:21:09331 std::vector<uint8> types;
[email protected]515face42012-02-29 05:43:15332 types.push_back(CLIENT_CERT_ECDSA_SIGN);
[email protected]9c4eff22012-03-20 22:42:29333 ServerBoundCertService::RequestHandle request_handle;
[email protected]fc58ffa82011-08-10 22:31:55334
[email protected]5bab49ec2012-05-04 21:13:19335 error = service_->GetDomainBoundCert(origin,
[email protected]550cee92011-12-06 04:21:09336 types,
337 &type,
[email protected]fc58ffa82011-08-10 22:31:55338 &private_key_info,
339 &der_cert,
[email protected]0f7804ec2011-10-07 20:04:18340 base::Bind(&FailTest),
[email protected]fc58ffa82011-08-10 22:31:55341 &request_handle);
342 EXPECT_EQ(ERR_IO_PENDING, error);
[email protected]2d07fa962013-01-09 22:13:31343 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.
359TEST_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 }
[email protected]fc58ffa82011-08-10 22:31:55379
[email protected]5bab49ec2012-05-04 21:13:19380 // Wait for generation to finish.
381 sequenced_worker_pool_->FlushForTesting();
382 // Wait for reply from ServerBoundCertServiceWorker to be posted back to the
383 // ServerBoundCertService.
[email protected]b4c62eb2012-11-14 18:36:51384 MessageLoop::current()->RunUntilIdle();
[email protected]550cee92011-12-06 04:21:09385
386 // Even though the original request was cancelled, the service will still
387 // store the result, it just doesn't call the callback.
[email protected]5bab49ec2012-05-04 21:13:19388 EXPECT_EQ(1, service_->cert_count());
[email protected]fc58ffa82011-08-10 22:31:55389}
390
[email protected]5bab49ec2012-05-04 21:13:19391TEST_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);
[email protected]2d07fa962013-01-09 22:13:31408 EXPECT_TRUE(request_handle.is_active());
[email protected]5bab49ec2012-05-04 21:13:19409
410 // Cancel request and destroy the ServerBoundCertService.
[email protected]2d07fa962013-01-09 22:13:31411 request_handle.Cancel();
[email protected]5bab49ec2012-05-04 21:13:19412 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.
[email protected]b4c62eb2012-11-14 18:36:51419 MessageLoop::current()->RunUntilIdle();
[email protected]5bab49ec2012-05-04 21:13:19420
421 // If we got here without crashing or a valgrind error, it worked.
422}
423
424// Tests that simultaneous creation of different certs works.
425TEST_F(ServerBoundCertServiceTest, SimultaneousCreation) {
426 int error;
427 std::vector<uint8> types;
428 types.push_back(CLIENT_CERT_ECDSA_SIGN);
[email protected]5bab49ec2012-05-04 21:13:19429
430 std::string origin1("https://encrypted.google.com:443");
431 SSLClientCertType type1;
432 std::string private_key_info1, der_cert1;
433 TestCompletionCallback callback1;
[email protected]2d07fa962013-01-09 22:13:31434 ServerBoundCertService::RequestHandle request_handle1;
[email protected]5bab49ec2012-05-04 21:13:19435
436 std::string origin2("https://foo.com:443");
437 SSLClientCertType type2;
438 std::string private_key_info2, der_cert2;
439 TestCompletionCallback callback2;
[email protected]2d07fa962013-01-09 22:13:31440 ServerBoundCertService::RequestHandle request_handle2;
[email protected]5bab49ec2012-05-04 21:13:19441
442 std::string origin3("https://bar.com:443");
443 SSLClientCertType type3;
444 std::string private_key_info3, der_cert3;
445 TestCompletionCallback callback3;
[email protected]2d07fa962013-01-09 22:13:31446 ServerBoundCertService::RequestHandle request_handle3;
[email protected]5bab49ec2012-05-04 21:13:19447
448 error = service_->GetDomainBoundCert(origin1,
449 types,
450 &type1,
451 &private_key_info1,
452 &der_cert1,
453 callback1.callback(),
[email protected]2d07fa962013-01-09 22:13:31454 &request_handle1);
[email protected]5bab49ec2012-05-04 21:13:19455 EXPECT_EQ(ERR_IO_PENDING, error);
[email protected]2d07fa962013-01-09 22:13:31456 EXPECT_TRUE(request_handle1.is_active());
[email protected]5bab49ec2012-05-04 21:13:19457
458 error = service_->GetDomainBoundCert(origin2,
459 types,
460 &type2,
461 &private_key_info2,
462 &der_cert2,
463 callback2.callback(),
[email protected]2d07fa962013-01-09 22:13:31464 &request_handle2);
[email protected]5bab49ec2012-05-04 21:13:19465 EXPECT_EQ(ERR_IO_PENDING, error);
[email protected]2d07fa962013-01-09 22:13:31466 EXPECT_TRUE(request_handle2.is_active());
[email protected]5bab49ec2012-05-04 21:13:19467
468 error = service_->GetDomainBoundCert(origin3,
469 types,
470 &type3,
471 &private_key_info3,
472 &der_cert3,
473 callback3.callback(),
[email protected]2d07fa962013-01-09 22:13:31474 &request_handle3);
[email protected]5bab49ec2012-05-04 21:13:19475 EXPECT_EQ(ERR_IO_PENDING, error);
[email protected]2d07fa962013-01-09 22:13:31476 EXPECT_TRUE(request_handle3.is_active());
[email protected]5bab49ec2012-05-04 21:13:19477
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
508TEST_F(ServerBoundCertServiceTest, Expiration) {
509 ServerBoundCertStore* store = service_->GetCertStore();
[email protected]eb7974c2012-01-25 17:38:48510 base::Time now = base::Time::Now();
[email protected]9c4eff22012-03-20 22:42:29511 store->SetServerBoundCert("good",
[email protected]515face42012-02-29 05:43:15512 CLIENT_CERT_ECDSA_SIGN,
[email protected]eb7974c2012-01-25 17:38:48513 now,
514 now + base::TimeDelta::FromDays(1),
[email protected]4082fa22011-12-22 01:46:19515 "a",
516 "b");
[email protected]9c4eff22012-03-20 22:42:29517 store->SetServerBoundCert("expired",
[email protected]515face42012-02-29 05:43:15518 CLIENT_CERT_ECDSA_SIGN,
[email protected]eb7974c2012-01-25 17:38:48519 now - base::TimeDelta::FromDays(2),
520 now - base::TimeDelta::FromDays(1),
[email protected]4082fa22011-12-22 01:46:19521 "c",
522 "d");
[email protected]5bab49ec2012-05-04 21:13:19523 EXPECT_EQ(2, service_->cert_count());
[email protected]4082fa22011-12-22 01:46:19524
525 int error;
526 std::vector<uint8> types;
[email protected]515face42012-02-29 05:43:15527 types.push_back(CLIENT_CERT_ECDSA_SIGN);
[email protected]4082fa22011-12-22 01:46:19528 TestCompletionCallback callback;
[email protected]9c4eff22012-03-20 22:42:29529 ServerBoundCertService::RequestHandle request_handle;
[email protected]4082fa22011-12-22 01:46:19530
531 // Cert still valid - synchronous completion.
532 SSLClientCertType type1;
533 std::string private_key_info1, der_cert1;
[email protected]5bab49ec2012-05-04 21:13:19534 error = service_->GetDomainBoundCert(
[email protected]4082fa22011-12-22 01:46:19535 "https://good", types, &type1, &private_key_info1, &der_cert1,
536 callback.callback(), &request_handle);
537 EXPECT_EQ(OK, error);
[email protected]2d07fa962013-01-09 22:13:31538 EXPECT_FALSE(request_handle.is_active());
[email protected]5bab49ec2012-05-04 21:13:19539 EXPECT_EQ(2, service_->cert_count());
[email protected]515face42012-02-29 05:43:15540 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type1);
[email protected]4082fa22011-12-22 01:46:19541 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;
[email protected]5bab49ec2012-05-04 21:13:19547 error = service_->GetDomainBoundCert(
[email protected]4082fa22011-12-22 01:46:19548 "https://expired", types, &type2, &private_key_info2, &der_cert2,
549 callback.callback(), &request_handle);
550 EXPECT_EQ(ERR_IO_PENDING, error);
[email protected]2d07fa962013-01-09 22:13:31551 EXPECT_TRUE(request_handle.is_active());
[email protected]4082fa22011-12-22 01:46:19552 error = callback.WaitForResult();
553 EXPECT_EQ(OK, error);
[email protected]5bab49ec2012-05-04 21:13:19554 EXPECT_EQ(2, service_->cert_count());
[email protected]515face42012-02-29 05:43:15555 EXPECT_EQ(CLIENT_CERT_ECDSA_SIGN, type2);
[email protected]4082fa22011-12-22 01:46:19556 EXPECT_LT(1U, private_key_info2.size());
557 EXPECT_LT(1U, der_cert2.size());
558}
559
[email protected]f687f1a2011-08-03 19:34:11560#endif // !defined(USE_OPENSSL)
561
[email protected]0f7804ec2011-10-07 20:04:18562} // namespace
563
[email protected]97301cd2011-07-29 02:32:39564} // namespace net