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
|
// 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_KCER_TOKEN_UTILS_H_
#define CHROMEOS_ASH_COMPONENTS_KCER_KCER_TOKEN_UTILS_H_
#include "chromeos/ash/components/kcer/attributes.pb.h"
#include "chromeos/ash/components/kcer/chaps/high_level_chaps_client.h"
#include "chromeos/ash/components/kcer/chaps/session_chaps_client.h"
#include "chromeos/ash/components/kcer/helpers/pkcs12_reader.h"
#include "chromeos/ash/components/kcer/kcer.h"
namespace kcer::internal {
// Calculate PKCS#11 id (see CKA_ID) from the bytes of the public key. Designed
// to be backwards compatible with ids produced by NSS.
Pkcs11Id MakePkcs11Id(base::span<const uint8_t> public_key_data);
// Creates Public key SPKI for an RSA public key from its `modulus` and
// `exponent`.
PublicKeySpki MakeRsaSpki(const base::span<const uint8_t>& modulus,
const base::span<const uint8_t>& exponent);
// Creates kcer::PublicKey from an RSA public key data.
base::expected<PublicKey, Error> MakeRsaPublicKey(
Token token,
base::span<const uint8_t> modulus,
base::span<const uint8_t> public_exponent);
// Creates Public key SPKI for an EC public key from its `ec_point`.
PublicKeySpki MakeEcSpki(const base::span<const uint8_t>& ec_point);
// Creates kcer::PublicKey from an EC public key data.
base::expected<PublicKey, Error> MakeEcPublicKey(
Token token,
base::span<const uint8_t> ec_point);
// Temporary class to share code between KcerTokenImpl and KcerTokenImplNss. Can
// be merged into KcerTokenImpl when KcerTokenImplNss is removed. Mostly
// contains operations that have to communicate with Chaps directly.
class KcerTokenUtils {
public:
using ObjectHandle = SessionChapsClient::ObjectHandle;
using ImportPkcs12Callback =
base::OnceCallback<void(bool /*did_modify*/,
base::expected<void, Error> /*result*/)>;
// `chaps_client` must outlive KcerTokenUtils.
KcerTokenUtils(Token token, HighLevelChapsClient* chaps_client);
~KcerTokenUtils();
// Should be called before any other methods.
void Initialize(SessionChapsClient::SlotId pkcs_11_slot_id);
// Returns handles for private key objects with PKCS#11 `id` and PKCS11_CKR_OK
// on success, or some other result code on failure. (In practice there should
// be only 1 or 0 handles.)
void FindPrivateKey(Pkcs11Id id,
base::OnceCallback<void(std::vector<ObjectHandle>,
uint32_t result_code)> callback);
// Creates a certificate object in Chaps. Does not check whether such an
// object already exists. If `kcer_error` is not empty - import failed without
// talking with Chaps. Otherwise returns the result from Chaps.
void ImportCert(const bssl::UniquePtr<X509>& cert,
const Pkcs11Id& pkcs11_id,
const std::string& nickname,
const CertDer& cert_der,
bool is_hardware_backed,
bool mark_as_migrated,
base::OnceCallback<void(std::optional<Error> kcer_error,
ObjectHandle cert_handle,
uint32_t result_code)> callback);
// Imports an EVP_KEY into Chaps as a pair of public and private objects.
// Skips the actual import if the key already exists.
struct ImportKeyTask {
ImportKeyTask(KeyData in_key_data,
bool in_hardware_backed,
bool in_mark_as_migrated,
Kcer::GenerateKeyCallback in_callback);
ImportKeyTask(ImportKeyTask&& other);
~ImportKeyTask();
KeyData key_data;
const bool hardware_backed;
const bool mark_as_migrated;
Kcer::GenerateKeyCallback callback;
int attemps_left = 5;
};
void ImportKey(ImportKeyTask task);
void ImportPkcs12(KeyData key_data,
std::vector<CertData> certs_data,
bool hardware_backed,
bool mark_as_migrated,
ImportPkcs12Callback callback);
private:
void ImportRsaKey(ImportKeyTask task);
void ImportRsaKeyWithExistingKey(ImportKeyTask task,
bssl::UniquePtr<RSA> rsa_key,
PublicKey kcer_public_key,
std::vector<ObjectHandle> handles,
uint32_t result_code);
void DidImportRsaPrivateKey(ImportKeyTask task,
PublicKey kcer_public_key,
std::vector<uint8_t> public_modulus_bytes,
std::vector<uint8_t> public_exponent_bytes,
ObjectHandle priv_key_handle,
uint32_t result_code);
void ImportEcKey(ImportKeyTask task);
void ImportEcKeyWithExistingKey(ImportKeyTask task,
bssl::UniquePtr<EC_KEY> ec_key,
PublicKey kcer_public_key,
std::vector<uint8_t> ec_point_oct,
std::vector<ObjectHandle> handles,
uint32_t result_code);
void DidImportEcPrivateKey(ImportKeyTask task,
PublicKey kcer_public_key,
std::vector<uint8_t> ec_point_der,
std::vector<uint8_t> ec_params_der,
ObjectHandle priv_key_handle,
uint32_t result_code);
void DidImportKey(ImportKeyTask task,
PublicKey kcer_public_key,
ObjectHandle priv_key_handle,
ObjectHandle pub_key_handle,
uint32_t result_code);
void ImportPkc12DidImportKey(kcer::KeyType key_type,
Pkcs11Id pkcs11_id,
std::vector<CertData> certs_data,
bool hardware_backed,
bool mark_as_migrated,
ImportPkcs12Callback callback,
base::expected<PublicKey, Error> imported_key);
struct ImportAllCertsTask {
ImportAllCertsTask(Pkcs11Id in_pkcs11_id,
std::vector<CertData> in_certs_data,
bool in_hardware_backed,
bool in_mark_as_migrated,
bool in_multi_cert_import,
KeyType in_key_type,
ImportPkcs12Callback in_callback);
ImportAllCertsTask(ImportAllCertsTask&& other);
~ImportAllCertsTask();
Pkcs11Id pkcs11_id;
std::vector<CertData> certs_data;
const bool hardware_backed;
const bool mark_as_migrated;
const bool multi_cert_import;
KeyType key_type;
ImportPkcs12Callback callback;
int attemps_left = 5;
};
void ImportAllCerts(ImportAllCertsTask task);
void ImportAllCertsImpl(ImportAllCertsTask task,
std::vector<const CertData*> certs_data,
int imports_failed);
void ImportAllCertsDidImportOneCert(
ImportAllCertsTask task,
std::vector<const CertData*> certs_data,
int imports_failed,
std::optional<Error> kcer_error,
SessionChapsClient::ObjectHandle cert_handle,
uint32_t result_code);
const Token token_;
// The id of the slot associated with this token. It's used to perform D-Bus
// requests to Chaps. The default value is very unlikely to represent any real
// slot and is not used until it's overwritten in Initialize.
SessionChapsClient::SlotId pkcs_11_slot_id_ =
SessionChapsClient::SlotId(0xFFFFFFFF);
const raw_ptr<HighLevelChapsClient> chaps_client_;
base::WeakPtrFactory<KcerTokenUtils> weak_factory_{this};
};
} // namespace kcer::internal
#endif // CHROMEOS_ASH_COMPONENTS_KCER_KCER_TOKEN_UTILS_H_
|