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 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
|
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_ASH_CERT_PROVISIONING_CERT_PROVISIONING_PLATFORM_KEYS_HELPERS_H_
#define CHROME_BROWSER_ASH_CERT_PROVISIONING_CERT_PROVISIONING_PLATFORM_KEYS_HELPERS_H_
#include <optional>
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/ash/cert_provisioning/cert_provisioning_common.h"
#include "net/cert/x509_certificate.h"
namespace ash {
namespace platform_keys {
class PlatformKeysService;
}
namespace cert_provisioning {
// ========= CertIterator ======================================================
using CertIteratorForEachCallback =
base::RepeatingCallback<void(scoped_refptr<net::X509Certificate> cert,
const CertProfileId& cert_profile_id,
chromeos::platform_keys::Status status)>;
using CertIteratorOnFinishedCallback =
base::OnceCallback<void(chromeos::platform_keys::Status status)>;
// Iterates over all existing certificates of a given |cert_scope| and combines
// them with their certificate provisioning ids when possible. Runs |callback|
// on every (cert, cert_profile_id) pair that had a present and non-empty
// |cert_profile_id|. If |error_message| is not empty, then the pair is not
// valid.
class CertIterator {
public:
CertIterator(CertScope cert_scope,
platform_keys::PlatformKeysService* platform_keys_service);
CertIterator(const CertIterator&) = delete;
CertIterator& operator=(const CertIterator&) = delete;
~CertIterator();
// Can be called more than once. If previous iteration is not finished, it
// will be canceled.
void IterateAll(CertIteratorForEachCallback for_each_callback,
CertIteratorOnFinishedCallback on_finished_callback);
void Cancel();
private:
void OnGetCertificatesDone(
std::unique_ptr<net::CertificateList> existing_certs,
chromeos::platform_keys::Status status);
void OnGetAttributeForKeyDone(scoped_refptr<net::X509Certificate> cert,
std::optional<std::vector<uint8_t>> attr_value,
chromeos::platform_keys::Status status);
void StopIteration(chromeos::platform_keys::Status status);
const CertScope cert_scope_ = CertScope::kDevice;
const raw_ptr<platform_keys::PlatformKeysService> platform_keys_service_ =
nullptr;
size_t wait_counter_ = 0;
CertIteratorForEachCallback for_each_callback_;
CertIteratorOnFinishedCallback on_finished_callback_;
SEQUENCE_CHECKER(sequence_checker_);
base::WeakPtrFactory<CertIterator> weak_factory_{this};
};
// ========= LatestCertsWithIdsGetter ==========================================
using LatestCertsWithIdsGetterCallback = base::OnceCallback<void(
base::flat_map<CertProfileId, scoped_refptr<net::X509Certificate>>
certs_with_ids,
chromeos::platform_keys::Status status)>;
// Collects map of certificates with their certificate provisioning ids and
// returns it via |callback|. If there are several certificates for the same id,
// only the newest one will be stored in the map. Only one call to
// GetCertsWithIds() for one instance is allowed.
class LatestCertsWithIdsGetter {
public:
LatestCertsWithIdsGetter(
CertScope cert_scope,
platform_keys::PlatformKeysService* platform_keys_service);
LatestCertsWithIdsGetter(const LatestCertsWithIdsGetter&) = delete;
LatestCertsWithIdsGetter& operator=(const LatestCertsWithIdsGetter&) = delete;
~LatestCertsWithIdsGetter();
// Can be called more than once. If previous task is not finished, it will be
// canceled.
void GetCertsWithIds(LatestCertsWithIdsGetterCallback callback);
bool IsRunning() const;
void Cancel();
private:
void ProcessOneCert(scoped_refptr<net::X509Certificate> new_cert,
const CertProfileId& cert_profile_id,
chromeos::platform_keys::Status status);
void OnIterationFinished(chromeos::platform_keys::Status status);
CertIterator iterator_;
// Accumulates results that will be returned at the end via |callback_|.
base::flat_map<CertProfileId, scoped_refptr<net::X509Certificate>>
certs_with_ids_;
LatestCertsWithIdsGetterCallback callback_;
SEQUENCE_CHECKER(sequence_checker_);
base::WeakPtrFactory<LatestCertsWithIdsGetter> weak_factory_{this};
};
// ========= CertDeleter =======================================================
using CertDeleterCallback =
base::OnceCallback<void(chromeos::platform_keys::Status status)>;
// Finds and deletes certificates that 1) have ids that are not in
// |cert_profile_ids_to_keep| set or 2) have another certificate for the same
// id with later expiration date. Only one call to DeleteCerts() for one
// instance is allowed.
class CertDeleter {
public:
CertDeleter(CertScope cert_scope,
platform_keys::PlatformKeysService* platform_keys_service);
CertDeleter(const CertDeleter&) = delete;
CertDeleter& operator=(const CertDeleter&) = delete;
~CertDeleter();
void Cancel();
// Can be called more than once. If previous task is not finished, it will be
// canceled.
void DeleteCerts(base::flat_set<CertProfileId> cert_profile_ids_to_keep,
CertDeleterCallback callback);
private:
void ProcessOneCert(scoped_refptr<net::X509Certificate> cert,
const CertProfileId& cert_profile_id,
chromeos::platform_keys::Status status);
void RememberOrDelete(scoped_refptr<net::X509Certificate> new_cert,
const CertProfileId& cert_profile_id);
void DeleteCert(scoped_refptr<net::X509Certificate> cert);
void OnDeleteCertDone(chromeos::platform_keys::Status status);
void OnIterationFinished(chromeos::platform_keys::Status status);
void CheckStateAndMaybeFinish();
void ReturnStatus(chromeos::platform_keys::Status status);
const CertScope cert_scope_ = CertScope::kDevice;
const raw_ptr<platform_keys::PlatformKeysService> platform_keys_service_ =
nullptr;
CertIterator iterator_;
bool iteration_finished_ = false;
size_t pending_delete_tasks_counter_ = 0;
CertDeleterCallback callback_;
// Contains list of currently existing certificate profile ids. Certificates
// with ids outside of this set can be deleted.
base::flat_set<CertProfileId> cert_profile_ids_to_keep_;
// Stores previously seen certificates that allows to find duplicates.
base::flat_map<CertProfileId, scoped_refptr<net::X509Certificate>>
certs_with_ids_;
SEQUENCE_CHECKER(sequence_checker_);
base::WeakPtrFactory<CertDeleter> weak_factory_{this};
};
} // namespace cert_provisioning
} // namespace ash
#endif // CHROME_BROWSER_ASH_CERT_PROVISIONING_CERT_PROVISIONING_PLATFORM_KEYS_HELPERS_H_
|