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
|
// 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. In case of a failure,
// the task might be retried up to `max_retries` times.
// 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()`
// TODO(crbug.com/405408610): remove `max_retries` parameter once all callers
// adopt the retry logic.
virtual 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) = 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_
|