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.
5 #include "chrome/browser/certificate_manager_model.h"
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"
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)
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)
55 using content::BrowserThread;
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.
61 // The initialization flow is roughly:
63 // UI thread IO Thread
65 // CertificateManagerModel::Create
66 // \--------------------------------------v
67 // CertificateManagerModel::GetCertDBOnIOThread
69 // NssCertDatabaseGetter
71 // CertificateManagerModel::DidGetCertDBOnIOThread
72 // v--------------------------------------/
73 // CertificateManagerModel::DidGetCertDBOnUIThread
75 // new CertificateManagerModel
81 std::string GetCertificateOrg(CERTCertificate* cert) {
83 x509_certificate_model::GetSubjectOrgName(cert, std::string());
85 org = x509_certificate_model::GetSubjectDisplayName(cert);
90 #if BUILDFLAG(IS_CHROMEOS)
91 // Log message for an operation that can not be performed on a certificate of a
93 constexpr char kOperationNotPermitted[] =
94 "Operation not permitted on a certificate. Source: ";
95 #endif // BUILDFLAG(IS_CHROMEOS)
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 {
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) {}
109 CertsSource(const CertsSource&) = delete;
110 CertsSource& operator=(const CertsSource&) = delete;
112 virtual ~CertsSource() = default;
114 // Returns the CertInfos provided by this CertsSource.
115 const std::vector<std::unique_ptr<CertificateManagerModel::CertInfo>>&
117 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
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)
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;
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_; }
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,
144 net::NSSCertDatabase::TrustBits trust_bits) = 0;
146 // Remove the cert from the cert database.
147 virtual void RemoveFromDatabase(
148 net::ScopedCERTCertificate cert,
149 base::OnceCallback<void(bool /*success*/)> callback) = 0;
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.
157 std::vector<std::unique_ptr<CertificateManagerModel::CertInfo>>
159 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
160 cert_infos_.swap(cert_infos);
161 SetHoldBackUpdates(false);
162 certs_source_updated_callback_.Run();
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
170 void SetHoldBackUpdates(bool hold_back_updates) {
171 hold_back_updates_ = hold_back_updates;
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_);
180 // Cached CertInfos provided by this CertsSource.
181 std::vector<std::unique_ptr<CertificateManagerModel::CertInfo>> cert_infos_;
183 // Invoked when the list of certificates provided by this CertsSource has
185 base::RepeatingClosure certs_source_updated_callback_;
187 // If true, the CertificateManagerModel should be holding back update
189 bool hold_back_updates_ = false;
193 // Provides certificates enumerable from a NSSCertDatabase.
194 class CertsSourcePlatformNSS : public CertificateManagerModel::CertsSource,
195 net::CertDatabase::Observer {
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());
205 CertsSourcePlatformNSS(const CertsSourcePlatformNSS&) = delete;
206 CertsSourcePlatformNSS& operator=(const CertsSourcePlatformNSS&) = delete;
208 ~CertsSourcePlatformNSS() override = default;
210 // net::CertDatabase::Observer
211 void OnTrustStoreChanged() override {
212 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
215 void OnClientCertStoreChanged() override {
216 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
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()));
235 bool SetCertTrust(CERTCertificate* cert,
237 net::NSSCertDatabase::TrustBits trust_bits) override {
238 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
239 return cert_db_->SetCertTrust(cert, type, trust_bits);
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));
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)));
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
271 net::NSSCertDatabase::NSSRootsHandling::kInclude
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";
280 std::vector<std::unique_ptr<CertificateManagerModel::CertInfo>> cert_infos;
281 cert_infos.reserve(cert_info_list.size());
283 for (auto& cert_info : cert_info_list) {
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);
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));
298 SetCertInfos(std::move(cert_infos));
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));
313 // The source NSSCertDatabase used for listing certificates.
314 raw_ptr<net::NSSCertDatabase> cert_db_;
316 // ScopedObservation to keep track of the observer for net::CertDatabase.
317 base::ScopedObservation<net::CertDatabase, net::CertDatabase::Observer>
318 cert_database_observation_{this};
320 base::WeakPtrFactory<CertsSourcePlatformNSS> weak_ptr_factory_{this};
323 #if BUILDFLAG(IS_CHROMEOS)
324 // Provides certificates installed through enterprise policy.
325 class CertsSourcePolicy : public CertificateManagerModel::CertsSource,
326 ash::PolicyCertificateProvider::Observer {
328 // Defines which policy-provided certificates this CertsSourcePolicy instance
331 // Only certificates which are installed by enterprise policy, but not Web
333 kPolicyCertsWithoutWebTrust,
334 // Only certificates which are installed by enterprise policy and Web
336 kPolicyCertsWithWebTrust
339 CertsSourcePolicy(base::RepeatingClosure certs_source_updated_callback,
340 ash::PolicyCertificateProvider* policy_certs_provider,
342 : CertsSource(certs_source_updated_callback),
343 policy_certs_provider_(policy_certs_provider),
345 policy_certs_provider_->AddPolicyProvidedCertsObserver(this);
348 CertsSourcePolicy(const CertsSourcePolicy&) = delete;
349 CertsSourcePolicy& operator=(const CertsSourcePolicy&) = delete;
351 ~CertsSourcePolicy() override {
352 policy_certs_provider_->RemovePolicyProvidedCertsObserver(this);
355 // ash::PolicyCertificateProvider::Observer
356 void OnPolicyProvidedCertsChanged() override {
357 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
361 void Refresh() override {
362 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
364 case Mode::kPolicyCertsWithoutWebTrust:
365 RefreshImpl(policy_certs_provider_->GetCertificatesWithoutWebTrust(
366 chromeos::onc::CertificateScope::Default()),
367 false /* policy_web_trusted */);
369 case Mode::kPolicyCertsWithWebTrust:
370 RefreshImpl(policy_certs_provider_->GetWebTrustedCertificates(
371 chromeos::onc::CertificateScope::Default()),
372 true /* policy_web_trusted */);
379 bool SetCertTrust(CERTCertificate* cert,
381 net::NSSCertDatabase::TrustBits trust_bits) override {
382 // Trust of policy-provided certificates can not be changed.
383 LOG(WARNING) << kOperationNotPermitted << "Policy";
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));
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());
401 for (const auto& policy_cert : certificates) {
402 net::ScopedCERTCertificate nss_cert(
403 net::x509_util::CreateCERTCertificateFromX509Certificate(
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 */));
419 SetCertInfos(std::move(cert_infos));
422 raw_ptr<ash::PolicyCertificateProvider> policy_certs_provider_;
426 // Provides certificates made available by extensions through the
427 // chrome.certificateProvider API.
428 class CertsSourceExtensions : public CertificateManagerModel::CertsSource {
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)) {
437 CertsSourceExtensions(const CertsSourceExtensions&) = delete;
438 CertsSourceExtensions& operator=(const CertsSourceExtensions&) = delete;
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()));
446 bool SetCertTrust(CERTCertificate* cert,
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";
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));
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;
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()));
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));
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 */));
489 SetCertInfos(std::move(cert_infos));
492 std::unique_ptr<chromeos::CertificateProvider> certificate_provider_service_;
494 base::WeakPtrFactory<CertsSourceExtensions> weak_ptr_factory_{this};
496 #endif // BUILDFLAG(IS_CHROMEOS)
500 CertificateManagerModel::CertInfo::CertInfo(net::ScopedCERTCertificate cert,
506 bool web_trust_anchor,
507 bool hardware_backed,
509 : cert_(std::move(cert)),
511 name_(std::move(name)),
512 can_be_deleted_(can_be_deleted),
513 untrusted_(untrusted),
515 web_trust_anchor_(web_trust_anchor),
516 hardware_backed_(hardware_backed),
517 device_wide_(device_wide) {}
519 CertificateManagerModel::CertInfo::~CertInfo() {}
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());
531 CertificateManagerModel::Params::Params() = default;
532 CertificateManagerModel::Params::~Params() = default;
533 CertificateManagerModel::Params::Params(Params&& other) = default;
536 void CertificateManagerModel::Create(
537 content::BrowserContext* browser_context,
538 CertificateManagerModel::Observer* observer,
539 CreationCallback callback) {
540 DCHECK_CURRENTLY_ON(BrowserThread::UI);
542 std::unique_ptr<Params> params = std::make_unique<Params>();
543 #if BUILDFLAG(IS_CHROMEOS)
544 params->policy_certs_provider =
545 policy::UserNetworkConfigurationUpdaterFactory::GetForBrowserContext(
548 chromeos::CertificateProviderService* certificate_provider_service =
549 chromeos::CertificateProviderServiceFactory::GetForBrowserContext(
551 params->extension_certificate_provider =
552 certificate_provider_service->CreateCertificateProvider();
555 content::GetIOThreadTaskRunner({})->PostTask(
557 base::BindOnce(&CertificateManagerModel::GetCertDBOnIOThread,
559 NssServiceFactory::GetForContext(browser_context)
560 ->CreateNSSCertDatabaseGetterForIOThread(),
561 observer, std::move(callback)));
564 CertificateManagerModel::CertificateManagerModel(
565 std::unique_ptr<Params> params,
567 net::NSSCertDatabase* nss_cert_database)
568 : cert_db_(nss_cert_database), observer_(observer) {
569 DCHECK_CURRENTLY_ON(BrowserThread::UI);
571 // Fill |certs_sources_|. Note that the order matters. Higher priority
572 // CertsSources must come first.
574 base::RepeatingClosure certs_source_updated_callback = base::BindRepeating(
575 &CertificateManagerModel::OnCertsSourceUpdated, base::Unretained(this));
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
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));
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));
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));
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)));
613 CertificateManagerModel::~CertificateManagerModel() {}
615 void CertificateManagerModel::OnCertsSourceUpdated() {
616 if (hold_back_updates_)
618 for (const auto& certs_source : certs_sources_) {
619 if (certs_source->IsHoldBackUpdates()) {
624 observer_->CertificatesRefreshed();
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();
636 void CertificateManagerModel::Refresh() {
637 hold_back_updates_ = true;
639 for (auto& certs_source : certs_sources_)
640 certs_source->Refresh();
642 hold_back_updates_ = false;
643 OnCertsSourceUpdated();
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)
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());
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));
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,
674 int CertificateManagerModel::ImportUserCert(const std::string& data) {
675 return cert_db_->ImportUserCert(data);
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);
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();
691 cert_db_->ImportServerCert(certificates, trust_bits, not_imported);
692 if (result && not_imported->size() != num_certs)
697 bool CertificateManagerModel::SetCertTrust(
698 CERTCertificate* cert,
700 net::NSSCertDatabase::TrustBits trust_bits) {
701 CertsSource* certs_source = FindCertsSourceForCert(cert);
704 return certs_source->SetCertTrust(cert, type, trust_bits);
707 void CertificateManagerModel::RemoveFromDatabase(
708 net::ScopedCERTCertificate cert,
709 base::OnceCallback<void(bool)> callback) {
710 CertsSource* certs_source = FindCertsSourceForCert(cert.get());
712 base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
713 FROM_HERE, base::BindOnce(std::move(callback), false));
716 return certs_source->RemoveFromDatabase(std::move(cert), std::move(callback));
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);
727 std::unique_ptr<CertificateManagerModel> model =
728 std::make_unique<CertificateManagerModel>(std::move(params), observer,
730 std::move(callback).Run(std::move(model));
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);
741 content::GetUIThreadTaskRunner({})->PostTask(
743 base::BindOnce(&CertificateManagerModel::DidGetCertDBOnUIThread,
744 std::move(params), observer, std::move(callback),
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);
756 auto split_callback = base::SplitOnceCallback(
757 base::BindOnce(&CertificateManagerModel::DidGetCertDBOnIOThread,
758 std::move(params), observer, std::move(callback)));
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.
765 std::move(split_callback.second).Run(cert_db);