aboutsummaryrefslogtreecommitdiff
path: root/rpc_pkey.c
diff options
context:
space:
mode:
Diffstat (limited to 'rpc_pkey.c')
-rw-r--r--rpc_pkey.c537
1 files changed, 340 insertions, 197 deletions
diff --git a/rpc_pkey.c b/rpc_pkey.c
index d6efbe7..e2e42c9 100644
--- a/rpc_pkey.c
+++ b/rpc_pkey.c
@@ -39,35 +39,12 @@
#include "hal.h"
#include "hal_internal.h"
-typedef struct {
- hal_client_handle_t client_handle;
- hal_session_handle_t session_handle;
- hal_pkey_handle_t pkey_handle;
- hal_key_type_t type;
- hal_curve_name_t curve;
- hal_key_flags_t flags;
- uint8_t name[HAL_RPC_PKEY_NAME_MAX];
- size_t name_len;
- int ks_hint;
- /*
- * This might be where we'd stash a (hal_core_t *) pointing to a
- * core which has already been loaded with the key, if we were
- * trying to be clever about using multiple signing cores. Moot
- * point (ie, no way we could possibly test such a thing) as long as
- * the FPGA is too small to hold more than one modexp core and ECDSA
- * is entirely software, so skip it for now, but the implied
- * semantics are interesting: a pkey handle starts to resemble an
- * initialized signing core, and once all the cores are in use, one
- * can't load another key without closing an existing pkey handle.
- */
-} pkey_slot_t;
-
#ifndef HAL_STATIC_PKEY_STATE_BLOCKS
#define HAL_STATIC_PKEY_STATE_BLOCKS 0
#endif
#if HAL_STATIC_PKEY_STATE_BLOCKS > 0
-static pkey_slot_t pkey_handle[HAL_STATIC_PKEY_STATE_BLOCKS];
+static hal_pkey_slot_t pkey_handle[HAL_STATIC_PKEY_STATE_BLOCKS];
#endif
/*
@@ -78,27 +55,28 @@ static pkey_slot_t pkey_handle[HAL_STATIC_PKEY_STATE_BLOCKS];
* soon, to help identify use-after-free bugs in calling code.
*
* The high order bit of the pkey handle is left free for
- * HAL_PKEY_HANDLE_PROXIMATE_FLAG, which is used by the mixed-mode
+ * HAL_PKEY_HANDLE_TOKEN_FLAG, which is used by the mixed-mode
* handlers to route calls to the appropriate destination.
*/
-static inline pkey_slot_t *alloc_slot(const hal_key_flags_t flags)
+static inline hal_pkey_slot_t *alloc_slot(const hal_key_flags_t flags)
{
#if HAL_STATIC_PKEY_STATE_BLOCKS > 0
static uint16_t next_glop = 0;
uint32_t glop = ++next_glop << 16;
next_glop %= 0x7FFF;
- assert((glop & HAL_PKEY_HANDLE_PROXIMATE_FLAG) == 0);
+ assert((glop & HAL_PKEY_HANDLE_TOKEN_FLAG) == 0);
- if ((flags & HAL_KEY_FLAG_PROXIMATE) != 0)
- glop |= HAL_PKEY_HANDLE_PROXIMATE_FLAG;
+ if ((flags & HAL_KEY_FLAG_TOKEN) != 0)
+ glop |= HAL_PKEY_HANDLE_TOKEN_FLAG;
for (int i = 0; i < sizeof(pkey_handle)/sizeof(*pkey_handle); i++) {
if (pkey_handle[i].type != HAL_KEY_TYPE_NONE)
continue;
+ memset(&pkey_handle[i], 0, sizeof(pkey_handle[i]));
pkey_handle[i].pkey_handle.handle = i | glop;
- pkey_handle[i].ks_hint = -1;
+ pkey_handle[i].hint = -1;
return &pkey_handle[i];
}
#endif
@@ -111,7 +89,7 @@ static inline pkey_slot_t *alloc_slot(const hal_key_flags_t flags)
* the right glop. Returns slot pointer on success, NULL otherwise.
*/
-static inline pkey_slot_t *find_handle(const hal_pkey_handle_t handle)
+static inline hal_pkey_slot_t *find_handle(const hal_pkey_handle_t handle)
{
#if HAL_STATIC_PKEY_STATE_BLOCKS > 0
const int i = (int) (handle.handle & 0xFFFF);
@@ -123,61 +101,67 @@ static inline pkey_slot_t *find_handle(const hal_pkey_handle_t handle)
return NULL;
}
-#warning Still need access control on pkey objects based on current login state
/*
- * This would be simple, except for PKCS #11 non-token objects (CKA_TOKEN = CK_FALSE).
- * Need to check detailed PKCS #11 rules, but, from memory, we may be supposed to allow
- * access to non-token objects even when not logged in. Maybe. Rules are complex.
+ * Access rules are a bit complicated, mostly due to PKCS #11.
*
- * I think the libhal translation of this resolves around what we've
- * been calling the PROXIMATE flags (which probably ought to be
- * renamed to *_NONTOKEN_*, slightly less confusing name). For token
- * objects, we insist on being logged in properly; for non-token
- * objects, we do whatever silly thing PKCS #11 wants us to do,
- * probably defaulting to requiring login if PKCS #11 gives us a choice.
- */
-
-/*
- * Construct a PKCS #1 DigestInfo object. This requires some (very
- * basic) ASN.1 encoding, which we perform inline.
+ * The simple, obvious rule would be that one must be logged in as
+ * HAL_USER_NORMAL to create, see, use, or delete a key, full stop.
+ *
+ * That's almost the rule that PKCS #11 follows for so-called
+ * "private" objects (CKA_PRIVATE = CK_TRUE), but PKCS #11 has a more
+ * model which not only allows wider visibility to "public" objects
+ * (CKA_PRIVATE = CK_FALSE) but also allows write access to "public
+ * session" (CKA_PRIVATE = CK_FALSE, CKA_TOKEN = CK_FALSE) objects
+ * regardless of login state.
+ *
+ * PKCS #11 also has a concept of read-only sessions, which we don't
+ * bother to implement at all on the HSM, since the PIN is required to
+ * be the same as for the corresponding read-write session, so this
+ * would just be additional compexity without adding any security on
+ * the HSM; the PKCS #11 library still has to support read-only
+ * sessions, but that's not our problem here.
+ *
+ * In general, non-PKCS #11 users of this API should probably never
+ * set HAL_KEY_FLAG_PUBLIC, in which case they'll get the simple rule.
+ *
+ * Note that keystore drivers may need to implement additional
+ * additional checks, eg, ks_volatile needs to enforce the rule that
+ * session objects are only visible to the client which created them
+ * (not the session, that would be too simple, thanks PKCS #11). In
+ * practice, this should not be a serious problem, since such checks
+ * will likely only apply to existing objects. The thing we really
+ * want to avoid is doing all the work to create a large key only to
+ * have the keystore driver reject access at the end, but since, by
+ * definition, that only occurs when creating new objects, the access
+ * decision doesn't depend on preexisting data, so the rules here
+ * should suffice. That's the theory, anyway, if this is wrong we may
+ * need to refactor.
*/
-hal_error_t hal_rpc_pkey_pkcs1_construct_digestinfo(const hal_hash_handle_t handle,
- uint8_t *digest_info, size_t *digest_info_len, const size_t digest_info_max)
+static inline hal_error_t check_normal_or_wheel(const hal_client_handle_t client)
{
- assert(digest_info != NULL && digest_info_len != NULL);
-
- hal_digest_algorithm_t alg;
- size_t len, alg_len;
- hal_error_t err;
-
- if ((err = hal_rpc_hash_get_algorithm(handle, &alg)) != HAL_OK ||
- (err = hal_rpc_hash_get_digest_length(alg, &len)) != HAL_OK ||
- (err = hal_rpc_hash_get_digest_algorithm_id(alg, NULL, &alg_len, 0)) != HAL_OK)
- return err;
-
- *digest_info_len = len + alg_len + 4;
-
- if (*digest_info_len >= digest_info_max)
- return HAL_ERROR_RESULT_TOO_LONG;
-
- assert(*digest_info_len < 130);
-
- uint8_t *d = digest_info;
-
- *d++ = 0x30; /* SEQUENCE */
- *d++ = (uint8_t) (*digest_info_len - 2);
+ const hal_error_t err = hal_rpc_is_logged_in(client, HAL_USER_NORMAL);
+ return (err == HAL_ERROR_FORBIDDEN
+ ? hal_rpc_is_logged_in(client, HAL_USER_WHEEL)
+ : err);
+}
- if ((err = hal_rpc_hash_get_digest_algorithm_id(alg, d, NULL, alg_len)) != HAL_OK)
- return err;
- d += alg_len;
+static inline hal_error_t check_readable(const hal_client_handle_t client,
+ const hal_key_flags_t flags)
+{
+ if ((flags & HAL_KEY_FLAG_PUBLIC) != 0)
+ return HAL_OK;
- *d++ = 0x04; /* OCTET STRING */
- *d++ = (uint8_t) len;
+ return check_normal_or_wheel(client);
+}
- assert(digest_info + *digest_info_len == d + len);
+static inline hal_error_t check_writable(const hal_client_handle_t client,
+ const hal_key_flags_t flags)
+{
+ if ((flags & (HAL_KEY_FLAG_TOKEN | HAL_KEY_FLAG_PUBLIC)) == HAL_KEY_FLAG_PUBLIC)
+ return HAL_OK;
- return hal_rpc_hash_finalize(handle, d, len);
+ return check_normal_or_wheel(client);
}
/*
@@ -223,6 +207,18 @@ static hal_error_t pkcs1_5_pad(const uint8_t * const data, const size_t data_len
}
/*
+ * Given key flags, open appropriate keystore driver.
+ */
+
+static inline hal_error_t ks_open_from_flags(hal_ks_t **ks, const hal_key_flags_t flags)
+{
+ return hal_ks_open((flags & HAL_KEY_FLAG_TOKEN) == 0
+ ? hal_ks_volatile_driver
+ : hal_ks_token_driver,
+ ks);
+}
+
+/*
* Receive key from application, store it with supplied name, return a key handle.
*/
@@ -231,30 +227,44 @@ static hal_error_t pkey_local_load(const hal_client_handle_t client,
hal_pkey_handle_t *pkey,
const hal_key_type_t type,
const hal_curve_name_t curve,
- const uint8_t * const name, const size_t name_len,
+ hal_uuid_t *name,
const uint8_t * const der, const size_t der_len,
const hal_key_flags_t flags)
{
- pkey_slot_t *slot;
+ assert(pkey != NULL && name != NULL);
+
+ hal_pkey_slot_t *slot;
+ hal_ks_t *ks = NULL;
hal_error_t err;
- assert(sizeof(slot->name) >= name_len && pkey != NULL);
+ if ((err = check_writable(client, flags)) != HAL_OK)
+ return err;
if ((slot = alloc_slot(flags)) == NULL)
return HAL_ERROR_NO_KEY_SLOTS_AVAILABLE;
- if ((err = hal_ks_store(type, curve, flags, name, name_len, der, der_len, &slot->ks_hint)) != HAL_OK)
+ if ((err = hal_uuid_gen(&slot->name)) != HAL_OK)
return err;
- memcpy(slot->name, name, name_len);
- slot->client_handle = client;
+ slot->client_handle = client;
slot->session_handle = session;
- slot->type = type;
+ slot->type = type;
slot->curve = curve;
slot->flags = flags;
- slot->name_len = name_len;
+
+ if ((err = ks_open_from_flags(&ks, flags)) == HAL_OK &&
+ (err = hal_ks_store(ks, slot, der, der_len)) == HAL_OK)
+ err = hal_ks_close(ks);
+ else if (ks != NULL)
+ (void) hal_ks_close(ks);
+
+ if (err != HAL_OK) {
+ slot->type = HAL_KEY_TYPE_NONE;
+ return err;
+ }
*pkey = slot->pkey_handle;
+ *name = slot->name;
return HAL_OK;
}
@@ -262,29 +272,38 @@ static hal_error_t pkey_local_load(const hal_client_handle_t client,
* Look up a key given its name, return a key handle.
*/
-static hal_error_t pkey_local_find(const hal_client_handle_t client,
+static hal_error_t pkey_local_open(const hal_client_handle_t client,
const hal_session_handle_t session,
hal_pkey_handle_t *pkey,
- const hal_key_type_t type,
- const uint8_t * const name, const size_t name_len,
+ const hal_uuid_t * const name,
const hal_key_flags_t flags)
{
- pkey_slot_t *slot;
+ assert(pkey != NULL && name != NULL);
+
+ hal_pkey_slot_t *slot;
+ hal_ks_t *ks = NULL;
hal_error_t err;
- assert(sizeof(slot->name) >= name_len && pkey != NULL);
+ if ((err = check_readable(client, flags)) != HAL_OK)
+ return err;
if ((slot = alloc_slot(flags)) == NULL)
return HAL_ERROR_NO_KEY_SLOTS_AVAILABLE;
- if ((err = hal_ks_fetch(type, name, name_len, &slot->curve, &slot->flags, NULL, NULL, 0, &slot->ks_hint)) != HAL_OK)
- return err;
-
- memcpy(slot->name, name, name_len);
+ slot->name = *name;
slot->client_handle = client;
slot->session_handle = session;
- slot->type = type;
- slot->name_len = name_len;
+
+ if ((err = ks_open_from_flags(&ks, flags)) == HAL_OK &&
+ (err = hal_ks_fetch(ks, slot, NULL, NULL, 0)) == HAL_OK)
+ err = hal_ks_close(ks);
+ else if (ks != NULL)
+ (void) hal_ks_close(ks);
+
+ if (err != HAL_OK) {
+ slot->type = HAL_KEY_TYPE_NONE;
+ return err;
+ }
*pkey = slot->pkey_handle;
return HAL_OK;
@@ -297,48 +316,60 @@ static hal_error_t pkey_local_find(const hal_client_handle_t client,
static hal_error_t pkey_local_generate_rsa(const hal_client_handle_t client,
const hal_session_handle_t session,
hal_pkey_handle_t *pkey,
- const uint8_t * const name, const size_t name_len,
+ hal_uuid_t *name,
const unsigned key_length,
const uint8_t * const public_exponent, const size_t public_exponent_len,
const hal_key_flags_t flags)
{
- pkey_slot_t *slot;
+ assert(pkey != NULL && name != NULL && (key_length & 7) == 0);
+
+ uint8_t keybuf[hal_rsa_key_t_size];
+ hal_rsa_key_t *key = NULL;
+ hal_pkey_slot_t *slot;
+ hal_ks_t *ks = NULL;
hal_error_t err;
- assert(sizeof(slot->name) >= name_len && pkey != NULL && (key_length & 7) == 0);
+ if ((err = check_writable(client, flags)) != HAL_OK)
+ return err;
if ((slot = alloc_slot(flags)) == NULL)
return HAL_ERROR_NO_KEY_SLOTS_AVAILABLE;
- uint8_t keybuf[hal_rsa_key_t_size];
- hal_rsa_key_t *key = NULL;
+ if ((err = hal_uuid_gen(&slot->name)) != HAL_OK)
+ return err;
+
+ slot->client_handle = client;
+ slot->session_handle = session;
+ slot->type = HAL_KEY_TYPE_RSA_PRIVATE;
+ slot->curve = HAL_CURVE_NONE;
+ slot->flags = flags;
if ((err = hal_rsa_key_gen(NULL, &key, keybuf, sizeof(keybuf), key_length / 8,
- public_exponent, public_exponent_len)) != HAL_OK)
+ public_exponent, public_exponent_len)) != HAL_OK) {
+ slot->type = HAL_KEY_TYPE_NONE;
return err;
+ }
uint8_t der[hal_rsa_private_key_to_der_len(key)];
size_t der_len;
- if ((err = hal_rsa_private_key_to_der(key, der, &der_len, sizeof(der))) == HAL_OK)
- err = hal_ks_store(HAL_KEY_TYPE_RSA_PRIVATE, HAL_CURVE_NONE, flags,
- name, name_len, der, der_len, &slot->ks_hint);
+ if ((err = hal_rsa_private_key_to_der(key, der, &der_len, sizeof(der))) == HAL_OK &&
+ (err = ks_open_from_flags(&ks, flags)) == HAL_OK &&
+ (err = hal_ks_store(ks, slot, der, der_len)) == HAL_OK)
+ err = hal_ks_close(ks);
+ else if (ks != NULL)
+ (void) hal_ks_close(ks);
memset(keybuf, 0, sizeof(keybuf));
memset(der, 0, sizeof(der));
- if (err != HAL_OK)
+ if (err != HAL_OK) {
+ slot->type = HAL_KEY_TYPE_NONE;
return err;
-
- memcpy(slot->name, name, name_len);
- slot->client_handle = client;
- slot->session_handle = session;
- slot->type = HAL_KEY_TYPE_RSA_PRIVATE;
- slot->curve = HAL_CURVE_NONE;
- slot->flags = flags;
- slot->name_len = name_len;
+ }
*pkey = slot->pkey_handle;
+ *name = slot->name;
return HAL_OK;
}
@@ -350,46 +381,58 @@ static hal_error_t pkey_local_generate_rsa(const hal_client_handle_t client,
static hal_error_t pkey_local_generate_ec(const hal_client_handle_t client,
const hal_session_handle_t session,
hal_pkey_handle_t *pkey,
- const uint8_t * const name, const size_t name_len,
+ hal_uuid_t *name,
const hal_curve_name_t curve,
const hal_key_flags_t flags)
{
- pkey_slot_t *slot;
+ assert(pkey != NULL && name != NULL);
+
+ uint8_t keybuf[hal_ecdsa_key_t_size];
+ hal_ecdsa_key_t *key = NULL;
+ hal_pkey_slot_t *slot;
+ hal_ks_t *ks = NULL;
hal_error_t err;
- assert(sizeof(slot->name) >= name_len && pkey != NULL);
+ if ((err = check_writable(client, flags)) != HAL_OK)
+ return err;
if ((slot = alloc_slot(flags)) == NULL)
return HAL_ERROR_NO_KEY_SLOTS_AVAILABLE;
- uint8_t keybuf[hal_ecdsa_key_t_size];
- hal_ecdsa_key_t *key = NULL;
+ if ((err = hal_uuid_gen(&slot->name)) != HAL_OK)
+ return err;
- if ((err = hal_ecdsa_key_gen(NULL, &key, keybuf, sizeof(keybuf), curve)) != HAL_OK)
+ slot->client_handle = client;
+ slot->session_handle = session;
+ slot->type = HAL_KEY_TYPE_EC_PRIVATE;
+ slot->curve = curve;
+ slot->flags = flags;
+
+ if ((err = hal_ecdsa_key_gen(NULL, &key, keybuf, sizeof(keybuf), curve)) != HAL_OK) {
+ slot->type = HAL_KEY_TYPE_NONE;
return err;
+ }
uint8_t der[hal_ecdsa_private_key_to_der_len(key)];
size_t der_len;
- if ((err = hal_ecdsa_private_key_to_der(key, der, &der_len, sizeof(der))) == HAL_OK)
- err = hal_ks_store(HAL_KEY_TYPE_EC_PRIVATE, curve, flags,
- name, name_len, der, der_len, &slot->ks_hint);
+ if ((err = hal_ecdsa_private_key_to_der(key, der, &der_len, sizeof(der))) == HAL_OK &&
+ (err = ks_open_from_flags(&ks, flags)) == HAL_OK &&
+ (err = hal_ks_store(ks, slot, der, der_len)) == HAL_OK)
+ err = hal_ks_close(ks);
+ else if (ks != NULL)
+ (void) hal_ks_close(ks);
memset(keybuf, 0, sizeof(keybuf));
memset(der, 0, sizeof(der));
- if (err != HAL_OK)
+ if (err != HAL_OK) {
+ slot->type = HAL_KEY_TYPE_NONE;
return err;
-
- memcpy(slot->name, name, name_len);
- slot->client_handle = client;
- slot->session_handle = session;
- slot->type = HAL_KEY_TYPE_EC_PRIVATE;
- slot->curve = curve;
- slot->flags = flags;
- slot->name_len = name_len;
+ }
*pkey = slot->pkey_handle;
+ *name = slot->name;
return HAL_OK;
}
@@ -399,7 +442,7 @@ static hal_error_t pkey_local_generate_ec(const hal_client_handle_t client,
static hal_error_t pkey_local_close(const hal_pkey_handle_t pkey)
{
- pkey_slot_t *slot;
+ hal_pkey_slot_t *slot;
if ((slot = find_handle(pkey)) == NULL)
return HAL_ERROR_KEY_NOT_FOUND;
@@ -415,12 +458,22 @@ static hal_error_t pkey_local_close(const hal_pkey_handle_t pkey)
static hal_error_t pkey_local_delete(const hal_pkey_handle_t pkey)
{
- pkey_slot_t *slot = find_handle(pkey);
+ hal_pkey_slot_t *slot = find_handle(pkey);
if (slot == NULL)
return HAL_ERROR_KEY_NOT_FOUND;
- hal_error_t err = hal_ks_delete(slot->type, slot->name, slot->name_len, &slot->ks_hint);
+ hal_ks_t *ks = NULL;
+ hal_error_t err;
+
+ if ((err = check_writable(slot->client_handle, slot->flags)) != HAL_OK)
+ return err;
+
+ if ((err = ks_open_from_flags(&ks, slot->flags)) == HAL_OK &&
+ (err = hal_ks_delete(ks, slot)) == HAL_OK)
+ err = hal_ks_close(ks);
+ else if (ks != NULL)
+ (void) hal_ks_close(ks);
if (err == HAL_OK || err == HAL_ERROR_KEY_NOT_FOUND)
memset(slot, 0, sizeof(*slot));
@@ -429,45 +482,41 @@ static hal_error_t pkey_local_delete(const hal_pkey_handle_t pkey)
}
/*
- * Rename a key in the key store, given its key handle and a new name.
+ * Get type of key associated with handle.
*/
-static hal_error_t pkey_local_rename(const hal_pkey_handle_t pkey,
- const uint8_t * const name, const size_t name_len)
+static hal_error_t pkey_local_get_key_type(const hal_pkey_handle_t pkey,
+ hal_key_type_t *type)
{
- pkey_slot_t *slot = find_handle(pkey);
+ if (type == NULL)
+ return HAL_ERROR_BAD_ARGUMENTS;
+
+ hal_pkey_slot_t *slot = find_handle(pkey);
if (slot == NULL)
return HAL_ERROR_KEY_NOT_FOUND;
- hal_error_t err = hal_ks_rename(slot->type, slot->name, slot->name_len, name, name_len, &slot->ks_hint);
-
- if (err == HAL_OK) {
- assert(name_len <= sizeof(slot->name));
- memcpy(slot->name, name, name_len);
- memset(slot->name + name_len, 0, sizeof(slot->name) - name_len);
- slot->name_len = name_len;
- }
+ *type = slot->type;
- return err;
+ return HAL_OK;
}
/*
- * Get type of key associated with handle.
+ * Get curve of key associated with handle.
*/
-static hal_error_t pkey_local_get_key_type(const hal_pkey_handle_t pkey,
- hal_key_type_t *type)
+static hal_error_t pkey_local_get_key_curve(const hal_pkey_handle_t pkey,
+ hal_curve_name_t *curve)
{
- if (type == NULL)
+ if (curve == NULL)
return HAL_ERROR_BAD_ARGUMENTS;
- pkey_slot_t *slot = find_handle(pkey);
+ hal_pkey_slot_t *slot = find_handle(pkey);
if (slot == NULL)
return HAL_ERROR_KEY_NOT_FOUND;
- *type = slot->type;
+ *curve = slot->curve;
return HAL_OK;
}
@@ -482,7 +531,7 @@ static hal_error_t pkey_local_get_key_flags(const hal_pkey_handle_t pkey,
if (flags == NULL)
return HAL_ERROR_BAD_ARGUMENTS;
- pkey_slot_t *slot = find_handle(pkey);
+ hal_pkey_slot_t *slot = find_handle(pkey);
if (slot == NULL)
return HAL_ERROR_KEY_NOT_FOUND;
@@ -498,7 +547,7 @@ static hal_error_t pkey_local_get_key_flags(const hal_pkey_handle_t pkey,
static size_t pkey_local_get_public_key_len(const hal_pkey_handle_t pkey)
{
- pkey_slot_t *slot = find_handle(pkey);
+ hal_pkey_slot_t *slot = find_handle(pkey);
if (slot == NULL)
return 0;
@@ -510,9 +559,16 @@ static size_t pkey_local_get_public_key_len(const hal_pkey_handle_t pkey)
hal_ecdsa_key_t *ecdsa_key = NULL;
uint8_t der[HAL_KS_WRAPPED_KEYSIZE];
size_t der_len;
+ hal_ks_t *ks = NULL;
+ hal_error_t err;
- if (hal_ks_fetch(slot->type, slot->name, slot->name_len, NULL, NULL,
- der, &der_len, sizeof(der), &slot->ks_hint) == HAL_OK) {
+ if ((err = ks_open_from_flags(&ks, slot->flags)) == HAL_OK &&
+ (err = hal_ks_fetch(ks, slot, der, &der_len, sizeof(der))) == HAL_OK)
+ err = hal_ks_close(ks);
+ else if (ks != NULL)
+ (void) hal_ks_close(ks);
+
+ if (err == HAL_OK) {
switch (slot->type) {
case HAL_KEY_TYPE_RSA_PUBLIC:
@@ -548,7 +604,7 @@ static size_t pkey_local_get_public_key_len(const hal_pkey_handle_t pkey)
static hal_error_t pkey_local_get_public_key(const hal_pkey_handle_t pkey,
uint8_t *der, size_t *der_len, const size_t der_max)
{
- pkey_slot_t *slot = find_handle(pkey);
+ hal_pkey_slot_t *slot = find_handle(pkey);
if (slot == NULL)
return HAL_ERROR_KEY_NOT_FOUND;
@@ -558,10 +614,16 @@ static hal_error_t pkey_local_get_public_key(const hal_pkey_handle_t pkey,
hal_ecdsa_key_t *ecdsa_key = NULL;
uint8_t buf[HAL_KS_WRAPPED_KEYSIZE];
size_t buf_len;
+ hal_ks_t *ks = NULL;
hal_error_t err;
- if ((err = hal_ks_fetch(slot->type, slot->name, slot->name_len, NULL, NULL,
- buf, &buf_len, sizeof(buf), &slot->ks_hint)) == HAL_OK) {
+ if ((err = ks_open_from_flags(&ks, slot->flags)) == HAL_OK &&
+ (err = hal_ks_fetch(ks, slot, buf, &buf_len, sizeof(buf))) == HAL_OK)
+ err = hal_ks_close(ks);
+ else if (ks != NULL)
+ (void) hal_ks_close(ks);
+
+ if (err == HAL_OK) {
switch (slot->type) {
case HAL_KEY_TYPE_RSA_PUBLIC:
@@ -622,8 +684,8 @@ static hal_error_t pkey_local_sign_rsa(uint8_t *keybuf, const size_t keybuf_len,
if (*signature_len > signature_max)
return HAL_ERROR_RESULT_TOO_LONG;
- if (input == NULL) {
- if ((err = hal_rpc_pkey_pkcs1_construct_digestinfo(hash, signature, &input_len, *signature_len)) != HAL_OK)
+ if (input == NULL || input_len == 0) {
+ if ((err = hal_rpc_pkcs1_construct_digestinfo(hash, signature, &input_len, *signature_len)) != HAL_OK)
return err;
input = signature;
}
@@ -650,7 +712,7 @@ static hal_error_t pkey_local_sign_ecdsa(uint8_t *keybuf, const size_t keybuf_le
if ((err = hal_ecdsa_private_key_from_der(&key, keybuf, keybuf_len, der, der_len)) != HAL_OK)
return err;
- if (input == NULL) {
+ if (input == NULL || input_len == 0) {
hal_digest_algorithm_t alg;
if ((err = hal_rpc_hash_get_algorithm(hash, &alg)) != HAL_OK ||
@@ -672,13 +734,12 @@ static hal_error_t pkey_local_sign_ecdsa(uint8_t *keybuf, const size_t keybuf_le
return HAL_OK;
}
-static hal_error_t pkey_local_sign(const hal_session_handle_t session,
- const hal_pkey_handle_t pkey,
+static hal_error_t pkey_local_sign(const hal_pkey_handle_t pkey,
const hal_hash_handle_t hash,
const uint8_t * const input, const size_t input_len,
uint8_t * signature, size_t *signature_len, const size_t signature_max)
{
- pkey_slot_t *slot = find_handle(pkey);
+ hal_pkey_slot_t *slot = find_handle(pkey);
if (slot == NULL)
return HAL_ERROR_KEY_NOT_FOUND;
@@ -703,9 +764,14 @@ static hal_error_t pkey_local_sign(const hal_session_handle_t session,
uint8_t keybuf[hal_rsa_key_t_size > hal_ecdsa_key_t_size ? hal_rsa_key_t_size : hal_ecdsa_key_t_size];
uint8_t der[HAL_KS_WRAPPED_KEYSIZE];
size_t der_len;
+ hal_ks_t *ks = NULL;
hal_error_t err;
- err = hal_ks_fetch(slot->type, slot->name, slot->name_len, NULL, NULL, der, &der_len, sizeof(der), &slot->ks_hint);
+ if ((err = ks_open_from_flags(&ks, slot->flags)) == HAL_OK &&
+ (err = hal_ks_fetch(ks, slot, der, &der_len, sizeof(der))) == HAL_OK)
+ err = hal_ks_close(ks);
+ else if (ks != NULL)
+ (void) hal_ks_close(ks);
if (err == HAL_OK)
err = signer(keybuf, sizeof(keybuf), der, der_len, hash, input, input_len, signature, signature_len, signature_max);
@@ -750,8 +816,8 @@ static hal_error_t pkey_local_verify_rsa(uint8_t *keybuf, const size_t keybuf_le
if (err != HAL_OK)
return err;
- if (input == NULL) {
- if ((err = hal_rpc_pkey_pkcs1_construct_digestinfo(hash, expected, &input_len, sizeof(expected))) != HAL_OK)
+ if (input == NULL || input_len == 0) {
+ if ((err = hal_rpc_pkcs1_construct_digestinfo(hash, expected, &input_len, sizeof(expected))) != HAL_OK)
return err;
input = expected;
}
@@ -797,7 +863,7 @@ static hal_error_t pkey_local_verify_ecdsa(uint8_t *keybuf, const size_t keybuf_
if (err != HAL_OK)
return err;
- if (input == NULL) {
+ if (input == NULL || input_len == 0) {
hal_digest_algorithm_t alg;
if ((err = hal_rpc_hash_get_algorithm(hash, &alg)) != HAL_OK ||
@@ -814,13 +880,12 @@ static hal_error_t pkey_local_verify_ecdsa(uint8_t *keybuf, const size_t keybuf_
return HAL_OK;
}
-static hal_error_t pkey_local_verify(const hal_session_handle_t session,
- const hal_pkey_handle_t pkey,
+static hal_error_t pkey_local_verify(const hal_pkey_handle_t pkey,
const hal_hash_handle_t hash,
const uint8_t * const input, const size_t input_len,
const uint8_t * const signature, const size_t signature_len)
{
- pkey_slot_t *slot = find_handle(pkey);
+ hal_pkey_slot_t *slot = find_handle(pkey);
if (slot == NULL)
return HAL_ERROR_KEY_NOT_FOUND;
@@ -847,9 +912,14 @@ static hal_error_t pkey_local_verify(const hal_session_handle_t session,
uint8_t keybuf[hal_rsa_key_t_size > hal_ecdsa_key_t_size ? hal_rsa_key_t_size : hal_ecdsa_key_t_size];
uint8_t der[HAL_KS_WRAPPED_KEYSIZE];
size_t der_len;
+ hal_ks_t *ks = NULL;
hal_error_t err;
- err = hal_ks_fetch(slot->type, slot->name, slot->name_len, NULL, NULL, der, &der_len, sizeof(der), &slot->ks_hint);
+ if ((err = ks_open_from_flags(&ks, slot->flags)) == HAL_OK &&
+ (err = hal_ks_fetch(ks, slot, der, &der_len, sizeof(der))) == HAL_OK)
+ err = hal_ks_close(ks);
+ else if (ks != NULL)
+ (void) hal_ks_close(ks);
if (err == HAL_OK)
err = verifier(keybuf, sizeof(keybuf), slot->type, der, der_len, hash, input, input_len, signature, signature_len);
@@ -860,34 +930,107 @@ static hal_error_t pkey_local_verify(const hal_session_handle_t session,
return err;
}
+static hal_error_t pkey_local_match(const hal_client_handle_t client,
+ const hal_session_handle_t session,
+ const hal_key_type_t type,
+ const hal_curve_name_t curve,
+ const hal_key_flags_t flags,
+ const hal_pkey_attribute_t *attributes,
+ const unsigned attributes_len,
+ hal_uuid_t *result,
+ unsigned *result_len,
+ const unsigned result_max,
+ const hal_uuid_t * const previous_uuid)
+{
+ hal_ks_t *ks = NULL;
+ hal_error_t err;
-/*
- * List keys in the key store.
- */
+ err = check_readable(client, flags);
+
+ if (err == HAL_ERROR_FORBIDDEN) {
+ assert(result_len != NULL);
+ *result_len = 0;
+ return HAL_OK;
+ }
+
+ if (err != HAL_OK)
+ return err;
+
+ if ((err = ks_open_from_flags(&ks, flags)) == HAL_OK &&
+ (err = hal_ks_match(ks, client, session, type, curve, flags, attributes, attributes_len,
+ result, result_len, result_max, previous_uuid)) == HAL_OK)
+ err = hal_ks_close(ks);
+ else if (ks != NULL)
+ (void) hal_ks_close(ks);
+
+ return err;
+}
+
+static hal_error_t pkey_local_set_attributes(const hal_pkey_handle_t pkey,
+ const hal_pkey_attribute_t *attributes,
+ const unsigned attributes_len)
+{
+ hal_pkey_slot_t *slot = find_handle(pkey);
+
+ if (slot == NULL)
+ return HAL_ERROR_KEY_NOT_FOUND;
+
+ hal_ks_t *ks = NULL;
+ hal_error_t err;
+
+ if ((err = check_writable(slot->client_handle, slot->flags)) != HAL_OK)
+ return err;
+
+ if ((err = ks_open_from_flags(&ks, slot->flags)) == HAL_OK &&
+ (err = hal_ks_set_attributes(ks, slot, attributes, attributes_len)) == HAL_OK)
+ err = hal_ks_close(ks);
+ else if (ks != NULL)
+ (void) hal_ks_close(ks);
+
+ return err;
+}
-static hal_error_t pkey_local_list(hal_pkey_info_t *result,
- unsigned *result_len,
- const unsigned result_max,
- hal_key_flags_t flags)
+static hal_error_t pkey_local_get_attributes(const hal_pkey_handle_t pkey,
+ hal_pkey_attribute_t *attributes,
+ const unsigned attributes_len,
+ uint8_t *attributes_buffer,
+ const size_t attributes_buffer_len)
{
- return hal_ks_list(result, result_len, result_max);
+ hal_pkey_slot_t *slot = find_handle(pkey);
+
+ if (slot == NULL)
+ return HAL_ERROR_KEY_NOT_FOUND;
+
+ hal_ks_t *ks = NULL;
+ hal_error_t err;
+
+ if ((err = ks_open_from_flags(&ks, slot->flags)) == HAL_OK &&
+ (err = hal_ks_get_attributes(ks, slot, attributes, attributes_len,
+ attributes_buffer, attributes_buffer_len)) == HAL_OK)
+ err = hal_ks_close(ks);
+ else if (ks != NULL)
+ (void) hal_ks_close(ks);
+
+ return err;
}
const hal_rpc_pkey_dispatch_t hal_rpc_local_pkey_dispatch = {
- pkey_local_load,
- pkey_local_find,
- pkey_local_generate_rsa,
- pkey_local_generate_ec,
- pkey_local_close,
- pkey_local_delete,
- pkey_local_rename,
- pkey_local_get_key_type,
- pkey_local_get_key_flags,
- pkey_local_get_public_key_len,
- pkey_local_get_public_key,
- pkey_local_sign,
- pkey_local_verify,
- pkey_local_list
+ .load = pkey_local_load,
+ .open = pkey_local_open,
+ .generate_rsa = pkey_local_generate_rsa,
+ .generate_ec = pkey_local_generate_ec,
+ .close = pkey_local_close,
+ .delete = pkey_local_delete,
+ .get_key_type = pkey_local_get_key_type,
+ .get_key_curve = pkey_local_get_key_curve,
+ .get_key_flags = pkey_local_get_key_flags,
+ .get_public_key_len = pkey_local_get_public_key_len,
+ .get_public_key = pkey_local_get_public_key,
+ .sign = pkey_local_sign,
+ .verify = pkey_local_verify,
+ .match = pkey_local_match,
+ .set_attributes = pkey_local_set_attributes,
+ .get_attributes = pkey_local_get_attributes
};
/*