1 // Copyright (c) 2012 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/certificate_manager_model.h"
10 #include "base/callback_helpers.h"
11 #include "base/i18n/time_formatting.h"
12 #include "base/logging.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/scoped_observation.h"
15 #include "base/sequence_checker.h"
16 #include "base/strings/utf_string_conversions.h"
17 #include "build/build_config.h"
18 #include "build/chromeos_buildflags.h"
19 #include "chrome/browser/net/nss_context.h"
20 #include "chrome/browser/ui/crypto_module_password_dialog_nss.h"
21 #include "chrome/common/net/x509_certificate_model_nss.h"
22 #include "chrome/grit/generated_resources.h"
23 #include "content/public/browser/browser_context.h"
24 #include "content/public/browser/browser_task_traits.h"
25 #include "content/public/browser/browser_thread.h"
26 #include "content/public/browser/resource_context.h"
27 #include "crypto/nss_util.h"
28 #include "net/base/net_errors.h"
29 #include "net/cert/cert_database.h"
30 #include "net/cert/x509_certificate.h"
31 #include "net/cert/x509_util_nss.h"
32 #include "ui/base/l10n/l10n_util.h"
34 #if BUILDFLAG(IS_CHROMEOS_ASH)
35 #include "chrome/browser/ash/certificate_provider/certificate_provider.h"
36 #include "chrome/browser/ash/certificate_provider/certificate_provider_service.h"
37 #include "chrome/browser/ash/certificate_provider/certificate_provider_service_factory.h"
38 #include "chrome/browser/ash/policy/networking/user_network_configuration_updater.h"
39 #include "chrome/browser/ash/policy/networking/user_network_configuration_updater_factory.h"
40 #include "chromeos/network/onc/certificate_scope.h"
41 #include "chromeos/network/policy_certificate_provider.h"
44 using content::BrowserThread;
46 // CertificateManagerModel is created on the UI thread. It needs a
47 // NSSCertDatabase handle (and on ChromeOS it needs to get the TPM status) which
48 // needs to be done on the IO thread.
50 // The initialization flow is roughly:
52 // UI thread IO Thread
54 // CertificateManagerModel::Create
55 // \--------------------------------------v
56 // CertificateManagerModel::GetCertDBOnIOThread
58 // NssCertDatabaseGetter
60 // CertificateManagerModel::DidGetCertDBOnIOThread
62 // crypto::IsTPMTokenEnabledForNSS
63 // v--------------------------------------/
64 // CertificateManagerModel::DidGetCertDBOnUIThread
66 // new CertificateManagerModel
72 std::string GetCertificateOrg(CERTCertificate* cert) {
74 x509_certificate_model::GetSubjectOrgName(cert, std::string());
76 org = x509_certificate_model::GetSubjectDisplayName(cert);
81 #if BUILDFLAG(IS_CHROMEOS_ASH)
82 // Log message for an operation that can not be performed on a certificate of a
84 constexpr char kOperationNotPermitted[] =
85 "Operation not permitted on a certificate. Source: ";
86 #endif // BUILDFLAG(IS_CHROMEOS_ASH)
90 // A source of certificates that should be displayed on the certificate manager
91 // UI. Currently, a CertsSource yields CertInfo objects. Each CertInfo contains
92 // a NSS ScopedCERTCertificate.
93 class CertificateManagerModel::CertsSource {
95 // |certs_source_updated_callback| will be invoked when the list of
96 // certificates provided by this CertsSource changes.
97 explicit CertsSource(base::RepeatingClosure certs_source_updated_callback)
98 : certs_source_updated_callback_(certs_source_updated_callback) {}
99 virtual ~CertsSource() = default;
101 // Returns the CertInfos provided by this CertsSource.
102 const std::vector<std::unique_ptr<CertificateManagerModel::CertInfo>>&
104 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
108 // Returns true if |cert| is in this CertsSource's certificate list.
109 bool HasCert(CERTCertificate* cert) const {
110 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
111 for (const auto& cert_info : cert_infos_) {
112 if (cert_info->cert() == cert)
118 // Triggers a refresh of this CertsSource. When done, the
119 // |certs_source_updated_callback| passed to the constructor will be invoked.
120 virtual void Refresh() = 0;
122 // If any CertsSource's |IsHoldBackUpdates| is returning true, the
123 // CertificateManagerModel will not notify its Observer about updates.
124 bool IsHoldBackUpdates() const { return hold_back_updates_; }
126 // Set trust values for certificate.
127 // |trust_bits| should be a bit field of TRUST* values from NSSCertDatabase.
128 // Returns true on success or false on failure.
129 virtual bool SetCertTrust(CERTCertificate* cert,
131 net::NSSCertDatabase::TrustBits trust_bits) = 0;
133 // Delete the cert. Returns true on success. |cert| is still valid when this
135 virtual bool Delete(CERTCertificate* cert) = 0;
138 // To be called by subclasses to set the CertInfo list provided by this
139 // CertsSource. If this CertsSource is signalling that updates should be held
140 // back (|SetHoldBackUpdates(true)|, this will be set to false. The
141 // |certs_source_updated_callback| passed to the constructor will be invoked.
143 std::vector<std::unique_ptr<CertificateManagerModel::CertInfo>>
145 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
146 cert_infos_.swap(cert_infos);
147 SetHoldBackUpdates(false);
148 certs_source_updated_callback_.Run();
151 // Signal to |CertificateManagerModel| that updates to its Observer should be
152 // held back. This will be automatically taken back on |SetCertInfos|.
153 // This should only be used by |CertsSource|s that provide their list of
154 // certificates asynchronously but expect their certificate listing to be
156 void SetHoldBackUpdates(bool hold_back_updates) {
157 hold_back_updates_ = hold_back_updates;
160 // Used to verify that the constructor, and accessing |cert_infos_| are
161 // performed on the same sequence. Offered to subclasses so they can also
162 // check that they're being called on a valid sequence.
163 SEQUENCE_CHECKER(sequence_checker_);
166 // Cached CertInfos provided by this CertsSource.
167 std::vector<std::unique_ptr<CertificateManagerModel::CertInfo>> cert_infos_;
169 // Invoked when the list of certificates provided by this CertsSource has
171 base::RepeatingClosure certs_source_updated_callback_;
173 // If true, the CertificateManagerModel should be holding back update
175 bool hold_back_updates_ = false;
177 DISALLOW_COPY_AND_ASSIGN(CertsSource);
181 // Provides certificates enumerable from a NSSCertDatabase.
182 class CertsSourcePlatformNSS : public CertificateManagerModel::CertsSource,
183 net::CertDatabase::Observer {
185 CertsSourcePlatformNSS(base::RepeatingClosure certs_source_updated_callback,
186 net::NSSCertDatabase* nss_cert_database)
187 : CertsSource(certs_source_updated_callback),
188 cert_db_(nss_cert_database) {
189 // Observe CertDatabase changes to refresh when it's updated.
190 cert_database_observation_.Observe(net::CertDatabase::GetInstance());
192 ~CertsSourcePlatformNSS() override = default;
194 // net::CertDatabase::Observer
195 void OnCertDBChanged() override {
196 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
200 void Refresh() override {
201 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
202 SetHoldBackUpdates(true);
203 DVLOG(1) << "refresh started";
204 std::vector<crypto::ScopedPK11Slot> modules;
205 cert_db_->ListModules(&modules, false);
206 DVLOG(1) << "refresh waiting for unlocking...";
207 chrome::UnlockSlotsIfNecessary(
208 std::move(modules), kCryptoModulePasswordListCerts,
209 net::HostPortPair(), // unused.
210 nullptr, // TODO(mattm): supply parent window.
211 base::BindOnce(&CertsSourcePlatformNSS::RefreshSlotsUnlocked,
212 weak_ptr_factory_.GetWeakPtr()));
215 bool SetCertTrust(CERTCertificate* cert,
217 net::NSSCertDatabase::TrustBits trust_bits) override {
218 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
219 return cert_db_->SetCertTrust(cert, type, trust_bits);
222 bool Delete(CERTCertificate* cert) override {
223 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
224 return cert_db_->DeleteCertAndKey(cert);
228 void RefreshSlotsUnlocked() {
229 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
230 DVLOG(1) << "refresh listing certs...";
231 cert_db_->ListCertsInfo(base::BindOnce(&CertsSourcePlatformNSS::DidGetCerts,
232 weak_ptr_factory_.GetWeakPtr()));
235 void DidGetCerts(net::NSSCertDatabase::CertInfoList cert_info_list) {
236 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
237 DVLOG(1) << "refresh finished for platform provided certificates";
239 std::vector<std::unique_ptr<CertificateManagerModel::CertInfo>> cert_infos;
240 cert_infos.reserve(cert_info_list.size());
242 for (auto& cert_info : cert_info_list) {
244 x509_certificate_model::GetType(cert_info.cert.get());
245 bool can_be_deleted = !cert_info.on_read_only_slot;
246 bool hardware_backed = cert_info.hardware_backed;
247 std::u16string name = GetName(cert_info.cert.get(), hardware_backed);
249 cert_infos.push_back(std::make_unique<CertificateManagerModel::CertInfo>(
250 /*cert=*/std::move(cert_info.cert), type, name, can_be_deleted,
251 /*untrusted=*/cert_info.untrusted,
252 /*source=*/CertificateManagerModel::CertInfo::Source::kPlatform,
253 /*web_trust_anchor=*/cert_info.web_trust_anchor, hardware_backed,
254 /*device_wide=*/cert_info.device_wide));
257 SetCertInfos(std::move(cert_infos));
260 static std::u16string GetName(CERTCertificate* cert,
261 bool is_hardware_backed) {
262 std::u16string name =
263 base::UTF8ToUTF16(x509_certificate_model::GetCertNameOrNickname(cert));
264 if (is_hardware_backed) {
265 name = l10n_util::GetStringFUTF16(
266 IDS_CERT_MANAGER_HARDWARE_BACKED_KEY_FORMAT, name,
267 l10n_util::GetStringUTF16(IDS_CERT_MANAGER_HARDWARE_BACKED));
272 // The source NSSCertDatabase used for listing certificates.
273 net::NSSCertDatabase* cert_db_;
275 // ScopedObservation to keep track of the observer for net::CertDatabase.
276 base::ScopedObservation<net::CertDatabase, net::CertDatabase::Observer>
277 cert_database_observation_{this};
279 base::WeakPtrFactory<CertsSourcePlatformNSS> weak_ptr_factory_{this};
281 DISALLOW_COPY_AND_ASSIGN(CertsSourcePlatformNSS);
284 #if BUILDFLAG(IS_CHROMEOS_ASH)
285 // Provides certificates installed through enterprise policy.
286 class CertsSourcePolicy : public CertificateManagerModel::CertsSource,
287 chromeos::PolicyCertificateProvider::Observer {
289 // Defines which policy-provided certificates this CertsSourcePolicy instance
292 // Only certificates which are installed by enterprise policy, but not Web
294 kPolicyCertsWithoutWebTrust,
295 // Only certificates which are installed by enterprise policy and Web
297 kPolicyCertsWithWebTrust
300 CertsSourcePolicy(base::RepeatingClosure certs_source_updated_callback,
301 chromeos::PolicyCertificateProvider* policy_certs_provider,
303 : CertsSource(certs_source_updated_callback),
304 policy_certs_provider_(policy_certs_provider),
306 policy_certs_provider_->AddPolicyProvidedCertsObserver(this);
309 ~CertsSourcePolicy() override {
310 policy_certs_provider_->RemovePolicyProvidedCertsObserver(this);
313 // chromeos::PolicyCertificateProvider::Observer
314 void OnPolicyProvidedCertsChanged() override {
315 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
319 void Refresh() override {
320 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
322 case Mode::kPolicyCertsWithoutWebTrust:
323 RefreshImpl(policy_certs_provider_->GetCertificatesWithoutWebTrust(
324 chromeos::onc::CertificateScope::Default()),
325 false /* policy_web_trusted */);
327 case Mode::kPolicyCertsWithWebTrust:
328 RefreshImpl(policy_certs_provider_->GetWebTrustedCertificates(
329 chromeos::onc::CertificateScope::Default()),
330 true /* policy_web_trusted */);
337 bool SetCertTrust(CERTCertificate* cert,
339 net::NSSCertDatabase::TrustBits trust_bits) override {
340 // Trust of policy-provided certificates can not be changed.
341 LOG(WARNING) << kOperationNotPermitted << "Policy";
345 bool Delete(CERTCertificate* cert) override {
346 // Policy-provided certificates can not be deleted.
347 LOG(WARNING) << kOperationNotPermitted << "Policy";
352 void RefreshImpl(const net::CertificateList& certificates,
353 bool policy_web_trusted) {
354 std::vector<std::unique_ptr<CertificateManagerModel::CertInfo>> cert_infos;
355 cert_infos.reserve(certificates.size());
357 for (const auto& policy_cert : certificates) {
358 net::ScopedCERTCertificate nss_cert(
359 net::x509_util::CreateCERTCertificateFromX509Certificate(
364 net::CertType type = x509_certificate_model::GetType(nss_cert.get());
365 std::u16string cert_name = base::UTF8ToUTF16(
366 x509_certificate_model::GetCertNameOrNickname(nss_cert.get()));
367 cert_infos.push_back(std::make_unique<CertificateManagerModel::CertInfo>(
368 std::move(nss_cert), type, std::move(cert_name),
369 false /* can_be_deleted */, false /* untrusted */,
370 CertificateManagerModel::CertInfo::Source::kPolicy,
371 policy_web_trusted /* web_trust_anchor */,
372 false /* hardware_backed */, false /* device_wide */));
375 SetCertInfos(std::move(cert_infos));
378 chromeos::PolicyCertificateProvider* policy_certs_provider_;
381 DISALLOW_COPY_AND_ASSIGN(CertsSourcePolicy);
384 // Provides certificates made available by extensions through the
385 // chrome.certificateProvider API.
386 class CertsSourceExtensions : public CertificateManagerModel::CertsSource {
388 CertsSourceExtensions(base::RepeatingClosure certs_source_updated_callback,
389 std::unique_ptr<chromeos::CertificateProvider>
390 certificate_provider_service)
391 : CertsSource(certs_source_updated_callback),
392 certificate_provider_service_(std::move(certificate_provider_service)) {
395 void Refresh() override {
396 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
397 certificate_provider_service_->GetCertificates(base::BindOnce(
398 &CertsSourceExtensions::DidGetCerts, weak_ptr_factory_.GetWeakPtr()));
401 bool SetCertTrust(CERTCertificate* cert,
403 net::NSSCertDatabase::TrustBits trust_bits) override {
404 // Extension-provided certificates are user certificates; changing trust
405 // does not make sense here.
406 LOG(WARNING) << kOperationNotPermitted << "Extension";
410 bool Delete(CERTCertificate* cert) override {
411 // Extension-provided certificates can not be deleted.
412 LOG(WARNING) << kOperationNotPermitted << "Extension";
417 void DidGetCerts(net::ClientCertIdentityList cert_identities) {
418 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
419 std::vector<std::unique_ptr<CertificateManagerModel::CertInfo>> cert_infos;
421 cert_infos.reserve(cert_identities.size());
422 for (const auto& identity : cert_identities) {
423 net::ScopedCERTCertificate nss_cert(
424 net::x509_util::CreateCERTCertificateFromX509Certificate(
425 identity->certificate()));
429 std::u16string cert_name = base::UTF8ToUTF16(
430 x509_certificate_model::GetCertNameOrNickname(nss_cert.get()));
431 std::u16string display_name = l10n_util::GetStringFUTF16(
432 IDS_CERT_MANAGER_EXTENSION_PROVIDED_FORMAT, std::move(cert_name));
434 cert_infos.push_back(std::make_unique<CertificateManagerModel::CertInfo>(
435 std::move(nss_cert), net::CertType::USER_CERT /* type */,
436 display_name, false /* can_be_deleted */, false /* untrusted */,
437 CertificateManagerModel::CertInfo::Source::kExtension,
438 false /* web_trust_anchor */, false /* hardware_backed */,
439 false /* device_wide */));
442 SetCertInfos(std::move(cert_infos));
445 std::unique_ptr<chromeos::CertificateProvider> certificate_provider_service_;
447 base::WeakPtrFactory<CertsSourceExtensions> weak_ptr_factory_{this};
449 DISALLOW_COPY_AND_ASSIGN(CertsSourceExtensions);
452 #endif // BUILDFLAG(IS_CHROMEOS_ASH)
456 CertificateManagerModel::CertInfo::CertInfo(net::ScopedCERTCertificate cert,
462 bool web_trust_anchor,
463 bool hardware_backed,
465 : cert_(std::move(cert)),
467 name_(std::move(name)),
468 can_be_deleted_(can_be_deleted),
469 untrusted_(untrusted),
471 web_trust_anchor_(web_trust_anchor),
472 hardware_backed_(hardware_backed),
473 device_wide_(device_wide) {}
475 CertificateManagerModel::CertInfo::~CertInfo() {}
478 std::unique_ptr<CertificateManagerModel::CertInfo>
479 CertificateManagerModel::CertInfo::Clone(const CertInfo* cert_info) {
480 return std::make_unique<CertInfo>(
481 net::x509_util::DupCERTCertificate(cert_info->cert()), cert_info->type(),
482 cert_info->name(), cert_info->can_be_deleted(), cert_info->untrusted(),
483 cert_info->source(), cert_info->web_trust_anchor(),
484 cert_info->hardware_backed(), cert_info->device_wide());
487 CertificateManagerModel::Params::Params() = default;
488 CertificateManagerModel::Params::~Params() = default;
489 CertificateManagerModel::Params::Params(Params&& other) = default;
492 void CertificateManagerModel::Create(
493 content::BrowserContext* browser_context,
494 CertificateManagerModel::Observer* observer,
495 CreationCallback callback) {
496 DCHECK_CURRENTLY_ON(BrowserThread::UI);
498 std::unique_ptr<Params> params = std::make_unique<Params>();
499 #if BUILDFLAG(IS_CHROMEOS_ASH)
500 policy::UserNetworkConfigurationUpdater* user_network_configuration_updater =
501 policy::UserNetworkConfigurationUpdaterFactory::GetForBrowserContext(
503 params->policy_certs_provider = user_network_configuration_updater;
505 chromeos::CertificateProviderService* certificate_provider_service =
506 chromeos::CertificateProviderServiceFactory::GetForBrowserContext(
508 params->extension_certificate_provider =
509 certificate_provider_service->CreateCertificateProvider();
512 content::GetIOThreadTaskRunner({})->PostTask(
513 FROM_HERE, base::BindOnce(&CertificateManagerModel::GetCertDBOnIOThread,
515 CreateNSSCertDatabaseGetter(browser_context),
516 observer, std::move(callback)));
519 CertificateManagerModel::CertificateManagerModel(
520 std::unique_ptr<Params> params,
522 net::NSSCertDatabase* nss_cert_database,
523 bool is_user_db_available,
524 bool is_tpm_available)
525 : cert_db_(nss_cert_database),
526 is_user_db_available_(is_user_db_available),
527 is_tpm_available_(is_tpm_available),
528 observer_(observer) {
529 DCHECK_CURRENTLY_ON(BrowserThread::UI);
531 // Fill |certs_sources_|. Note that the order matters. Higher priority
532 // CertsSources must come first.
534 base::RepeatingClosure certs_source_updated_callback = base::BindRepeating(
535 &CertificateManagerModel::OnCertsSourceUpdated, base::Unretained(this));
537 #if BUILDFLAG(IS_CHROMEOS_ASH)
538 // Certificates installed and web trusted by enterprise policy is the highest
539 // priority CertsSource.
540 // UserNetworkConfigurationUpdater is only available for the primary user's
542 if (params->policy_certs_provider) {
543 certs_sources_.push_back(std::make_unique<CertsSourcePolicy>(
544 certs_source_updated_callback, params->policy_certs_provider,
545 CertsSourcePolicy::Mode::kPolicyCertsWithWebTrust));
549 // Add the main NSS DB based CertsSource.
550 certs_sources_.push_back(std::make_unique<CertsSourcePlatformNSS>(
551 certs_source_updated_callback, nss_cert_database));
553 #if BUILDFLAG(IS_CHROMEOS_ASH)
554 // Certificates installed by enterprise policy without web trust are lower
555 // priority than the main NSS DB based CertsSource.
556 // Rationale: The user should be able to add trust to policy-provided
557 // certificates by re-importing them and modifying their trust settings.
558 if (params->policy_certs_provider) {
559 certs_sources_.push_back(std::make_unique<CertsSourcePolicy>(
560 certs_source_updated_callback, params->policy_certs_provider,
561 CertsSourcePolicy::Mode::kPolicyCertsWithoutWebTrust));
564 // Extensions is the lowest priority CertsSource.
565 if (params->extension_certificate_provider) {
566 certs_sources_.push_back(std::make_unique<CertsSourceExtensions>(
567 certs_source_updated_callback,
568 std::move(params->extension_certificate_provider)));
573 CertificateManagerModel::~CertificateManagerModel() {}
575 void CertificateManagerModel::OnCertsSourceUpdated() {
576 if (hold_back_updates_)
578 for (const auto& certs_source : certs_sources_) {
579 if (certs_source->IsHoldBackUpdates()) {
584 observer_->CertificatesRefreshed();
587 CertificateManagerModel::CertsSource*
588 CertificateManagerModel::FindCertsSourceForCert(CERTCertificate* cert) {
589 for (auto& certs_source : certs_sources_) {
590 if (certs_source->HasCert(cert))
591 return certs_source.get();
596 void CertificateManagerModel::Refresh() {
597 hold_back_updates_ = true;
599 for (auto& certs_source : certs_sources_)
600 certs_source->Refresh();
602 hold_back_updates_ = false;
603 OnCertsSourceUpdated();
606 void CertificateManagerModel::FilterAndBuildOrgGroupingMap(
607 net::CertType filter_type,
608 CertificateManagerModel::OrgGroupingMap* out_org_grouping_map) const {
609 std::map<CERTCertificate*, std::unique_ptr<CertInfo>> cert_info_map;
610 for (const auto& certs_source : certs_sources_) {
611 for (const auto& cert_info : certs_source->cert_infos()) {
612 if (cert_info->type() != filter_type)
615 if (cert_info_map.find(cert_info->cert()) == cert_info_map.end())
616 cert_info_map[cert_info->cert()] = CertInfo::Clone(cert_info.get());
620 for (auto& cert_info_kv : cert_info_map) {
621 std::string org = GetCertificateOrg(cert_info_kv.second->cert());
622 (*out_org_grouping_map)[org].push_back(std::move(cert_info_kv.second));
626 int CertificateManagerModel::ImportFromPKCS12(PK11SlotInfo* slot_info,
627 const std::string& data,
628 const std::u16string& password,
629 bool is_extractable) {
630 return cert_db_->ImportFromPKCS12(slot_info, data, password, is_extractable,
634 int CertificateManagerModel::ImportUserCert(const std::string& data) {
635 return cert_db_->ImportUserCert(data);
638 bool CertificateManagerModel::ImportCACerts(
639 const net::ScopedCERTCertificateList& certificates,
640 net::NSSCertDatabase::TrustBits trust_bits,
641 net::NSSCertDatabase::ImportCertFailureList* not_imported) {
642 return cert_db_->ImportCACerts(certificates, trust_bits, not_imported);
645 bool CertificateManagerModel::ImportServerCert(
646 const net::ScopedCERTCertificateList& certificates,
647 net::NSSCertDatabase::TrustBits trust_bits,
648 net::NSSCertDatabase::ImportCertFailureList* not_imported) {
649 const size_t num_certs = certificates.size();
651 cert_db_->ImportServerCert(certificates, trust_bits, not_imported);
652 if (result && not_imported->size() != num_certs)
657 bool CertificateManagerModel::SetCertTrust(
658 CERTCertificate* cert,
660 net::NSSCertDatabase::TrustBits trust_bits) {
661 CertsSource* certs_source = FindCertsSourceForCert(cert);
664 return certs_source->SetCertTrust(cert, type, trust_bits);
667 bool CertificateManagerModel::Delete(CERTCertificate* cert) {
668 CertsSource* certs_source = FindCertsSourceForCert(cert);
671 return certs_source->Delete(cert);
675 void CertificateManagerModel::DidGetCertDBOnUIThread(
676 std::unique_ptr<Params> params,
677 CertificateManagerModel::Observer* observer,
678 CreationCallback callback,
679 net::NSSCertDatabase* cert_db,
680 bool is_user_db_available,
681 bool is_tpm_available) {
682 DCHECK_CURRENTLY_ON(BrowserThread::UI);
684 std::unique_ptr<CertificateManagerModel> model =
685 std::make_unique<CertificateManagerModel>(std::move(params), observer,
686 cert_db, is_user_db_available,
688 std::move(callback).Run(std::move(model));
692 void CertificateManagerModel::DidGetCertDBOnIOThread(
693 std::unique_ptr<Params> params,
694 CertificateManagerModel::Observer* observer,
695 CreationCallback callback,
696 net::NSSCertDatabase* cert_db) {
697 DCHECK_CURRENTLY_ON(BrowserThread::IO);
699 bool is_user_db_available = !!cert_db->GetPublicSlot();
700 bool is_tpm_available = false;
701 #if BUILDFLAG(IS_CHROMEOS_ASH)
702 is_tpm_available = crypto::IsTPMTokenEnabledForNSS();
704 content::GetUIThreadTaskRunner({})->PostTask(
706 base::BindOnce(&CertificateManagerModel::DidGetCertDBOnUIThread,
707 std::move(params), observer, std::move(callback), cert_db,
708 is_user_db_available, is_tpm_available));
712 void CertificateManagerModel::GetCertDBOnIOThread(
713 std::unique_ptr<Params> params,
714 NssCertDatabaseGetter database_getter,
715 CertificateManagerModel::Observer* observer,
716 CreationCallback callback) {
717 DCHECK_CURRENTLY_ON(BrowserThread::IO);
719 auto split_callback = base::SplitOnceCallback(
720 base::BindOnce(&CertificateManagerModel::DidGetCertDBOnIOThread,
721 std::move(params), observer, std::move(callback)));
723 net::NSSCertDatabase* cert_db =
724 std::move(database_getter).Run(std::move(split_callback.first));
725 // If the NSS database was already available, |cert_db| is non-null and
726 // |did_get_cert_db_callback| has not been called. Call it explicitly.
728 std::move(split_callback.second).Run(cert_db);