Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / chromeos / certificate_provider / certificate_provider_service_unittest.cc
blob096e6476bc8664193e42db3c38714b7dc348d780
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"
7 #include <set>
9 #include "base/bind.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"
20 namespace chromeos {
22 namespace {
24 const char kExtension1[] = "extension1";
25 const char kExtension2[] = "extension2";
27 void ExpectEmptySignatureAndStoreError(net::Error* out_error,
28 net::Error error,
29 const std::vector<uint8_t>& signature) {
30 EXPECT_TRUE(signature.empty());
31 *out_error = error;
34 void ExpectOKAndStoreSignature(std::vector<uint8_t>* out_signature,
35 net::Error error,
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) {
43 if (out_certs)
44 *out_certs = 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 "
53 << cert_filename;
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;
58 return cert_info;
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)) {
70 return false;
74 return key->GetType() == info.type &&
75 key->GetMaxSignatureLengthInBytes() ==
76 info.max_signature_length_in_bytes;
79 class TestDelegate : public CertificateProviderService::Delegate {
80 public:
81 enum class RequestType { NONE, SIGN, GET_CERTIFICATES };
83 TestDelegate() {}
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,
98 int sign_request_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 last_certificate_ = certificate;
106 expected_request_type_ = RequestType::NONE;
107 return true;
110 // Prepares this delegate for the dispatch of a request of type
111 // |expected_request_type|. The first request of the right type will cause
112 // |expected_request_type_| to be reset to NONE. The request's arguments will
113 // be stored in |last_*_request_id_| and |last_extension_id_|. Any additional
114 // request and any request of the wrong type will fail the test.
115 void ClearAndExpectRequest(RequestType expected_request_type) {
116 last_extension_id_.clear();
117 last_sign_request_id_ = -1;
118 last_cert_request_id_ = -1;
119 last_certificate_ = nullptr;
120 expected_request_type_ = expected_request_type;
123 int last_sign_request_id_ = -1;
124 int last_cert_request_id_ = -1;
125 scoped_refptr<net::X509Certificate> last_certificate_;
126 std::string last_extension_id_;
127 std::set<std::string> provider_extensions_;
128 RequestType expected_request_type_ = RequestType::NONE;
130 private:
131 DISALLOW_COPY_AND_ASSIGN(TestDelegate);
134 } // namespace
136 class CertificateProviderServiceTest : public testing::Test {
137 public:
138 CertificateProviderServiceTest()
139 : task_runner_(new base::TestMockTimeTaskRunner()),
140 task_runner_handle_(task_runner_),
141 client_key_store_(net::ClientKeyStore::GetInstance()),
142 service_(new CertificateProviderService()),
143 cert_info1_(CreateCertInfo("client_1.pem")),
144 cert_info2_(CreateCertInfo("client_2.pem")) {
145 scoped_ptr<TestDelegate> test_delegate(new TestDelegate);
146 test_delegate_ = test_delegate.get();
147 service_->SetDelegate(test_delegate.Pass());
149 certificate_provider_ = service_->CreateCertificateProvider();
150 EXPECT_TRUE(certificate_provider_);
152 test_delegate_->provider_extensions_.insert(kExtension1);
155 // Triggers a GetCertificates request and returns the request id. Assumes that
156 // at least one extension is registered as a certificate provider.
157 int RequestCertificatesFromExtensions(net::CertificateList* certs) {
158 test_delegate_->ClearAndExpectRequest(
159 TestDelegate::RequestType::GET_CERTIFICATES);
161 certificate_provider_->GetCertificates(
162 base::Bind(&StoreCertificates, certs));
164 task_runner_->RunUntilIdle();
165 EXPECT_EQ(TestDelegate::RequestType::NONE,
166 test_delegate_->expected_request_type_);
167 return test_delegate_->last_cert_request_id_;
170 // Provides |cert_info1_| through kExtension1.
171 void ProvideDefaultCert() {
172 const int cert_request_id = RequestCertificatesFromExtensions(nullptr);
173 SetCertificateProvidedByExtension(kExtension1, cert_request_id,
174 cert_info1_);
175 task_runner_->RunUntilIdle();
178 // Like service_->SetCertificatesProvidedByExtension but taking a single
179 // CertificateInfo instead of a list.
180 void SetCertificateProvidedByExtension(
181 const std::string& extension_id,
182 int cert_request_id,
183 const certificate_provider::CertificateInfo& cert_info) {
184 certificate_provider::CertificateInfoList infos;
185 infos.push_back(cert_info);
186 service_->SetCertificatesProvidedByExtension(extension_id, cert_request_id,
187 infos);
190 bool CheckLookUpCertificate(
191 const certificate_provider::CertificateInfo& cert_info,
192 bool expected_is_certificate_known,
193 bool expected_is_currently_provided,
194 const std::string& expected_extension_id) {
195 bool is_currently_provided = !expected_is_currently_provided;
196 std::string extension_id;
197 if (expected_is_certificate_known !=
198 service_->LookUpCertificate(*cert_info.certificate,
199 &is_currently_provided, &extension_id)) {
200 LOG(ERROR) << "Wrong return value.";
201 return false;
203 if (expected_is_currently_provided != is_currently_provided) {
204 LOG(ERROR) << "Wrong |is_currently_provided|.";
205 return false;
207 if (expected_extension_id != extension_id) {
208 LOG(ERROR) << "Wrong extension id. Got " << extension_id;
209 return false;
211 return true;
214 scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
215 base::ThreadTaskRunnerHandle task_runner_handle_;
216 TestDelegate* test_delegate_ = nullptr;
217 net::ClientKeyStore* const client_key_store_;
218 scoped_ptr<CertificateProvider> certificate_provider_;
219 scoped_ptr<CertificateProviderService> service_;
220 const certificate_provider::CertificateInfo cert_info1_;
221 const certificate_provider::CertificateInfo cert_info2_;
223 private:
224 DISALLOW_COPY_AND_ASSIGN(CertificateProviderServiceTest);
227 TEST_F(CertificateProviderServiceTest, GetCertificates) {
228 test_delegate_->provider_extensions_.insert(kExtension2);
230 net::CertificateList certs;
231 const int cert_request_id = RequestCertificatesFromExtensions(&certs);
233 task_runner_->RunUntilIdle();
234 // No certificates set until all registered extensions replied.
235 EXPECT_TRUE(certs.empty());
237 SetCertificateProvidedByExtension(kExtension1, cert_request_id, cert_info1_);
239 task_runner_->RunUntilIdle();
240 // No certificates set until all registered extensions replied.
241 EXPECT_TRUE(certs.empty());
243 SetCertificateProvidedByExtension(kExtension2, cert_request_id, cert_info2_);
245 task_runner_->RunUntilIdle();
246 EXPECT_EQ(2u, certs.size());
248 // Verify that the ClientKeyStore returns key handles for the provide certs.
249 EXPECT_TRUE(
250 client_key_store_->FetchClientCertPrivateKey(*cert_info1_.certificate));
251 EXPECT_TRUE(
252 client_key_store_->FetchClientCertPrivateKey(*cert_info2_.certificate));
254 // Deregister the extensions as certificate providers. The next
255 // GetCertificates call must report an empty list of certs.
256 test_delegate_->provider_extensions_.clear();
258 // No request expected.
259 test_delegate_->ClearAndExpectRequest(TestDelegate::RequestType::NONE);
261 certificate_provider_->GetCertificates(
262 base::Bind(&StoreCertificates, &certs));
264 task_runner_->RunUntilIdle();
265 // As |certs| was not empty before, this ensures that StoreCertificates() was
266 // called.
267 EXPECT_TRUE(certs.empty());
270 TEST_F(CertificateProviderServiceTest, LookUpCertificate) {
271 // Provide only |cert_info1_|.
273 const int cert_request_id = RequestCertificatesFromExtensions(nullptr);
274 SetCertificateProvidedByExtension(kExtension1, cert_request_id,
275 cert_info1_);
276 task_runner_->RunUntilIdle();
279 EXPECT_TRUE(CheckLookUpCertificate(cert_info1_, true /* is known */,
280 true /* is currently provided */,
281 kExtension1));
283 EXPECT_TRUE(CheckLookUpCertificate(cert_info2_, false /* is not known */,
284 false /* is currently not provided */,
285 std::string()));
287 // Provide only |cert_info2_| from |kExtension2|.
288 test_delegate_->provider_extensions_.insert(kExtension2);
290 const int cert_request_id = RequestCertificatesFromExtensions(nullptr);
291 service_->SetCertificatesProvidedByExtension(
292 kExtension1, cert_request_id,
293 certificate_provider::CertificateInfoList());
294 SetCertificateProvidedByExtension(kExtension2, cert_request_id,
295 cert_info2_);
296 task_runner_->RunUntilIdle();
299 EXPECT_TRUE(CheckLookUpCertificate(cert_info1_, true /* is known */,
300 false /* is currently not provided */,
301 std::string()));
303 EXPECT_TRUE(CheckLookUpCertificate(cert_info2_, true /* is known */,
304 true /* is currently provided */,
305 kExtension2));
307 // Deregister |kExtension2| as certificate provider and provide |cert_info1_|
308 // from |kExtension1|.
309 test_delegate_->provider_extensions_.erase(kExtension2);
312 const int cert_request_id = RequestCertificatesFromExtensions(nullptr);
313 SetCertificateProvidedByExtension(kExtension1, cert_request_id,
314 cert_info1_);
315 task_runner_->RunUntilIdle();
318 EXPECT_TRUE(CheckLookUpCertificate(cert_info1_, true /* is known */,
319 true /* is currently provided */,
320 kExtension1));
322 EXPECT_TRUE(CheckLookUpCertificate(cert_info2_, true /* is known */,
323 false /* is currently not provided */,
324 std::string()));
326 // Provide |cert_info2_| from |kExtension1|.
328 const int cert_request_id = RequestCertificatesFromExtensions(nullptr);
329 SetCertificateProvidedByExtension(kExtension1, cert_request_id,
330 cert_info2_);
331 task_runner_->RunUntilIdle();
335 bool is_currently_provided = true;
336 std::string extension_id;
337 // |cert_info1_.certificate| was provided before, so this must return true.
338 EXPECT_TRUE(service_->LookUpCertificate(
339 *cert_info1_.certificate, &is_currently_provided, &extension_id));
340 EXPECT_FALSE(is_currently_provided);
341 EXPECT_TRUE(extension_id.empty());
345 bool is_currently_provided = false;
346 std::string extension_id;
347 EXPECT_TRUE(service_->LookUpCertificate(
348 *cert_info2_.certificate, &is_currently_provided, &extension_id));
349 EXPECT_TRUE(is_currently_provided);
350 EXPECT_EQ(kExtension1, extension_id);
353 EXPECT_TRUE(CheckLookUpCertificate(cert_info1_, true /* is known */,
354 false /* is currently not provided */,
355 std::string()));
357 EXPECT_TRUE(CheckLookUpCertificate(cert_info2_, true /* is known */,
358 true /* is currently provided */,
359 kExtension1));
362 TEST_F(CertificateProviderServiceTest, GetCertificatesTimeout) {
363 test_delegate_->provider_extensions_.insert(kExtension2);
365 net::CertificateList certs;
366 const int cert_request_id = RequestCertificatesFromExtensions(&certs);
368 certificate_provider::CertificateInfoList infos;
369 SetCertificateProvidedByExtension(kExtension1, cert_request_id, cert_info1_);
371 task_runner_->RunUntilIdle();
372 // No certificates set until all registered extensions replied or a timeout
373 // occurred.
374 EXPECT_TRUE(certs.empty());
376 task_runner_->FastForwardUntilNoTasksRemain();
377 // After the timeout, only extension1_'s certificates are returned.
378 // This verifies that the timeout delay is > 0 but not how long the delay is.
379 EXPECT_EQ(1u, certs.size());
381 EXPECT_TRUE(
382 client_key_store_->FetchClientCertPrivateKey(*cert_info1_.certificate));
385 TEST_F(CertificateProviderServiceTest, UnloadExtensionAfterGetCertificates) {
386 test_delegate_->provider_extensions_.insert(kExtension2);
388 const int cert_request_id = RequestCertificatesFromExtensions(nullptr);
390 SetCertificateProvidedByExtension(kExtension1, cert_request_id, cert_info1_);
391 SetCertificateProvidedByExtension(kExtension2, cert_request_id, cert_info2_);
392 task_runner_->RunUntilIdle();
394 // Private key handles for both certificates must be available now.
395 EXPECT_TRUE(
396 client_key_store_->FetchClientCertPrivateKey(*cert_info1_.certificate));
397 EXPECT_TRUE(
398 client_key_store_->FetchClientCertPrivateKey(*cert_info2_.certificate));
400 // Unload one of the extensions.
401 service_->OnExtensionUnloaded(kExtension2);
403 // extension1 isn't affected by the uninstall.
404 EXPECT_TRUE(
405 client_key_store_->FetchClientCertPrivateKey(*cert_info1_.certificate));
406 // No key handles that were backed by the uninstalled extension must be
407 // returned.
408 EXPECT_FALSE(
409 client_key_store_->FetchClientCertPrivateKey(*cert_info2_.certificate));
412 TEST_F(CertificateProviderServiceTest, UnloadExtensionDuringGetCertificates) {
413 test_delegate_->provider_extensions_.insert(kExtension2);
415 net::CertificateList certs;
416 const int cert_request_id = RequestCertificatesFromExtensions(&certs);
418 SetCertificateProvidedByExtension(kExtension1, cert_request_id, cert_info1_);
420 // The pending certificate request is only waiting for kExtension2. Unloading
421 // that extension must cause the request to be finished.
422 service_->OnExtensionUnloaded(kExtension2);
424 task_runner_->RunUntilIdle();
425 EXPECT_EQ(1u, certs.size());
428 // Trying to sign data using the exposed SSLPrivateKey must cause a sign
429 // request. The reply must be correctly routed back to the private key.
430 TEST_F(CertificateProviderServiceTest, SignRequest) {
431 ProvideDefaultCert();
433 scoped_ptr<net::SSLPrivateKey> private_key(
434 client_key_store_->FetchClientCertPrivateKey(*cert_info1_.certificate));
436 ASSERT_TRUE(private_key);
437 EXPECT_TRUE(IsKeyEqualToCertInfo(cert_info1_, private_key.get()));
439 test_delegate_->ClearAndExpectRequest(TestDelegate::RequestType::SIGN);
441 std::vector<uint8_t> received_signature;
442 private_key->SignDigest(
443 net::SSLPrivateKey::Hash::SHA256, std::string("any input data"),
444 base::Bind(&ExpectOKAndStoreSignature, &received_signature));
446 task_runner_->RunUntilIdle();
448 const int sign_request_id = test_delegate_->last_sign_request_id_;
449 EXPECT_EQ(TestDelegate::RequestType::NONE,
450 test_delegate_->expected_request_type_);
451 EXPECT_TRUE(
452 cert_info1_.certificate->Equals(test_delegate_->last_certificate_.get()));
454 // No signature received until the extension replied to the service.
455 EXPECT_TRUE(received_signature.empty());
457 std::vector<uint8_t> signature_reply;
458 signature_reply.push_back(5);
459 signature_reply.push_back(7);
460 signature_reply.push_back(8);
461 service_->ReplyToSignRequest(kExtension1, sign_request_id, signature_reply);
463 task_runner_->RunUntilIdle();
464 EXPECT_EQ(signature_reply, received_signature);
467 TEST_F(CertificateProviderServiceTest, UnloadExtensionDuringSign) {
468 ProvideDefaultCert();
470 scoped_ptr<net::SSLPrivateKey> private_key(
471 client_key_store_->FetchClientCertPrivateKey(*cert_info1_.certificate));
472 ASSERT_TRUE(private_key);
474 test_delegate_->ClearAndExpectRequest(TestDelegate::RequestType::SIGN);
476 net::Error error = net::OK;
477 private_key->SignDigest(
478 net::SSLPrivateKey::Hash::SHA256, std::string("any input data"),
479 base::Bind(&ExpectEmptySignatureAndStoreError, &error));
481 task_runner_->RunUntilIdle();
483 // No signature received until the extension replied to the service or is
484 // unloaded.
485 EXPECT_EQ(net::OK, error);
487 // Unload the extension.
488 service_->OnExtensionUnloaded(kExtension1);
490 task_runner_->RunUntilIdle();
491 EXPECT_EQ(net::ERR_FAILED, error);
494 } // namespace chromeos