1 // Copyright 2018 The Chromium Authors
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/certificate_manager_model.h"
7 #include "base/memory/raw_ptr.h"
8 #include "base/observer_list.h"
9 #include "base/run_loop.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "base/test/test_future.h"
12 #include "build/chromeos_buildflags.h"
13 #include "content/public/test/browser_task_environment.h"
14 #include "crypto/scoped_test_nss_db.h"
15 #include "net/cert/nss_cert_database.h"
16 #include "net/cert/scoped_nss_types.h"
17 #include "net/cert/x509_util_nss.h"
18 #include "net/ssl/client_cert_identity_test_util.h"
19 #include "net/test/cert_builder.h"
20 #include "net/test/cert_test_util.h"
21 #include "net/test/test_data_directory.h"
22 #include "testing/gtest/include/gtest/gtest.h"
24 #if BUILDFLAG(IS_CHROMEOS)
25 #include "chrome/browser/certificate_provider/certificate_provider.h"
26 #include "chromeos/ash/components/network/policy_certificate_provider.h"
27 #include "chromeos/components/onc/certificate_scope.h"
28 #endif // BUILDFLAG(IS_CHROMEOS)
32 // A fake CertificateManagerModel::Observer that has the ability to execute a
33 // OnceClosure passed to it when |CertificatesRefreshed| is called.
34 class FakeObserver : public CertificateManagerModel::Observer {
36 void CertificatesRefreshed() override {
37 if (!run_on_refresh_.is_null())
38 std::move(run_on_refresh_).Run();
41 // Execute |closure| on the next |CertificatesRefreshed| invocation.
42 void RunOnNextRefresh(base::OnceClosure closure) {
43 run_on_refresh_ = std::move(closure);
47 base::OnceClosure run_on_refresh_;
50 // Looks up a |CertInfo| in |org_grouping_map| corresponding to |cert|. Returns
51 // nullptr if no such |CertInfo| was found.
52 CertificateManagerModel::CertInfo* GetCertInfoFromOrgGroupingMap(
53 const CertificateManagerModel::OrgGroupingMap& org_grouping_map,
54 CERTCertificate* cert) {
55 for (const auto& org_and_cert_info_list : org_grouping_map) {
56 for (const auto& cert_info : org_and_cert_info_list.second) {
57 if (net::x509_util::IsSameCertificate(cert_info->cert(), cert))
58 return cert_info.get();
66 class CertificateManagerModelTest : public testing::Test {
68 CertificateManagerModelTest() {}
70 CertificateManagerModelTest(const CertificateManagerModelTest&) = delete;
71 CertificateManagerModelTest& operator=(const CertificateManagerModelTest&) =
75 void SetUp() override {
76 ASSERT_TRUE(test_nssdb_.is_open());
78 nss_cert_db_ = std::make_unique<net::NSSCertDatabase>(
79 crypto::ScopedPK11Slot(
80 PK11_ReferenceSlot(test_nssdb_.slot())) /* public slot */,
81 crypto::ScopedPK11Slot(
82 PK11_ReferenceSlot(test_nssdb_.slot())) /* private slot */);
84 fake_observer_ = std::make_unique<FakeObserver>();
85 certificate_manager_model_ = std::make_unique<CertificateManagerModel>(
86 GetCertificateManagerModelParams(), fake_observer_.get(),
90 void TearDown() override {
91 certificate_manager_model_.reset();
95 // Provides the platform-specific |Params| (containing policy/extension
96 // certificate provides on Chrome OS).
97 virtual std::unique_ptr<CertificateManagerModel::Params>
98 GetCertificateManagerModelParams() {
99 return std::make_unique<CertificateManagerModel::Params>();
103 // Invoke an explicit Refresh if the refresh is triggered and wait until the
104 // observer has been notified.
105 void WaitForRefresh(bool trigger_refresh) {
106 base::RunLoop run_loop;
107 fake_observer_->RunOnNextRefresh(run_loop.QuitClosure());
108 if (trigger_refresh) {
109 certificate_manager_model_->Refresh();
114 content::BrowserTaskEnvironment task_environment_;
115 crypto::ScopedTestNSSDB test_nssdb_;
116 std::unique_ptr<net::NSSCertDatabase> nss_cert_db_;
117 std::unique_ptr<FakeObserver> fake_observer_;
118 std::unique_ptr<CertificateManagerModel> certificate_manager_model_;
121 // CertificateManagerModel correctly lists CA certificates from the platform NSS
123 TEST_F(CertificateManagerModelTest, ListsCertsFromPlatform) {
124 net::CertificateList orig_certs = CreateCertificateListFromFile(
125 net::GetTestCertsDirectory(), "websocket_cacert.pem",
126 net::X509Certificate::FORMAT_AUTO);
127 ASSERT_EQ(1U, orig_certs.size());
129 net::CertBuilder cert_builder(orig_certs[0]->cert_buffer(), nullptr);
130 scoped_refptr<net::X509Certificate> x509_cert =
131 cert_builder.GetX509Certificate();
133 net::ScopedCERTCertificate cert =
134 net::x509_util::CreateCERTCertificateFromX509Certificate(x509_cert.get());
135 std::string cert_subject_name = x509_cert->subject().GetDisplayName();
137 ASSERT_EQ(SECSuccess,
138 PK11_ImportCert(test_nssdb_.slot(), cert.get(), CK_INVALID_HANDLE,
139 "cert", PR_FALSE /* includeTrust (unused) */));
140 WaitForRefresh(true /*tigger_for_refresh*/);
143 CertificateManagerModel::OrgGroupingMap org_grouping_map;
144 certificate_manager_model_->FilterAndBuildOrgGroupingMap(
145 net::CertType::CA_CERT, &org_grouping_map);
146 CertificateManagerModel::CertInfo* cert_info =
147 GetCertInfoFromOrgGroupingMap(org_grouping_map, cert.get());
148 ASSERT_TRUE(cert_info);
150 EXPECT_EQ(net::CertType::CA_CERT, cert_info->type());
151 EXPECT_EQ(base::UTF8ToUTF16(cert_subject_name), cert_info->name());
152 EXPECT_TRUE(cert_info->can_be_deleted());
153 // This platform cert is untrusted because it is self-signed and has no
155 EXPECT_TRUE(cert_info->untrusted());
156 EXPECT_EQ(CertificateManagerModel::CertInfo::Source::kPlatform,
157 cert_info->source());
158 EXPECT_FALSE(cert_info->web_trust_anchor());
159 EXPECT_FALSE(cert_info->hardware_backed());
162 certificate_manager_model_->SetCertTrust(cert.get(), net::CertType::CA_CERT,
163 net::NSSCertDatabase::TRUSTED_SSL);
164 // Wait for refresh without triggering because observer should be notified by
165 // net::CertDatabase and refresh automatically.
166 WaitForRefresh(false /*tigger_for_refresh*/);
168 CertificateManagerModel::OrgGroupingMap org_grouping_map;
169 certificate_manager_model_->FilterAndBuildOrgGroupingMap(
170 net::CertType::CA_CERT, &org_grouping_map);
171 CertificateManagerModel::CertInfo* cert_info =
172 GetCertInfoFromOrgGroupingMap(org_grouping_map, cert.get());
173 ASSERT_TRUE(cert_info);
175 EXPECT_FALSE(cert_info->untrusted());
176 EXPECT_TRUE(cert_info->web_trust_anchor());
180 // CertificateManagerModel correctly lists client certificates from the platform
182 TEST_F(CertificateManagerModelTest, ListsClientCertsFromPlatform) {
183 net::ScopedCERTCertificate platform_client_cert;
184 net::ImportClientCertAndKeyFromFile(
185 net::GetTestCertsDirectory(), "client_1.pem", "client_1.pk8",
186 test_nssdb_.slot(), &platform_client_cert);
188 WaitForRefresh(true /*tigger_for_refresh*/);
190 CertificateManagerModel::OrgGroupingMap org_grouping_map;
191 certificate_manager_model_->FilterAndBuildOrgGroupingMap(
192 net::CertType::USER_CERT, &org_grouping_map);
193 CertificateManagerModel::CertInfo* platform_cert_info =
194 GetCertInfoFromOrgGroupingMap(org_grouping_map,
195 platform_client_cert.get());
196 ASSERT_TRUE(platform_cert_info);
198 EXPECT_EQ(net::CertType::USER_CERT, platform_cert_info->type());
199 EXPECT_EQ(u"Client Cert A", platform_cert_info->name());
200 EXPECT_TRUE(platform_cert_info->can_be_deleted());
201 EXPECT_EQ(CertificateManagerModel::CertInfo::Source::kPlatform,
202 platform_cert_info->source());
203 EXPECT_FALSE(platform_cert_info->web_trust_anchor());
204 EXPECT_FALSE(platform_cert_info->hardware_backed());
207 #if BUILDFLAG(IS_CHROMEOS)
210 class FakePolicyCertificateProvider : public ash::PolicyCertificateProvider {
212 void AddPolicyProvidedCertsObserver(Observer* observer) override {
213 observer_list_.AddObserver(observer);
216 void RemovePolicyProvidedCertsObserver(Observer* observer) override {
217 observer_list_.RemoveObserver(observer);
220 net::CertificateList GetAllServerAndAuthorityCertificates(
221 const chromeos::onc::CertificateScope& scope) const override {
222 // The CertificateManagerModel only retrieves profile-wide certificates.
223 EXPECT_EQ(chromeos::onc::CertificateScope::Default(), scope);
225 net::CertificateList merged;
226 merged.insert(merged.end(), web_trusted_certs_.begin(),
227 web_trusted_certs_.end());
228 merged.insert(merged.end(), not_web_trusted_certs_.begin(),
229 not_web_trusted_certs_.end());
233 net::CertificateList GetAllAuthorityCertificates(
234 const chromeos::onc::CertificateScope& scope) const override {
235 // This function is not called by CertificateManagerModel.
237 return net::CertificateList();
240 net::CertificateList GetWebTrustedCertificates(
241 const chromeos::onc::CertificateScope& scope) const override {
242 // The CertificateManagerModel only retrieves profile-wide certificates.
243 EXPECT_EQ(chromeos::onc::CertificateScope::Default(), scope);
245 return web_trusted_certs_;
248 net::CertificateList GetCertificatesWithoutWebTrust(
249 const chromeos::onc::CertificateScope& scope) const override {
250 // The CertificateManagerModel only retrieves profile-wide certificates.
251 EXPECT_EQ(chromeos::onc::CertificateScope::Default(), scope);
253 return not_web_trusted_certs_;
256 const std::set<std::string>& GetExtensionIdsWithPolicyCertificates()
258 // This function is not called by CertificateManagerModel.
260 return kNoExtensions;
263 void SetPolicyProvidedCertificates(
264 const net::CertificateList& web_trusted_certs,
265 const net::CertificateList& not_web_trusted_certs) {
266 web_trusted_certs_ = web_trusted_certs;
267 not_web_trusted_certs_ = not_web_trusted_certs;
270 void NotifyObservers() {
271 for (auto& observer : observer_list_)
272 observer.OnPolicyProvidedCertsChanged();
276 base::ObserverList<PolicyCertificateProvider::Observer,
277 true /* check_empty */>::Unchecked observer_list_;
278 net::CertificateList web_trusted_certs_;
279 net::CertificateList not_web_trusted_certs_;
280 const std::set<std::string> kNoExtensions = {};
283 class FakeExtensionCertificateProvider : public chromeos::CertificateProvider {
285 FakeExtensionCertificateProvider(
286 const net::CertificateList* extension_client_certificates,
287 const bool* extensions_hang)
288 : extension_client_certificates_(extension_client_certificates),
289 extensions_hang_(extensions_hang) {}
291 void GetCertificates(
292 base::OnceCallback<void(net::ClientCertIdentityList)> callback) override {
293 if (*extensions_hang_)
296 std::move(callback).Run(FakeClientCertIdentityListFromCertificateList(
297 *extension_client_certificates_));
301 raw_ptr<const net::CertificateList> extension_client_certificates_;
303 // If *|extensions_hang| is true, the |FakeExtensionCertificateProvider| hangs
304 // - it never calls the callbacks passed to |GetCertificates|.
305 raw_ptr<const bool> extensions_hang_;
308 // Looks up a |CertInfo| in |org_grouping_map| corresponding to |cert|. Returns
309 // nullptr if no such |CertInfo| was found.
310 CertificateManagerModel::CertInfo* GetCertInfoFromOrgGroupingMap(
311 const CertificateManagerModel::OrgGroupingMap& org_grouping_map,
312 const net::X509Certificate* cert) {
313 for (const auto& org_and_cert_info_list : org_grouping_map) {
314 for (const auto& cert_info : org_and_cert_info_list.second) {
315 if (net::x509_util::IsSameCertificate(cert_info->cert(), cert))
316 return cert_info.get();
324 class CertificateManagerModelChromeOSTest : public CertificateManagerModelTest {
326 std::unique_ptr<CertificateManagerModel::Params>
327 GetCertificateManagerModelParams() override {
328 auto params = std::make_unique<CertificateManagerModel::Params>();
329 params->policy_certs_provider = &policy_certs_provider_;
330 params->extension_certificate_provider =
331 std::make_unique<FakeExtensionCertificateProvider>(
332 &extension_client_certs_, &extensions_hang_);
336 void NotifyPolicyObserversAndWaitForRefresh() {
337 base::RunLoop run_loop;
338 fake_observer_->RunOnNextRefresh(run_loop.QuitClosure());
339 policy_certs_provider_.NotifyObservers();
343 // Provider for policy certificates. In a non-test environment, this would
344 // usually be the UserNetworkConfigurationUpdater.
345 FakePolicyCertificateProvider policy_certs_provider_;
347 // List of certificates that will be returned from the
348 // FakeExtensionCertificateProvider.
349 net::CertificateList extension_client_certs_;
350 // If true, the FakeExtensionCertificateProvider hangs.
351 bool extensions_hang_ = false;
354 // CertificateManagerModel correctly lists policy-provided certificates with web
356 TEST_F(CertificateManagerModelChromeOSTest, ListsWebTrustedCertsFromPolicy) {
357 scoped_refptr<net::X509Certificate> cert = net::ImportCertFromFile(
358 net::GetTestCertsDirectory(), "websocket_cacert.pem");
359 ASSERT_TRUE(cert.get());
360 policy_certs_provider_.SetPolicyProvidedCertificates({cert}, {});
362 NotifyPolicyObserversAndWaitForRefresh();
364 CertificateManagerModel::OrgGroupingMap org_grouping_map;
365 certificate_manager_model_->FilterAndBuildOrgGroupingMap(
366 net::CertType::CA_CERT, &org_grouping_map);
367 CertificateManagerModel::CertInfo* cert_info =
368 GetCertInfoFromOrgGroupingMap(org_grouping_map, cert.get());
369 ASSERT_TRUE(cert_info);
371 EXPECT_EQ(net::CertType::CA_CERT, cert_info->type());
372 EXPECT_EQ(u"pywebsocket", cert_info->name());
373 EXPECT_FALSE(cert_info->can_be_deleted());
374 EXPECT_FALSE(cert_info->untrusted());
375 EXPECT_EQ(CertificateManagerModel::CertInfo::Source::kPolicy,
376 cert_info->source());
377 EXPECT_TRUE(cert_info->web_trust_anchor());
378 EXPECT_FALSE(cert_info->hardware_backed());
381 // CertificateManagerModel correctly lists policy-provided certificates without
383 TEST_F(CertificateManagerModelChromeOSTest, ListsNotWebTrustedCertsFromPolicy) {
384 scoped_refptr<net::X509Certificate> cert = net::ImportCertFromFile(
385 net::GetTestCertsDirectory(), "websocket_cacert.pem");
386 ASSERT_TRUE(cert.get());
387 policy_certs_provider_.SetPolicyProvidedCertificates({}, {cert});
389 NotifyPolicyObserversAndWaitForRefresh();
391 CertificateManagerModel::OrgGroupingMap org_grouping_map;
392 certificate_manager_model_->FilterAndBuildOrgGroupingMap(
393 net::CertType::CA_CERT, &org_grouping_map);
394 CertificateManagerModel::CertInfo* cert_info =
395 GetCertInfoFromOrgGroupingMap(org_grouping_map, cert.get());
396 ASSERT_TRUE(cert_info);
398 EXPECT_EQ(net::CertType::CA_CERT, cert_info->type());
399 EXPECT_EQ(u"pywebsocket", cert_info->name());
400 EXPECT_FALSE(cert_info->can_be_deleted());
401 EXPECT_FALSE(cert_info->untrusted());
402 EXPECT_EQ(CertificateManagerModel::CertInfo::Source::kPolicy,
403 cert_info->source());
404 EXPECT_FALSE(cert_info->web_trust_anchor());
405 EXPECT_FALSE(cert_info->hardware_backed());
408 // CertificateManagerModel correctly lists CA certificates that are in the
409 // platform NSS database and provided by policy with web trust. The
410 // policy-provided certificate hides the platform certificate in this case.
411 TEST_F(CertificateManagerModelChromeOSTest,
412 WebTrustedPolicyCertsWinOverPlatformCerts) {
413 net::ScopedCERTCertificateList certs = CreateCERTCertificateListFromFile(
414 net::GetTestCertsDirectory(), "websocket_cacert.pem",
415 net::X509Certificate::FORMAT_AUTO);
416 ASSERT_EQ(1U, certs.size());
417 CERTCertificate* platform_cert = certs[0].get();
418 ASSERT_EQ(SECSuccess, PK11_ImportCert(test_nssdb_.slot(), platform_cert,
419 CK_INVALID_HANDLE, "cert",
420 PR_FALSE /* includeTrust (unused) */));
422 scoped_refptr<net::X509Certificate> policy_cert = net::ImportCertFromFile(
423 net::GetTestCertsDirectory(), "websocket_cacert.pem");
424 ASSERT_TRUE(policy_cert.get());
425 policy_certs_provider_.SetPolicyProvidedCertificates({policy_cert}, {});
427 WaitForRefresh(true /*tigger_for_refresh*/);
430 CertificateManagerModel::OrgGroupingMap org_grouping_map;
431 certificate_manager_model_->FilterAndBuildOrgGroupingMap(
432 net::CertType::CA_CERT, &org_grouping_map);
433 CertificateManagerModel::CertInfo* platform_cert_info =
434 GetCertInfoFromOrgGroupingMap(org_grouping_map, platform_cert);
435 ASSERT_TRUE(platform_cert_info);
436 CertificateManagerModel::CertInfo* policy_cert_info =
437 GetCertInfoFromOrgGroupingMap(org_grouping_map, policy_cert.get());
438 ASSERT_TRUE(policy_cert_info);
440 EXPECT_EQ(platform_cert_info, policy_cert_info);
442 EXPECT_EQ(net::CertType::CA_CERT, policy_cert_info->type());
443 EXPECT_EQ(u"pywebsocket", policy_cert_info->name());
444 EXPECT_FALSE(policy_cert_info->can_be_deleted());
445 EXPECT_FALSE(policy_cert_info->untrusted());
446 EXPECT_EQ(CertificateManagerModel::CertInfo::Source::kPolicy,
447 policy_cert_info->source());
448 EXPECT_TRUE(policy_cert_info->web_trust_anchor());
449 EXPECT_FALSE(policy_cert_info->hardware_backed());
452 // Remove the cert from policy-provided certs again. The platform certificate
453 // should be visible afterwards.
454 policy_certs_provider_.SetPolicyProvidedCertificates({}, {});
455 NotifyPolicyObserversAndWaitForRefresh();
458 CertificateManagerModel::OrgGroupingMap org_grouping_map;
459 certificate_manager_model_->FilterAndBuildOrgGroupingMap(
460 net::CertType::CA_CERT, &org_grouping_map);
461 CertificateManagerModel::CertInfo* platform_cert_info =
462 GetCertInfoFromOrgGroupingMap(org_grouping_map, platform_cert);
463 ASSERT_TRUE(platform_cert_info);
465 EXPECT_EQ(net::CertType::CA_CERT, platform_cert_info->type());
466 EXPECT_EQ(u"pywebsocket", platform_cert_info->name());
467 EXPECT_TRUE(platform_cert_info->can_be_deleted());
468 EXPECT_TRUE(platform_cert_info->untrusted());
469 EXPECT_EQ(CertificateManagerModel::CertInfo::Source::kPlatform,
470 platform_cert_info->source());
471 EXPECT_FALSE(platform_cert_info->web_trust_anchor());
472 EXPECT_FALSE(platform_cert_info->hardware_backed());
476 // CertificateManagerModel correctly lists CA certificates that are in the
477 // platform NSS database and provided by policy without web trust. The platform
478 // certificate hides the policy-provided certificate in this case.
479 TEST_F(CertificateManagerModelChromeOSTest,
480 PlatformCertsWinOverNotWebTrustedCerts) {
481 net::ScopedCERTCertificateList certs = CreateCERTCertificateListFromFile(
482 net::GetTestCertsDirectory(), "websocket_cacert.pem",
483 net::X509Certificate::FORMAT_AUTO);
484 ASSERT_EQ(1U, certs.size());
485 CERTCertificate* platform_cert = certs[0].get();
486 ASSERT_EQ(SECSuccess, PK11_ImportCert(test_nssdb_.slot(), platform_cert,
487 CK_INVALID_HANDLE, "cert",
488 PR_FALSE /* includeTrust (unused) */));
490 scoped_refptr<net::X509Certificate> policy_cert = net::ImportCertFromFile(
491 net::GetTestCertsDirectory(), "websocket_cacert.pem");
492 ASSERT_TRUE(policy_cert.get());
493 policy_certs_provider_.SetPolicyProvidedCertificates({}, {policy_cert});
495 WaitForRefresh(true /*tigger_for_refresh*/);
498 CertificateManagerModel::OrgGroupingMap org_grouping_map;
499 certificate_manager_model_->FilterAndBuildOrgGroupingMap(
500 net::CertType::CA_CERT, &org_grouping_map);
501 CertificateManagerModel::CertInfo* platform_cert_info =
502 GetCertInfoFromOrgGroupingMap(org_grouping_map, platform_cert);
503 ASSERT_TRUE(platform_cert_info);
504 CertificateManagerModel::CertInfo* policy_cert_info =
505 GetCertInfoFromOrgGroupingMap(org_grouping_map, policy_cert.get());
506 ASSERT_TRUE(policy_cert_info);
508 EXPECT_EQ(platform_cert_info, policy_cert_info);
510 EXPECT_EQ(net::CertType::CA_CERT, platform_cert_info->type());
511 EXPECT_EQ(u"pywebsocket", platform_cert_info->name());
512 EXPECT_TRUE(platform_cert_info->can_be_deleted());
513 EXPECT_TRUE(platform_cert_info->untrusted());
514 EXPECT_EQ(CertificateManagerModel::CertInfo::Source::kPlatform,
515 platform_cert_info->source());
516 EXPECT_FALSE(platform_cert_info->web_trust_anchor());
517 EXPECT_FALSE(platform_cert_info->hardware_backed());
520 // Remove the certificate from the platform NSS database. The policy-provided
521 // certificate should be visible afterwards.
522 base::RunLoop run_loop;
523 fake_observer_->RunOnNextRefresh(run_loop.QuitClosure());
524 base::test::TestFuture<bool> remove_result;
525 certificate_manager_model_->RemoveFromDatabase(
526 net::x509_util::DupCERTCertificate(platform_cert),
527 remove_result.GetCallback());
528 EXPECT_TRUE(remove_result.Get());
532 CertificateManagerModel::OrgGroupingMap org_grouping_map;
533 certificate_manager_model_->FilterAndBuildOrgGroupingMap(
534 net::CertType::CA_CERT, &org_grouping_map);
535 CertificateManagerModel::CertInfo* policy_cert_info =
536 GetCertInfoFromOrgGroupingMap(org_grouping_map, policy_cert.get());
537 ASSERT_TRUE(policy_cert_info);
539 EXPECT_EQ(net::CertType::CA_CERT, policy_cert_info->type());
540 EXPECT_EQ(u"pywebsocket", policy_cert_info->name());
541 EXPECT_FALSE(policy_cert_info->can_be_deleted());
542 EXPECT_FALSE(policy_cert_info->untrusted());
543 EXPECT_EQ(CertificateManagerModel::CertInfo::Source::kPolicy,
544 policy_cert_info->source());
545 EXPECT_FALSE(policy_cert_info->web_trust_anchor());
546 EXPECT_FALSE(policy_cert_info->hardware_backed());
550 // When the Extension CertificateProvider hangs (e.g. because an extension is
551 // not responding), policy and platform certificates are still listed.
552 TEST_F(CertificateManagerModelChromeOSTest,
553 PlatformAndPolicyCertsListedWhenExtensionsHang) {
554 extensions_hang_ = true;
556 net::ScopedCERTCertificateList certs = CreateCERTCertificateListFromFile(
557 net::GetTestCertsDirectory(), "websocket_cacert.pem",
558 net::X509Certificate::FORMAT_AUTO);
559 ASSERT_EQ(1U, certs.size());
560 CERTCertificate* platform_cert = certs[0].get();
561 ASSERT_EQ(SECSuccess, PK11_ImportCert(test_nssdb_.slot(), platform_cert,
562 CK_INVALID_HANDLE, "cert",
563 PR_FALSE /* includeTrust (unused) */));
565 scoped_refptr<net::X509Certificate> policy_cert =
566 net::ImportCertFromFile(net::GetTestCertsDirectory(), "root_ca_cert.pem");
567 ASSERT_TRUE(policy_cert.get());
568 policy_certs_provider_.SetPolicyProvidedCertificates({policy_cert}, {});
570 WaitForRefresh(true /*tigger_for_refresh*/);
572 CertificateManagerModel::OrgGroupingMap org_grouping_map;
573 certificate_manager_model_->FilterAndBuildOrgGroupingMap(
574 net::CertType::CA_CERT, &org_grouping_map);
575 CertificateManagerModel::CertInfo* platform_cert_info =
576 GetCertInfoFromOrgGroupingMap(org_grouping_map, platform_cert);
577 ASSERT_TRUE(platform_cert_info);
578 CertificateManagerModel::CertInfo* policy_cert_info =
579 GetCertInfoFromOrgGroupingMap(org_grouping_map, policy_cert.get());
580 ASSERT_TRUE(policy_cert_info);
582 EXPECT_NE(platform_cert_info, policy_cert_info);
585 // CertificateManagerModel lists client certificates provided by extensions.
586 TEST_F(CertificateManagerModelChromeOSTest, ListsExtensionCerts) {
587 scoped_refptr<net::X509Certificate> extension_cert =
588 net::ImportCertFromFile(net::GetTestCertsDirectory(), "client_1.pem");
589 ASSERT_TRUE(extension_cert.get());
590 extension_client_certs_.push_back(extension_cert);
592 WaitForRefresh(true /*tigger_for_refresh*/);
594 CertificateManagerModel::OrgGroupingMap org_grouping_map;
595 certificate_manager_model_->FilterAndBuildOrgGroupingMap(
596 net::CertType::USER_CERT, &org_grouping_map);
597 CertificateManagerModel::CertInfo* extension_cert_info =
598 GetCertInfoFromOrgGroupingMap(org_grouping_map, extension_cert.get());
599 ASSERT_TRUE(extension_cert_info);
601 EXPECT_EQ(net::CertType::USER_CERT, extension_cert_info->type());
602 EXPECT_EQ(u"Client Cert A (extension provided)", extension_cert_info->name());
603 EXPECT_FALSE(extension_cert_info->can_be_deleted());
604 EXPECT_EQ(CertificateManagerModel::CertInfo::Source::kExtension,
605 extension_cert_info->source());
606 EXPECT_FALSE(extension_cert_info->web_trust_anchor());
607 EXPECT_FALSE(extension_cert_info->hardware_backed());
610 TEST_F(CertificateManagerModelChromeOSTest,
611 PlatformCertsWinOverExtensionCerts) {
612 net::ScopedCERTCertificate platform_client_cert;
613 net::ImportClientCertAndKeyFromFile(
614 net::GetTestCertsDirectory(), "client_1.pem", "client_1.pk8",
615 test_nssdb_.slot(), &platform_client_cert);
617 scoped_refptr<net::X509Certificate> extension_cert =
618 net::ImportCertFromFile(net::GetTestCertsDirectory(), "client_1.pem");
619 ASSERT_TRUE(extension_cert.get());
620 extension_client_certs_.push_back(extension_cert);
622 WaitForRefresh(true /*tigger_for_refresh*/);
625 CertificateManagerModel::OrgGroupingMap org_grouping_map;
626 certificate_manager_model_->FilterAndBuildOrgGroupingMap(
627 net::CertType::USER_CERT, &org_grouping_map);
628 CertificateManagerModel::CertInfo* platform_cert_info =
629 GetCertInfoFromOrgGroupingMap(org_grouping_map,
630 platform_client_cert.get());
631 ASSERT_TRUE(platform_cert_info);
632 CertificateManagerModel::CertInfo* extension_cert_info =
633 GetCertInfoFromOrgGroupingMap(org_grouping_map, extension_cert.get());
634 ASSERT_TRUE(extension_cert_info);
636 EXPECT_EQ(platform_cert_info, extension_cert_info);
638 EXPECT_EQ(net::CertType::USER_CERT, platform_cert_info->type());
639 EXPECT_EQ(u"Client Cert A", platform_cert_info->name());
640 EXPECT_TRUE(platform_cert_info->can_be_deleted());
641 EXPECT_EQ(CertificateManagerModel::CertInfo::Source::kPlatform,
642 platform_cert_info->source());
643 EXPECT_FALSE(platform_cert_info->web_trust_anchor());
644 EXPECT_FALSE(platform_cert_info->hardware_backed());
647 // Remove the platform client certificate. The extension-provided client
648 // certificate should be visible afterwards.
649 base::RunLoop run_loop;
650 fake_observer_->RunOnNextRefresh(run_loop.QuitClosure());
651 base::test::TestFuture<bool> remove_result;
652 certificate_manager_model_->RemoveFromDatabase(
653 std::move(platform_client_cert), remove_result.GetCallback());
654 EXPECT_TRUE(remove_result.Get());
658 CertificateManagerModel::OrgGroupingMap org_grouping_map;
659 certificate_manager_model_->FilterAndBuildOrgGroupingMap(
660 net::CertType::USER_CERT, &org_grouping_map);
661 CertificateManagerModel::CertInfo* extension_cert_info =
662 GetCertInfoFromOrgGroupingMap(org_grouping_map, extension_cert.get());
663 ASSERT_TRUE(extension_cert_info);
665 EXPECT_EQ(net::CertType::USER_CERT, extension_cert_info->type());
666 EXPECT_EQ(u"Client Cert A (extension provided)",
667 extension_cert_info->name());
668 EXPECT_FALSE(extension_cert_info->can_be_deleted());
669 EXPECT_EQ(CertificateManagerModel::CertInfo::Source::kExtension,
670 extension_cert_info->source());
671 EXPECT_FALSE(extension_cert_info->web_trust_anchor());
672 EXPECT_FALSE(extension_cert_info->hardware_backed());
676 #endif // BUILDFLAG(IS_CHROMEOS)