aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2016-11-20 23:30:39 -0500
committerRob Austein <sra@hactrn.net>2016-11-20 23:30:39 -0500
commite4aab24cfe9cfa59e872f246b208fd7692e582b8 (patch)
tree7084bad97c3d04f8d922bc6e97302de95032e852
parent40d6b71c7e7bc9891b309747cc09e6627d4d9b0e (diff)
Compiles without SQLite3. Does not run (yet).
-rw-r--r--pkcs11.c1264
1 files changed, 641 insertions, 623 deletions
diff --git a/pkcs11.c b/pkcs11.c
index fd8d156..96afb4b 100644
--- a/pkcs11.c
+++ b/pkcs11.c
@@ -155,8 +155,11 @@ typedef struct p11_session {
CK_STATE state; /* State (CKS_*) of this session */
CK_NOTIFY notify; /* Notification callback */
CK_VOID_PTR application; /* Application data */
- hal_rpc_pkey_attribute *find_query; /* FindObject*() query state */
- int find_query_done; /* find_query has terminated */
+ hal_rpc_pkey_attribute_t *find_query; /* FindObject*() query state */
+ unsigned find_query_token : 1; /* Find query for token objects in progress */
+ unsigned find_query_session : 1; /* Find query for session objects in progress */
+ unsigned find_query_n : 30; /* Number of entries in find_query */
+ hal_uuid_t find_query_previous_uuid; /* Previous UUID for find queries */
hal_digest_algorithm_t
digest_algorithm, /* Hash algorithm for C_Digest*() */
sign_digest_algorithm, /* Hash algorithm for C_Sign*() */
@@ -222,11 +225,11 @@ static enum {
* PKCS #11 sessions and object handles for this application.
*/
-static p11_session_t p11_sessions[P11_MAX_SESSION_HANDLES];
-static p11_object_t p11_objects [P11_MAX_OBJECT_HANDLES];
+static p11_session_t p11_sessions [P11_MAX_SESSION_HANDLES];
+static p11_object_t p11_objects [P11_MAX_OBJECT_HANDLES];
+static unsigned p11_object_uuids [P11_MAX_OBJECT_HANDLES];
-static unsigned p11_sessions_in_use, p11_session_next;
-static unsigned p11_objects_in_use, p11_object_next;
+static unsigned p11_sessions_in_use, p11_objects_in_use;
/*
* Mutex callbacks.
@@ -660,7 +663,7 @@ static inline CK_ULONG handle_compose(const handle_flavor_t flavor,
{
return (mask_dpb(HANDLE_MASK_FLAVOR, flavor) |
mask_dpb(HANDLE_MASK_NONCE, nonce) |
- mask_dbp(HANDLE_MASK_INDEX, index));
+ mask_dpb(HANDLE_MASK_INDEX, index));
}
static inline handle_flavor_t handle_flavor(const CK_ULONG handle)
@@ -670,7 +673,7 @@ static inline handle_flavor_t handle_flavor(const CK_ULONG handle)
static inline unsigned handle_index(const CK_ULONG handle)
{
- return mask_ldb(HANDLE_INDEX, handle);
+ return mask_ldb(HANDLE_MASK_INDEX, handle);
}
// Backwards compatability, probably phase this out
@@ -679,79 +682,64 @@ static inline unsigned handle_index(const CK_ULONG handle)
/*
- * Attribute methods.
+ * Descriptor methods. Descriptors are generated at compile time by
+ * an auxiliary Python script, see attributes.* for details.
*/
/*
- * Set an attribute for a given object.
- *
- * It would be trivial to generalize this to take a CK_ATTRIBUTE_PTR
- * template instead of a single attribute, at the cost of losing the
- * const specifiers (CK_ATTRIBUTE_PTR has an internal non-const void*).
+ * Return the descriptor associated with a particular object class and
+ * key type.
*/
-static int p11_attribute_set(const hal_pkey_handle_t pkey,
- const CK_ATTRIBUTE_TYPE type,
- const void * const value,
- const CK_ULONG length)
+static const p11_descriptor_t *p11_descriptor_from_key_type(const CK_OBJECT_CLASS object_class,
+ const CK_KEY_TYPE key_type)
{
- const hal_rpc_pkey_attribute_t attribute = {.type = type, .length = length, .value = value};
- return hal_check(hal_rpc_pkey_set_attributes(pkey, &attribute, 1));
+ int i;
+
+ for (i = 0; i < sizeof(p11_descriptor_keyclass_map)/sizeof(*p11_descriptor_keyclass_map); i++) {
+ const p11_descriptor_keyclass_map_t * const m = &p11_descriptor_keyclass_map[i];
+ if (m->object_class == object_class && m->key_type == key_type)
+ return m->descriptor;
+ }
+
+ return NULL;
}
/*
- * Get a single attribute from a given object.
- *
- * This could easily be generalized to take a CK_ATTRIBUTE_PTR, at the
- * cost of more complicated error semantics.
+ * Find the entry for a particular attribute in a descriptor.
*/
-static int p11_attribute_get(const hal_pkey_handle_t pkey,
- const CK_ATTRIBUTE_TYPE type,
- void *value,
- CK_ULONG *length,
- const CK_ULONG maxlength)
+static const p11_attribute_descriptor_t *p11_find_attribute_in_descriptor(const p11_descriptor_t *descriptor,
+ const CK_ATTRIBUTE_TYPE type)
{
- hal_rpc_pkey_attribute_t attribute = {.type = type};
-
- if (!hal_check(hal_rpc_pkey_get_attributes(pkey, &attribute, 1, value, maxlength)))
- return 0;
+ int i;
- if (length != NULL)
- *length = attribute.length;
+ if (descriptor != NULL && descriptor->attributes != NULL)
+ for (i = 0; i < descriptor->n_attributes; i++)
+ if (descriptor->attributes[i].type == type)
+ return &descriptor->attributes[i];
- return 1;
+ return NULL;
}
/*
- * Wrappers to set and get CK_BBOOL and CK_ULONG values.
+ * Check whether an attribute is marked as sensitive. If we don't
+ * recognize the attribute, report it as sensitive (safer than the
+ * alternative).
*/
-static int p11_attribute_set_bbool(const hal_pkey_handle_t pkey, const CK_ATTRIBUTE_TYPE type, const CK_BBOOL value)
-{
- return p11_attribute_set(pkey, type, &value, sizeof(value));
-}
-
-#if 0
-
-static int p11_attribute_set_ulong(const hal_pkey_handle_t pkey, const CK_ATTRIBUTE_TYPE type, const CK_ULONG value)
+static int p11_attribute_is_sensitive(const p11_descriptor_t *descriptor,
+ const CK_ATTRIBUTE_TYPE type)
{
- return p11_attribute_set(pkey, type, &value, sizeof(value));
+ const p11_attribute_descriptor_t *a = p11_find_attribute_in_descriptor(descriptor, type);
+ return a == NULL || (a->flags & P11_DESCRIPTOR_SENSITIVE) != 0;
}
-#endif
-
-static int p11_attribute_get_bbool(const hal_pkey_handle_t pkey, const CK_ATTRIBUTE_TYPE type, CK_BBOOL *value)
-{
- CK_ULONG length;
- return p11_attribute_get(pkey, type, value, &length, sizeof(*value)) && length == sizeof(*value);
-}
+
-static int p11_attribute_get_ulong(const hal_pkey_handle_t pkey, const CK_ATTRIBUTE_TYPE type, CK_ULONG *value)
-{
- CK_ULONG length;
- return p11_attribute_get(pkey, type, value, &length, sizeof(*value)) && length == sizeof(*value);
-}
+/*
+ * Attribute methods.
+ */
/*
* Find an attribute in a CK_ATTRIBUTE_PTR template. Returns index
@@ -784,6 +772,104 @@ static void *p11_attribute_find_value_in_template(const CK_ATTRIBUTE_TYPE type,
}
/*
+ * Set attributes for a newly-created or newly-uploaded HSM key.
+ */
+
+static int p11_attributes_set(const hal_pkey_handle_t pkey,
+ const CK_ATTRIBUTE_PTR template,
+ const CK_ULONG template_length,
+ const p11_descriptor_t * const descriptor,
+ const hal_rpc_pkey_attribute_t *extra,
+ const unsigned extra_length)
+{
+ assert(template != NULL && descriptor != NULL && (extra_length == 0 || extra != NULL));
+
+ /*
+ * Populate attributes, starting with the application's template,
+ * which we assume has already been blessed by the API function that
+ * called this method.
+ *
+ * If the attribute is flagged as sensitive in the descriptor, we
+ * don't store it as an attribute. Generally, this only arises for
+ * private key components of objects created with C_CreateObject(),
+ * but in theory there are some corner cases in which a user could
+ * choose to mark a private key as extractable and not sensitive, so
+ * we might have to back-fill missing values in those cases if
+ * anyone ever thinks up a sane reason for supporting them. For
+ * now, assume that private keys are bloody well supposed to be
+ * private.
+ */
+
+ hal_rpc_pkey_attribute_t attributes[template_length + descriptor->n_attributes + extra_length];
+ unsigned n = 0;
+
+ for (int i = 0; i < template_length; i++) {
+ const CK_ATTRIBUTE_TYPE type = template[i].type;
+ const void * val = template[i].pValue;
+ const int len = template[i].ulValueLen;
+
+ if (p11_attribute_is_sensitive(descriptor, type))
+ continue;
+
+ if (n >= sizeof(attributes) / sizeof(*attributes))
+ return 0;
+
+ attributes[n].type = type;
+ attributes[n].value = val;
+ attributes[n].length = len;
+ n++;
+ }
+
+ /*
+ * Next, add defaults from the descriptor.
+ */
+
+ for (int i = 0; i < descriptor->n_attributes; i++) {
+ const CK_ATTRIBUTE_TYPE type = descriptor->attributes[i].type;
+ const void * val = descriptor->attributes[i].value;
+ const int len = descriptor->attributes[i].length;
+ const unsigned flags = descriptor->attributes[i].flags;
+
+ if (val == NULL && (flags & P11_DESCRIPTOR_DEFAULT_VALUE) != 0)
+ val = "";
+
+ if (val == NULL || p11_attribute_find_in_template(type, template, template_length) >= 0)
+ continue;
+
+ if (n >= sizeof(attributes) / sizeof(*attributes))
+ return 0;
+
+ attributes[n].type = type;
+ attributes[n].value = val;
+ attributes[n].length = len;
+ n++;
+ }
+
+ /*
+ * Finally, add any attributes provided by the calling function itself.
+ */
+
+ for (int i = 0; i < extra_length; i++) {
+ if (n >= sizeof(attributes) / sizeof(*attributes))
+ return 0;
+
+ attributes[n].type = extra[i].type;
+ attributes[n].value = extra[i].value;
+ attributes[n].length = extra[i].length;
+ n++;
+ }
+
+ /*
+ * Set all those attributes.
+ */
+
+ if (!hal_check(hal_rpc_pkey_set_attributes(pkey, attributes, n)))
+ return 0;
+
+ return 1;
+}
+
+/*
* Map a keyusage-related attribute to a keyusage bit flag.
*
* Assumes that calling code has already checked whether this
@@ -832,65 +918,42 @@ static void p11_attribute_apply_keyusage(hal_key_flags_t *keyusage, const CK_ATT
/*
- * Descriptor methods. Descriptors are generated at compile time by
- * an auxiliary Python script, see attributes.* for details.
+ * Object methods.
*/
/*
- * Return the descriptor associated with a particular object class and
- * key type.
- */
-
-static const p11_descriptor_t *p11_descriptor_from_key_type(const CK_OBJECT_CLASS object_class,
- const CK_KEY_TYPE key_type)
-{
- int i;
-
- for (i = 0; i < sizeof(p11_descriptor_keyclass_map)/sizeof(*p11_descriptor_keyclass_map); i++) {
- const p11_descriptor_keyclass_map_t * const m = &p11_descriptor_keyclass_map[i];
- if (m->object_class == object_class && m->key_type == key_type)
- return m->descriptor;
- }
-
- return NULL;
-}
-
-/*
- * Find the entry for a particular attribute in a descriptor.
+ * Look up an object's UUID in the object index table, return
+ * indication of whether it's present or not and the position it
+ * should occupy within the index table in either case.
+ *
+ * NB: *where is a position in p11_object_uuids[], not p11_objects[].
*/
-static const p11_attribute_descriptor_t *p11_find_attribute_in_descriptor(const p11_descriptor_t *descriptor,
- const CK_ATTRIBUTE_TYPE type)
+static int p11_object_uuid_bsearch(const hal_uuid_t * const uuid, int *where)
{
- int i;
-
- if (descriptor != NULL && descriptor->attributes != NULL)
- for (i = 0; i < descriptor->n_attributes; i++)
- if (descriptor->attributes[i].type == type)
- return &descriptor->attributes[i];
+ assert(uuid != NULL && where != NULL);
- return NULL;
-}
+ int lo = -1;
+ int hi = p11_objects_in_use;
-/*
- * Check whether an attribute is marked as sensitive. If we don't
- * recognize the attribute, report it as sensitive (safer than the
- * alternative).
- */
-
-static int p11_attribute_is_sensitive(const p11_descriptor_t *descriptor,
- const CK_ATTRIBUTE_TYPE type)
-{
- const p11_attribute_descriptor_t *a = p11_find_attribute_in_descriptor(descriptor, type);
- return a == NULL || (a->flags & P11_DESCRIPTOR_SENSITIVE) != 0;
+ for (;;) {
+ int m = (lo + hi) / 2;
+ if (hi == 0 || m == lo) {
+ *where = hi;
+ return 0;
+ }
+ const int cmp = hal_uuid_cmp(uuid, &p11_objects[p11_object_uuids[m]].uuid);
+ if (cmp < 0)
+ hi = m;
+ else if (cmp > 0)
+ lo = m;
+ else {
+ *where = m;
+ return 1;
+ }
+ }
}
-
-
-/*
- * Object methods.
- */
-
/*
* Allocate a new object.
*/
@@ -905,6 +968,17 @@ static CK_OBJECT_HANDLE p11_object_allocate(const handle_flavor_t flavor,
if (flavor != handle_flavor_token_object && flavor != handle_flavor_session_object)
return CK_INVALID_HANDLE;
+ int where;
+
+ if (p11_object_uuid_bsearch(uuid, &where)) {
+ assert(where >= 0 && where < p11_objects_in_use);
+ const CK_OBJECT_HANDLE handle = p11_objects[p11_object_uuids[where]].handle;
+ return handle_flavor(handle) == flavor ? handle : CK_INVALID_HANDLE;
+ }
+
+ if (p11_objects_in_use >= sizeof(p11_objects) / sizeof(*p11_objects))
+ return CK_INVALID_HANDLE;
+
static unsigned next_index, nonce;
const unsigned last_index = next_index;
p11_object_t *object = NULL;
@@ -919,13 +993,22 @@ static CK_OBJECT_HANDLE p11_object_allocate(const handle_flavor_t flavor,
if (next_index == 0)
++nonce;
- object = p11_objects[next_index];
+ object = &p11_objects[next_index];
- } while (object.handle == CK_INVALID_HANDLE);
+ } while (object->handle != CK_INVALID_HANDLE);
- object->handle = handle_compose(flavor, nonce, next_handle);
+ object->handle = handle_compose(flavor, nonce, next_index);
object->uuid = *uuid;
object->session = flavor == handle_flavor_session_object ? session->handle : CK_INVALID_HANDLE;
+
+ if (where < p11_objects_in_use)
+ memmove(&p11_object_uuids[where + 1], &p11_object_uuids[where],
+ (p11_objects_in_use - where) * sizeof(*p11_object_uuids));
+
+ p11_object_uuids[where] = next_index;
+
+ p11_objects_in_use++;
+
return object->handle;
}
@@ -938,16 +1021,44 @@ static void p11_object_free(p11_object_t *object)
if (object == NULL)
return;
-#warning Should we delete session objects here?
+ int where;
+
+ if (p11_objects_in_use > 0 &&
+ p11_object_uuid_bsearch(&object->uuid, &where) &&
+ --p11_objects_in_use > where)
+ memmove(&p11_object_uuids[where], &p11_object_uuids[where + 1],
+ (p11_objects_in_use - where) * sizeof(*p11_object_uuids));
memset(object, 0, sizeof(*object));
}
/*
- * Find an object.
+ * Find an object given its UUID.
*/
-static p11_object_t *p11_object_find(const CK_OBJECT_HANDLE object_handle)
+static p11_object_t *p11_object_by_uuid(const hal_uuid_t * const uuid)
+{
+ int where;
+
+ if (uuid == NULL || !p11_object_uuid_bsearch(uuid, &where))
+ return NULL;
+
+ assert(where >= 0 && where < p11_objects_in_use);
+
+ p11_object_t *object = &p11_objects[p11_object_uuids[where]];
+
+ if (handle_flavor(object->handle) != handle_flavor_session_object &&
+ handle_flavor(object->handle) != handle_flavor_token_object)
+ return NULL;
+
+ return object;
+}
+
+/*
+ * Find an object given its handle.
+ */
+
+static p11_object_t *p11_object_by_handle(const CK_OBJECT_HANDLE object_handle)
{
if (handle_flavor(object_handle) != handle_flavor_session_object &&
handle_flavor(object_handle) != handle_flavor_token_object)
@@ -966,25 +1077,27 @@ static p11_object_t *p11_object_find(const CK_OBJECT_HANDLE object_handle)
return object;
}
+#if 0
+
/*
* Iterate over object handles. Start with CK_INVALID_HANDLE,
* returns CK_INVALID_HANDLE when done.
*/
-static CK_BJECT_HANDLE p11_object_handle_iterate(const CK_OBJECT_HANDLE object_handle)
+static CK_OBJECT_HANDLE p11_object_handle_iterate(const CK_OBJECT_HANDLE object_handle)
{
if (handle_flavor(object_handle) != handle_flavor_session_object &&
handle_flavor(object_handle) != handle_flavor_token_object)
- return CK_HANDLE_INVALID;
+ return CK_INVALID_HANDLE;
- for (unsigned index = session_handle == CK_INVALID_HANDLE ? 0 : handle_index(session_handle) + 1;
+ for (unsigned index = object_handle == CK_INVALID_HANDLE ? 0 : handle_index(object_handle) + 1;
index < sizeof(p11_sessions) / sizeof(*p11_sessions);
index++)
if (handle_flavor(p11_sessions[index].handle) == handle_flavor_session_object ||
handle_flavor(p11_sessions[index].handle) == handle_flavor_token_object)
return p11_sessions[index].handle;
- return CK_HANDLE_INVALID;
+ return CK_INVALID_HANDLE;
}
/*
@@ -996,9 +1109,11 @@ static p11_object_t *p11_object_iterate(p11_object_t *object)
if (object == NULL)
return NULL;
- return p11_object_find(p11_object_handle_iterate(object->handle));
+ return p11_object_by_handle(p11_object_handle_iterate(object->handle));
}
+#endif
+
/*
* Translate CKA_TOKEN value to handle flavor.
*/
@@ -1008,6 +1123,12 @@ static inline handle_flavor_t p11_object_flavor_from_cka_token(const CK_BBOOL *b
return (bbool != NULL && *bbool) ? handle_flavor_token_object : handle_flavor_session_object;
}
+static inline hal_key_flags_t p11_object_hal_flags(const CK_OBJECT_HANDLE handle)
+{
+ return handle_flavor(handle) == handle_flavor_token_object ? HAL_KEY_FLAG_TOKEN : 0;
+}
+
+
/*
* Open the HSM pkey object (if any) corresponding to the PKCS #11 handle.
*/
@@ -1016,12 +1137,13 @@ static int p11_object_pkey_open(const p11_session_t *session,
const CK_OBJECT_HANDLE object_handle,
hal_pkey_handle_t *pkey)
{
- return (session != NULL && pkey != NULL &&
+ const p11_object_t *object = p11_object_by_handle(object_handle);
+
+ return (session != NULL && pkey != NULL && object != NULL &&
hal_check(hal_rpc_pkey_open(p11_session_hal_client(session),
p11_session_hal_session(session),
- pkey,
- p11_object_get_uuid(object_handle),
- p11_object_get_hal_flags(object_handle))));
+ pkey, &object->uuid,
+ p11_object_hal_flags(object_handle))));
}
/*
@@ -1032,25 +1154,15 @@ typedef enum { p11_object_access_read, p11_object_access_write } p11_object_acce
static CK_RV p11_object_check_rights(const p11_session_t *session,
const CK_OBJECT_HANDLE object_handle,
- const p11_object_access_t rights)
+ const p11_object_access_t rights,
+ const CK_BBOOL cka_private,
+ const CK_BBOOL cka_token)
{
- hal_pkey_handle_t pkey = {HAL_HANDLE_NONE};
- CK_BBOOL cka_private;
- CK_BBOOL cka_token;
CK_RV rv;
if (session == NULL)
lose(CKR_SESSION_HANDLE_INVALID);
- if (!p11_object_pkey_open(session, object_handle, &pkey))
- lose(CKR_OBJECT_HANDLE_INVALID);
-
- if (!p11_attribute_get_bbool(pkey, CKA_PRIVATE, &cka_private))
- cka_private = CK_TRUE;
-
- if (!p11_attribute_get_bbool(pkey, CKA_TOKEN, &cka_token))
- cka_token = CK_FALSE;
-
/*
* Read-only sessions are, um, read-only. Well, except, in PKCS #11,
* read-only only sort of means what you might expect.
@@ -1091,122 +1203,10 @@ static CK_RV p11_object_check_rights(const p11_session_t *session,
rv = CKR_OK;
fail:
- (void) hal_check(hal_rpc_pkey_close(pkey));
return rv;
}
/*
- * Given a pkey handle and UUID for a newly created HSM key, attach
- * attributes and create an object handle.
- */
-
-static CK_OBJECT_HANDLE p11_object_create(const p11_session_t *session,
- const hal_pkey_handle_t pkey,
- const hal_uuid_t *uuid,
- const handle_flavor_t flavor,
- const CK_ATTRIBUTE_PTR template,
- const CK_ULONG template_length,
- const p11_descriptor_t * const descriptor,
- const hal_rpc_pkey_attribute_t *extra,
- const unsigned extra_length)
-{
- assert(session != NULL && template != NULL && descriptor != NULL && uuid != NULL &&
- (extra_length == 0 || extra != NULL) &&
- (flavor == handle_flavor_token_object || flavor == handle_flavor_session_object));
-
- /*
- * Populate attributes, starting with the application's template,
- * which we assume has already been blessed by the API function that
- * called this method.
- *
- * If the attribute is flagged as sensitive in the descriptor, we
- * don't store it as an attribute. Generally, this only arises for
- * private key components of objects created with C_CreateObject(),
- * but in theory there are some corner cases in which a user could
- * choose to mark a private key as extractable and not sensitive, so
- * we might have to back-fill missing values in those cases if
- * anyone ever thinks up a sane reason for supporting them. For
- * now, assume that private keys are bloody well supposed to be
- * private.
- */
-
- hal_rpc_pkey_attribute_t attributes[template_length + descriptor->n_attributes + extra_length];
- unsigned n = 0;
-
- for (int i = 0; i < template_length; i++) {
- const CK_ATTRIBUTE_TYPE type = template[i].type;
- const void * val = template[i].pValue;
- const int len = template[i].ulValueLen;
-
- if (p11_attribute_is_sensitive(descriptor, type))
- continue;
-
- if (n >= sizeof(attributes) / sizeof(*attributes))
- lose(CKR_FUNCTION_FAILED);
-
- attributes[n].type = type;
- attributes[n].value = val;
- attributes[n].length = len;
- n++;
- }
-
- /*
- * Next, add defaults from the descriptor.
- */
-
- for (int i = 0; i < descriptor->n_attributes; i++) {
- const CK_ATTRIBUTE_TYPE type = descriptor->attributes[i].type;
- const void * val = descriptor->attributes[i].value;
- const int len = descriptor->attributes[i].length;
- const unsigned flags = descriptor->attributes[i].flags;
-
- if (val == NULL && (flags & P11_DESCRIPTOR_DEFAULT_VALUE) != 0)
- val = "";
-
- if (val == NULL || p11_attribute_find_in_template(type, template, template_length) >= 0)
- continue;
-
- if (n >= sizeof(attributes) / sizeof(*attributes))
- lose(CKR_FUNCTION_FAILED);
-
- attributes[n].type = type;
- attributes[n].value = val;
- attributes[n].length = len;
- n++;
- }
-
- /*
- * Finally, add any attributes provided by the calling function itself.
- */
-
- for (int i = 0; i < extra_length; i++) {
- if (n >= sizeof(attributes) / sizeof(*attributes))
- lose(CKR_FUNCTION_FAILED);
-
- attributes[n].type = extra[i].type;
- attributes[n].value = extra[i].value;
- attributes[n].length = extra[i].length;
- n++;
- }
-
- /*
- * Set all those attributes.
- */
-
- if (!hal_check(hal_rpc_pkey_set_attributes(pkey, attributes, n)))
- lose(CKR_FUNCTION_FAILED);
-
- /*
- * Create the object handle, then we're done.
- */
-
- return p11_object_allocate(flavor, uuid, session);
-
- fail:
- return CK_INVALID_HANDLE;
-}
-
-/*
* Create pkeys to go with PKCS #11 key objects loaded by C_CreateObject().
*/
@@ -1218,13 +1218,14 @@ static int p11_object_create_rsa_public_key(const p11_session_t * const session,
CK_OBJECT_HANDLE_PTR phObject,
const hal_key_flags_t flags)
{
- const hal_rpc_pkey_attributes extra[] = {
- {.type = CKA_LOCAL, .value = &const_CKA_FALSE, .length = sizeof(const_CKA_FALSE)}
+ const hal_rpc_pkey_attribute_t extra[] = {
+ {.type = CKA_LOCAL, .value = &const_CK_FALSE, .length = sizeof(const_CK_FALSE)}
};
hal_pkey_handle_t pkey = {HAL_HANDLE_NONE};
uint8_t keybuf[hal_rsa_key_t_size];
hal_rsa_key_t *key = NULL;
+ hal_uuid_t uuid;
const uint8_t *cka_modulus = NULL;
size_t cka_modulus_len = 0;
@@ -1246,7 +1247,6 @@ static int p11_object_create_rsa_public_key(const p11_session_t * const session,
if (ok) {
uint8_t der[hal_rsa_public_key_to_der_len(key)];
- hal_uuid_t uuid;
ok = (hal_check(hal_rsa_public_key_to_der(key, der, NULL, sizeof(der))) &&
hal_check(hal_rpc_pkey_load(p11_session_hal_client(session),
p11_session_hal_session(session),
@@ -1254,9 +1254,12 @@ static int p11_object_create_rsa_public_key(const p11_session_t * const session,
&uuid, der, sizeof(der), flags)));
}
+ if (ok)
+ ok = p11_attributes_set(pkey, template, template_len, descriptor,
+ extra, sizeof(extra)/sizeof(*extra));
+
if (ok) {
- *phObject = p11_object_create(session, pkey, &uuid, flavor, template, template_len,
- descriptor, extra, sizeof(extra)/sizeof(*extra));
+ *phObject = p11_object_allocate(flavor, &uuid, session);
ok = *phObject != CK_INVALID_HANDLE;
}
@@ -1276,14 +1279,15 @@ static int p11_object_create_ec_public_key(const p11_session_t * const session,
CK_OBJECT_HANDLE_PTR phObject,
const hal_key_flags_t flags)
{
- const hal_rpc_pkey_attributes extra[] = {
- {.type = CKA_LOCAL, .value = &const_CKA_FALSE, .length = sizeof(const_CKA_FALSE)}
+ const hal_rpc_pkey_attribute_t extra[] = {
+ {.type = CKA_LOCAL, .value = &const_CK_FALSE, .length = sizeof(const_CK_FALSE)}
};
hal_pkey_handle_t pkey = {HAL_HANDLE_NONE};
uint8_t keybuf[hal_ecdsa_key_t_size];
hal_ecdsa_key_t *key = NULL;
hal_curve_name_t curve;
+ hal_uuid_t uuid;
const uint8_t *cka_ec_point = NULL; size_t cka_ec_point_len = 0;
const uint8_t *cka_ec_params = NULL; size_t cka_ec_params_len = 0;
@@ -1305,7 +1309,6 @@ static int p11_object_create_ec_public_key(const p11_session_t * const session,
if (ok) {
uint8_t der[hal_ecdsa_public_key_to_der_len(key)];
- hal_uuid_t uuid;
ok = (hal_check(hal_ecdsa_public_key_to_der(key, der, NULL, sizeof(der))) &&
hal_check(hal_rpc_pkey_load(p11_session_hal_client(session),
p11_session_hal_session(session),
@@ -1313,9 +1316,12 @@ static int p11_object_create_ec_public_key(const p11_session_t * const session,
&uuid, der, sizeof(der), flags)));
}
+ if (ok)
+ ok = p11_attributes_set(pkey, template, template_len, descriptor,
+ extra, sizeof(extra)/sizeof(*extra));
+
if (ok) {
- *phObject = p11_object_create(session, pkey, &uuid, flavor, template, template_len,
- descriptor, extra, sizeof(extra)/sizeof(*extra));
+ *phObject = p11_object_allocate(flavor, &uuid, session);
ok = *phObject != CK_INVALID_HANDLE;
}
@@ -1335,10 +1341,10 @@ static int p11_object_create_rsa_private_key(const p11_session_t * const session
CK_OBJECT_HANDLE_PTR phObject,
const hal_key_flags_t flags)
{
- const hal_rpc_pkey_attributes extra[] = {
- {.type = CKA_LOCAL, .value = &const_CKA_FALSE, .length = sizeof(const_CKA_FALSE)},
- {.type = CKA_ALWAYS_SENSITIVE, .value = &const_CKA_FALSE, .length = sizeof(const_CKA_FALSE)},
- {.type = CKA_NEVER_EXTRACTABLE, .value = &const_CKA_FALSE, .length = sizeof(const_CKA_FALSE)}
+ const hal_rpc_pkey_attribute_t extra[] = {
+ {.type = CKA_LOCAL, .value = &const_CK_FALSE, .length = sizeof(const_CK_FALSE)},
+ {.type = CKA_ALWAYS_SENSITIVE, .value = &const_CK_FALSE, .length = sizeof(const_CK_FALSE)},
+ {.type = CKA_NEVER_EXTRACTABLE, .value = &const_CK_FALSE, .length = sizeof(const_CK_FALSE)}
};
hal_pkey_handle_t pkey = {HAL_HANDLE_NONE};
@@ -1394,9 +1400,12 @@ static int p11_object_create_rsa_private_key(const p11_session_t * const session
memset(keybuf, 0, sizeof(keybuf));
+ if (ok)
+ ok = p11_attributes_set(pkey, template, template_len, descriptor,
+ extra, sizeof(extra)/sizeof(*extra));
+
if (ok) {
- *phObject = p11_object_create(session, pkey, &uuid, flavor, template, template_len,
- descriptor, extra, sizeof(extra)/sizeof(*extra));
+ *phObject = p11_object_allocate(flavor, &uuid, session);
ok = *phObject != CK_INVALID_HANDLE;
}
@@ -1416,16 +1425,17 @@ static int p11_object_create_ec_private_key(const p11_session_t * const session,
CK_OBJECT_HANDLE_PTR phObject,
const hal_key_flags_t flags)
{
- const hal_rpc_pkey_attributes extra[] = {
- {.type = CKA_LOCAL, .value = &const_CKA_FALSE, .length = sizeof(const_CKA_FALSE)},
- {.type = CKA_ALWAYS_SENSITIVE, .value = &const_CKA_FALSE, .length = sizeof(const_CKA_FALSE)},
- {.type = CKA_NEVER_EXTRACTABLE, .value = &const_CKA_FALSE, .length = sizeof(const_CKA_FALSE)}
+ const hal_rpc_pkey_attribute_t extra[] = {
+ {.type = CKA_LOCAL, .value = &const_CK_FALSE, .length = sizeof(const_CK_FALSE)},
+ {.type = CKA_ALWAYS_SENSITIVE, .value = &const_CK_FALSE, .length = sizeof(const_CK_FALSE)},
+ {.type = CKA_NEVER_EXTRACTABLE, .value = &const_CK_FALSE, .length = sizeof(const_CK_FALSE)}
};
hal_pkey_handle_t pkey = {HAL_HANDLE_NONE};
uint8_t keybuf[hal_ecdsa_key_t_size];
hal_ecdsa_key_t *key = NULL;
hal_curve_name_t curve;
+ hal_uuid_t uuid;
const uint8_t *cka_value = NULL; size_t cka_value_len = 0;
const uint8_t *cka_ec_point = NULL; size_t cka_ec_point_len = 0;
@@ -1453,7 +1463,6 @@ static int p11_object_create_ec_private_key(const p11_session_t * const session,
if (ok) {
uint8_t der[hal_ecdsa_private_key_to_der_len(key)];
- hal_uuid_t uuid;
ok = (hal_check(hal_ecdsa_private_key_to_der(key, der, NULL, sizeof(der))) &&
hal_check(hal_rpc_pkey_load(p11_session_hal_client(session),
p11_session_hal_session(session),
@@ -1464,9 +1473,12 @@ static int p11_object_create_ec_private_key(const p11_session_t * const session,
memset(keybuf, 0, sizeof(keybuf));
+ if (ok)
+ ok = p11_attributes_set(pkey, template, template_len, descriptor,
+ extra, sizeof(extra)/sizeof(*extra));
+
if (ok) {
- *phObject = p11_object_create(session, pkey, &uuid, flavor, template, template_len,
- descriptor, extra, sizeof(extra)/sizeof(*extra));
+ *phObject = p11_object_allocate(flavor, &uuid, session);
ok = *phObject != CK_INVALID_HANDLE;
}
@@ -1507,12 +1519,12 @@ static p11_session_t *p11_session_allocate(void)
if (next_index == 0)
++nonce;
- session = p11_sessions[next_index];
+ session = &p11_sessions[next_index];
- } while (session.handle == CK_INVALID_HANDLE);
+ } while (session->handle != CK_INVALID_HANDLE);
memset(session, 0, sizeof(*session));
- session.handle = handle_compose(handle_flavor_session, nonce, next_handle);
+ session->handle = handle_compose(handle_flavor_session, nonce, next_index);
p11_sessions_in_use++;
return session;
}
@@ -1576,7 +1588,7 @@ static p11_session_t *p11_session_find(const CK_SESSION_HANDLE session_handle)
static CK_SESSION_HANDLE p11_session_handle_iterate(const CK_SESSION_HANDLE session_handle)
{
if (handle_flavor(session_handle) != handle_flavor_session)
- return CK_HANDLE_INVALID;
+ return CK_INVALID_HANDLE;
for (unsigned index = session_handle == CK_INVALID_HANDLE ? 0 : handle_index(session_handle) + 1;
index < sizeof(p11_sessions) / sizeof(*p11_sessions);
@@ -1584,7 +1596,7 @@ static CK_SESSION_HANDLE p11_session_handle_iterate(const CK_SESSION_HANDLE sess
if (handle_flavor(p11_sessions[index].handle) == handle_flavor_session)
return p11_sessions[index].handle;
- return CK_HANDLE_INVALID;
+ return CK_INVALID_HANDLE;
}
/*
@@ -1995,21 +2007,22 @@ static CK_RV generate_keypair_rsa_pkcs(p11_session_t *session,
lose(CKR_FUNCTION_FAILED);
const hal_rpc_pkey_attribute_t extra[] = {
- {.type = CKA_LOCAL,
- .value = &const_CK_TRUE, .length = sizeof(const_CK_TRUE)},
- {.type = CKA_KEY_GEN_MECHANISM,
- .value = &mechanism->mechanism, .length = sizeof(mechanism->mechanism)},
- {.type = CKA_MODULUS,
- value = modulus, .length = modulus_len}
+ {.type = CKA_LOCAL,
+ .value = &const_CK_TRUE, .length = sizeof(const_CK_TRUE)},
+ {.type = CKA_KEY_GEN_MECHANISM,
+ .value = &pMechanism->mechanism, .length = sizeof(pMechanism->mechanism)},
+ {.type = CKA_MODULUS,
+ .value = modulus, .length = modulus_len}
};
- *phPrivateKey = p11_object_create(session, private_pkey, &private_uuid, private_handle_flavor,
- pPrivateKeyTemplate, ulPrivateKeyAttributeCount,
- private_descriptor, extra, sizeof(extra)/sizeof(*extra));
+ if (!p11_attributes_set(private_pkey, pPrivateKeyTemplate, ulPrivateKeyAttributeCount,
+ private_descriptor, extra, sizeof(extra)/sizeof(*extra)) ||
+ !p11_attributes_set(public_pkey, pPublicKeyTemplate, ulPublicKeyAttributeCount,
+ public_descriptor, extra, sizeof(extra)/sizeof(*extra)))
+ lose(CKR_FUNCTION_FAILED);
- *phPublicKey = p11_object_create(session, public_handle_flavor,
- pPublicKeyTemplate, ulPublicKeyAttributeCount,
- public_descriptor, extra, sizeof(extra)/sizeof(*extra));
+ *phPrivateKey = p11_object_allocate(private_handle_flavor, &private_uuid, session);
+ *phPublicKey = p11_object_allocate(public_handle_flavor, &public_uuid, session);
if (*phPrivateKey == CK_INVALID_HANDLE || *phPublicKey == CK_INVALID_HANDLE)
lose(CKR_FUNCTION_FAILED);
@@ -2094,23 +2107,24 @@ static CK_RV generate_keypair_ec(p11_session_t *session,
lose(CKR_FUNCTION_FAILED);
const hal_rpc_pkey_attribute_t extra[] = {
- {.type = CKA_LOCAL,
- .value = &const_CK_TRUE, .length = sizeof(const_CK_TRUE)},
- {.type = CKA_KEY_GEN_MECHANISM,
- .value = &mechanism->mechanism, .length = sizeof(mechanism->mechanism)},
- {.type = CKA_EC_PARAMS,
- value = params, .length = params_len},
- {.type = CKA_EC_POINT,
- value = point, .length = sizeof(point)}
+ {.type = CKA_LOCAL,
+ .value = &const_CK_TRUE, .length = sizeof(const_CK_TRUE)},
+ {.type = CKA_KEY_GEN_MECHANISM,
+ .value = &pMechanism->mechanism, .length = sizeof(pMechanism->mechanism)},
+ {.type = CKA_EC_PARAMS,
+ .value = params, .length = params_len},
+ {.type = CKA_EC_POINT,
+ .value = point, .length = sizeof(point)}
};
- *phPrivateKey = p11_object_create(session, private_pkey, &private_uuid, private_handle_flavor,
- pPrivateKeyTemplate, ulPrivateKeyAttributeCount,
- private_descriptor, extra, sizeof(extra)/sizeof(*extra) - 1);
+ if (!p11_attributes_set(private_pkey, pPrivateKeyTemplate, ulPrivateKeyAttributeCount,
+ private_descriptor, extra, sizeof(extra)/sizeof(*extra) - 1) ||
+ !p11_attributes_set(public_pkey, pPublicKeyTemplate, ulPublicKeyAttributeCount,
+ public_descriptor, extra, sizeof(extra)/sizeof(*extra)))
+ lose(CKR_FUNCTION_FAILED);
- *phPublicKey = p11_object_create(session, public_handle_flavor,
- pPublicKeyTemplate, ulPublicKeyAttributeCount,
- public_descriptor, extra, sizeof(extra)/sizeof(*extra));
+ *phPrivateKey = p11_object_allocate(private_handle_flavor, &private_uuid, session);
+ *phPublicKey = p11_object_allocate(public_handle_flavor, &public_uuid, session);
if (*phPrivateKey == CK_INVALID_HANDLE || *phPublicKey == CK_INVALID_HANDLE)
lose(CKR_FUNCTION_FAILED);
@@ -2318,36 +2332,37 @@ static void digest_cleanup(hal_hash_handle_t *handle)
}
/*
- * Compute the length of a signature based on the key. We could get
- * this via the RPC API, but its probably faster to look in the local
- * attribute database. Rewrite this later if this proves incorrect.
+ * Compute the length of a signature based on the key.
*/
-static int get_signature_len(const CK_OBJECT_HANDLE object_handle,
- const hal_pkey_handle_t pkey,
+static int get_signature_len(const hal_pkey_handle_t pkey,
size_t *signature_len)
{
assert(signature_len != NULL);
- CK_KEY_TYPE cka_key_type;
+ hal_rpc_pkey_attribute_t attribute;
+ uint8_t attribute_buffer[sizeof(CK_KEY_TYPE)];
hal_curve_name_t curve;
CK_BYTE oid[20];
- CK_ULONG len;
- if (!p11_attribute_get_ulong(session, object_handle, CKA_KEY_TYPE, &cka_key_type))
+ attribute.type = CKA_KEY_TYPE;
+ if (!hal_check(hal_rpc_pkey_get_attributes(pkey, &attribute, 1,
+ attribute_buffer, sizeof(attribute_buffer))))
return 0;
- switch (cka_key_type) {
+ switch (*(CK_KEY_TYPE*)attribute.value) {
case CKK_RSA:
- if (!p11_attribute_get(session, object_handle, CKA_MODULUS, NULL, &len, 0))
+ attribute.type = CKA_MODULUS;
+ if (!hal_check(hal_rpc_pkey_get_attributes(pkey, &attribute, 1, NULL, 0)))
return 0;
- *signature_len = len;
+ *signature_len = attribute.length;
return 1;
case CKK_EC:
- if (!p11_attribute_get(session, object_handle, CKA_EC_PARAMS, oid, &len, sizeof(oid)) ||
- !ec_curve_oid_to_name(oid, len, &curve))
+ attribute.type = CKA_EC_PARAMS;
+ if (!hal_check(hal_rpc_pkey_get_attributes(pkey, &attribute, 1, oid, sizeof(oid))) ||
+ !ec_curve_oid_to_name(attribute.value, attribute.length, &curve))
return 0;
switch (curve) {
case HAL_CURVE_P256: *signature_len = 64; return 1;
@@ -2379,7 +2394,7 @@ static CK_RV sign_hal_rpc(p11_session_t *session,
if (!p11_object_pkey_open(session, session->sign_key_handle, &pkey))
lose(CKR_FUNCTION_FAILED);
- if (!get_signature_len(session->sign_key_handle, pkey, &signature_len))
+ if (!get_signature_len(pkey, &signature_len))
lose(CKR_FUNCTION_FAILED);
rv = pSignature != NULL && signature_len > *pulSignatureLen ? CKR_BUFFER_TOO_SMALL : CKR_OK;
@@ -2560,7 +2575,7 @@ CK_RV C_Finalize(CK_VOID_PTR pReserved)
* Destroy all current sessions.
*/
- p11_session_delete_all();
+ p11_session_free_all();
/*
* At this point we're pretty well committed to shutting down, so
@@ -2795,12 +2810,17 @@ CK_RV C_CloseSession(CK_SESSION_HANDLE hSession)
{
ENTER_PUBLIC_FUNCTION(C_CloseSession);
- CK_RV rv;
+ p11_session_t *session;
+ CK_RV rv = CKR_OK;
mutex_lock_or_return_failure(p11_global_mutex);
- rv = p11_session_delete(hSession);
+ if ((session = p11_session_find(hSession)) == NULL)
+ lose(CKR_SESSION_HANDLE_INVALID);
+
+ p11_session_free(session);
+ fail:
mutex_unlock_return_with_rv(rv, p11_global_mutex);
}
@@ -2813,7 +2833,7 @@ CK_RV C_CloseAllSessions(CK_SLOT_ID slotID)
mutex_lock_or_return_failure(p11_global_mutex);
- p11_session_delete_all();
+ p11_session_free_all();
return mutex_unlock(p11_global_mutex);
}
@@ -2924,6 +2944,7 @@ CK_RV C_Logout(CK_SESSION_HANDLE hSession)
ENTER_PUBLIC_FUNCTION(C_Logout);
const hal_client_handle_t client = {HAL_HANDLE_NONE};
+ p11_session_t *session = NULL;
CK_RV rv = CKR_OK;
mutex_lock_or_return_failure(p11_global_mutex);
@@ -2934,7 +2955,7 @@ CK_RV C_Logout(CK_SESSION_HANDLE hSession)
* anything special for "this" session.
*/
- if (p11_session_find(hSession) == NULL)
+ if ((session = p11_session_find(hSession)) == NULL)
lose(CKR_SESSION_HANDLE_INVALID);
if (logged_in_as == not_logged_in)
@@ -2950,7 +2971,7 @@ CK_RV C_Logout(CK_SESSION_HANDLE hSession)
const hal_session_handle_t session_handle_none = {HAL_HANDLE_NONE};
- const hal_rpc_pkey_attribute attrs[] = {
+ const hal_rpc_pkey_attribute_t attrs[] = {
{.type = CKA_PRIVATE, .value = &const_CK_TRUE, .length = sizeof(const_CK_TRUE)}
};
@@ -2965,12 +2986,13 @@ CK_RV C_Logout(CK_SESSION_HANDLE hSession)
HAL_KEY_TYPE_NONE, HAL_CURVE_NONE,
0,
attrs, sizeof(attrs)/sizeof(*attrs),
- uuids, &n, sizeof(uuids)/sizeof(*uuuids),
- &uuids[sizeof(uuids)/sizeof(*uuuids) - 1]));
+ uuids, &n, sizeof(uuids)/sizeof(*uuids),
+ &uuids[sizeof(uuids)/sizeof(*uuids) - 1]));
if (rv != CKR_OK)
goto fail;
for (int i = 0; i < n; i++) {
+ p11_object_free(p11_object_by_uuid(&uuids[i]));
hal_pkey_handle_t pkey;
rv = p11_whine_from_hal(hal_rpc_pkey_open(p11_session_hal_client(session),
session_handle_none, &pkey, &uuids[i], 0));
@@ -2982,17 +3004,7 @@ CK_RV C_Logout(CK_SESSION_HANDLE hSession)
}
}
- if (n > 0) {
- for (CK_OBJECT_HANDLE handle = p11_object_handle_iterate(CK_INVALID_HANDLE);
- handle != CK_INVALID_HANDLE; handle = p11_object_handle_iterate(handle)) {
- p11_object_t *object = p11_object_find(handle);
- assert(object != NULL);
- if (bsearch(&object->uuid, uuids, n, sizeof(*uuids), hal_uuid_cmp) != NULL)
- p11_object_free(object);
- }
- }
-
- } while (n == sizeof(uuids)/sizeof(*uuuids));
+ } while (n == sizeof(uuids)/sizeof(*uuids));
memset(uuids, 0, sizeof(uuids));
do {
@@ -3002,22 +3014,15 @@ CK_RV C_Logout(CK_SESSION_HANDLE hSession)
HAL_KEY_TYPE_NONE, HAL_CURVE_NONE,
HAL_KEY_FLAG_TOKEN,
attrs, sizeof(attrs)/sizeof(*attrs),
- uuids, &n, sizeof(uuids)/sizeof(*uuuids),
- &uuids[sizeof(uuids)/sizeof(*uuuids) - 1]));
+ uuids, &n, sizeof(uuids)/sizeof(*uuids),
+ &uuids[sizeof(uuids)/sizeof(*uuids) - 1]));
if (rv != CKR_OK)
goto fail;
- if (n > 0) {
- for (CK_OBJECT_HANDLE handle = p11_object_handle_iterate(CK_INVALID_HANDLE);
- handle != CK_INVALID_HANDLE; handle = p11_object_handle_iterate(handle)) {
- p11_object_t *object = p11_object_find(handle);
- assert(object != NULL);
- if (bsearch(&object->uuid, uuids, n, sizeof(*uuids), hal_uuid_cmp) != NULL)
- p11_object_free(object);
- }
- }
+ for (int i = 0; i < n; i++)
+ p11_object_free(p11_object_by_uuid(&uuids[i]));
- } while (n == sizeof(uuids)/sizeof(*uuuids));
+ } while (n == sizeof(uuids)/sizeof(*uuids));
for (p11_session_t *session = p11_session_iterate(NULL);
session != NULL; session = p11_session_iterate(session)) {
@@ -3054,7 +3059,6 @@ CK_RV C_CreateObject(CK_SESSION_HANDLE hSession,
{
ENTER_PUBLIC_FUNCTION(C_CreateObject);
- CK_OBJECT_HANDLE handle = CK_INVALID_HANDLE;
p11_session_t *session;
CK_RV rv;
@@ -3145,7 +3149,14 @@ CK_RV C_DestroyObject(CK_SESSION_HANDLE hSession,
{
ENTER_PUBLIC_FUNCTION(C_DestroyObject);
+ uint8_t attributes_buffer[2 * sizeof(CK_BBOOL)];
hal_pkey_handle_t pkey = {HAL_HANDLE_NONE};
+ hal_rpc_pkey_attribute_t attributes[] = {
+ [0].type = CKA_PRIVATE,
+ [1].type = CKA_TOKEN
+ };
+ CK_BBOOL cka_private;
+ CK_BBOOL cka_token;
p11_session_t *session;
CK_RV rv = CKR_OK;
@@ -3153,20 +3164,29 @@ CK_RV C_DestroyObject(CK_SESSION_HANDLE hSession,
session = p11_session_find(hSession);
- if ((rv = p11_object_check_rights(session, hObject, p11_object_access_write)) != CKR_OK)
- goto fail;
-
if (!p11_object_pkey_open(session, hObject, &pkey))
lose(CKR_FUNCTION_FAILED);
- if (!hal_check(hal_rpc_pkey_delete(pkey))) {
- (void) hal_rpc_pkey_close(pkey);
+ if (!hal_check(hal_rpc_pkey_get_attributes(pkey, attributes, sizeof(attributes)/sizeof(*attributes),
+ attributes_buffer, sizeof(attributes_buffer))))
+ lose(CKR_KEY_HANDLE_INVALID);
+
+ cka_private = *(CK_BBOOL*) attributes[0].value;
+ cka_token = *(CK_BBOOL*) attributes[1].value;
+
+ rv = p11_object_check_rights(session, hObject, p11_object_access_write, cka_private, cka_token);
+
+ if (rv != CKR_OK)
+ goto fail;
+
+ if (!hal_check(hal_rpc_pkey_delete(pkey)))
lose(CKR_FUNCTION_FAILED);
- }
- p11_object_free(p11_object_find(hObject));
+ p11_object_free(p11_object_by_handle(hObject));
fail:
+ if (pkey.handle != HAL_HANDLE_NONE)
+ (void) hal_rpc_pkey_close(pkey);
mutex_unlock_return_with_rv(rv, p11_global_mutex);
}
@@ -3177,12 +3197,14 @@ CK_RV C_GetAttributeValue(CK_SESSION_HANDLE hSession,
{
ENTER_PUBLIC_FUNCTION(C_GetAttributeValue);
- p11_session_t *session;
+ hal_pkey_handle_t pkey = {HAL_HANDLE_NONE};
const p11_descriptor_t *descriptor = NULL;
- CK_BBOOL cka_sensitive, cka_extractable;
+ CK_BBOOL cka_extractable, cka_sensitive;
CK_OBJECT_CLASS cka_class;
- CK_KEY_TYPE cka_key_type;
+ CK_BBOOL cka_private;
+ CK_BBOOL cka_token;
int sensitive_object = 0;
+ p11_session_t *session;
CK_RV rv;
mutex_lock_or_return_failure(p11_global_mutex);
@@ -3192,70 +3214,122 @@ CK_RV C_GetAttributeValue(CK_SESSION_HANDLE hSession,
session = p11_session_find(hSession);
- if ((rv = p11_object_check_rights(session, hObject, p11_object_access_read)) != CKR_OK)
- goto fail;
-
- if (!p11_attribute_get_ulong(session, hObject, CKA_CLASS, &cka_class))
+ if (!p11_object_pkey_open(session, hObject, &pkey))
lose(CKR_OBJECT_HANDLE_INVALID);
- switch (cka_class) {
+ {
+ hal_rpc_pkey_attribute_t attributes[] = {
+ [0].type = CKA_CLASS,
+ [1].type = CKA_PRIVATE,
+ [2].type = CKA_TOKEN
+ };
+ uint8_t attributes_buffer[sizeof(CK_OBJECT_CLASS) + 2 * sizeof(CK_BBOOL)];
- case CKO_PRIVATE_KEY:
- case CKO_SECRET_KEY:
- if (!p11_attribute_get_bbool(session, hObject, CKA_EXTRACTABLE, &cka_extractable) ||
- !p11_attribute_get_bbool(session, hObject, CKA_SENSITIVE, &cka_sensitive))
+ if (!hal_check(hal_rpc_pkey_get_attributes(pkey,
+ attributes, sizeof(attributes)/sizeof(*attributes),
+ attributes_buffer, sizeof(attributes_buffer))))
lose(CKR_OBJECT_HANDLE_INVALID);
- sensitive_object = cka_sensitive || !cka_extractable;
+ cka_class = *(CK_OBJECT_CLASS*) attributes[0].value;
+ cka_private = *(CK_BBOOL*) attributes[1].value;
+ cka_token = *(CK_BBOOL*) attributes[2].value;
- /* Fall through */
+ rv = p11_object_check_rights(session, hObject, p11_object_access_read, cka_private, cka_token);
- case CKO_PUBLIC_KEY:
- if (!p11_attribute_get_ulong(session, hObject, CKA_KEY_TYPE, &cka_key_type))
+ if (rv != CKR_OK)
+ goto fail;
+ }
+
+ if (cka_class == CKO_PRIVATE_KEY || cka_class == CKO_SECRET_KEY) {
+ hal_rpc_pkey_attribute_t attributes[] = {
+ [0].type = CKA_EXTRACTABLE,
+ [1].type = CKA_SENSITIVE
+ };
+ uint8_t attributes_buffer[sizeof(CK_OBJECT_CLASS) + sizeof(CK_KEY_TYPE)];
+
+ if (!hal_check(hal_rpc_pkey_get_attributes(pkey,
+ attributes, sizeof(attributes)/sizeof(*attributes),
+ attributes_buffer, sizeof(attributes_buffer))))
lose(CKR_OBJECT_HANDLE_INVALID);
- descriptor = p11_descriptor_from_key_type(cka_class, cka_key_type);
+
+ cka_extractable = *(CK_BBOOL*) attributes[0].value;
+ cka_sensitive = *(CK_BBOOL*) attributes[1].value;
+
+ sensitive_object = cka_sensitive || !cka_extractable;
}
- if (!sql_check_ok(sql_prepare(&q, select_format, flavor)) ||
- !sql_check_ok(sqlite3_bind_int64(q, 1, hObject)))
- lose(CKR_FUNCTION_FAILED);
+ {
+ hal_rpc_pkey_attribute_t attributes[ulCount];
- rv = CKR_OK;
+ memset(attributes, 0, sizeof(attributes));
- for (int i = 0; i < ulCount; i++) {
+ for (int i = 0; i < ulCount; i++)
+ attributes[i].type = pTemplate[i].type;
- if (sensitive_object && p11_attribute_is_sensitive(descriptor, pTemplate[i].type)) {
- pTemplate[i].ulValueLen = -1;
- rv = CKR_ATTRIBUTE_SENSITIVE;
- }
+ if (!hal_check(hal_rpc_pkey_get_attributes(pkey,
+ attributes, sizeof(attributes)/sizeof(*attributes),
+ NULL, 0)))
+ lose(CKR_OBJECT_HANDLE_INVALID);
- else if (!sql_check_ok(sqlite3_reset(q)) ||
- !sql_check_ok(sqlite3_bind_int64(q, 2, pTemplate[i].type)) ||
- (ret = sqlite3_step(q)) != SQLITE_ROW) {
- if (ret != SQLITE_DONE)
- sql_whine_step();
- pTemplate[i].ulValueLen = -1;
- rv = CKR_ATTRIBUTE_TYPE_INVALID;
- }
+ rv = CKR_OK;
- else if (pTemplate[i].pValue == NULL) {
- pTemplate[i].ulValueLen = sqlite3_column_bytes(q, 0);
- }
+ size_t attributes_buffer_len = 0;
- else if (pTemplate[i].ulValueLen >= sqlite3_column_bytes(q, 0)) {
- pTemplate[i].ulValueLen = sqlite3_column_bytes(q, 0);
- memcpy(pTemplate[i].pValue, sqlite3_column_blob(q, 0), pTemplate[i].ulValueLen);
+ for (int i = 0; i < ulCount; i++) {
+ if (sensitive_object && p11_attribute_is_sensitive(descriptor, pTemplate[i].type)) {
+ pTemplate[i].ulValueLen = -1;
+ rv = CKR_ATTRIBUTE_SENSITIVE;
+ continue;
+ }
+ if (attributes[i].length == 0) {
+ pTemplate[i].ulValueLen = -1;
+ rv = CKR_ATTRIBUTE_TYPE_INVALID;
+ continue;
+ }
+ if (pTemplate[i].pValue == NULL) {
+ pTemplate[i].ulValueLen = attributes[i].length;
+ continue;
+ }
+ if (pTemplate[i].ulValueLen < attributes[i].length) {
+ pTemplate[i].ulValueLen = -1;
+ rv = CKR_BUFFER_TOO_SMALL;
+ continue;
+ }
+ attributes_buffer_len += attributes[i].length;
}
- else {
- pTemplate[i].ulValueLen = -1;
- rv = CKR_BUFFER_TOO_SMALL;
- }
+ if (attributes_buffer_len == 0)
+ goto fail;
+
+ uint8_t attributes_buffer[attributes_buffer_len];
+ unsigned n = 0;
+
+ for (int i = 0; i < ulCount; i++)
+ if (pTemplate[i].pValue != NULL && pTemplate[i].ulValueLen != -1)
+ attributes[n++].type = pTemplate[i].type;
+
+ if (!hal_check(hal_rpc_pkey_get_attributes(pkey, attributes, n,
+ attributes_buffer, sizeof(attributes_buffer))))
+ lose(CKR_OBJECT_HANDLE_INVALID);
+
+ for (int i = 0; i < n; i++) {
+ int j = p11_attribute_find_in_template(attributes[i].type, pTemplate, ulCount);
+
+ if (j < 0 || pTemplate[j].ulValueLen == -1 || pTemplate[j].ulValueLen < attributes[i].length)
+ lose(CKR_FUNCTION_FAILED);
+ memcpy(pTemplate[j].pValue, attributes[i].value, attributes[i].length);
+ pTemplate[j].ulValueLen = attributes[i].length;
+ }
}
fail:
- sqlite3_finalize(q);
+ if (pkey.handle != HAL_HANDLE_NONE) {
+ if (rv == CKR_OK)
+ rv = p11_whine_from_hal(hal_rpc_pkey_close(pkey));
+ else
+ (void) hal_rpc_pkey_close(pkey);
+ }
mutex_unlock_return_with_rv(rv, p11_global_mutex);
}
@@ -3265,139 +3339,76 @@ CK_RV C_FindObjectsInit(CK_SESSION_HANDLE hSession,
{
ENTER_PUBLIC_FUNCTION(C_FindObjectsInit);
- static const char select_missing[] =
- " WITH"
- " known AS (SELECT token_object_id FROM object WHERE token_object_id IS NOT NULL)"
- " SELECT token_object_id FROM token_object WHERE token_object_id NOT IN known";
-
- static const char insert_missing[] =
- " INSERT INTO object (object_handle, token_object_id) VALUES (?1, ?2)";
-
- static const char create_format[] =
- " CREATE TEMPORARY TABLE findobjects_%lu AS"
- " SELECT object_id FROM object NATURAL LEFT JOIN session"
- " WHERE session_handle IS NULL OR session_handle = ?1";
-
- static const char drop_format[] =
- " DROP TABLE IF EXISTS findobjects_%lu";
-
- static const char delete_format[] =
- " WITH"
- " matches AS (SELECT object_id"
- " FROM object NATURAL JOIN session_attribute"
- " WHERE type = ?1 AND value = ?2"
- " UNION"
- " SELECT object_id"
- " FROM object NATURAL JOIN token_attribute"
- " WHERE type = ?1 AND value = ?2)"
- " DELETE FROM findobjects_%lu WHERE object_id NOT IN matches";
-
- static const char select_format[] =
- " SELECT object_handle FROM findobjects_%lu NATURAL JOIN object ORDER BY object_id";
-
+ const size_t attributes_len = sizeof(hal_rpc_pkey_attribute_t) * (ulCount + 1);
+ size_t len = attributes_len;
+ CK_BBOOL *cka_private = NULL;
+ CK_BBOOL *cka_token = NULL;
p11_session_t *session;
- sqlite3_stmt *q1 = NULL, *q2 = NULL;
CK_RV rv = CKR_OK;
- int i, ret;
+ uint8_t *mem;
mutex_lock_or_return_failure(p11_global_mutex);
if ((session = p11_session_find(hSession)) == NULL)
lose(CKR_SESSION_HANDLE_INVALID);
- if (ulCount > 0 && pTemplate == NULL)
+ if (ulCount > 0 && pTemplate == NULL)
lose(CKR_ARGUMENTS_BAD);
if (session->find_query != NULL)
lose(CKR_OPERATION_ACTIVE);
- /*
- * Assign handles to any token objects that don't have them yet.
- */
+ assert(!session->find_query_token && !session->find_query_session);
- if (!sql_check_ok(sql_prepare(&q1, select_missing)) ||
- !sql_check_ok(sql_prepare(&q2, insert_missing)))
- lose(CKR_FUNCTION_FAILED);
+ for (int i = 0; i < ulCount; i++) {
+ if (pTemplate[i].pValue == NULL || pTemplate[i].ulValueLen == 0)
+ lose(CKR_ARGUMENTS_BAD);
+ len += pTemplate[i].ulValueLen;
+ }
- while ((ret = sqlite3_step(q1)) == SQLITE_ROW) {
- sqlite3_int64 token_object_id = sqlite3_column_int64(q1, 0);
- CK_OBJECT_HANDLE object_handle = p11_allocate_unused_handle(handle_flavor_token_object);
+ if ((mem = malloc(len)) == NULL)
+ lose(CKR_HOST_MEMORY);
- if (!sql_check_ok(sqlite3_reset(q2)) ||
- !sql_check_ok(sqlite3_bind_int64(q2, 1, object_handle)) ||
- !sql_check_ok(sqlite3_bind_int64(q2, 2, token_object_id)) ||
- !sql_check_done(sqlite3_step(q2)))
- lose(CKR_FUNCTION_FAILED);
- }
+ session->find_query = (hal_rpc_pkey_attribute_t *) mem;
+ mem += attributes_len;
- if (ret != SQLITE_DONE) {
- sql_whine_step();
- lose(CKR_FUNCTION_FAILED);
+ for (int i = 0; i < ulCount; i++) {
+ len = pTemplate[i].ulValueLen;
+ session->find_query[i].type = pTemplate[i].type;
+ session->find_query[i].value = mem;
+ session->find_query[i].length = len;
+ memcpy(mem, pTemplate[i].pValue, len);
+ mem += len;
}
- /*
- * Create a temporary table to hold this session's FindObjects
- * state. Populate this with every object this session knows about,
- * then prune based on login status and whatever filter attributes
- * the caller supplied.
- */
+ cka_private = p11_attribute_find_value_in_template(CKA_PRIVATE, pTemplate, ulCount);
+ cka_token = p11_attribute_find_value_in_template(CKA_TOKEN, pTemplate, ulCount);
- if (!sql_check_ok(sql_finalize_and_clear(&q1)) ||
- !sql_check_ok(sql_finalize_and_clear(&q2)) ||
- !sql_check_ok(sql_prepare(&q1, drop_format, hSession)) ||
- !sql_check_done(sqlite3_step(q1)) ||
- !sql_check_ok(sql_prepare(&q2, create_format, hSession)) ||
- !sql_check_ok(sqlite3_bind_int64(q2, 1, hSession)) ||
- !sql_check_done(sqlite3_step(q2)) ||
- !sql_check_ok(sql_finalize_and_clear(&q1)) ||
- !sql_check_ok(sql_finalize_and_clear(&q2)) ||
- !sql_check_ok(sql_prepare(&q1, delete_format, hSession)))
- lose(CKR_FUNCTION_FAILED);
+ session->find_query_n = ulCount;
+ session->find_query_token = cka_token == NULL || *cka_token;
+ session->find_query_session = cka_token == NULL || !*cka_token;
+ memset(&session->find_query_previous_uuid, 0, sizeof(session->find_query_previous_uuid));
/*
- * If we're not logged in as the regular user, run an extra filter
- * cycle to remove all private objects before we get to the
- * caller-supplied template.
+ * Quietly enforce object privacy even if template tries to bypass,
+ * per PCKS #11 specification.
*/
- if (logged_in_as != logged_in_as_user) {
- if (!sql_check_ok(sqlite3_bind_int64(q1, 1, CKA_PRIVATE)) ||
- !sql_check_ok(sqlite3_bind_blob( q1, 2,
- &const_CK_FALSE,
- sizeof(const_CK_FALSE),
- NULL)) ||
- !sql_check_done(sqlite3_step(q1)))
- lose(CKR_FUNCTION_FAILED);
+ if (logged_in_as != logged_in_as_user && cka_private == NULL) {
+ session->find_query[ulCount].type = CKA_PRIVATE;
+ session->find_query[ulCount].value = &const_CK_FALSE;
+ session->find_query[ulCount].length = sizeof(const_CK_FALSE);
+ session->find_query_n++;
}
- /*
- * Filter through the caller-supplied template.
- *
- * NB: This doesn't support some of the more obscure searches, such
- * as searches for sessions or hardware features. Too much rope
- * already, worry about those if we ever really need them.
- */
-
- for (i = 0; i < ulCount; i++)
- if (!sql_check_ok(sqlite3_reset(q1)) ||
- !sql_check_ok(sqlite3_bind_int64(q1, 1, pTemplate[i].type)) ||
- !sql_check_ok(sqlite3_bind_blob( q1, 2, pTemplate[i].pValue,
- pTemplate[i].ulValueLen, NULL)) ||
- !sql_check_done(sqlite3_step(q1)))
- lose(CKR_FUNCTION_FAILED);
-
- /*
- * Stash a prepared query in the session object which will return
- * whatever object handles survived all that filtering.
- */
-
- if (!sql_check_ok(sql_prepare(&session->find_query, select_format, hSession)))
- lose(CKR_FUNCTION_FAILED);
- session->find_query_done = 0;
+ if (logged_in_as != logged_in_as_user && cka_private != NULL && *cka_private) {
+ int i = p11_attribute_find_in_template(CKA_PRIVATE, pTemplate, ulCount);
+ assert(i >= 0 && i < ulCount);
+ session->find_query[i].value = &const_CK_FALSE;
+ session->find_query[i].length = sizeof(const_CK_FALSE);
+ }
fail:
- sqlite3_finalize(q1);
- sqlite3_finalize(q2);
mutex_unlock_return_with_rv(rv, p11_global_mutex);
}
@@ -3408,8 +3419,8 @@ CK_RV C_FindObjects(CK_SESSION_HANDLE hSession,
{
ENTER_PUBLIC_FUNCTION(C_FindObjects);
+ hal_uuid_t previous_uuid = {{0}};
p11_session_t *session;
- int i, ret = SQLITE_OK;
CK_RV rv = CKR_OK;
mutex_lock_or_return_failure(p11_global_mutex);
@@ -3423,35 +3434,55 @@ CK_RV C_FindObjects(CK_SESSION_HANDLE hSession,
if (phObject == NULL || pulObjectCount == NULL)
lose(CKR_ARGUMENTS_BAD);
- /*
- * C_FindObjectsInit() did all the heavy lifting, we just have to
- * return the resulting handles.
- */
+ *pulObjectCount = 0;
- i = 0;
+ while (*pulObjectCount < ulMaxObjectCount &&
+ (session->find_query_token || session->find_query_session)) {
+ hal_uuid_t uuids[ulMaxObjectCount - *pulObjectCount];
+ handle_flavor_t flavor;
+ hal_key_flags_t flags;
+ unsigned n;
- if (!session->find_query_done)
- while (i < ulMaxObjectCount && (ret = sqlite3_step(session->find_query)) == SQLITE_ROW)
- phObject[i++] = (CK_OBJECT_HANDLE) sqlite3_column_int64(session->find_query, 0);
+ if (session->find_query_token) {
+ flavor = handle_flavor_token_object;
+ flags = HAL_KEY_FLAG_TOKEN;
+ }
+ else {
+ flavor = handle_flavor_session_object;
+ flags = 0;
+ }
- switch (ret) {
+ rv = p11_whine_from_hal(hal_rpc_pkey_match(p11_session_hal_client(session),
+ p11_session_hal_session(session),
+ HAL_KEY_TYPE_NONE, HAL_CURVE_NONE, flags,
+ session->find_query, session->find_query_n,
+ uuids, &n, sizeof(uuids)/sizeof(*uuids),
+ &previous_uuid));
+ if (rv != CKR_OK)
+ goto fail;
- case SQLITE_DONE:
- session->find_query_done = 1;
- break;
+ for (int i = 0; i < n; i++) {
+ phObject[*pulObjectCount] = p11_object_allocate(flavor, &uuids[i], session);
+ if (phObject[*pulObjectCount] == CK_INVALID_HANDLE)
+ lose(CKR_FUNCTION_FAILED);
+ ++*pulObjectCount;
+ }
- case SQLITE_OK:
- case SQLITE_ROW:
- break;
+ if (n == sizeof(uuids)/sizeof(*uuids)) {
+ memcpy(&session->find_query_previous_uuid, &uuids[n - 1],
+ sizeof(session->find_query_previous_uuid));
+ }
- default:
- sql_whine_step();
- lose(CKR_FUNCTION_FAILED);
+ else {
+ memset(&session->find_query_previous_uuid, 0, sizeof(session->find_query_previous_uuid));
+ if (session->find_query_token)
+ session->find_query_token = 0;
+ else
+ session->find_query_session = 0;
+ }
}
- *pulObjectCount = i;
-
fail:
mutex_unlock_return_with_rv(rv, p11_global_mutex);
}
@@ -3460,11 +3491,7 @@ CK_RV C_FindObjectsFinal(CK_SESSION_HANDLE hSession)
{
ENTER_PUBLIC_FUNCTION(C_FindObjectsFinal);
- static const char drop_format[] =
- " DROP TABLE IF EXISTS findobjects_%lu";
-
p11_session_t *session;
- sqlite3_stmt *q = NULL;
CK_RV rv = CKR_OK;
mutex_lock_or_return_failure(p11_global_mutex);
@@ -3475,17 +3502,15 @@ CK_RV C_FindObjectsFinal(CK_SESSION_HANDLE hSession)
if (session->find_query == NULL)
lose(CKR_OPERATION_NOT_INITIALIZED);
- /*
- * Clean up result query and temporary table.
- */
+ free(session->find_query);
- if (!sql_check_ok(sql_finalize_and_clear(&session->find_query)) ||
- !sql_check_ok(sql_prepare(&q, drop_format, hSession)) ||
- !sql_check_done(sqlite3_step(q)))
- lose(CKR_FUNCTION_FAILED);
+ session->find_query = NULL;
+ session->find_query_n = 0;
+ session->find_query_token = 0;
+ session->find_query_session = 0;
+ memset(&session->find_query_previous_uuid, 0, sizeof(session->find_query_previous_uuid));
fail:
- sqlite3_finalize(q);
mutex_unlock_return_with_rv(rv, p11_global_mutex);
}
@@ -3662,10 +3687,19 @@ CK_RV C_SignInit(CK_SESSION_HANDLE hSession,
{
ENTER_PUBLIC_FUNCTION(C_SignInit);
+ uint8_t attributes_buffer[sizeof(CK_OBJECT_CLASS) + sizeof(CK_KEY_TYPE) + 3 * sizeof(CK_BBOOL)];
+ hal_pkey_handle_t pkey = {HAL_HANDLE_NONE};
+ hal_rpc_pkey_attribute_t attributes[] = {
+ [0].type = CKA_KEY_TYPE,
+ [1].type = CKA_SIGN,
+ [2].type = CKA_PRIVATE,
+ [3].type = CKA_TOKEN
+ };
+ CK_KEY_TYPE cka_key_type;
+ CK_BBOOL cka_sign;
+ CK_BBOOL cka_private;
+ CK_BBOOL cka_token;
p11_session_t *session;
- CK_OBJECT_CLASS key_class;
- CK_KEY_TYPE key_type;
- CK_BBOOL key_sign;
CK_RV rv = CKR_OK;
mutex_lock_or_return_failure(p11_global_mutex);
@@ -3676,19 +3710,28 @@ CK_RV C_SignInit(CK_SESSION_HANDLE hSession,
if (pMechanism == NULL)
lose(CKR_ARGUMENTS_BAD);
- if (session->sign_key_handle != CK_INVALID_HANDLE || session->sign_digest_algorithm != HAL_DIGEST_ALGORITHM_NONE)
+ if (session->sign_key_handle != CK_INVALID_HANDLE ||
+ session->sign_digest_algorithm != HAL_DIGEST_ALGORITHM_NONE)
lose(CKR_OPERATION_ACTIVE);
- if ((rv = p11_object_check_rights(session, hKey, p11_object_access_read)) != CKR_OK)
- goto fail;
+ if (!p11_object_pkey_open(session, hKey, &pkey))
+ lose(CKR_KEY_HANDLE_INVALID);
- if (!p11_attribute_get_ulong(session, hKey, CKA_CLASS, &key_class) ||
- !p11_attribute_get_ulong(session, hKey, CKA_KEY_TYPE, &key_type) ||
- !p11_attribute_get_bbool(session, hKey, CKA_SIGN, &key_sign) ||
- key_class != CKO_PRIVATE_KEY)
+ if (!hal_check(hal_rpc_pkey_get_attributes(pkey, attributes, sizeof(attributes)/sizeof(*attributes),
+ attributes_buffer, sizeof(attributes_buffer))))
lose(CKR_KEY_HANDLE_INVALID);
- if (!key_sign)
+ cka_key_type = *(CK_KEY_TYPE*) attributes[0].value;
+ cka_sign = *(CK_BBOOL*) attributes[1].value;
+ cka_private = *(CK_BBOOL*) attributes[2].value;
+ cka_token = *(CK_BBOOL*) attributes[3].value;
+
+ rv = p11_object_check_rights(session, hKey, p11_object_access_read, cka_private, cka_token);
+
+ if (rv != CKR_OK)
+ goto fail;
+
+ if (!cka_sign)
lose(CKR_KEY_FUNCTION_NOT_PERMITTED);
switch (pMechanism->mechanism) {
@@ -3698,7 +3741,7 @@ CK_RV C_SignInit(CK_SESSION_HANDLE hSession,
case CKM_SHA256_RSA_PKCS:
case CKM_SHA384_RSA_PKCS:
case CKM_SHA512_RSA_PKCS:
- if (key_type != CKK_RSA)
+ if (cka_key_type != CKK_RSA)
lose(CKR_KEY_TYPE_INCONSISTENT);
break;
case CKM_ECDSA:
@@ -3706,7 +3749,7 @@ CK_RV C_SignInit(CK_SESSION_HANDLE hSession,
case CKM_ECDSA_SHA256:
case CKM_ECDSA_SHA384:
case CKM_ECDSA_SHA512:
- if (key_type != CKK_EC)
+ if (cka_key_type != CKK_EC)
lose(CKR_KEY_TYPE_INCONSISTENT);
break;
default:
@@ -3743,10 +3786,12 @@ CK_RV C_SignInit(CK_SESSION_HANDLE hSession,
return CKR_MECHANISM_INVALID;
}
- return mutex_unlock(p11_global_mutex);
+ rv = CKR_OK;
fail:
- if (session != NULL) {
+ if (pkey.handle != HAL_HANDLE_NONE)
+ (void) hal_rpc_pkey_close(pkey);
+ if (rv != CKR_OK && session != NULL) {
session->sign_key_handle = CK_INVALID_HANDLE;
session->sign_digest_algorithm = HAL_DIGEST_ALGORITHM_NONE;
}
@@ -3762,7 +3807,6 @@ CK_RV C_Sign(CK_SESSION_HANDLE hSession,
ENTER_PUBLIC_FUNCTION(C_Sign);
p11_session_t *session;
- CK_KEY_TYPE key_type;
CK_RV rv;
mutex_lock_or_return_failure(p11_global_mutex);
@@ -3779,9 +3823,6 @@ CK_RV C_Sign(CK_SESSION_HANDLE hSession,
if (session->sign_digest_handle.handle != HAL_HANDLE_NONE)
lose(CKR_OPERATION_ACTIVE);
- if (!p11_attribute_get_ulong(session, session->sign_key_handle, CKA_KEY_TYPE, &key_type))
- lose(CKR_FUNCTION_FAILED);
-
if (session->sign_digest_algorithm != HAL_DIGEST_ALGORITHM_NONE && pSignature != NULL) {
if ((rv = digest_update(session, session->sign_digest_algorithm,
&session->sign_digest_handle, pData, ulDataLen)) != CKR_OK)
@@ -3790,16 +3831,8 @@ CK_RV C_Sign(CK_SESSION_HANDLE hSession,
ulDataLen = 0;
}
- switch (key_type) {
+ rv = sign_hal_rpc(session, pData, ulDataLen, pSignature, pulSignatureLen);
- case CKK_RSA:
- case CKK_EC:
- rv = sign_hal_rpc(session, pData, ulDataLen, pSignature, pulSignatureLen);
- break;
-
- default:
- lose(CKR_FUNCTION_FAILED);
- }
/* Fall through */
fail:
if (session != NULL && pSignature != NULL && rv != CKR_BUFFER_TOO_SMALL) {
@@ -3857,7 +3890,6 @@ CK_RV C_SignFinal(CK_SESSION_HANDLE hSession,
ENTER_PUBLIC_FUNCTION(C_SignFinal);
p11_session_t *session;
- CK_KEY_TYPE key_type;
CK_RV rv;
mutex_lock_or_return_failure(p11_global_mutex);
@@ -3868,22 +3900,12 @@ CK_RV C_SignFinal(CK_SESSION_HANDLE hSession,
if (pulSignatureLen == NULL)
lose(CKR_ARGUMENTS_BAD);
- if (session->sign_key_handle == CK_INVALID_HANDLE || session->sign_digest_handle.handle == HAL_HANDLE_NONE)
+ if (session->sign_key_handle == CK_INVALID_HANDLE ||
+ session->sign_digest_handle.handle == HAL_HANDLE_NONE)
lose(CKR_OPERATION_NOT_INITIALIZED);
- if (!p11_attribute_get_ulong(session, session->sign_key_handle, CKA_KEY_TYPE, &key_type))
- lose(CKR_FUNCTION_FAILED);
-
- switch (key_type) {
+ rv = sign_hal_rpc(session, NULL, 0, pSignature, pulSignatureLen);
- case CKK_RSA:
- case CKK_EC:
- rv = sign_hal_rpc(session, NULL, 0, pSignature, pulSignatureLen);
- break;
-
- default:
- lose(CKR_FUNCTION_FAILED);
- }
/* Fall through */
fail:
if (session != NULL && pSignature != NULL && rv != CKR_BUFFER_TOO_SMALL) {
@@ -3901,10 +3923,20 @@ CK_RV C_VerifyInit(CK_SESSION_HANDLE hSession,
{
ENTER_PUBLIC_FUNCTION(C_VerifyInit);
+ uint8_t attributes_buffer[sizeof(CK_OBJECT_CLASS) + sizeof(CK_KEY_TYPE) + 3 * sizeof(CK_BBOOL)];
+ hal_pkey_handle_t pkey = {HAL_HANDLE_NONE};
+ hal_rpc_pkey_attribute_t attributes[] = {
+ [0].type = CKA_KEY_TYPE,
+ [1].type = CKA_VERIFY,
+ [2].type = CKA_PRIVATE,
+ [3].type = CKA_TOKEN
+ };
+ CK_KEY_TYPE cka_key_type;
+ CK_BBOOL cka_verify;
+ CK_BBOOL cka_private;
+ CK_BBOOL cka_token;
+
p11_session_t *session;
- CK_OBJECT_CLASS key_class;
- CK_KEY_TYPE key_type;
- CK_BBOOL key_verify;
CK_RV rv = CKR_OK;
mutex_lock_or_return_failure(p11_global_mutex);
@@ -3915,19 +3947,28 @@ CK_RV C_VerifyInit(CK_SESSION_HANDLE hSession,
if (pMechanism == NULL)
lose(CKR_ARGUMENTS_BAD);
- if (session->verify_key_handle != CK_INVALID_HANDLE || session->verify_digest_algorithm != HAL_DIGEST_ALGORITHM_NONE)
+ if (session->verify_key_handle != CK_INVALID_HANDLE ||
+ session->verify_digest_algorithm != HAL_DIGEST_ALGORITHM_NONE)
lose(CKR_OPERATION_ACTIVE);
- if ((rv = p11_object_check_rights(session, hKey, p11_object_access_read)) != CKR_OK)
- goto fail;
+ if (!p11_object_pkey_open(session, hKey, &pkey))
+ lose(CKR_KEY_HANDLE_INVALID);
- if (!p11_attribute_get_ulong(session, hKey, CKA_CLASS, &key_class) ||
- !p11_attribute_get_ulong(session, hKey, CKA_KEY_TYPE, &key_type) ||
- !p11_attribute_get_bbool(session, hKey, CKA_VERIFY, &key_verify) ||
- key_class != CKO_PUBLIC_KEY)
+ if (!hal_check(hal_rpc_pkey_get_attributes(pkey, attributes, sizeof(attributes)/sizeof(*attributes),
+ attributes_buffer, sizeof(attributes_buffer))))
lose(CKR_KEY_HANDLE_INVALID);
- if (!key_verify)
+ cka_key_type = *(CK_KEY_TYPE*) attributes[0].value;
+ cka_verify = *(CK_BBOOL*) attributes[1].value;
+ cka_private = *(CK_BBOOL*) attributes[2].value;
+ cka_token = *(CK_BBOOL*) attributes[3].value;
+
+ rv = p11_object_check_rights(session, hKey, p11_object_access_read, cka_private, cka_token);
+
+ if (rv != CKR_OK)
+ goto fail;
+
+ if (!cka_verify)
lose(CKR_KEY_FUNCTION_NOT_PERMITTED);
switch (pMechanism->mechanism) {
@@ -3937,7 +3978,7 @@ CK_RV C_VerifyInit(CK_SESSION_HANDLE hSession,
case CKM_SHA256_RSA_PKCS:
case CKM_SHA384_RSA_PKCS:
case CKM_SHA512_RSA_PKCS:
- if (key_type != CKK_RSA)
+ if (cka_key_type != CKK_RSA)
lose(CKR_KEY_TYPE_INCONSISTENT);
break;
case CKM_ECDSA:
@@ -3945,7 +3986,7 @@ CK_RV C_VerifyInit(CK_SESSION_HANDLE hSession,
case CKM_ECDSA_SHA256:
case CKM_ECDSA_SHA384:
case CKM_ECDSA_SHA512:
- if (key_type != CKK_EC)
+ if (cka_key_type != CKK_EC)
lose(CKR_KEY_TYPE_INCONSISTENT);
break;
default:
@@ -3982,10 +4023,12 @@ CK_RV C_VerifyInit(CK_SESSION_HANDLE hSession,
return CKR_MECHANISM_INVALID;
}
- return mutex_unlock(p11_global_mutex);
+ rv = CKR_OK;
fail:
- if (session != NULL) {
+ if (pkey.handle != HAL_HANDLE_NONE)
+ (void) hal_rpc_pkey_close(pkey);
+ if (rv != CKR_OK && session != NULL) {
session->verify_key_handle = CK_INVALID_HANDLE;
session->verify_digest_algorithm = HAL_DIGEST_ALGORITHM_NONE;
}
@@ -4001,7 +4044,6 @@ CK_RV C_Verify(CK_SESSION_HANDLE hSession,
ENTER_PUBLIC_FUNCTION(C_Verify);
p11_session_t *session;
- CK_KEY_TYPE key_type;
CK_RV rv;
mutex_lock_or_return_failure(p11_global_mutex);
@@ -4023,19 +4065,7 @@ CK_RV C_Verify(CK_SESSION_HANDLE hSession,
ulDataLen = 0;
}
- if (!p11_attribute_get_ulong(session, session->verify_key_handle, CKA_KEY_TYPE, &key_type))
- lose(CKR_FUNCTION_FAILED);
-
- switch (key_type) {
-
- case CKK_RSA:
- case CKK_EC:
- rv = verify_hal_rpc(session, pData, ulDataLen, pSignature, ulSignatureLen);
- break;
-
- default:
- lose(CKR_FUNCTION_FAILED);
- }
+ rv = verify_hal_rpc(session, pData, ulDataLen, pSignature, ulSignatureLen);
fail: /* Fall through */
@@ -4094,7 +4124,6 @@ CK_RV C_VerifyFinal(CK_SESSION_HANDLE hSession,
ENTER_PUBLIC_FUNCTION(C_VerifyFinal);
p11_session_t *session;
- CK_KEY_TYPE key_type;
CK_RV rv;
mutex_lock_or_return_failure(p11_global_mutex);
@@ -4105,22 +4134,11 @@ CK_RV C_VerifyFinal(CK_SESSION_HANDLE hSession,
if (pSignature == NULL)
lose(CKR_ARGUMENTS_BAD);
- if (session->verify_key_handle == CK_INVALID_HANDLE || session->verify_digest_handle.handle == HAL_HANDLE_NONE)
+ if (session->verify_key_handle == CK_INVALID_HANDLE ||
+ session->verify_digest_handle.handle == HAL_HANDLE_NONE)
lose(CKR_OPERATION_NOT_INITIALIZED);
- if (!p11_attribute_get_ulong(session, session->verify_key_handle, CKA_KEY_TYPE, &key_type))
- lose(CKR_FUNCTION_FAILED);
-
- switch (key_type) {
-
- case CKK_RSA:
- case CKK_EC:
- rv = verify_hal_rpc(session, NULL, 0, pSignature, ulSignatureLen);
- break;
-
- default:
- lose(CKR_FUNCTION_FAILED);
- }
+ rv = verify_hal_rpc(session, NULL, 0, pSignature, ulSignatureLen);
fail: /* Fall through */