File: high_level_chaps_client.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (261 lines) | stat: -rw-r--r-- 11,714 bytes parent folder | download | duplicates (7)
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#ifndef CHROMEOS_ASH_COMPONENTS_KCER_CHAPS_HIGH_LEVEL_CHAPS_CLIENT_H_
#define CHROMEOS_ASH_COMPONENTS_KCER_CHAPS_HIGH_LEVEL_CHAPS_CLIENT_H_

#include <stdint.h>

#include <vector>

#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/sequence_checker.h"
#include "chromeos/ash/components/kcer/attributes.pb.h"
#include "chromeos/ash/components/kcer/chaps/session_chaps_client.h"
#include "chromeos/constants/pkcs11_definitions.h"
#include "third_party/cros_system_api/constants/pkcs11_custom_attributes.h"
#include "third_party/cros_system_api/dbus/chaps/dbus-constants.h"

namespace kcer {

// Adds an attribute with the given `type` to `attr_list` and sets the value to
// `data`.
COMPONENT_EXPORT(KCER)
void AddAttribute(chaps::AttributeList& attr_list,
                  chromeos::PKCS11_CK_ATTRIBUTE_TYPE type,
                  base::span<const uint8_t> data);

// Reinterprets the `value` as a sequence of bytes and returns it as a span.
// `T` must be a simple type, i.e. no internal pointers, etc.
// `value` must outlive the returned span.
template <typename T>
COMPONENT_EXPORT(KCER)
base::span<const uint8_t> MakeSpan(T* value) {
  static_assert(std::is_integral_v<T>);
  return base::as_bytes(base::span<T>(value, /*count=*/1u));
}

// The main class to communicate with Chaps. Further simplifies the D-Bus
// protocol (on top of SessionChapsClient):
// * Uses more friendly types for arguments.
// * Tries to guess attribute sizes for GetAttributeValue and handles the
// retrieval of the actual sizes when needed.
// * Adds additional convenience methods.
// If any of the methods fail with a session error (see
// SessionChapsClient::IsSessionError), all ObjectHandle-s become obsolete and
// should be immediately discarded (Chaps could still accept them, but they
// might start referring to different objects).
class HighLevelChapsClient {
 public:
  using GetAttributeValueCallback =
      base::OnceCallback<void(chaps::AttributeList attributes,
                              uint32_t result_code)>;

  // A list of all attributes supported by the GetAttributeValue,
  // SetAttributeValue methods, can be expanded as needed. It's allowed to cast
  // from AttributeId to uint32_t.
  enum class AttributeId : uint32_t {
    kModulus = chromeos::PKCS11_CKA_MODULUS,
    kPublicExponent = chromeos::PKCS11_CKA_PUBLIC_EXPONENT,
    kEcPoint = chromeos::PKCS11_CKA_EC_POINT,
    kPkcs11Id = chromeos::PKCS11_CKA_ID,
    kLabel = chromeos::PKCS11_CKA_LABEL,
    kKeyType = chromeos::PKCS11_CKA_KEY_TYPE,
    kValue = chromeos::PKCS11_CKA_VALUE,
    // Stored on the private key.
    kKeyInSoftware = chaps::kKeyInSoftwareAttribute,
    kKeyPermissions = pkcs11_custom_attributes::kCkaChromeOsKeyPermissions,
    kCertProvisioningId =
        pkcs11_custom_attributes::kCkaChromeOsBuiltinProvisioningProfileId,
  };

  HighLevelChapsClient() = default;
  virtual ~HighLevelChapsClient() = default;

  // PKCS #11 v2.20 section 11.5 page 111.
  virtual void GetMechanismList(
      SessionChapsClient::SlotId slot_id,
      SessionChapsClient::GetMechanismListCallback callback) = 0;
  // Similar to PKCS #11 v2.20 section 11.7 page 128.
  virtual void CreateObject(
      SessionChapsClient::SlotId slot_id,
      const chaps::AttributeList& attributes,
      SessionChapsClient::CreateObjectCallback callback) = 0;
  // Similar to PKCS #11 v2.20 section 11.7 page 131.
  virtual void DestroyObject(
      SessionChapsClient::SlotId slot_id,
      SessionChapsClient::ObjectHandle object_handle,
      SessionChapsClient::DestroyObjectCallback callback) = 0;
  // Similar to DestroyObject, but handles multiple objects at once and retries
  // the deletion on failure.
  virtual void DestroyObjectsWithRetries(
      SessionChapsClient::SlotId slot_id,
      std::vector<SessionChapsClient::ObjectHandle> object_handles,
      SessionChapsClient::DestroyObjectCallback callback) = 0;
  // Similar to PKCS #11 v2.20 section 11.7 page 133.
  // Tries to guess attribute sizes and when Chaps replies that the guessed size
  // is too small, queries the exact size and retries with it. If
  // CKR_ATTRIBUTE_SENSITIVE or CKR_ATTRIBUTE_TYPE_INVALID error is returned,
  // one or more attributes is not retrieved. If more than one attribute was
  // not retrieved, it's impossible to deduce whether the attribute is actually
  // there and available and just the guessed size was too small (especially
  // relevant for string attributes).
  virtual void GetAttributeValue(
      SessionChapsClient::SlotId slot_id,
      SessionChapsClient::ObjectHandle object_handle,
      std::vector<AttributeId> attribute_ids,
      HighLevelChapsClient::GetAttributeValueCallback callback) = 0;
  // Similar to PKCS #11 v2.20 section 11.7 page 135.
  virtual void SetAttributeValue(
      SessionChapsClient::SlotId slot_id,
      SessionChapsClient::ObjectHandle object_handle,
      const chaps::AttributeList& attributes,
      SessionChapsClient::SetAttributeValueCallback callback) = 0;
  // Same as SetAttributeValue above, but sets attributes on multiple objects at
  // once.
  virtual void SetAttributeValue(
      SessionChapsClient::SlotId slot_id,
      std::vector<SessionChapsClient::ObjectHandle> object_handles,
      const chaps::AttributeList& attributes,
      SessionChapsClient::SetAttributeValueCallback callback) = 0;
  // Combines FindObjects* methods, PKCS #11 v2.20 section 11.7 page 136-138.
  virtual void FindObjects(
      SessionChapsClient::SlotId slot_id,
      const chaps::AttributeList& attributes,
      SessionChapsClient::FindObjectsCallback callback) = 0;
  // Combines SignInit and Sign, PKCS #11 v2.20 section 11.7 page 152-153.
  // `mechanism_parameter` is the bytes of a struct containing the parameter.
  // RSA-PKCS1 and ECDSA mechanisms don't take any parameters, for RSA_PSS see
  // chromeos::PKCS11_CK_RSA_PKCS_PSS_PARAMS struct.
  virtual void Sign(SessionChapsClient::SlotId slot_id,
                    uint64_t mechanism_type,
                    const std::vector<uint8_t>& mechanism_parameter,
                    SessionChapsClient::ObjectHandle key_handle,
                    std::vector<uint8_t> data,
                    SessionChapsClient::SignCallback callback) = 0;
  // Similar to PKCS #11 v2.20 section 11.7 page 135.
  virtual void GenerateKeyPair(
      SessionChapsClient::SlotId slot_id,
      uint64_t mechanism_type,
      const std::vector<uint8_t>& mechanism_parameter,
      const chaps::AttributeList& public_key_attributes,
      const chaps::AttributeList& private_key_attributes,
      SessionChapsClient::GenerateKeyPairCallback callback) = 0;
};

// Exported for unit tests and KcerFactory only.
class COMPONENT_EXPORT(KCER) HighLevelChapsClientImpl
    : public HighLevelChapsClient {
 public:
  explicit HighLevelChapsClientImpl(SessionChapsClient* session_chaps_client);
  ~HighLevelChapsClientImpl() override;

  // Implements HighLevelChapsClient.
  void GetMechanismList(
      SessionChapsClient::SlotId slot_id,
      SessionChapsClient::GetMechanismListCallback callback) override;
  void CreateObject(SessionChapsClient::SlotId slot_id,
                    const chaps::AttributeList& attributes,
                    SessionChapsClient::CreateObjectCallback callback) override;
  void DestroyObject(
      SessionChapsClient::SlotId slot_id,
      SessionChapsClient::ObjectHandle object_handle,
      SessionChapsClient::DestroyObjectCallback callback) override;
  void DestroyObjectsWithRetries(
      SessionChapsClient::SlotId slot_id,
      std::vector<SessionChapsClient::ObjectHandle> object_handles,
      SessionChapsClient::DestroyObjectCallback callback) override;
  void GetAttributeValue(
      SessionChapsClient::SlotId slot_id,
      SessionChapsClient::ObjectHandle object_handle,
      std::vector<AttributeId> attribute_ids,
      HighLevelChapsClient::GetAttributeValueCallback callback) override;
  void SetAttributeValue(
      SessionChapsClient::SlotId slot_id,
      SessionChapsClient::ObjectHandle object_handle,
      const chaps::AttributeList& attributes,
      SessionChapsClient::SetAttributeValueCallback callback) override;
  void SetAttributeValue(
      SessionChapsClient::SlotId slot_id,
      std::vector<SessionChapsClient::ObjectHandle> object_handles,
      const chaps::AttributeList& attributes,
      SessionChapsClient::SetAttributeValueCallback callback) override;
  void FindObjects(SessionChapsClient::SlotId slot_id,
                   const chaps::AttributeList& attributes,
                   SessionChapsClient::FindObjectsCallback callback) override;
  void Sign(SessionChapsClient::SlotId slot_id,
            uint64_t mechanism_type,
            const std::vector<uint8_t>& mechanism_parameter,
            SessionChapsClient::ObjectHandle key_handle,
            std::vector<uint8_t> data,
            SessionChapsClient::SignCallback callback) override;
  void GenerateKeyPair(
      SessionChapsClient::SlotId slot_id,
      uint64_t mechanism_type,
      const std::vector<uint8_t>& mechanism_parameter,
      const chaps::AttributeList& public_key_attributes,
      const chaps::AttributeList& private_key_attributes,
      SessionChapsClient::GenerateKeyPairCallback callback) override;

  void SetSessionChapsClientForTesting(
      SessionChapsClient* session_chaps_client);

 private:
  void DestroyObjectsWithRetriesImpl(
      SessionChapsClient::SlotId slot_id,
      std::vector<SessionChapsClient::ObjectHandle> object_handles,
      std::vector<SessionChapsClient::ObjectHandle> failed_handles,
      uint32_t last_error,
      int retries_left,
      SessionChapsClient::DestroyObjectCallback callback);
  void DestroyObjectsWithRetriesHandleOneResult(
      SessionChapsClient::SlotId slot_id,
      std::vector<SessionChapsClient::ObjectHandle> object_handles,
      std::vector<SessionChapsClient::ObjectHandle> failed_handles,
      uint32_t last_error,
      int retries_left,
      SessionChapsClient::DestroyObjectCallback callback,
      uint32_t result_code);
  void DidGetAttributeValue(
      SessionChapsClient::SlotId slot_id,
      SessionChapsClient::ObjectHandle object_handle,
      HighLevelChapsClient::GetAttributeValueCallback callback,
      std::vector<uint8_t> attributes,
      uint32_t result_code);
  void DidGetAttributeLength(
      SessionChapsClient::SlotId slot_id,
      SessionChapsClient::ObjectHandle object_handle,
      HighLevelChapsClient::GetAttributeValueCallback callback,
      std::vector<uint8_t> attributes,
      uint32_t result_code);
  void DidGetAttributeValueWithLength(
      SessionChapsClient::SlotId slot_id,
      SessionChapsClient::ObjectHandle object_handle,
      HighLevelChapsClient::GetAttributeValueCallback callback,
      std::vector<uint8_t> attributes,
      uint32_t result_code);

  void SetAttributeValueImpl(
      SessionChapsClient::SlotId slot_id,
      std::vector<SessionChapsClient::ObjectHandle> object_handles,
      const chaps::AttributeList& attributes,
      SessionChapsClient::SetAttributeValueCallback callback,
      uint32_t last_error,
      uint32_t new_result_code);

  SEQUENCE_CHECKER(sequence_checker_);

  const raw_ptr<SessionChapsClient> session_chaps_client_;
  base::WeakPtrFactory<HighLevelChapsClientImpl> weak_factory_{this};
};

}  // namespace kcer

#endif  // CHROMEOS_ASH_COMPONENTS_KCER_CHAPS_HIGH_LEVEL_CHAPS_CLIENT_H_