1 // Copyright 2015 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 "chrome/browser/chromeos/certificate_provider/certificate_provider_service.h"
10 #include "base/stl_util.h"
11 #include "base/test/test_mock_time_task_runner.h"
12 #include "base/thread_task_runner_handle.h"
13 #include "chrome/browser/chromeos/certificate_provider/certificate_provider.h"
14 #include "net/base/net_errors.h"
15 #include "net/base/test_data_directory.h"
16 #include "net/ssl/client_key_store.h"
17 #include "net/test/cert_test_util.h"
18 #include "testing/gtest/include/gtest/gtest.h"
24 const char kExtension1
[] = "extension1";
25 const char kExtension2
[] = "extension2";
27 void ExpectEmptySignatureAndStoreError(net::Error
* out_error
,
29 const std::vector
<uint8_t>& signature
) {
30 EXPECT_TRUE(signature
.empty());
34 void ExpectOKAndStoreSignature(std::vector
<uint8_t>* out_signature
,
36 const std::vector
<uint8_t>& signature
) {
37 EXPECT_EQ(net::OK
, error
);
38 *out_signature
= signature
;
41 void StoreCertificates(net::CertificateList
* out_certs
,
42 const net::CertificateList
& certs
) {
47 certificate_provider::CertificateInfo
CreateCertInfo(
48 const std::string
& cert_filename
) {
49 certificate_provider::CertificateInfo cert_info
;
50 cert_info
.certificate
=
51 net::ImportCertFromFile(net::GetTestCertsDirectory(), cert_filename
);
52 EXPECT_NE(nullptr, cert_info
.certificate
) << "Could not load "
54 cert_info
.type
= net::SSLPrivateKey::Type::RSA
;
55 cert_info
.supported_hashes
.push_back(net::SSLPrivateKey::Hash::SHA256
);
56 cert_info
.max_signature_length_in_bytes
= 123;
61 bool IsKeyEqualToCertInfo(const certificate_provider::CertificateInfo
& info
,
62 net::SSLPrivateKey
* key
) {
63 const net::SSLPrivateKey::Hash hashes
[] = {
64 net::SSLPrivateKey::Hash::MD5_SHA1
, net::SSLPrivateKey::Hash::SHA1
,
65 net::SSLPrivateKey::Hash::SHA256
, net::SSLPrivateKey::Hash::SHA384
,
66 net::SSLPrivateKey::Hash::SHA512
};
68 for (const net::SSLPrivateKey::Hash hash
: hashes
) {
69 if (ContainsValue(info
.supported_hashes
, hash
) != key
->SupportsHash(hash
)) {
74 return key
->GetType() == info
.type
&&
75 key
->GetMaxSignatureLengthInBytes() ==
76 info
.max_signature_length_in_bytes
;
79 class TestDelegate
: public CertificateProviderService::Delegate
{
81 enum class RequestType
{ NONE
, SIGN
, GET_CERTIFICATES
};
85 std::vector
<std::string
> CertificateProviderExtensions() override
{
86 return std::vector
<std::string
>(provider_extensions_
.begin(),
87 provider_extensions_
.end());
90 void BroadcastCertificateRequest(int cert_request_id
) override
{
91 EXPECT_EQ(expected_request_type_
, RequestType::GET_CERTIFICATES
);
92 last_cert_request_id_
= cert_request_id
;
93 expected_request_type_
= RequestType::NONE
;
96 bool DispatchSignRequestToExtension(
97 const std::string
& extension_id
,
99 net::SSLPrivateKey::Hash hash
,
100 const scoped_refptr
<net::X509Certificate
>& certificate
,
101 const std::string
& input
) override
{
102 EXPECT_EQ(expected_request_type_
, RequestType::SIGN
);
103 last_sign_request_id_
= sign_request_id
;
104 last_extension_id_
= extension_id
;
105 expected_request_type_
= RequestType::NONE
;
109 // Prepares this delegate for the dispatch of a request of type
110 // |expected_request_type|. The first request of the right type will cause
111 // |expected_request_type_| to be reset to NONE. The request's arguments will
112 // be stored in |last_*_request_id_| and |last_extension_id_|. Any additional
113 // request and any request of the wrong type will fail the test.
114 void ClearAndExpectRequest(RequestType expected_request_type
) {
115 last_extension_id_
.clear();
116 last_sign_request_id_
= -1;
117 last_cert_request_id_
= -1;
118 expected_request_type_
= expected_request_type
;
121 int last_sign_request_id_
= -1;
122 int last_cert_request_id_
= -1;
123 std::string last_extension_id_
;
124 std::set
<std::string
> provider_extensions_
;
125 RequestType expected_request_type_
= RequestType::NONE
;
128 DISALLOW_COPY_AND_ASSIGN(TestDelegate
);
133 class CertificateProviderServiceTest
: public testing::Test
{
135 CertificateProviderServiceTest()
136 : task_runner_(new base::TestMockTimeTaskRunner()),
137 task_runner_handle_(task_runner_
),
138 client_key_store_(net::ClientKeyStore::GetInstance()),
139 service_(new CertificateProviderService()),
140 cert_info1_(CreateCertInfo("client_1.pem")),
141 cert_info2_(CreateCertInfo("client_2.pem")) {
142 scoped_ptr
<TestDelegate
> test_delegate(new TestDelegate
);
143 test_delegate_
= test_delegate
.get();
144 service_
->SetDelegate(test_delegate
.Pass());
146 certificate_provider_
= service_
->CreateCertificateProvider();
147 EXPECT_TRUE(certificate_provider_
);
149 test_delegate_
->provider_extensions_
.insert(kExtension1
);
152 // Triggers a GetCertificates request and returns the request id. Assumes that
153 // at least one extension is registered as a certificate provider.
154 int RequestCertificatesFromExtensions(net::CertificateList
* certs
) {
155 test_delegate_
->ClearAndExpectRequest(
156 TestDelegate::RequestType::GET_CERTIFICATES
);
158 certificate_provider_
->GetCertificates(
159 base::Bind(&StoreCertificates
, certs
));
161 task_runner_
->RunUntilIdle();
162 EXPECT_EQ(TestDelegate::RequestType::NONE
,
163 test_delegate_
->expected_request_type_
);
164 return test_delegate_
->last_cert_request_id_
;
167 // Provides |cert_info1_| through kExtension1.
168 void ProvideDefaultCert() {
169 const int cert_request_id
= RequestCertificatesFromExtensions(nullptr);
170 SetCertificateProvidedByExtension(kExtension1
, cert_request_id
,
172 task_runner_
->RunUntilIdle();
175 // Like service_->SetCertificatesProvidedByExtension but taking a single
176 // CertificateInfo instead of a list.
177 void SetCertificateProvidedByExtension(
178 const std::string
& extension_id
,
180 const certificate_provider::CertificateInfo
& cert_info
) {
181 certificate_provider::CertificateInfoList infos
;
182 infos
.push_back(cert_info
);
183 service_
->SetCertificatesProvidedByExtension(extension_id
, cert_request_id
,
187 scoped_refptr
<base::TestMockTimeTaskRunner
> task_runner_
;
188 base::ThreadTaskRunnerHandle task_runner_handle_
;
189 TestDelegate
* test_delegate_
= nullptr;
190 net::ClientKeyStore
* const client_key_store_
;
191 scoped_ptr
<CertificateProvider
> certificate_provider_
;
192 scoped_ptr
<CertificateProviderService
> service_
;
193 const certificate_provider::CertificateInfo cert_info1_
;
194 const certificate_provider::CertificateInfo cert_info2_
;
197 DISALLOW_COPY_AND_ASSIGN(CertificateProviderServiceTest
);
200 TEST_F(CertificateProviderServiceTest
, GetCertificates
) {
201 test_delegate_
->provider_extensions_
.insert(kExtension2
);
203 net::CertificateList certs
;
204 const int cert_request_id
= RequestCertificatesFromExtensions(&certs
);
206 task_runner_
->RunUntilIdle();
207 // No certificates set until all registered extensions replied.
208 EXPECT_TRUE(certs
.empty());
210 SetCertificateProvidedByExtension(kExtension1
, cert_request_id
, cert_info1_
);
212 task_runner_
->RunUntilIdle();
213 // No certificates set until all registered extensions replied.
214 EXPECT_TRUE(certs
.empty());
216 SetCertificateProvidedByExtension(kExtension2
, cert_request_id
, cert_info2_
);
218 task_runner_
->RunUntilIdle();
219 EXPECT_EQ(2u, certs
.size());
222 client_key_store_
->FetchClientCertPrivateKey(*cert_info1_
.certificate
));
224 client_key_store_
->FetchClientCertPrivateKey(*cert_info2_
.certificate
));
226 // Deregister the extensions as certificate providers. The next
227 // GetCertificates call must report an empty list of certs.
228 test_delegate_
->provider_extensions_
.clear();
230 // No request expected.
231 test_delegate_
->ClearAndExpectRequest(TestDelegate::RequestType::NONE
);
233 certificate_provider_
->GetCertificates(
234 base::Bind(&StoreCertificates
, &certs
));
236 task_runner_
->RunUntilIdle();
237 // As |certs| was not empty before, this ensures that StoreCertificates() was
239 EXPECT_TRUE(certs
.empty());
242 TEST_F(CertificateProviderServiceTest
, GetCertificatesTimeout
) {
243 test_delegate_
->provider_extensions_
.insert(kExtension2
);
245 net::CertificateList certs
;
246 const int cert_request_id
= RequestCertificatesFromExtensions(&certs
);
248 certificate_provider::CertificateInfoList infos
;
249 SetCertificateProvidedByExtension(kExtension1
, cert_request_id
, cert_info1_
);
251 task_runner_
->RunUntilIdle();
252 // No certificates set until all registered extensions replied or a timeout
254 EXPECT_TRUE(certs
.empty());
256 task_runner_
->FastForwardUntilNoTasksRemain();
257 // After the timeout, only extension1_'s certificates are returned.
258 // This verifies that the timeout delay is > 0 but not how long the delay is.
259 EXPECT_EQ(1u, certs
.size());
262 client_key_store_
->FetchClientCertPrivateKey(*cert_info1_
.certificate
));
265 TEST_F(CertificateProviderServiceTest
, UnloadExtensionAfterGetCertificates
) {
266 test_delegate_
->provider_extensions_
.insert(kExtension2
);
268 const int cert_request_id
= RequestCertificatesFromExtensions(nullptr);
270 SetCertificateProvidedByExtension(kExtension1
, cert_request_id
, cert_info1_
);
271 SetCertificateProvidedByExtension(kExtension2
, cert_request_id
, cert_info2_
);
272 task_runner_
->RunUntilIdle();
274 // Private key handles for both certificates must be available now.
276 client_key_store_
->FetchClientCertPrivateKey(*cert_info1_
.certificate
));
278 client_key_store_
->FetchClientCertPrivateKey(*cert_info2_
.certificate
));
280 // Unload one of the extensions.
281 service_
->OnExtensionUnloaded(kExtension2
);
283 // extension1 isn't affected by the uninstall.
285 client_key_store_
->FetchClientCertPrivateKey(*cert_info1_
.certificate
));
286 // No key handles that were backed by the uninstalled extension must be
289 client_key_store_
->FetchClientCertPrivateKey(*cert_info2_
.certificate
));
292 TEST_F(CertificateProviderServiceTest
, UnloadExtensionDuringGetCertificates
) {
293 test_delegate_
->provider_extensions_
.insert(kExtension2
);
295 net::CertificateList certs
;
296 const int cert_request_id
= RequestCertificatesFromExtensions(&certs
);
298 SetCertificateProvidedByExtension(kExtension1
, cert_request_id
, cert_info1_
);
300 // The pending certificate request is only waiting for kExtension2. Unloading
301 // that extension must cause the request to be finished.
302 service_
->OnExtensionUnloaded(kExtension2
);
304 task_runner_
->RunUntilIdle();
305 EXPECT_EQ(1u, certs
.size());
308 // Trying to sign data using the exposed SSLPrivateKey must cause a sign
309 // request. The reply must be correctly routed back to the private key.
310 TEST_F(CertificateProviderServiceTest
, SignRequest
) {
311 ProvideDefaultCert();
313 scoped_ptr
<net::SSLPrivateKey
> private_key(
314 client_key_store_
->FetchClientCertPrivateKey(*cert_info1_
.certificate
));
316 ASSERT_TRUE(private_key
);
317 EXPECT_TRUE(IsKeyEqualToCertInfo(cert_info1_
, private_key
.get()));
319 test_delegate_
->ClearAndExpectRequest(TestDelegate::RequestType::SIGN
);
321 std::vector
<uint8_t> received_signature
;
322 private_key
->SignDigest(
323 net::SSLPrivateKey::Hash::SHA256
, std::string("any input data"),
324 base::Bind(&ExpectOKAndStoreSignature
, &received_signature
));
326 task_runner_
->RunUntilIdle();
328 const int sign_request_id
= test_delegate_
->last_sign_request_id_
;
329 EXPECT_EQ(TestDelegate::RequestType::NONE
,
330 test_delegate_
->expected_request_type_
);
332 // No signature received until the extension replied to the service.
333 EXPECT_TRUE(received_signature
.empty());
335 std::vector
<uint8_t> signature_reply
;
336 signature_reply
.push_back(5);
337 signature_reply
.push_back(7);
338 signature_reply
.push_back(8);
339 service_
->ReplyToSignRequest(kExtension1
, sign_request_id
, signature_reply
);
341 task_runner_
->RunUntilIdle();
342 EXPECT_EQ(signature_reply
, received_signature
);
345 TEST_F(CertificateProviderServiceTest
, UnloadExtensionDuringSign
) {
346 ProvideDefaultCert();
348 scoped_ptr
<net::SSLPrivateKey
> private_key(
349 client_key_store_
->FetchClientCertPrivateKey(*cert_info1_
.certificate
));
350 ASSERT_TRUE(private_key
);
352 test_delegate_
->ClearAndExpectRequest(TestDelegate::RequestType::SIGN
);
354 net::Error error
= net::OK
;
355 private_key
->SignDigest(
356 net::SSLPrivateKey::Hash::SHA256
, std::string("any input data"),
357 base::Bind(&ExpectEmptySignatureAndStoreError
, &error
));
359 task_runner_
->RunUntilIdle();
361 // No signature received until the extension replied to the service or is
363 EXPECT_EQ(net::OK
, error
);
365 // Unload the extension.
366 service_
->OnExtensionUnloaded(kExtension1
);
368 task_runner_
->RunUntilIdle();
369 EXPECT_EQ(net::ERR_FAILED
, error
);
372 } // namespace chromeos