| // Copyright 2024 The Chromium Authors | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #ifndef COMPONENTS_SERVER_CERTIFICATE_DATABASE_SERVER_CERTIFICATE_DATABASE_SERVICE_H_ | 
 | #define COMPONENTS_SERVER_CERTIFICATE_DATABASE_SERVER_CERTIFICATE_DATABASE_SERVICE_H_ | 
 |  | 
 | #include <vector> | 
 |  | 
 | #include "base/callback_list.h" | 
 | #include "base/functional/callback.h" | 
 | #include "base/memory/weak_ptr.h" | 
 | #include "base/threading/sequence_bound.h" | 
 | #include "components/keyed_service/core/keyed_service.h" | 
 | #include "components/server_certificate_database/server_certificate_database.h" | 
 |  | 
 | #if BUILDFLAG(IS_CHROMEOS) | 
 | #include "components/server_certificate_database/server_certificate_database_nss_migrator.h" | 
 | #endif | 
 |  | 
 | class PrefRegistrySimple; | 
 | class PrefService; | 
 |  | 
 | namespace net { | 
 |  | 
 | #if BUILDFLAG(IS_CHROMEOS) | 
 | namespace prefs { | 
 | // Integer that indicates whether the user's NSS certificates have been | 
 | // migrated to ServerCertificateDatabase. The value is a | 
 | // ServerCertificateDatabaseService::NSSMigrationResultPref enum. | 
 | inline constexpr char kNSSCertsMigratedToServerCertDb[] = | 
 |     "certificates.nss_certs_migrated_to_server_cert_db"; | 
 | }  //  namespace prefs | 
 | #endif | 
 |  | 
 | // KeyedService that loads and provides policies around usage of Certificates | 
 | // for TLS. | 
 | class ServerCertificateDatabaseService : public KeyedService { | 
 |  public: | 
 | #if BUILDFLAG(IS_CHROMEOS) | 
 |   // These values are persisted to logs. Entries should not be renumbered and | 
 |   // numeric values should never be reused. | 
 |   enum class NSSMigrationResultHistogram { | 
 |     kNssDbEmpty = 0, | 
 |     kSuccess = 1, | 
 |     kPartialSuccess = 2, | 
 |     kFailed = 3, | 
 |     kMaxValue = kFailed, | 
 |   }; | 
 |  | 
 |   // Enum that will record migration state in user's preferences. In the | 
 |   // current implementation, migration is only attempted once, but saving state | 
 |   // about whether there were any errors with the migration might be useful in | 
 |   // case there are issues during the rollout and we need to add new code that | 
 |   // can try again for anyone that had errors. | 
 |   // These values are persisted to prefs. Entries should not be renumbered and | 
 |   // numeric values should never be reused. | 
 |   enum class NSSMigrationResultPref : int { | 
 |     kNotMigrated = 0, | 
 |     kMigratedSuccessfully = 1, | 
 |     kMigrationHadErrors = 2, | 
 |   }; | 
 | #endif | 
 |  | 
 |   using GetCertificatesCallback = base::OnceCallback<void( | 
 |       std::vector<net::ServerCertificateDatabase::CertInformation>)>; | 
 |  | 
 | #if BUILDFLAG(IS_CHROMEOS) | 
 |   explicit ServerCertificateDatabaseService( | 
 |       base::FilePath profile_path, | 
 |       PrefService* prefs, | 
 |       ServerCertificateDatabaseNSSMigrator::NssSlotGetter nss_slot_getter); | 
 | #else | 
 |   explicit ServerCertificateDatabaseService(base::FilePath profile_path); | 
 | #endif | 
 |  | 
 |   ServerCertificateDatabaseService(const ServerCertificateDatabaseService&) = | 
 |       delete; | 
 |   ServerCertificateDatabaseService& operator=( | 
 |       const ServerCertificateDatabaseService&) = delete; | 
 |  | 
 |   ~ServerCertificateDatabaseService() override; | 
 |  | 
 |   // Register a callback to be run every time the database is changed. | 
 |   base::CallbackListSubscription AddObserver(base::RepeatingClosure callback); | 
 |  | 
 |   // Add or update user settings with the included certificates. | 
 |   void AddOrUpdateUserCertificates( | 
 |       std::vector<net::ServerCertificateDatabase::CertInformation> cert_infos, | 
 |       base::OnceCallback<void(bool)> callback); | 
 |  | 
 |   // Read all certificates from the database. | 
 |   void GetAllCertificates(GetCertificatesCallback callback); | 
 |  | 
 |   // Run callback with `server_cert_database_`. The callback will be run on a | 
 |   // thread pool sequence where it is allowed to call methods on the database | 
 |   // object. This can be used to do multiple operations on the database without | 
 |   // repeated thread hops. | 
 |   // | 
 |   // TODO(https://crbug.com/40928765): This does NOT notify the observer if any | 
 |   // changes were made. For the current use case (only used by the NSS | 
 |   // migrator) this does not matter, but if anything else wants to use this to | 
 |   // change the database a solution would be needed. | 
 |   void PostTaskWithDatabase( | 
 |       base::OnceCallback<void(net::ServerCertificateDatabase*)> callback); | 
 |  | 
 |   void GetCertificatesCount(base::OnceCallback<void(uint32_t)> callback); | 
 |  | 
 |   void DeleteCertificate(const std::string& sha256hash_hex, | 
 |                          base::OnceCallback<void(bool)> callback); | 
 |  | 
 | #if BUILDFLAG(IS_CHROMEOS) | 
 |   static void RegisterProfilePrefs(PrefRegistrySimple* registry); | 
 |  | 
 |   static void DisableNSSCertMigrationForTesting(); | 
 | #endif | 
 |  | 
 |   base::WeakPtr<ServerCertificateDatabaseService> GetWeakPtr() { | 
 |     return weak_factory_.GetWeakPtr(); | 
 |   } | 
 |  | 
 |  private: | 
 |   void HandleModificationResult(base::OnceCallback<void(bool)> callback, | 
 |                                 bool success); | 
 |  | 
 | #if BUILDFLAG(IS_CHROMEOS) | 
 |   void NSSMigrationComplete( | 
 |       ServerCertificateDatabaseNSSMigrator::MigrationResult result); | 
 | #endif | 
 |  | 
 |   const base::FilePath profile_path_; | 
 |  | 
 |   base::SequenceBound<net::ServerCertificateDatabase> server_cert_database_; | 
 | #if BUILDFLAG(IS_CHROMEOS) | 
 |   raw_ptr<PrefService> prefs_; | 
 |   ServerCertificateDatabaseNSSMigrator::NssSlotGetter nss_slot_getter_; | 
 |   std::unique_ptr<ServerCertificateDatabaseNSSMigrator> nss_migrator_; | 
 |   std::vector<GetCertificatesCallback> get_certificates_pending_migration_; | 
 | #endif | 
 |  | 
 |   base::RepeatingClosureList observers_; | 
 |  | 
 |   base::WeakPtrFactory<ServerCertificateDatabaseService> weak_factory_{this}; | 
 | }; | 
 |  | 
 | }  // namespace net | 
 |  | 
 | #endif  // COMPONENTS_SERVER_CERTIFICATE_DATABASE_SERVER_CERTIFICATE_DATABASE_SERVICE_H_ |