blob: 530950c08db4b18b26b9bccb3701584decd26507 [file] [log] [blame]
// 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.
#ifndef COMPONENTS_UNEXPORTABLE_KEYS_UNEXPORTABLE_KEY_SERVICE_IMPL_H_
#define COMPONENTS_UNEXPORTABLE_KEYS_UNEXPORTABLE_KEY_SERVICE_IMPL_H_
#include <algorithm>
#include <map>
#include "base/containers/span.h"
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ref.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "components/unexportable_keys/background_task_priority.h"
#include "components/unexportable_keys/ref_counted_unexportable_signing_key.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"
#include "crypto/unexportable_key.h"
namespace unexportable_keys {
class MaybePendingUnexportableKeyId;
class UnexportableKeyTaskManager;
class COMPONENT_EXPORT(UNEXPORTABLE_KEYS) UnexportableKeyServiceImpl
: public UnexportableKeyService {
public:
// `task_manager` must outlive `UnexportableKeyServiceImpl`.
explicit UnexportableKeyServiceImpl(UnexportableKeyTaskManager& task_manager);
~UnexportableKeyServiceImpl() override;
// Returns whether the current platform has a support for unexportable signing
// keys. If this returns false, all service methods will return
// `ServiceError::kNoKeyProvider`.
static bool IsUnexportableKeyProviderSupported(
crypto::UnexportableKeyProvider::Config config);
// UnexportableKeyService:
void GenerateSigningKeySlowlyAsync(
base::span<const crypto::SignatureVerifier::SignatureAlgorithm>
acceptable_algorithms,
BackgroundTaskPriority priority,
base::OnceCallback<void(ServiceErrorOr<UnexportableKeyId>)> callback)
override;
void FromWrappedSigningKeySlowlyAsync(
base::span<const uint8_t> wrapped_key,
BackgroundTaskPriority priority,
base::OnceCallback<void(ServiceErrorOr<UnexportableKeyId>)> callback)
override;
void SignSlowlyAsync(
const UnexportableKeyId& key_id,
base::span<const uint8_t> data,
BackgroundTaskPriority priority,
size_t max_retries,
base::OnceCallback<void(ServiceErrorOr<std::vector<uint8_t>>)> callback)
override;
ServiceErrorOr<std::vector<uint8_t>> GetSubjectPublicKeyInfo(
UnexportableKeyId key_id) const override;
ServiceErrorOr<std::vector<uint8_t>> GetWrappedKey(
UnexportableKeyId key_id) const override;
ServiceErrorOr<crypto::SignatureVerifier::SignatureAlgorithm> GetAlgorithm(
UnexportableKeyId key_id) const override;
private:
// Comparator object that allows comparing containers of different types that
// are convertible to base::span<const uint8_t>.
struct WrappedKeyCmp {
using is_transparent = void;
bool operator()(base::span<const uint8_t> lhs,
base::span<const uint8_t> rhs) const {
return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(),
rhs.end());
}
};
using WrappedKeyMap = std::
map<std::vector<uint8_t>, MaybePendingUnexportableKeyId, WrappedKeyCmp>;
using KeyIdMap = std::map<UnexportableKeyId,
scoped_refptr<RefCountedUnexportableSigningKey>>;
// Callback for `GenerateSigningKeySlowlyAsync()`.
void OnKeyGenerated(
base::OnceCallback<void(ServiceErrorOr<UnexportableKeyId>)>
client_callback,
ServiceErrorOr<scoped_refptr<RefCountedUnexportableSigningKey>>
key_or_error);
// Callback for `FromWrappedSigningKeySlowlyAsync()`.
void OnKeyCreatedFromWrappedKey(
WrappedKeyMap::iterator pending_entry_it,
ServiceErrorOr<scoped_refptr<RefCountedUnexportableSigningKey>>
key_or_error);
const raw_ref<UnexportableKeyTaskManager, DanglingUntriaged> task_manager_;
// Helps mapping multiple `FromWrappedSigningKeySlowlyAsync()` requests with
// the same wrapped key into the same key ID.
WrappedKeyMap key_id_by_wrapped_key_;
// Stores unexportable signing keys that were created during the current
// session.
KeyIdMap key_by_key_id_;
base::WeakPtrFactory<UnexportableKeyServiceImpl> weak_ptr_factory_{this};
};
} // namespace unexportable_keys
#endif // COMPONENTS_UNEXPORTABLE_KEYS_UNEXPORTABLE_KEY_SERVICE_IMPL_H_