[M120][Tizen][Onscreen] Fix build errors for TV profile
[platform/framework/web/chromium-efl.git] / chrome / browser / certificate_manager_model.cc
1 // Copyright 2012 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 <utility>
8
9 #include "base/functional/bind.h"
10 #include "base/functional/callback_helpers.h"
11 #include "base/i18n/time_formatting.h"
12 #include "base/logging.h"
13 #include "base/memory/raw_ptr.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/scoped_observation.h"
16 #include "base/sequence_checker.h"
17 #include "base/strings/utf_string_conversions.h"
18 #include "base/task/bind_post_task.h"
19 #include "base/task/sequenced_task_runner.h"
20 #include "build/build_config.h"
21 #include "build/chromeos_buildflags.h"
22 #include "chrome/browser/net/nss_service.h"
23 #include "chrome/browser/net/nss_service_factory.h"
24 #include "chrome/browser/net/system_network_context_manager.h"
25 #include "chrome/browser/ui/crypto_module_password_dialog_nss.h"
26 #include "chrome/common/net/x509_certificate_model_nss.h"
27 #include "chrome/grit/generated_resources.h"
28 #include "content/public/browser/browser_context.h"
29 #include "content/public/browser/browser_task_traits.h"
30 #include "content/public/browser/browser_thread.h"
31 #include "content/public/browser/resource_context.h"
32 #include "crypto/scoped_nss_types.h"
33 #include "net/base/net_errors.h"
34 #include "net/cert/cert_database.h"
35 #include "net/cert/nss_cert_database.h"
36 #include "net/cert/x509_certificate.h"
37 #include "net/cert/x509_util_nss.h"
38 #include "net/net_buildflags.h"
39 #include "ui/base/l10n/l10n_util.h"
40
41 #if BUILDFLAG(IS_CHROMEOS)
42 #include "chrome/browser/certificate_provider/certificate_provider.h"
43 #include "chrome/browser/certificate_provider/certificate_provider_service.h"
44 #include "chrome/browser/certificate_provider/certificate_provider_service_factory.h"
45 #include "chrome/browser/policy/networking/user_network_configuration_updater.h"
46 #include "chrome/browser/policy/networking/user_network_configuration_updater_factory.h"
47 #include "chromeos/ash/components/network/policy_certificate_provider.h"
48 #endif  // BUILDFLAG(IS_CHROMEOS)
49
50 #if BUILDFLAG(IS_CHROMEOS_ASH)
51 #include "chrome/browser/policy/networking/user_network_configuration_updater_ash.h"
52 #include "chromeos/components/onc/certificate_scope.h"
53 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
54
55 using content::BrowserThread;
56
57 // CertificateManagerModel is created on the UI thread. It needs a
58 // NSSCertDatabase handle (and on ChromeOS it needs to get the TPM status) which
59 // needs to be done on the IO thread.
60 //
61 // The initialization flow is roughly:
62 //
63 //               UI thread                              IO Thread
64 //
65 //   CertificateManagerModel::Create
66 //                  \--------------------------------------v
67 //                                CertificateManagerModel::GetCertDBOnIOThread
68 //                                                         |
69 //                                               NssCertDatabaseGetter
70 //                                                         |
71 //                               CertificateManagerModel::DidGetCertDBOnIOThread
72 //                  v--------------------------------------/
73 // CertificateManagerModel::DidGetCertDBOnUIThread
74 //                  |
75 //     new CertificateManagerModel
76 //                  |
77 //               callback
78
79 namespace {
80
81 std::string GetCertificateOrg(CERTCertificate* cert) {
82   std::string org =
83       x509_certificate_model::GetSubjectOrgName(cert, std::string());
84   if (org.empty())
85     org = x509_certificate_model::GetSubjectDisplayName(cert);
86
87   return org;
88 }
89
90 #if BUILDFLAG(IS_CHROMEOS)
91 // Log message for an operation that can not be performed on a certificate of a
92 // given source.
93 constexpr char kOperationNotPermitted[] =
94     "Operation not permitted on a certificate. Source: ";
95 #endif  // BUILDFLAG(IS_CHROMEOS)
96
97 }  // namespace
98
99 // A source of certificates that should be displayed on the certificate manager
100 // UI. Currently, a CertsSource yields CertInfo objects. Each CertInfo contains
101 // a NSS ScopedCERTCertificate.
102 class CertificateManagerModel::CertsSource {
103  public:
104   // |certs_source_updated_callback| will be invoked when the list of
105   // certificates provided by this CertsSource changes.
106   explicit CertsSource(base::RepeatingClosure certs_source_updated_callback)
107       : certs_source_updated_callback_(certs_source_updated_callback) {}
108
109   CertsSource(const CertsSource&) = delete;
110   CertsSource& operator=(const CertsSource&) = delete;
111
112   virtual ~CertsSource() = default;
113
114   // Returns the CertInfos provided by this CertsSource.
115   const std::vector<std::unique_ptr<CertificateManagerModel::CertInfo>>&
116   cert_infos() const {
117     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
118     return cert_infos_;
119   }
120
121   // Returns true if |cert| is in this CertsSource's certificate list.
122   bool HasCert(CERTCertificate* cert) const {
123     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
124     for (const auto& cert_info : cert_infos_) {
125       if (cert_info->cert() == cert)
126         return true;
127     }
128     return false;
129   }
130
131   // Triggers a refresh of this CertsSource. When done, the
132   // |certs_source_updated_callback| passed to the constructor will be invoked.
133   virtual void Refresh() = 0;
134
135   // If any CertsSource's |IsHoldBackUpdates| is returning true, the
136   // CertificateManagerModel will not notify its Observer about updates.
137   bool IsHoldBackUpdates() const { return hold_back_updates_; }
138
139   // Set trust values for certificate.
140   // |trust_bits| should be a bit field of TRUST* values from NSSCertDatabase.
141   // Returns true on success or false on failure.
142   virtual bool SetCertTrust(CERTCertificate* cert,
143                             net::CertType type,
144                             net::NSSCertDatabase::TrustBits trust_bits) = 0;
145
146   // Remove the cert from the cert database.
147   virtual void RemoveFromDatabase(
148       net::ScopedCERTCertificate cert,
149       base::OnceCallback<void(bool /*success*/)> callback) = 0;
150
151  protected:
152   // To be called by subclasses to set the CertInfo list provided by this
153   // CertsSource. If this CertsSource is signalling that updates should be held
154   // back (|SetHoldBackUpdates(true)|, this will be set to false. The
155   // |certs_source_updated_callback| passed to the constructor will be invoked.
156   void SetCertInfos(
157       std::vector<std::unique_ptr<CertificateManagerModel::CertInfo>>
158           cert_infos) {
159     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
160     cert_infos_.swap(cert_infos);
161     SetHoldBackUpdates(false);
162     certs_source_updated_callback_.Run();
163   }
164
165   // Signal to |CertificateManagerModel| that updates to its Observer should be
166   // held back. This will be automatically taken back on |SetCertInfos|.
167   // This should only be used by |CertsSource|s that provide their list of
168   // certificates asynchronously but expect their certificate listing to be
169   // fast.
170   void SetHoldBackUpdates(bool hold_back_updates) {
171     hold_back_updates_ = hold_back_updates;
172   }
173
174   // Used to verify that the constructor, and accessing |cert_infos_| are
175   // performed on the same sequence. Offered to subclasses so they can also
176   // check that they're being called on a valid sequence.
177   SEQUENCE_CHECKER(sequence_checker_);
178
179  private:
180   // Cached CertInfos provided by this CertsSource.
181   std::vector<std::unique_ptr<CertificateManagerModel::CertInfo>> cert_infos_;
182
183   // Invoked when the list of certificates provided by this CertsSource has
184   // changed.
185   base::RepeatingClosure certs_source_updated_callback_;
186
187   // If true, the CertificateManagerModel should be holding back update
188   // notifications.
189   bool hold_back_updates_ = false;
190 };
191
192 namespace {
193 // Provides certificates enumerable from a NSSCertDatabase.
194 class CertsSourcePlatformNSS : public CertificateManagerModel::CertsSource,
195                                net::CertDatabase::Observer {
196  public:
197   CertsSourcePlatformNSS(base::RepeatingClosure certs_source_updated_callback,
198                          net::NSSCertDatabase* nss_cert_database)
199       : CertsSource(certs_source_updated_callback),
200         cert_db_(nss_cert_database) {
201     // Observe CertDatabase changes to refresh when it's updated.
202     cert_database_observation_.Observe(net::CertDatabase::GetInstance());
203   }
204
205   CertsSourcePlatformNSS(const CertsSourcePlatformNSS&) = delete;
206   CertsSourcePlatformNSS& operator=(const CertsSourcePlatformNSS&) = delete;
207
208   ~CertsSourcePlatformNSS() override = default;
209
210   // net::CertDatabase::Observer
211   void OnTrustStoreChanged() override {
212     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
213     Refresh();
214   }
215   void OnClientCertStoreChanged() override {
216     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
217     Refresh();
218   }
219
220   void Refresh() override {
221     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
222     SetHoldBackUpdates(true);
223     DVLOG(1) << "refresh started";
224     std::vector<crypto::ScopedPK11Slot> modules;
225     cert_db_->ListModules(&modules, false);
226     DVLOG(1) << "refresh waiting for unlocking...";
227     chrome::UnlockSlotsIfNecessary(
228         std::move(modules), kCryptoModulePasswordListCerts,
229         net::HostPortPair(),  // unused.
230         nullptr,              // TODO(mattm): supply parent window.
231         base::BindOnce(&CertsSourcePlatformNSS::RefreshSlotsUnlocked,
232                        weak_ptr_factory_.GetWeakPtr()));
233   }
234
235   bool SetCertTrust(CERTCertificate* cert,
236                     net::CertType type,
237                     net::NSSCertDatabase::TrustBits trust_bits) override {
238     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
239     return cert_db_->SetCertTrust(cert, type, trust_bits);
240   }
241
242   void RemoveFromDatabase(net::ScopedCERTCertificate cert,
243                           base::OnceCallback<void(bool)> callback) override {
244     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
245     auto callback_and_runner =
246         base::BindPostTaskToCurrentDefault(std::move(callback));
247
248     // Passing Unretained(cert_db_) is safe because the corresponding profile
249     // should be alive during this call and therefore the deletion task for the
250     // database can only be scheduled on the IO thread after this task.
251     content::GetIOThreadTaskRunner({})->PostTask(
252         FROM_HERE, base::BindOnce(&net::NSSCertDatabase::DeleteCertAndKeyAsync,
253                                   base::Unretained(cert_db_), std::move(cert),
254                                   std::move(callback_and_runner)));
255   }
256
257  private:
258   void RefreshSlotsUnlocked() {
259     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
260     DVLOG(1) << "refresh listing certs...";
261     cert_db_->ListCertsInfo(
262         base::BindOnce(&CertsSourcePlatformNSS::DidGetCerts,
263                        weak_ptr_factory_.GetWeakPtr()),
264 #if BUILDFLAG(CHROME_ROOT_STORE_OPTIONAL)
265         SystemNetworkContextManager::IsUsingChromeRootStore()
266             ? net::NSSCertDatabase::NSSRootsHandling::kExclude
267             : net::NSSCertDatabase::NSSRootsHandling::kInclude
268 #elif BUILDFLAG(CHROME_ROOT_STORE_ONLY)
269         net::NSSCertDatabase::NSSRootsHandling::kExclude
270 #else
271         net::NSSCertDatabase::NSSRootsHandling::kInclude
272 #endif
273     );
274   }
275
276   void DidGetCerts(net::NSSCertDatabase::CertInfoList cert_info_list) {
277     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
278     DVLOG(1) << "refresh finished for platform provided certificates";
279
280     std::vector<std::unique_ptr<CertificateManagerModel::CertInfo>> cert_infos;
281     cert_infos.reserve(cert_info_list.size());
282
283     for (auto& cert_info : cert_info_list) {
284       net::CertType type =
285           x509_certificate_model::GetType(cert_info.cert.get());
286       bool can_be_deleted = !cert_info.on_read_only_slot;
287       bool hardware_backed = cert_info.hardware_backed;
288       std::u16string name = GetName(cert_info.cert.get(), hardware_backed);
289
290       cert_infos.push_back(std::make_unique<CertificateManagerModel::CertInfo>(
291           /*cert=*/std::move(cert_info.cert), type, name, can_be_deleted,
292           /*untrusted=*/cert_info.untrusted,
293           /*source=*/CertificateManagerModel::CertInfo::Source::kPlatform,
294           /*web_trust_anchor=*/cert_info.web_trust_anchor, hardware_backed,
295           /*device_wide=*/cert_info.device_wide));
296     }
297
298     SetCertInfos(std::move(cert_infos));
299   }
300
301   static std::u16string GetName(CERTCertificate* cert,
302                                 bool is_hardware_backed) {
303     std::u16string name =
304         base::UTF8ToUTF16(x509_certificate_model::GetCertNameOrNickname(cert));
305     if (is_hardware_backed) {
306       name = l10n_util::GetStringFUTF16(
307           IDS_CERT_MANAGER_HARDWARE_BACKED_KEY_FORMAT, name,
308           l10n_util::GetStringUTF16(IDS_CERT_MANAGER_HARDWARE_BACKED));
309     }
310     return name;
311   }
312
313   // The source NSSCertDatabase used for listing certificates.
314   raw_ptr<net::NSSCertDatabase> cert_db_;
315
316   // ScopedObservation to keep track of the observer for net::CertDatabase.
317   base::ScopedObservation<net::CertDatabase, net::CertDatabase::Observer>
318       cert_database_observation_{this};
319
320   base::WeakPtrFactory<CertsSourcePlatformNSS> weak_ptr_factory_{this};
321 };
322
323 #if BUILDFLAG(IS_CHROMEOS)
324 // Provides certificates installed through enterprise policy.
325 class CertsSourcePolicy : public CertificateManagerModel::CertsSource,
326                           ash::PolicyCertificateProvider::Observer {
327  public:
328   // Defines which policy-provided certificates this CertsSourcePolicy instance
329   // should yield.
330   enum class Mode {
331     // Only certificates which are installed by enterprise policy, but not Web
332     // trusted.
333     kPolicyCertsWithoutWebTrust,
334     // Only certificates which are installed by enterprise policy and Web
335     // trusted.
336     kPolicyCertsWithWebTrust
337   };
338
339   CertsSourcePolicy(base::RepeatingClosure certs_source_updated_callback,
340                     ash::PolicyCertificateProvider* policy_certs_provider,
341                     Mode mode)
342       : CertsSource(certs_source_updated_callback),
343         policy_certs_provider_(policy_certs_provider),
344         mode_(mode) {
345     policy_certs_provider_->AddPolicyProvidedCertsObserver(this);
346   }
347
348   CertsSourcePolicy(const CertsSourcePolicy&) = delete;
349   CertsSourcePolicy& operator=(const CertsSourcePolicy&) = delete;
350
351   ~CertsSourcePolicy() override {
352     policy_certs_provider_->RemovePolicyProvidedCertsObserver(this);
353   }
354
355   // ash::PolicyCertificateProvider::Observer
356   void OnPolicyProvidedCertsChanged() override {
357     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
358     Refresh();
359   }
360
361   void Refresh() override {
362     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
363     switch (mode_) {
364       case Mode::kPolicyCertsWithoutWebTrust:
365         RefreshImpl(policy_certs_provider_->GetCertificatesWithoutWebTrust(
366                         chromeos::onc::CertificateScope::Default()),
367                     false /* policy_web_trusted */);
368         break;
369       case Mode::kPolicyCertsWithWebTrust:
370         RefreshImpl(policy_certs_provider_->GetWebTrustedCertificates(
371                         chromeos::onc::CertificateScope::Default()),
372                     true /* policy_web_trusted */);
373         break;
374       default:
375         NOTREACHED();
376     }
377   }
378
379   bool SetCertTrust(CERTCertificate* cert,
380                     net::CertType type,
381                     net::NSSCertDatabase::TrustBits trust_bits) override {
382     // Trust of policy-provided certificates can not be changed.
383     LOG(WARNING) << kOperationNotPermitted << "Policy";
384     return false;
385   }
386
387   void RemoveFromDatabase(net::ScopedCERTCertificate cert,
388                           base::OnceCallback<void(bool)> callback) override {
389     // Policy-provided certificates can not be deleted.
390     LOG(WARNING) << kOperationNotPermitted << "Policy";
391     base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
392         FROM_HERE, base::BindOnce(std::move(callback), false));
393   }
394
395  private:
396   void RefreshImpl(const net::CertificateList& certificates,
397                    bool policy_web_trusted) {
398     std::vector<std::unique_ptr<CertificateManagerModel::CertInfo>> cert_infos;
399     cert_infos.reserve(certificates.size());
400
401     for (const auto& policy_cert : certificates) {
402       net::ScopedCERTCertificate nss_cert(
403           net::x509_util::CreateCERTCertificateFromX509Certificate(
404               policy_cert.get()));
405       if (!nss_cert)
406         continue;
407
408       net::CertType type = x509_certificate_model::GetType(nss_cert.get());
409       std::u16string cert_name = base::UTF8ToUTF16(
410           x509_certificate_model::GetCertNameOrNickname(nss_cert.get()));
411       cert_infos.push_back(std::make_unique<CertificateManagerModel::CertInfo>(
412           std::move(nss_cert), type, std::move(cert_name),
413           false /* can_be_deleted */, false /* untrusted */,
414           CertificateManagerModel::CertInfo::Source::kPolicy,
415           policy_web_trusted /* web_trust_anchor */,
416           false /* hardware_backed */, false /* device_wide */));
417     }
418
419     SetCertInfos(std::move(cert_infos));
420   }
421
422   raw_ptr<ash::PolicyCertificateProvider> policy_certs_provider_;
423   Mode mode_;
424 };
425
426 // Provides certificates made available by extensions through the
427 // chrome.certificateProvider API.
428 class CertsSourceExtensions : public CertificateManagerModel::CertsSource {
429  public:
430   CertsSourceExtensions(base::RepeatingClosure certs_source_updated_callback,
431                         std::unique_ptr<chromeos::CertificateProvider>
432                             certificate_provider_service)
433       : CertsSource(certs_source_updated_callback),
434         certificate_provider_service_(std::move(certificate_provider_service)) {
435   }
436
437   CertsSourceExtensions(const CertsSourceExtensions&) = delete;
438   CertsSourceExtensions& operator=(const CertsSourceExtensions&) = delete;
439
440   void Refresh() override {
441     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
442     certificate_provider_service_->GetCertificates(base::BindOnce(
443         &CertsSourceExtensions::DidGetCerts, weak_ptr_factory_.GetWeakPtr()));
444   }
445
446   bool SetCertTrust(CERTCertificate* cert,
447                     net::CertType type,
448                     net::NSSCertDatabase::TrustBits trust_bits) override {
449     // Extension-provided certificates are user certificates; changing trust
450     // does not make sense here.
451     LOG(WARNING) << kOperationNotPermitted << "Extension";
452     return false;
453   }
454
455   void RemoveFromDatabase(net::ScopedCERTCertificate cert,
456                           base::OnceCallback<void(bool)> callback) override {
457     // Extension-provided certificates can not be deleted.
458     LOG(WARNING) << kOperationNotPermitted << "Extension";
459     base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
460         FROM_HERE, base::BindOnce(std::move(callback), false));
461   }
462
463  private:
464   void DidGetCerts(net::ClientCertIdentityList cert_identities) {
465     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
466     std::vector<std::unique_ptr<CertificateManagerModel::CertInfo>> cert_infos;
467
468     cert_infos.reserve(cert_identities.size());
469     for (const auto& identity : cert_identities) {
470       net::ScopedCERTCertificate nss_cert(
471           net::x509_util::CreateCERTCertificateFromX509Certificate(
472               identity->certificate()));
473       if (!nss_cert)
474         continue;
475
476       std::u16string cert_name = base::UTF8ToUTF16(
477           x509_certificate_model::GetCertNameOrNickname(nss_cert.get()));
478       std::u16string display_name = l10n_util::GetStringFUTF16(
479           IDS_CERT_MANAGER_EXTENSION_PROVIDED_FORMAT, std::move(cert_name));
480
481       cert_infos.push_back(std::make_unique<CertificateManagerModel::CertInfo>(
482           std::move(nss_cert), net::CertType::USER_CERT /* type */,
483           display_name, false /* can_be_deleted */, false /* untrusted */,
484           CertificateManagerModel::CertInfo::Source::kExtension,
485           false /* web_trust_anchor */, false /* hardware_backed */,
486           false /* device_wide */));
487     }
488
489     SetCertInfos(std::move(cert_infos));
490   }
491
492   std::unique_ptr<chromeos::CertificateProvider> certificate_provider_service_;
493
494   base::WeakPtrFactory<CertsSourceExtensions> weak_ptr_factory_{this};
495 };
496 #endif  // BUILDFLAG(IS_CHROMEOS)
497
498 }  // namespace
499
500 CertificateManagerModel::CertInfo::CertInfo(net::ScopedCERTCertificate cert,
501                                             net::CertType type,
502                                             std::u16string name,
503                                             bool can_be_deleted,
504                                             bool untrusted,
505                                             Source source,
506                                             bool web_trust_anchor,
507                                             bool hardware_backed,
508                                             bool device_wide)
509     : cert_(std::move(cert)),
510       type_(type),
511       name_(std::move(name)),
512       can_be_deleted_(can_be_deleted),
513       untrusted_(untrusted),
514       source_(source),
515       web_trust_anchor_(web_trust_anchor),
516       hardware_backed_(hardware_backed),
517       device_wide_(device_wide) {}
518
519 CertificateManagerModel::CertInfo::~CertInfo() {}
520
521 // static
522 std::unique_ptr<CertificateManagerModel::CertInfo>
523 CertificateManagerModel::CertInfo::Clone(const CertInfo* cert_info) {
524   return std::make_unique<CertInfo>(
525       net::x509_util::DupCERTCertificate(cert_info->cert()), cert_info->type(),
526       cert_info->name(), cert_info->can_be_deleted(), cert_info->untrusted(),
527       cert_info->source(), cert_info->web_trust_anchor(),
528       cert_info->hardware_backed(), cert_info->device_wide());
529 }
530
531 CertificateManagerModel::Params::Params() = default;
532 CertificateManagerModel::Params::~Params() = default;
533 CertificateManagerModel::Params::Params(Params&& other) = default;
534
535 // static
536 void CertificateManagerModel::Create(
537     content::BrowserContext* browser_context,
538     CertificateManagerModel::Observer* observer,
539     CreationCallback callback) {
540   DCHECK_CURRENTLY_ON(BrowserThread::UI);
541
542   std::unique_ptr<Params> params = std::make_unique<Params>();
543 #if BUILDFLAG(IS_CHROMEOS)
544   params->policy_certs_provider =
545       policy::UserNetworkConfigurationUpdaterFactory::GetForBrowserContext(
546           browser_context);
547
548   chromeos::CertificateProviderService* certificate_provider_service =
549       chromeos::CertificateProviderServiceFactory::GetForBrowserContext(
550           browser_context);
551   params->extension_certificate_provider =
552       certificate_provider_service->CreateCertificateProvider();
553 #endif
554
555   content::GetIOThreadTaskRunner({})->PostTask(
556       FROM_HERE,
557       base::BindOnce(&CertificateManagerModel::GetCertDBOnIOThread,
558                      std::move(params),
559                      NssServiceFactory::GetForContext(browser_context)
560                          ->CreateNSSCertDatabaseGetterForIOThread(),
561                      observer, std::move(callback)));
562 }
563
564 CertificateManagerModel::CertificateManagerModel(
565     std::unique_ptr<Params> params,
566     Observer* observer,
567     net::NSSCertDatabase* nss_cert_database)
568     : cert_db_(nss_cert_database), observer_(observer) {
569   DCHECK_CURRENTLY_ON(BrowserThread::UI);
570
571   // Fill |certs_sources_|. Note that the order matters. Higher priority
572   // CertsSources must come first.
573
574   base::RepeatingClosure certs_source_updated_callback = base::BindRepeating(
575       &CertificateManagerModel::OnCertsSourceUpdated, base::Unretained(this));
576
577 #if BUILDFLAG(IS_CHROMEOS)
578   // Certificates installed and web trusted by enterprise policy is the highest
579   // priority CertsSource.
580   // UserNetworkConfigurationUpdater is only available for the primary user's
581   // profile.
582   if (params->policy_certs_provider) {
583     certs_sources_.push_back(std::make_unique<CertsSourcePolicy>(
584         certs_source_updated_callback, params->policy_certs_provider,
585         CertsSourcePolicy::Mode::kPolicyCertsWithWebTrust));
586   }
587 #endif
588
589   // Add the main NSS DB based CertsSource.
590   certs_sources_.push_back(std::make_unique<CertsSourcePlatformNSS>(
591       certs_source_updated_callback, nss_cert_database));
592
593 #if BUILDFLAG(IS_CHROMEOS)
594   // Certificates installed by enterprise policy without web trust are lower
595   // priority than the main NSS DB based CertsSource.
596   // Rationale: The user should be able to add trust to policy-provided
597   // certificates by re-importing them and modifying their trust settings.
598   if (params->policy_certs_provider) {
599     certs_sources_.push_back(std::make_unique<CertsSourcePolicy>(
600         certs_source_updated_callback, params->policy_certs_provider,
601         CertsSourcePolicy::Mode::kPolicyCertsWithoutWebTrust));
602   }
603
604   // Extensions is the lowest priority CertsSource.
605   if (params->extension_certificate_provider) {
606     certs_sources_.push_back(std::make_unique<CertsSourceExtensions>(
607         certs_source_updated_callback,
608         std::move(params->extension_certificate_provider)));
609   }
610 #endif
611 }
612
613 CertificateManagerModel::~CertificateManagerModel() {}
614
615 void CertificateManagerModel::OnCertsSourceUpdated() {
616   if (hold_back_updates_)
617     return;
618   for (const auto& certs_source : certs_sources_) {
619     if (certs_source->IsHoldBackUpdates()) {
620       return;
621     }
622   }
623
624   observer_->CertificatesRefreshed();
625 }
626
627 CertificateManagerModel::CertsSource*
628 CertificateManagerModel::FindCertsSourceForCert(CERTCertificate* cert) {
629   for (auto& certs_source : certs_sources_) {
630     if (certs_source->HasCert(cert))
631       return certs_source.get();
632   }
633   return nullptr;
634 }
635
636 void CertificateManagerModel::Refresh() {
637   hold_back_updates_ = true;
638
639   for (auto& certs_source : certs_sources_)
640     certs_source->Refresh();
641
642   hold_back_updates_ = false;
643   OnCertsSourceUpdated();
644 }
645
646 void CertificateManagerModel::FilterAndBuildOrgGroupingMap(
647     net::CertType filter_type,
648     CertificateManagerModel::OrgGroupingMap* out_org_grouping_map) const {
649   std::map<CERTCertificate*, std::unique_ptr<CertInfo>> cert_info_map;
650   for (const auto& certs_source : certs_sources_) {
651     for (const auto& cert_info : certs_source->cert_infos()) {
652       if (cert_info->type() != filter_type)
653         continue;
654
655       if (cert_info_map.find(cert_info->cert()) == cert_info_map.end())
656         cert_info_map[cert_info->cert()] = CertInfo::Clone(cert_info.get());
657     }
658   }
659
660   for (auto& cert_info_kv : cert_info_map) {
661     std::string org = GetCertificateOrg(cert_info_kv.second->cert());
662     (*out_org_grouping_map)[org].push_back(std::move(cert_info_kv.second));
663   }
664 }
665
666 int CertificateManagerModel::ImportFromPKCS12(PK11SlotInfo* slot_info,
667                                               const std::string& data,
668                                               const std::u16string& password,
669                                               bool is_extractable) {
670   return cert_db_->ImportFromPKCS12(slot_info, data, password, is_extractable,
671                                     nullptr);
672 }
673
674 int CertificateManagerModel::ImportUserCert(const std::string& data) {
675   return cert_db_->ImportUserCert(data);
676 }
677
678 bool CertificateManagerModel::ImportCACerts(
679     const net::ScopedCERTCertificateList& certificates,
680     net::NSSCertDatabase::TrustBits trust_bits,
681     net::NSSCertDatabase::ImportCertFailureList* not_imported) {
682   return cert_db_->ImportCACerts(certificates, trust_bits, not_imported);
683 }
684
685 bool CertificateManagerModel::ImportServerCert(
686     const net::ScopedCERTCertificateList& certificates,
687     net::NSSCertDatabase::TrustBits trust_bits,
688     net::NSSCertDatabase::ImportCertFailureList* not_imported) {
689   const size_t num_certs = certificates.size();
690   bool result =
691       cert_db_->ImportServerCert(certificates, trust_bits, not_imported);
692   if (result && not_imported->size() != num_certs)
693     Refresh();
694   return result;
695 }
696
697 bool CertificateManagerModel::SetCertTrust(
698     CERTCertificate* cert,
699     net::CertType type,
700     net::NSSCertDatabase::TrustBits trust_bits) {
701   CertsSource* certs_source = FindCertsSourceForCert(cert);
702   if (!certs_source)
703     return false;
704   return certs_source->SetCertTrust(cert, type, trust_bits);
705 }
706
707 void CertificateManagerModel::RemoveFromDatabase(
708     net::ScopedCERTCertificate cert,
709     base::OnceCallback<void(bool)> callback) {
710   CertsSource* certs_source = FindCertsSourceForCert(cert.get());
711   if (!certs_source) {
712     base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
713         FROM_HERE, base::BindOnce(std::move(callback), false));
714     return;
715   }
716   return certs_source->RemoveFromDatabase(std::move(cert), std::move(callback));
717 }
718
719 // static
720 void CertificateManagerModel::DidGetCertDBOnUIThread(
721     std::unique_ptr<Params> params,
722     CertificateManagerModel::Observer* observer,
723     CreationCallback callback,
724     net::NSSCertDatabase* cert_db) {
725   DCHECK_CURRENTLY_ON(BrowserThread::UI);
726
727   std::unique_ptr<CertificateManagerModel> model =
728       std::make_unique<CertificateManagerModel>(std::move(params), observer,
729                                                 cert_db);
730   std::move(callback).Run(std::move(model));
731 }
732
733 // static
734 void CertificateManagerModel::DidGetCertDBOnIOThread(
735     std::unique_ptr<Params> params,
736     CertificateManagerModel::Observer* observer,
737     CreationCallback callback,
738     net::NSSCertDatabase* cert_db) {
739   DCHECK_CURRENTLY_ON(BrowserThread::IO);
740
741   content::GetUIThreadTaskRunner({})->PostTask(
742       FROM_HERE,
743       base::BindOnce(&CertificateManagerModel::DidGetCertDBOnUIThread,
744                      std::move(params), observer, std::move(callback),
745                      cert_db));
746 }
747
748 // static
749 void CertificateManagerModel::GetCertDBOnIOThread(
750     std::unique_ptr<Params> params,
751     NssCertDatabaseGetter database_getter,
752     CertificateManagerModel::Observer* observer,
753     CreationCallback callback) {
754   DCHECK_CURRENTLY_ON(BrowserThread::IO);
755
756   auto split_callback = base::SplitOnceCallback(
757       base::BindOnce(&CertificateManagerModel::DidGetCertDBOnIOThread,
758                      std::move(params), observer, std::move(callback)));
759
760   net::NSSCertDatabase* cert_db =
761       std::move(database_getter).Run(std::move(split_callback.first));
762   // If the NSS database was already available, |cert_db| is non-null and
763   // |did_get_cert_db_callback| has not been called. Call it explicitly.
764   if (cert_db)
765     std::move(split_callback.second).Run(cert_db);
766 }