File: unexportable_key_service.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (132 lines) | stat: -rw-r--r-- 5,999 bytes parent folder | download | duplicates (5)
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_