blob: 48166c175875051761e4583dcc031446a25df164 [file] [log] [blame]
// 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 "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);
#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_