blob: 756cd85589da0a59901b495e971707b4ee055e96 [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_H_
#define COMPONENTS_UNEXPORTABLE_KEYS_UNEXPORTABLE_KEY_SERVICE_H_
#include "base/component_export.h"
#include "base/containers/span.h"
#include "base/functional/callback_forward.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 "crypto/signature_verifier.h"
namespace unexportable_keys {
// Service providing access to `UnexportableSigningKey`s.
//
// The service doesn't give clients direct access to the keys. Instead,
// `UnexportableKeyService` returns a key handle, `UnexportableKeyId`, that can
// be passed back to the service to perform operations with the key.
//
// To use the same key across several sessions, a client should perform the
// following steps:
//
// 1. Generate a new `UnexportableSigningKey` and obtain its key ID:
//
// UnexportableKeyService& service = GetUnexportableKeyService();
// ServiceErrorOr<UnexportableKeyId> key_id;
// service.GenerateSigningKeySlowlyAsync(
// kAlgorithm, kPriority, [&key_id](auto result) { key_id = result; });
//
// 2. Get a wrapped key for this key and save it to disk:
//
// std::vector<uint8_t> wrapped_key = service.GetWrappedKey(*key_id);
// SaveToDisk(wrapped_key);
//
// 3. After the process restart, restore the same `UnexportableSigningKey` from
// the wrapped key:
//
// UnexportableKeyService& service = GetUnexportableKeyService();
// ServiceErrorOr<UnexportableKeyId> key_id;
// std::vector<uint8_t> wrapped_key = ReadFromDisk();
// service.FromWrappedSigningKeySlowlyAsync(
// wrapped_key, kPriority, [&key_id](auto result) { key_id = result; });
//
// 4. Use obtained key ID to sign data:
//
// service.SignSlowlyAsync(*key_id, kData, kPriority, std::move(callback));
class COMPONENT_EXPORT(UNEXPORTABLE_KEYS) UnexportableKeyService {
public:
UnexportableKeyService() = default;
UnexportableKeyService(const UnexportableKeyService&) = delete;
UnexportableKeyService& operator=(const UnexportableKeyService&) = delete;
virtual ~UnexportableKeyService() = default;
// Generates a new signing key asynchronously and returns an ID of this key.
// Returned `UnexportableKeyId` can be used later to perform key operations on
// this `UnexportableKeyService`.
// The first supported value of `acceptable_algorithms` determines the type of
// the key.
// Invokes `callback` with a `ServiceError` if no supported hardware exists,
// if no value in `acceptable_algorithms` is supported, or if there was an
// error creating the key.
virtual void GenerateSigningKeySlowlyAsync(
base::span<const crypto::SignatureVerifier::SignatureAlgorithm>
acceptable_algorithms,
BackgroundTaskPriority priority,
base::OnceCallback<void(ServiceErrorOr<UnexportableKeyId>)> callback) = 0;
// Creates a new signing key from a `wrapped_key` asynchronously and returns
// an ID of this key.
// Returned `UnexportableKeyId` can be used later to perform key operations on
// this `UnexportableKeyService`.
// `wrapped_key` can be read from disk but must have initially resulted from
// calling `GetWrappedKey()` on a previous instance of `UnexportableKeyId`.
// Invokes `callback` with a `ServiceError` if `wrapped_key` cannot be
// imported.
virtual void FromWrappedSigningKeySlowlyAsync(
base::span<const uint8_t> wrapped_key,
BackgroundTaskPriority priority,
base::OnceCallback<void(ServiceErrorOr<UnexportableKeyId>)> callback) = 0;
// Schedules a new asynchronous signing task.
// Might return a cached result if a task with the same combination of
// `signing_key` and `data` has been completed recently.
// Invokes `callback` with a signature of `data`, or a `ServiceError` if
// `key_id` is/ not found or an error occurs during signing.
// `key_id` must have resulted from calling `GenerateSigningKeySlowlyAsync()`
// or `FromWrappedSigningKeySlowlyAsync()`
virtual void SignSlowlyAsync(
const UnexportableKeyId& key_id,
base::span<const uint8_t> data,
BackgroundTaskPriority priority,
base::OnceCallback<void(ServiceErrorOr<std::vector<uint8_t>>)>
callback) = 0;
// Returns an SPKI that contains the public key of a key that `key_id` refers
// to.
// Returns a `ServiceError` if `key_id` is not found.
// `key_id` must have resulted from calling `GenerateSigningKeySlowlyAsync()`
// or `FromWrappedSigningKeySlowlyAsync()`
virtual ServiceErrorOr<std::vector<uint8_t>> GetSubjectPublicKeyInfo(
UnexportableKeyId key_id) const = 0;
// Returns the encrypted private key of a key that `key_id` refers to. It is
// encrypted to a key that is kept in hardware and the unencrypted private key
// never exists in the CPU's memory.
// Returns a `ServiceError` if `key_id` is not found.
// `key_id` must have resulted from calling `GenerateSigningKeySlowlyAsync()`
// or `FromWrappedSigningKeySlowlyAsync()`
virtual ServiceErrorOr<std::vector<uint8_t>> GetWrappedKey(
UnexportableKeyId key_id) const = 0;
// Returns the algorithm of a key that `key_id` refers to.
// Returns a `ServiceError` if `key_id` is not found.
// `key_id` must have resulted from calling `GenerateSigningKeySlowlyAsync()`
// or `FromWrappedSigningKeySlowlyAsync()`
virtual ServiceErrorOr<crypto::SignatureVerifier::SignatureAlgorithm>
GetAlgorithm(UnexportableKeyId key_id) const = 0;
};
} // namespace unexportable_keys
#endif // COMPONENTS_UNEXPORTABLE_KEYS_UNEXPORTABLE_KEY_SERVICE_H_