| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/unexportable_keys/unexportable_key_loader.h" |
| |
| #include <memory> |
| |
| #include "base/containers/span.h" |
| #include "base/functional/bind.h" |
| #include "base/functional/callback.h" |
| #include "base/memory/ptr_util.h" |
| #include "base/memory/raw_ref.h" |
| #include "base/memory/weak_ptr.h" |
| #include "components/unexportable_keys/background_task_priority.h" |
| #include "components/unexportable_keys/service_error.h" |
| #include "components/unexportable_keys/unexportable_key_id.h" |
| #include "components/unexportable_keys/unexportable_key_service.h" |
| #include "crypto/signature_verifier.h" |
| |
| namespace unexportable_keys { |
| |
| // static |
| std::unique_ptr<UnexportableKeyLoader> |
| UnexportableKeyLoader::CreateFromWrappedKey( |
| UnexportableKeyService& unexportable_key_service, |
| base::span<const uint8_t> wrapped_key, |
| BackgroundTaskPriority priority) { |
| std::unique_ptr<UnexportableKeyLoader> loader = |
| base::WrapUnique(new UnexportableKeyLoader()); |
| loader->LoadFromWrappedKey(unexportable_key_service, wrapped_key, priority); |
| return loader; |
| } |
| |
| // static |
| std::unique_ptr<UnexportableKeyLoader> UnexportableKeyLoader::CreateWithNewKey( |
| UnexportableKeyService& unexportable_key_service, |
| base::span<const crypto::SignatureVerifier::SignatureAlgorithm> |
| acceptable_algorithms, |
| BackgroundTaskPriority priority) { |
| std::unique_ptr<UnexportableKeyLoader> loader = |
| base::WrapUnique(new UnexportableKeyLoader()); |
| loader->GenerateNewKey(unexportable_key_service, acceptable_algorithms, |
| priority); |
| return loader; |
| } |
| |
| UnexportableKeyLoader::~UnexportableKeyLoader() = default; |
| |
| void UnexportableKeyLoader::InvokeCallbackAfterKeyLoaded( |
| base::OnceCallback<void(ServiceErrorOr<UnexportableKeyId>)> callback) { |
| if (state_ == State::kReady) { |
| // The key is ready, we can invoke the callback immediately. |
| std::move(callback).Run(key_id_or_error_); |
| return; |
| } |
| CHECK_EQ(state_, State::kLoading); |
| on_load_callbacks_.push_back(std::move(callback)); |
| } |
| |
| ServiceErrorOr<UnexportableKeyId> |
| UnexportableKeyLoader::GetKeyIdOrErrorForTesting() { |
| return key_id_or_error_; |
| } |
| |
| UnexportableKeyLoader::State UnexportableKeyLoader::GetStateForTesting() { |
| return state_; |
| } |
| |
| UnexportableKeyLoader::UnexportableKeyLoader() = default; |
| |
| void UnexportableKeyLoader::LoadFromWrappedKey( |
| UnexportableKeyService& unexportable_key_service, |
| base::span<const uint8_t> wrapped_key, |
| BackgroundTaskPriority priority) { |
| CHECK_EQ(state_, State::kNotStarted); |
| state_ = State::kLoading; |
| unexportable_key_service.FromWrappedSigningKeySlowlyAsync( |
| wrapped_key, priority, |
| base::BindOnce(&UnexportableKeyLoader::OnKeyLoaded, |
| weak_ptr_factory_.GetWeakPtr())); |
| } |
| void UnexportableKeyLoader::GenerateNewKey( |
| UnexportableKeyService& unexportable_key_service, |
| base::span<const crypto::SignatureVerifier::SignatureAlgorithm> |
| acceptable_algorithms, |
| BackgroundTaskPriority priority) { |
| CHECK_EQ(state_, State::kNotStarted); |
| state_ = State::kLoading; |
| unexportable_key_service.GenerateSigningKeySlowlyAsync( |
| acceptable_algorithms, priority, |
| base::BindOnce(&UnexportableKeyLoader::OnKeyLoaded, |
| weak_ptr_factory_.GetWeakPtr())); |
| } |
| |
| void UnexportableKeyLoader::OnKeyLoaded( |
| ServiceErrorOr<UnexportableKeyId> key_id_or_error) { |
| CHECK_EQ(state_, State::kLoading); |
| state_ = State::kReady; |
| key_id_or_error_ = key_id_or_error; |
| |
| std::vector<base::OnceCallback<void(ServiceErrorOr<UnexportableKeyId>)>> |
| callbacks; |
| callbacks.swap(on_load_callbacks_); |
| for (auto& callback : callbacks) { |
| std::move(callback).Run(key_id_or_error_); |
| } |
| } |
| |
| } // namespace unexportable_keys |