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
|
// 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.
#ifndef CHROMEOS_ASH_COMPONENTS_KCER_CHAPS_SESSION_CHAPS_CLIENT_H_
#define CHROMEOS_ASH_COMPONENTS_KCER_CHAPS_SESSION_CHAPS_CLIENT_H_
#include <stdint.h>
#include <vector>
#include "base/containers/flat_map.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "base/types/strong_alias.h"
#include "chromeos/ash/components/dbus/chaps/chaps_client.h"
#include "chromeos/ash/components/kcer/attributes.pb.h"
namespace kcer {
// Opens PKCS#11 sessions that are required for most requests to Chaps. Opens a
// new session when there's none for the required slot at the beginning of each
// public method. `attempts_left` determines how many attempts the method has
// for opening a session. On failing to open a session the method will return
// `chaps::kFailedToOpenSessionError`. If there was an open session at the
// beginning of the method, but it got closed, one of the
// PKCS11_CKR_SESSION_HANDLE_INVALID, PKCS11_CKR_SESSION_CLOSED errors will be
// returned and the caller is expected to discard all cached object handles and
// try again (potentially repeating some earlier requests).
// Exported for unit tests and KcerFactory only.
class COMPONENT_EXPORT(KCER) SessionChapsClient {
public:
// Strong alias for some types to prevent incorrect cross-assignment.
using SlotId = base::StrongAlias<class TypeTagSlotId, uint64_t>;
using SessionId = base::StrongAlias<class TypeTagSessionId, uint64_t>;
using ObjectHandle = base::StrongAlias<class TypeTagObjectHandle, uint64_t>;
using GetMechanismListCallback =
base::OnceCallback<void(const std::vector<uint64_t>& mechanism_list,
uint32_t result_code)>;
using CreateObjectCallback =
base::OnceCallback<void(ObjectHandle object_handle,
uint32_t result_code)>;
using DestroyObjectCallback = base::OnceCallback<void(uint32_t result_code)>;
using GetAttributeValueCallback =
base::OnceCallback<void(std::vector<uint8_t> attributes,
uint32_t result_code)>;
using SetAttributeValueCallback =
base::OnceCallback<void(uint32_t result_code)>;
using FindObjectsCallback =
base::OnceCallback<void(std::vector<ObjectHandle> object_list,
uint32_t result_code)>;
using SignCallback = base::OnceCallback<void(std::vector<uint8_t> signature,
uint32_t result_code)>;
using GenerateKeyPairCallback =
base::OnceCallback<void(ObjectHandle public_key_handle,
ObjectHandle private_key_handle,
uint32_t result_code)>;
SessionChapsClient();
virtual ~SessionChapsClient();
// Returns true if the `result_code` contains an error related to
// problems with PKCS#11 session, i.e. if the session cannot be used
// anymore. In most cases it means that all existing ObjectHandler-s
// should be discarded and the operation should be retried.
static bool IsSessionError(uint32_t result_code);
// A convenience method for serializing `chaps::AttributeList`.
static std::vector<uint8_t> SerializeToBytes(
const chaps::AttributeList& attr_list);
// PKCS #11 v2.20 section 11.5 page 111.
virtual void GetMechanismList(SlotId slot_id,
GetMechanismListCallback callback) = 0;
// PKCS #11 v2.20 section 11.7 page 128.
virtual void CreateObject(SlotId slot_id,
// Serialized chaps::AttributeList.
const std::vector<uint8_t>& attributes,
int attempts_left,
CreateObjectCallback callback) = 0;
// PKCS #11 v2.20 section 11.7 page 131.
virtual void DestroyObject(SlotId slot_id,
ObjectHandle object_handle,
int attempts_left,
DestroyObjectCallback callback) = 0;
// PKCS #11 v2.20 section 11.7 page 133.
virtual void GetAttributeValue(SlotId slot_id,
ObjectHandle object_handle,
// Serialized chaps::AttributeList.
std::vector<uint8_t> attributes_query,
int attempts_left,
GetAttributeValueCallback callback) = 0;
// PKCS #11 v2.20 section 11.7 page 135.
virtual void SetAttributeValue(SlotId slot_id,
ObjectHandle object_handle,
// Serialized chaps::AttributeList.
std::vector<uint8_t> attributes,
int attempts_left,
SetAttributeValueCallback callback) = 0;
// Combines FindObjects* methods, PKCS #11 v2.20 section 11.7 page
// 136-138. Can return up to the `kFindObjectsMaxCount` object handles.
virtual void FindObjects(SlotId slot_id,
// Serialized chaps::AttributeList.
std::vector<uint8_t> attributes,
int attempts_left,
FindObjectsCallback callback) = 0;
// Combines SignInit and Sign, PKCS #11 v2.20 section 11.7 page 152-153.
virtual void Sign(SlotId slot_id,
uint64_t mechanism_type,
std::vector<uint8_t> mechanism_parameter,
ObjectHandle key_handle,
std::vector<uint8_t> data,
int attempts_left,
SignCallback callback) = 0;
// PKCS #11 v2.20 section 11.14 page 176.
virtual void GenerateKeyPair(SlotId slot_id,
uint64_t mechanism_type,
// Serialized chaps::AttributeList-s.
std::vector<uint8_t> mechanism_parameter,
std::vector<uint8_t> public_key_attributes,
std::vector<uint8_t> private_key_attributes,
int attempts_left,
GenerateKeyPairCallback callback) = 0;
};
// Exported for unit tests and KcerFactory only.
class COMPONENT_EXPORT(KCER) SessionChapsClientImpl
: public SessionChapsClient {
public:
explicit SessionChapsClientImpl();
~SessionChapsClientImpl() override;
// Implements SessionChapsClient.
void GetMechanismList(SlotId slot_id,
GetMechanismListCallback callback) override;
void CreateObject(SlotId slot_id,
const std::vector<uint8_t>& attributes,
int attempts_left,
CreateObjectCallback callback) override;
void DestroyObject(SlotId slot_id,
ObjectHandle object_handle,
int attempts_left,
DestroyObjectCallback callback) override;
void GetAttributeValue(SlotId slot_id,
ObjectHandle object_handle,
// Serialized chaps::AttributeList.
std::vector<uint8_t> attributes_query,
int attempts_left,
GetAttributeValueCallback callback) override;
void SetAttributeValue(SlotId slot_id,
ObjectHandle object_handle,
// Serialized chaps::AttributeList.
std::vector<uint8_t> attributes,
int attempts_left,
SetAttributeValueCallback callback) override;
void FindObjects(SlotId slot_id,
// Serialized chaps::AttributeList.
std::vector<uint8_t> attributes,
int attempts_left,
FindObjectsCallback callback) override;
void Sign(SlotId slot_id,
uint64_t mechanism_type,
std::vector<uint8_t> mechanism_parameter,
ObjectHandle key_handle,
std::vector<uint8_t> data,
int attempts_left,
SignCallback callback) override;
void GenerateKeyPair(SlotId slot_id,
uint64_t mechanism_type,
// Serialized chaps::AttributeList-s.
std::vector<uint8_t> mechanism_parameter,
std::vector<uint8_t> public_attributes,
std::vector<uint8_t> private_attributes,
int attempts_left,
GenerateKeyPairCallback callback) override;
private:
void DidCreateObject(SlotId slot_id,
CreateObjectCallback callback,
uint64_t object_handle,
uint32_t result_code);
void DidDestroyObject(SlotId slot_id,
DestroyObjectCallback callback,
uint32_t result_code);
void DidGetAttributeValue(SlotId slot_id,
GetAttributeValueCallback callback,
const std::vector<uint8_t>& attributes,
uint32_t result_code);
void DidSetAttributeValue(SlotId slot_id,
SetAttributeValueCallback callback,
uint32_t result_code);
void DidFindObjectsInit(SlotId slot_id,
FindObjectsCallback callback,
uint32_t result_code);
void DidFindObjects(SlotId slot_id,
FindObjectsCallback callback,
const std::vector<uint64_t>& object_list,
uint32_t result_code);
void DidFindObjectsFinal(SlotId slot_id,
FindObjectsCallback callback,
std::vector<ObjectHandle> object_list,
uint32_t result_code);
void DidSignInit(SlotId slot_id,
std::vector<uint8_t> data,
SignCallback callback,
uint32_t result_code);
void DidSign(SlotId slot_id,
SignCallback callback,
uint64_t actual_out_length,
const std::vector<uint8_t>& signature,
uint32_t result_code);
void DidGenerateKeyPair(SlotId slot_id,
GenerateKeyPairCallback callback,
uint64_t public_key_id,
uint64_t private_key_id,
uint32_t result_code);
void SaveSessionId(SlotId slot_id,
base::OnceClosure callback,
uint64_t session_id,
uint32_t result_code);
SessionId GetSessionForSlot(SlotId slot_id) const;
SEQUENCE_CHECKER(sequence_checker_);
base::flat_map<SlotId, SessionId> sessions_map_;
base::WeakPtrFactory<SessionChapsClientImpl> weak_factory_{this};
};
} // namespace kcer
#endif // CHROMEOS_ASH_COMPONENTS_KCER_CHAPS_SESSION_CHAPS_CLIENT_H_
|