1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
// 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_
|