| // Copyright 2020 The Chromium Authors. All rights reserved. |
| // 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 "base/callback.h" |
| #include "base/containers/flat_map.h" |
| #include "base/containers/flat_set.h" |
| #include "base/memory/weak_ptr.h" |
| #include "chrome/browser/ash/cert_provisioning/cert_provisioning_common.h" |
| #include "third_party/abseil-cpp/absl/types/optional.h" |
| // TODO(https://crbug.com/1164001): forward declare PlatformKeysService |
| // after //chrom/browser/chromeos/platform_keys is moved to ash. |
| #include "chrome/browser/chromeos/platform_keys/platform_keys_service.h" |
| #include "net/cert/x509_certificate.h" |
| |
| namespace ash { |
| 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, |
| const absl::optional<std::string>& attr_value, |
| chromeos::platform_keys::Status status); |
| void StopIteration(chromeos::platform_keys::Status status); |
| |
| const CertScope cert_scope_ = CertScope::kDevice; |
| platform_keys::PlatformKeysService* const 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; |
| platform_keys::PlatformKeysService* const 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_ |