[M120][Tizen][Onscreen] Fix build errors for TV profile
[platform/framework/web/chromium-efl.git] / chrome / browser / certificate_manager_model_unittest.cc
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.
4
5 #include "chrome/browser/certificate_manager_model.h"
6
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"
23
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)
29
30 namespace {
31
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 {
35  public:
36   void CertificatesRefreshed() override {
37     if (!run_on_refresh_.is_null())
38       std::move(run_on_refresh_).Run();
39   }
40
41   // Execute |closure| on the next |CertificatesRefreshed| invocation.
42   void RunOnNextRefresh(base::OnceClosure closure) {
43     run_on_refresh_ = std::move(closure);
44   }
45
46  private:
47   base::OnceClosure run_on_refresh_;
48 };
49
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();
59     }
60   }
61   return nullptr;
62 }
63
64 }  // namespace
65
66 class CertificateManagerModelTest : public testing::Test {
67  public:
68   CertificateManagerModelTest() {}
69
70   CertificateManagerModelTest(const CertificateManagerModelTest&) = delete;
71   CertificateManagerModelTest& operator=(const CertificateManagerModelTest&) =
72       delete;
73
74  protected:
75   void SetUp() override {
76     ASSERT_TRUE(test_nssdb_.is_open());
77
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 */);
83
84     fake_observer_ = std::make_unique<FakeObserver>();
85     certificate_manager_model_ = std::make_unique<CertificateManagerModel>(
86         GetCertificateManagerModelParams(), fake_observer_.get(),
87         nss_cert_db_.get());
88   }
89
90   void TearDown() override {
91     certificate_manager_model_.reset();
92     nss_cert_db_.reset();
93   }
94
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>();
100   }
101
102  protected:
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();
110     }
111     run_loop.Run();
112   }
113
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_;
119 };
120
121 // CertificateManagerModel correctly lists CA certificates from the platform NSS
122 // Database.
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());
128
129   net::CertBuilder cert_builder(orig_certs[0]->cert_buffer(), nullptr);
130   scoped_refptr<net::X509Certificate> x509_cert =
131       cert_builder.GetX509Certificate();
132
133   net::ScopedCERTCertificate cert =
134       net::x509_util::CreateCERTCertificateFromX509Certificate(x509_cert.get());
135   std::string cert_subject_name = x509_cert->subject().GetDisplayName();
136
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*/);
141
142   {
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);
149
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
154     // trust bits.
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());
160   }
161
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*/);
167   {
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);
174
175     EXPECT_FALSE(cert_info->untrusted());
176     EXPECT_TRUE(cert_info->web_trust_anchor());
177   }
178 }
179
180 // CertificateManagerModel correctly lists client certificates from the platform
181 // NSS Database.
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);
187
188   WaitForRefresh(true /*tigger_for_refresh*/);
189
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);
197
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());
205 }
206
207 #if BUILDFLAG(IS_CHROMEOS)
208 namespace {
209
210 class FakePolicyCertificateProvider : public ash::PolicyCertificateProvider {
211  public:
212   void AddPolicyProvidedCertsObserver(Observer* observer) override {
213     observer_list_.AddObserver(observer);
214   }
215
216   void RemovePolicyProvidedCertsObserver(Observer* observer) override {
217     observer_list_.RemoveObserver(observer);
218   }
219
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);
224
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());
230     return merged;
231   }
232
233   net::CertificateList GetAllAuthorityCertificates(
234       const chromeos::onc::CertificateScope& scope) const override {
235     // This function is not called by CertificateManagerModel.
236     NOTREACHED();
237     return net::CertificateList();
238   }
239
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);
244
245     return web_trusted_certs_;
246   }
247
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);
252
253     return not_web_trusted_certs_;
254   }
255
256   const std::set<std::string>& GetExtensionIdsWithPolicyCertificates()
257       const override {
258     // This function is not called by CertificateManagerModel.
259     NOTREACHED();
260     return kNoExtensions;
261   }
262
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;
268   }
269
270   void NotifyObservers() {
271     for (auto& observer : observer_list_)
272       observer.OnPolicyProvidedCertsChanged();
273   }
274
275  private:
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 = {};
281 };
282
283 class FakeExtensionCertificateProvider : public chromeos::CertificateProvider {
284  public:
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) {}
290
291   void GetCertificates(
292       base::OnceCallback<void(net::ClientCertIdentityList)> callback) override {
293     if (*extensions_hang_)
294       return;
295
296     std::move(callback).Run(FakeClientCertIdentityListFromCertificateList(
297         *extension_client_certificates_));
298   }
299
300  private:
301   raw_ptr<const net::CertificateList> extension_client_certificates_;
302
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_;
306 };
307
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();
317     }
318   }
319   return nullptr;
320 }
321
322 }  // namespace
323
324 class CertificateManagerModelChromeOSTest : public CertificateManagerModelTest {
325  protected:
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_);
333     return params;
334   }
335
336   void NotifyPolicyObserversAndWaitForRefresh() {
337     base::RunLoop run_loop;
338     fake_observer_->RunOnNextRefresh(run_loop.QuitClosure());
339     policy_certs_provider_.NotifyObservers();
340     run_loop.Run();
341   }
342
343   // Provider for policy certificates. In a non-test environment, this would
344   // usually be the UserNetworkConfigurationUpdater.
345   FakePolicyCertificateProvider policy_certs_provider_;
346
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;
352 };
353
354 // CertificateManagerModel correctly lists policy-provided certificates with web
355 // trust.
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}, {});
361
362   NotifyPolicyObserversAndWaitForRefresh();
363
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);
370
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());
379 }
380
381 // CertificateManagerModel correctly lists policy-provided certificates without
382 // web trust.
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});
388
389   NotifyPolicyObserversAndWaitForRefresh();
390
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);
397
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());
406 }
407
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) */));
421
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}, {});
426
427   WaitForRefresh(true /*tigger_for_refresh*/);
428
429   {
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);
439
440     EXPECT_EQ(platform_cert_info, policy_cert_info);
441
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());
450   }
451
452   // Remove the cert from policy-provided certs again. The platform certificate
453   // should be visible afterwards.
454   policy_certs_provider_.SetPolicyProvidedCertificates({}, {});
455   NotifyPolicyObserversAndWaitForRefresh();
456
457   {
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);
464
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());
473   }
474 }
475
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) */));
489
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});
494
495   WaitForRefresh(true /*tigger_for_refresh*/);
496
497   {
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);
507
508     EXPECT_EQ(platform_cert_info, policy_cert_info);
509
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());
518   }
519
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());
529   run_loop.Run();
530
531   {
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);
538
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());
547   }
548 }
549
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;
555
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) */));
564
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}, {});
569
570   WaitForRefresh(true /*tigger_for_refresh*/);
571
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);
581
582   EXPECT_NE(platform_cert_info, policy_cert_info);
583 }
584
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);
591
592   WaitForRefresh(true /*tigger_for_refresh*/);
593
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);
600
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());
608 }
609
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);
616
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);
621
622   WaitForRefresh(true /*tigger_for_refresh*/);
623
624   {
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);
635
636     EXPECT_EQ(platform_cert_info, extension_cert_info);
637
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());
645   }
646
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());
655   run_loop.Run();
656
657   {
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);
664
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());
673   }
674 }
675
676 #endif  // BUILDFLAG(IS_CHROMEOS)