Add new certificateProvider extension API.
[chromium-blink-merge.git] / chrome / browser / chromeos / certificate_provider / certificate_provider_service_unittest.cc
bloba15061dd03d31afac0985a4107321891318d9496
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 expected_request_type_ = RequestType::NONE;
106 return true;
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;
127 private:
128 DISALLOW_COPY_AND_ASSIGN(TestDelegate);
131 } // namespace
133 class CertificateProviderServiceTest : public testing::Test {
134 public:
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,
171 cert_info1_);
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,
179 int cert_request_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,
184 infos);
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_;
196 private:
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());
221 EXPECT_TRUE(
222 client_key_store_->FetchClientCertPrivateKey(*cert_info1_.certificate));
223 EXPECT_TRUE(
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
238 // called.
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
253 // occurred.
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());
261 EXPECT_TRUE(
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.
275 EXPECT_TRUE(
276 client_key_store_->FetchClientCertPrivateKey(*cert_info1_.certificate));
277 EXPECT_TRUE(
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.
284 EXPECT_TRUE(
285 client_key_store_->FetchClientCertPrivateKey(*cert_info1_.certificate));
286 // No key handles that were backed by the uninstalled extension must be
287 // returned.
288 EXPECT_FALSE(
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
362 // unloaded.
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