[gnome-keyring/dbus-api] [gp11] Implement support for generate, wrap, unwrap, derive.
- From: Stefan Walter <stefw src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-keyring/dbus-api] [gp11] Implement support for generate, wrap, unwrap, derive.
- Date: Mon, 23 Nov 2009 01:42:18 +0000 (UTC)
commit e616479ba2976a9e58b02d11c379ed68919dbbf7
Author: Stef Walter <stef memberwebs com>
Date: Fri Nov 20 17:29:53 2009 +0000
[gp11] Implement support for generate, wrap, unwrap, derive.
Implement gp11_session_generate_key_pair...(),
gp11_session_wrap_key...(), gp11_session_unwrap_key...(),
and gp11_session_derive_key...().
gp11/gp11-misc.c | 83 ++++
gp11/gp11-session.c | 852 +++++++++++++++++++++++++++++++++---
gp11/gp11.h | 158 ++++---
gp11/tests/Makefile.am | 1 +
gp11/tests/gp11-test-module.c | 253 ++++++++++-
gp11/tests/gp11-test.h | 13 +
gp11/tests/test-gp11-mechanism.c | 60 +++
gp11/tests/unit-test-gp11-crypto.c | 353 +++++++++++++--
8 files changed, 1573 insertions(+), 200 deletions(-)
---
diff --git a/gp11/gp11-misc.c b/gp11/gp11-misc.c
index 5b097f0..35fa958 100644
--- a/gp11/gp11-misc.c
+++ b/gp11/gp11-misc.c
@@ -352,3 +352,86 @@ _gp11_ulong_equal (gconstpointer v1, gconstpointer v2)
{
return *((const gulong*)v1) == *((const gulong*)v2);
}
+
+static GQuark mechanism_quark = 0;
+
+static void
+free_refs (gpointer data)
+{
+ gint *refs = data;
+ g_assert (refs);
+ g_assert (*refs == 0);
+ g_slice_free (gint, data);
+}
+
+GP11Mechanism*
+gp11_mechanism_new (gulong type)
+{
+ return gp11_mechanism_new_with_param (type, NULL, 0);
+}
+
+GP11Mechanism*
+gp11_mechanism_new_with_param (gulong type, gconstpointer parameter,
+ gulong n_parameter)
+{
+ static volatile gsize inited_quark = 0;
+ GP11Mechanism *mech;
+ gint *refs;
+
+ /* Initialize first time around */
+ if (g_once_init_enter (&inited_quark)) {
+ mechanism_quark = g_quark_from_static_string ("GP11Mechanism::refs");
+ g_once_init_leave (&inited_quark, 1);
+ }
+
+ mech = g_slice_new (GP11Mechanism);
+ mech->type = type;
+ mech->parameter = g_memdup (parameter, n_parameter);
+ mech->n_parameter = n_parameter;
+
+ refs = g_slice_new (gint);
+ *refs = 1;
+ g_dataset_id_set_data_full (mech, mechanism_quark, refs, free_refs);
+
+ return mech;
+}
+
+GP11Mechanism*
+gp11_mechanism_ref (GP11Mechanism* mech)
+{
+ gint *refs;
+
+ g_return_val_if_fail (mech, NULL);
+
+ refs = g_dataset_id_get_data (mech, mechanism_quark);
+ if (refs == NULL) {
+ g_warning ("Encountered invalid GP11Mechanism struct. Either it was unreffed or "
+ "possibly allocated on the stack. Always use gp11_mechanism_new () and friends.");
+ return NULL;
+ }
+
+ g_atomic_int_add (refs, 1);
+ return mech;
+}
+
+void
+gp11_mechanism_unref (GP11Mechanism* mech)
+{
+ gint *refs;
+
+ if (!mech)
+ return;
+
+ refs = g_dataset_id_get_data (mech, mechanism_quark);
+ if (refs == NULL) {
+ g_warning ("Encountered invalid GP11Mechanism struct. Either it was unreffed or "
+ "possibly allocated on the stack. Always use gp11_mechanism_new () and friends.");
+ return;
+ }
+
+ if (g_atomic_int_dec_and_test (refs)) {
+ g_free (mech->parameter);
+ g_dataset_id_remove_data (mech, mechanism_quark);
+ g_slice_free (GP11Mechanism, mech);
+ }
+}
diff --git a/gp11/gp11-session.c b/gp11/gp11-session.c
index 452c60d..08bc11e 100644
--- a/gp11/gp11-session.c
+++ b/gp11/gp11-session.c
@@ -1039,6 +1039,736 @@ gp11_session_find_objects_finish (GP11Session *self, GAsyncResult *result, GErro
return objlist_from_handles (self, args->objects, args->n_objects);
}
+/* -----------------------------------------------------------------------------
+ * KEY PAIR GENERATION
+ */
+
+typedef struct _GenerateKeyPair {
+ GP11Arguments base;
+ GP11Mechanism *mechanism;
+ GP11Attributes *public_attrs;
+ GP11Attributes *private_attrs;
+ CK_OBJECT_HANDLE public_key;
+ CK_OBJECT_HANDLE private_key;
+} GenerateKeyPair;
+
+static void
+free_generate_key_pair (GenerateKeyPair *args)
+{
+ gp11_mechanism_unref (args->mechanism);
+ gp11_attributes_unref (args->public_attrs);
+ gp11_attributes_unref (args->private_attrs);
+ g_free (args);
+}
+
+static CK_RV
+perform_generate_key_pair (GenerateKeyPair *args)
+{
+ CK_ATTRIBUTE_PTR pub_attrs, priv_attrs;
+ CK_ULONG n_pub_attrs, n_priv_attrs;
+
+ g_assert (sizeof (CK_MECHANISM) == sizeof (GP11Mechanism));
+
+ pub_attrs = _gp11_attributes_commit_out (args->public_attrs, &n_pub_attrs);
+ priv_attrs = _gp11_attributes_commit_out (args->private_attrs, &n_priv_attrs);
+
+ return (args->base.pkcs11->C_GenerateKeyPair) (args->base.handle,
+ (CK_MECHANISM_PTR)args->mechanism,
+ pub_attrs, n_pub_attrs,
+ priv_attrs, n_priv_attrs,
+ &args->public_key,
+ &args->private_key);
+}
+
+/**
+ * gp11_session_generate_key_pair_full:
+ * @self: The session to use.
+ * @mechanism: The mechanism to use for key generation.
+ * @public_attrs: Additional attributes for the generated public key.
+ * @private_attrs: Additional attributes for the generated private key.
+ * @public_key: A location to return the resulting public key.
+ * @private_key: A location to return the resulting private key.
+ * @cancellable: Optional cancellation object, or NULL.
+ * @err: A location to return an error, or NULL.
+ *
+ * Generate a new key pair of public and private keys. This call may block for an
+ * indefinite period.
+ *
+ * Return value: TRUE if the operation succeeded.
+ **/
+gboolean
+gp11_session_generate_key_pair_full (GP11Session *self, GP11Mechanism *mechanism,
+ GP11Attributes *public_attrs, GP11Attributes *private_attrs,
+ GP11Object **public_key, GP11Object **private_key,
+ GCancellable *cancellable, GError **err)
+{
+ GP11SessionData *data = GP11_SESSION_GET_DATA (self);
+ GenerateKeyPair args = { GP11_ARGUMENTS_INIT, mechanism, public_attrs, private_attrs, 0, 0 };
+ gboolean ret;
+
+ g_return_val_if_fail (GP11_IS_SESSION (self), FALSE);
+ g_return_val_if_fail (mechanism, FALSE);
+ g_return_val_if_fail (public_attrs, FALSE);
+ g_return_val_if_fail (private_attrs, FALSE);
+ g_return_val_if_fail (public_key, FALSE);
+ g_return_val_if_fail (private_key, FALSE);
+
+ _gp11_attributes_lock (public_attrs);
+ _gp11_attributes_lock (private_attrs);
+ ret = _gp11_call_sync (self, perform_generate_key_pair, NULL, &args, cancellable, err);
+ _gp11_attributes_unlock (private_attrs);
+ _gp11_attributes_unlock (public_attrs);
+
+ if (!ret)
+ return FALSE;
+
+ *public_key = gp11_object_from_handle (data->slot, args.public_key);
+ *private_key = gp11_object_from_handle (data->slot, args.private_key);
+ return TRUE;
+}
+
+/**
+ * gp11_session_generate_key_pair_async:
+ * @self: The session to use.
+ * @mechanism: The mechanism to use for key generation.
+ * @public_attrs: Additional attributes for the generated public key.
+ * @private_attrs: Additional attributes for the generated private key.
+ * @cancellable: Optional cancellation object or NULL.
+ * @callback: Called when the operation completes.
+ * @user_data: Data to pass to the callback.
+ *
+ * Generate a new key pair of public and private keys. This call will
+ * return immediately and complete asynchronously.
+ **/
+void
+gp11_session_generate_key_pair_async (GP11Session *self, GP11Mechanism *mechanism,
+ GP11Attributes *public_attrs, GP11Attributes *private_attrs,
+ GCancellable *cancellable, GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GenerateKeyPair *args = _gp11_call_async_prep (self, self, perform_generate_key_pair,
+ NULL, sizeof (*args), free_generate_key_pair);
+
+ g_return_if_fail (GP11_IS_SESSION (self));
+ g_return_if_fail (mechanism);
+ g_return_if_fail (public_attrs);
+ g_return_if_fail (private_attrs);
+
+ args->public_attrs = gp11_attributes_ref (public_attrs);
+ _gp11_attributes_lock (public_attrs);
+ args->private_attrs = gp11_attributes_ref (private_attrs);
+ _gp11_attributes_lock (private_attrs);
+ args->mechanism = gp11_mechanism_ref (mechanism);
+
+ _gp11_call_async_ready_go (args, cancellable, callback, user_data);
+}
+
+/**
+ * gp11_session_generate_key_pair_finish:
+ * @self: The session to use.
+ * @result: The async result passed to the callback.
+ * @public_key: A location to return the resulting public key.
+ * @private_key: A location to return the resulting private key.
+ * @err: A location to return an error.
+ *
+ * Get the result of a generate key pair operation.
+ *
+ * Return value: TRUE if the operation succeeded.
+ **/
+gboolean
+gp11_session_generate_key_pair_finish (GP11Session *self, GAsyncResult *result,
+ GP11Object **public_key, GP11Object **private_key,
+ GError **err)
+{
+ GP11SessionData *data = GP11_SESSION_GET_DATA (self);
+ GenerateKeyPair *args;
+
+ g_return_val_if_fail (GP11_IS_SESSION (self), FALSE);
+ g_return_val_if_fail (public_key, FALSE);
+ g_return_val_if_fail (private_key, FALSE);
+
+ args = _gp11_call_arguments (result, GenerateKeyPair);
+ _gp11_attributes_unlock (args->public_attrs);
+ _gp11_attributes_unlock (args->private_attrs);
+
+ if (!_gp11_call_basic_finish (result, err))
+ return FALSE;
+
+ *public_key = gp11_object_from_handle (data->slot, args->public_key);
+ *private_key = gp11_object_from_handle (data->slot, args->private_key);
+ return TRUE;
+}
+
+/* -----------------------------------------------------------------------------
+ * KEY WRAPPING
+ */
+
+typedef struct _WrapKey {
+ GP11Arguments base;
+ GP11Mechanism *mechanism;
+ CK_OBJECT_HANDLE wrapper;
+ CK_OBJECT_HANDLE wrapped;
+ gpointer result;
+ gulong n_result;
+} WrapKey;
+
+static void
+free_wrap_key (WrapKey *args)
+{
+ gp11_mechanism_unref (args->mechanism);
+ g_free (args->result);
+ g_free (args);
+}
+
+static CK_RV
+perform_wrap_key (WrapKey *args)
+{
+ CK_RV rv;
+
+ g_assert (sizeof (CK_MECHANISM) == sizeof (GP11Mechanism));
+
+ /* Get the length of the result */
+ rv = (args->base.pkcs11->C_WrapKey) (args->base.handle,
+ (CK_MECHANISM_PTR)args->mechanism,
+ args->wrapper, args->wrapped,
+ NULL, &args->n_result);
+ if (rv != CKR_OK)
+ return rv;
+
+ /* And try again with a real buffer */
+ args->result = g_malloc0 (args->n_result);
+ return (args->base.pkcs11->C_WrapKey) (args->base.handle,
+ (CK_MECHANISM_PTR)args->mechanism,
+ args->wrapper, args->wrapped,
+ args->result, &args->n_result);
+}
+
+/**
+ * gp11_session_wrap_key:
+ * @self: The session to use.
+ * @wrapper: The key to use for wrapping.
+ * @mechanism: The mechanism type to use for wrapping.
+ * @wrapped: The key to wrap.
+ * @n_result: A location in which to return the length of the wrapped data.
+ * @err: A location to return an error, or NULL.
+ *
+ * Wrap a key into a byte stream. This call may block for an
+ * indefinite period.
+ *
+ * Return value: The wrapped data or NULL if the operation failed.
+ **/
+gpointer
+gp11_session_wrap_key (GP11Session *self, GP11Object *key, gulong mech_type,
+ GP11Object *wrapped, gsize *n_result, GError **err)
+{
+ GP11Mechanism mech = { mech_type, NULL, 0 };
+ return gp11_session_wrap_key_full (self, key, &mech, wrapped, n_result, NULL, err);
+}
+
+/**
+ * gp11_session_wrap_key_full:
+ * @self: The session to use.
+ * @wrapper: The key to use for wrapping.
+ * @mechanism: The mechanism to use for wrapping.
+ * @wrapped: The key to wrap.
+ * @n_result: A location in which to return the length of the wrapped data.
+ * @cancellable: Optional cancellation object, or NULL.
+ * @err: A location to return an error, or NULL.
+ *
+ * Wrap a key into a byte stream. This call may block for an
+ * indefinite period.
+ *
+ * Return value: The wrapped data or NULL if the operation failed.
+ **/
+gpointer
+gp11_session_wrap_key_full (GP11Session *self, GP11Object *wrapper, GP11Mechanism *mechanism,
+ GP11Object *wrapped, gsize *n_result, GCancellable *cancellable,
+ GError **err)
+{
+ WrapKey args = { GP11_ARGUMENTS_INIT, mechanism, 0, 0, NULL, 0 };
+ gboolean ret;
+
+ g_return_val_if_fail (GP11_IS_SESSION (self), FALSE);
+ g_return_val_if_fail (mechanism, FALSE);
+ g_return_val_if_fail (GP11_IS_OBJECT (wrapped), FALSE);
+ g_return_val_if_fail (GP11_IS_OBJECT (wrapper), FALSE);
+ g_return_val_if_fail (n_result, FALSE);
+
+ g_object_get (wrapper, "handle", &args.wrapper, NULL);
+ g_return_val_if_fail (args.wrapper != 0, NULL);
+ g_object_get (wrapped, "handle", &args.wrapped, NULL);
+ g_return_val_if_fail (args.wrapped != 0, NULL);
+
+ ret = _gp11_call_sync (self, perform_wrap_key, NULL, &args, cancellable, err);
+
+ if (!ret)
+ return FALSE;
+
+ *n_result = args.n_result;
+ return args.result;
+}
+
+/**
+ * gp11_session_wrap_key_async:
+ * @self: The session to use.
+ * @wrapper: The key to use for wrapping.
+ * @mechanism: The mechanism to use for wrapping.
+ * @wrapped: The key to wrap.
+ * @cancellable: Optional cancellation object or NULL.
+ * @callback: Called when the operation completes.
+ * @user_data: Data to pass to the callback.
+ *
+ * Wrap a key into a byte stream. This call will
+ * return immediately and complete asynchronously.
+ **/
+void
+gp11_session_wrap_key_async (GP11Session *self, GP11Object *key, GP11Mechanism *mechanism,
+ GP11Object *wrapped, GCancellable *cancellable,
+ GAsyncReadyCallback callback, gpointer user_data)
+{
+ WrapKey *args = _gp11_call_async_prep (self, self, perform_wrap_key,
+ NULL, sizeof (*args), free_wrap_key);
+
+ g_return_if_fail (GP11_IS_SESSION (self));
+ g_return_if_fail (mechanism);
+ g_return_if_fail (GP11_IS_OBJECT (wrapped));
+ g_return_if_fail (GP11_IS_OBJECT (key));
+
+ args->mechanism = gp11_mechanism_ref (mechanism);
+ g_object_get (key, "handle", &args->wrapper, NULL);
+ g_return_if_fail (args->wrapper != 0);
+ g_object_get (wrapped, "handle", &args->wrapped, NULL);
+ g_return_if_fail (args->wrapped != 0);
+
+ _gp11_call_async_ready_go (args, cancellable, callback, user_data);
+}
+
+/**
+ * gp11_session_wrap_key_finish:
+ * @self: The session to use.
+ * @result: The async result passed to the callback.
+ * @n_result: A location in which to return the length of the wrapped data.
+ * @err: A location to return an error.
+ *
+ * Get the result of a wrap key operation.
+ *
+ * Return value: The wrapped data or NULL if the operation failed.
+ **/
+gpointer
+gp11_session_wrap_key_finish (GP11Session *self, GAsyncResult *result,
+ gsize *n_result, GError **err)
+{
+ WrapKey *args;
+ gpointer ret;
+
+ g_return_val_if_fail (GP11_IS_SESSION (self), NULL);
+ g_return_val_if_fail (n_result, NULL);
+
+ args = _gp11_call_arguments (result, WrapKey);
+
+ if (!_gp11_call_basic_finish (result, err))
+ return NULL;
+
+ *n_result = args->n_result;
+ args->n_result = 0;
+ ret = args->result;
+ args->result = NULL;
+
+ return ret;
+}
+
+/* -----------------------------------------------------------------------------
+ * KEY UNWRAPPING
+ */
+
+typedef struct _UnwrapKey {
+ GP11Arguments base;
+ GP11Mechanism *mechanism;
+ GP11Attributes *attrs;
+ CK_OBJECT_HANDLE wrapper;
+ gconstpointer input;
+ gulong n_input;
+ CK_OBJECT_HANDLE unwrapped;
+} UnwrapKey;
+
+static void
+free_unwrap_key (UnwrapKey *args)
+{
+ gp11_mechanism_unref (args->mechanism);
+ gp11_attributes_unref (args->attrs);
+ g_free (args);
+}
+
+static CK_RV
+perform_unwrap_key (UnwrapKey *args)
+{
+ CK_ATTRIBUTE_PTR attrs;
+ CK_ULONG n_attrs;
+
+ g_assert (sizeof (CK_MECHANISM) == sizeof (GP11Mechanism));
+
+ attrs = _gp11_attributes_commit_out (args->attrs, &n_attrs);
+
+ return (args->base.pkcs11->C_UnwrapKey) (args->base.handle,
+ (CK_MECHANISM_PTR)args->mechanism,
+ args->wrapper, (CK_BYTE_PTR)args->input,
+ args->n_input, attrs, n_attrs,
+ &args->unwrapped);
+}
+
+/**
+ * gp11_session_unwrap_key:
+ * @self: The session to use.
+ * @wrapper: The key to use for unwrapping.
+ * @mech_type: The mechanism type to use for derivation.
+ * @input: The wrapped data as a byte stream.
+ * @n_input: The length of the wrapped data.
+ * @err: A location to return an error, or NULL.
+ * @...: Additional attributes for the unwrapped key.
+ *
+ * Unwrap a key from a byte stream. This call may block for an
+ * indefinite period.
+ *
+ * The arguments must be triples of: attribute type, data type, value
+ *
+ * <para>The variable argument list should contain:
+ * <variablelist>
+ * <varlistentry>
+ * <term>a)</term>
+ * <listitem><para>The gulong attribute type (ie: CKA_LABEL). </para></listitem>
+ * </varlistentry>
+ * <varlistentry>
+ * <term>b)</term>
+ * <listitem><para>The attribute data type (one of GP11_BOOLEAN, GP11_ULONG,
+ * GP11_STRING, GP11_DATE) orthe raw attribute value length.</para></listitem>
+ * </varlistentry>
+ * <varlistentry>
+ * <term>c)</term>
+ * <listitem><para>The attribute value, either a gboolean, gulong, gchar*, GDate* or
+ * a pointer to a raw attribute value.</para></listitem>
+ * </varlistentry>
+ * </variablelist>
+ * The variable argument list should be terminated with GP11_INVALID.</para>
+ *
+ * Return value: The new unwrapped key or NULL if the operation failed.
+ **/
+GP11Object*
+gp11_session_unwrap_key (GP11Session *self, GP11Object *key, gulong mech_type,
+ gconstpointer input, gsize n_input, GError **err, ...)
+{
+ GP11Mechanism mech = { mech_type, NULL, 0 };
+ GP11Attributes *attrs;
+ GP11Object *object;
+ va_list va;
+
+ va_start (va, err);
+ attrs = gp11_attributes_new_valist (g_realloc, va);
+ va_end (va);
+
+ object = gp11_session_unwrap_key_full (self, key, &mech, input, n_input, attrs, NULL, err);
+ gp11_attributes_unref (attrs);
+ return object;
+}
+
+/**
+ * gp11_session_unwrap_key_full:
+ * @self: The session to use.
+ * @wrapper: The key to use for unwrapping.
+ * @mechanism: The mechanism to use for unwrapping.
+ * @input: The wrapped data as a byte stream.
+ * @n_input: The length of the wrapped data.
+ * @attrs: Additional attributes for the unwrapped key.
+ * @cancellable: Optional cancellation object, or NULL.
+ * @err: A location to return an error, or NULL.
+ *
+ * Unwrap a key from a byte stream. This call may block for an
+ * indefinite period.
+ *
+ * Return value: The new unwrapped key or NULL if the operation failed.
+ **/
+GP11Object*
+gp11_session_unwrap_key_full (GP11Session *self, GP11Object *wrapper, GP11Mechanism *mechanism,
+ gconstpointer input, gsize n_input, GP11Attributes *attrs,
+ GCancellable *cancellable, GError **err)
+{
+ GP11SessionData *data = GP11_SESSION_GET_DATA (self);
+ UnwrapKey args = { GP11_ARGUMENTS_INIT, mechanism, attrs, 0, input, n_input, 0 };
+ gboolean ret;
+
+ g_return_val_if_fail (GP11_IS_SESSION (self), FALSE);
+ g_return_val_if_fail (GP11_IS_OBJECT (wrapper), FALSE);
+ g_return_val_if_fail (mechanism, FALSE);
+ g_return_val_if_fail (attrs, FALSE);
+
+ g_object_get (wrapper, "handle", &args.wrapper, NULL);
+ g_return_val_if_fail (args.wrapper != 0, NULL);
+
+ _gp11_attributes_lock (attrs);
+ ret = _gp11_call_sync (self, perform_unwrap_key, NULL, &args, cancellable, err);
+ _gp11_attributes_unlock (attrs);
+
+ if (!ret)
+ return NULL;
+
+ return gp11_object_from_handle (data->slot, args.unwrapped);
+}
+
+/**
+ * gp11_session_unwrap_key_async:
+ * @self: The session to use.
+ * @wrapper: The key to use for unwrapping.
+ * @mechanism: The mechanism to use for unwrapping.
+ * @input: The wrapped data as a byte stream.
+ * @n_input: The length of the wrapped data.
+ * @attrs: Additional attributes for the unwrapped key.
+ * @cancellable: Optional cancellation object or NULL.
+ * @callback: Called when the operation completes.
+ * @user_data: Data to pass to the callback.
+ *
+ * Unwrap a key from a byte stream. This call will
+ * return immediately and complete asynchronously.
+ **/
+void
+gp11_session_unwrap_key_async (GP11Session *self, GP11Object *wrapper, GP11Mechanism *mechanism,
+ gconstpointer input, gsize n_input, GP11Attributes *attrs,
+ GCancellable *cancellable, GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ UnwrapKey *args = _gp11_call_async_prep (self, self, perform_unwrap_key,
+ NULL, sizeof (*args), free_unwrap_key);
+
+ g_return_if_fail (GP11_IS_SESSION (self));
+ g_return_if_fail (GP11_IS_OBJECT (wrapper));
+ g_return_if_fail (attrs);
+
+ g_object_get (wrapper, "handle", &args->wrapper, NULL);
+ g_return_if_fail (args->wrapper != 0);
+
+ args->mechanism = gp11_mechanism_ref (mechanism);
+ args->attrs = gp11_attributes_ref (attrs);
+ args->input = input;
+ args->n_input = n_input;
+ _gp11_attributes_lock (attrs);
+
+ _gp11_call_async_ready_go (args, cancellable, callback, user_data);
+}
+
+/**
+ * gp11_session_wrap_key_finish:
+ * @self: The session to use.
+ * @result: The async result passed to the callback.
+ * @err: A location to return an error.
+ *
+ * Get the result of a unwrap key operation.
+ *
+ * Return value: The new unwrapped key or NULL if the operation failed.
+ **/
+GP11Object*
+gp11_session_unwrap_key_finish (GP11Session *self, GAsyncResult *result, GError **err)
+{
+ GP11SessionData *data = GP11_SESSION_GET_DATA (self);
+ UnwrapKey *args;
+
+ g_return_val_if_fail (GP11_IS_SESSION (self), NULL);
+
+ args = _gp11_call_arguments (result, UnwrapKey);
+ _gp11_attributes_unlock (args->attrs);
+
+ if (!_gp11_call_basic_finish (result, err))
+ return NULL;
+ return gp11_object_from_handle (data->slot, args->unwrapped);
+}
+
+/* -----------------------------------------------------------------------------
+ * KEY DERIVATION
+ */
+
+typedef struct _DeriveKey {
+ GP11Arguments base;
+ GP11Mechanism *mechanism;
+ GP11Attributes *attrs;
+ CK_OBJECT_HANDLE key;
+ CK_OBJECT_HANDLE derived;
+} DeriveKey;
+
+static void
+free_derive_key (DeriveKey *args)
+{
+ gp11_mechanism_unref (args->mechanism);
+ gp11_attributes_unref (args->attrs);
+ g_free (args);
+}
+
+static CK_RV
+perform_derive_key (DeriveKey *args)
+{
+ CK_ATTRIBUTE_PTR attrs;
+ CK_ULONG n_attrs;
+
+ g_assert (sizeof (CK_MECHANISM) == sizeof (GP11Mechanism));
+
+ attrs = _gp11_attributes_commit_out (args->attrs, &n_attrs);
+
+ return (args->base.pkcs11->C_DeriveKey) (args->base.handle,
+ (CK_MECHANISM_PTR)args->mechanism,
+ args->key, attrs, n_attrs,
+ &args->derived);
+}
+
+/**
+ * gp11_session_derive_key_full:
+ * @self: The session to use.
+ * @base: The key to derive from.
+ * @mech_type: The mechanism type to use for derivation.
+ * @err: A location to return an error, or NULL.
+ * @...: Additional attributes for the derived key.
+ *
+ * Derive a key from another key. This call may block for an
+ * indefinite period.
+ *
+ * The arguments must be triples of: attribute type, data type, value
+ *
+ * <para>The variable argument list should contain:
+ * <variablelist>
+ * <varlistentry>
+ * <term>a)</term>
+ * <listitem><para>The gulong attribute type (ie: CKA_LABEL). </para></listitem>
+ * </varlistentry>
+ * <varlistentry>
+ * <term>b)</term>
+ * <listitem><para>The attribute data type (one of GP11_BOOLEAN, GP11_ULONG,
+ * GP11_STRING, GP11_DATE) orthe raw attribute value length.</para></listitem>
+ * </varlistentry>
+ * <varlistentry>
+ * <term>c)</term>
+ * <listitem><para>The attribute value, either a gboolean, gulong, gchar*, GDate* or
+ * a pointer to a raw attribute value.</para></listitem>
+ * </varlistentry>
+ * </variablelist>
+ * The variable argument list should be terminated with GP11_INVALID.</para>
+ *
+ * Return value: The new derived key or NULL if the operation failed.
+ **/
+GP11Object*
+gp11_session_derive_key (GP11Session *self, GP11Object *key, gulong mech_type,
+ GError **err, ...)
+{
+ GP11Mechanism mech = { mech_type, NULL, 0 };
+ GP11Attributes *attrs;
+ GP11Object *object;
+ va_list va;
+
+ va_start (va, err);
+ attrs = gp11_attributes_new_valist (g_realloc, va);
+ va_end (va);
+
+ object = gp11_session_derive_key_full (self, key, &mech, attrs, NULL, err);
+ gp11_attributes_unref (attrs);
+ return object;
+}
+
+/**
+ * gp11_session_derive_key_full:
+ * @self: The session to use.
+ * @base: The key to derive from.
+ * @mechanism: The mechanism to use for derivation.
+ * @attrs: Additional attributes for the derived key.
+ * @cancellable: Optional cancellation object, or NULL.
+ * @err: A location to return an error, or NULL.
+ *
+ * Derive a key from another key. This call may block for an
+ * indefinite period.
+ *
+ * Return value: The new derived key or NULL if the operation failed.
+ **/
+GP11Object*
+gp11_session_derive_key_full (GP11Session *self, GP11Object *base, GP11Mechanism *mechanism,
+ GP11Attributes *attrs, GCancellable *cancellable, GError **err)
+{
+ GP11SessionData *data = GP11_SESSION_GET_DATA (self);
+ DeriveKey args = { GP11_ARGUMENTS_INIT, mechanism, attrs, 0, 0 };
+ gboolean ret;
+
+ g_return_val_if_fail (GP11_IS_SESSION (self), FALSE);
+ g_return_val_if_fail (GP11_IS_OBJECT (base), FALSE);
+ g_return_val_if_fail (mechanism, FALSE);
+ g_return_val_if_fail (attrs, FALSE);
+
+ g_object_get (base, "handle", &args.key, NULL);
+ g_return_val_if_fail (args.key != 0, NULL);
+
+ _gp11_attributes_lock (attrs);
+ ret = _gp11_call_sync (self, perform_derive_key, NULL, &args, cancellable, err);
+ _gp11_attributes_unlock (attrs);
+
+ if (!ret)
+ return NULL;
+
+ return gp11_object_from_handle (data->slot, args.derived);
+}
+
+/**
+ * gp11_session_derive_key_async:
+ * @self: The session to use.
+ * @base: The key to derive from.
+ * @mechanism: The mechanism to use for derivation.
+ * @attrs: Additional attributes for the derived key.
+ * @cancellable: Optional cancellation object or NULL.
+ * @callback: Called when the operation completes.
+ * @user_data: Data to pass to the callback.
+ *
+ * Derive a key from another key. This call will
+ * return immediately and complete asynchronously.
+ **/
+void
+gp11_session_derive_key_async (GP11Session *self, GP11Object *base, GP11Mechanism *mechanism,
+ GP11Attributes *attrs, GCancellable *cancellable,
+ GAsyncReadyCallback callback, gpointer user_data)
+{
+ DeriveKey *args = _gp11_call_async_prep (self, self, perform_derive_key,
+ NULL, sizeof (*args), free_derive_key);
+
+ g_return_if_fail (GP11_IS_SESSION (self));
+ g_return_if_fail (GP11_IS_OBJECT (base));
+ g_return_if_fail (attrs);
+
+ g_object_get (base, "handle", &args->key, NULL);
+ g_return_if_fail (args->key != 0);
+
+ args->mechanism = gp11_mechanism_ref (mechanism);
+ args->attrs = gp11_attributes_ref (attrs);
+ _gp11_attributes_lock (attrs);
+
+ _gp11_call_async_ready_go (args, cancellable, callback, user_data);
+}
+
+/**
+ * gp11_session_wrap_key_finish:
+ * @self: The session to use.
+ * @result: The async result passed to the callback.
+ * @err: A location to return an error.
+ *
+ * Get the result of a derive key operation.
+ *
+ * Return value: The new derived key or NULL if the operation failed.
+ **/
+GP11Object*
+gp11_session_derive_key_finish (GP11Session *self, GAsyncResult *result, GError **err)
+{
+ GP11SessionData *data = GP11_SESSION_GET_DATA (self);
+ DeriveKey *args;
+
+ g_return_val_if_fail (GP11_IS_SESSION (self), NULL);
+
+ args = _gp11_call_arguments (result, DeriveKey);
+ _gp11_attributes_unlock (args->attrs);
+
+ if (!_gp11_call_basic_finish (result, err))
+ return NULL;
+
+ return gp11_object_from_handle (data->slot, args->derived);
+}
+
/* --------------------------------------------------------------------------------------------------
* AUTHENTICATE
*/
@@ -1227,7 +1957,7 @@ typedef struct _Crypt {
/* Input */
CK_OBJECT_HANDLE key;
- CK_MECHANISM mech;
+ GP11Mechanism *mech;
guchar *input;
CK_ULONG n_input;
@@ -1249,7 +1979,7 @@ perform_crypt (Crypt *args)
g_assert (!args->n_result);
/* Initialize the crypt operation */
- rv = (args->init_func) (args->base.handle, &args->mech, args->key);
+ rv = (args->init_func) (args->base.handle, (CK_MECHANISM_PTR)args->mech, args->key);
if (rv != CKR_OK)
return rv;
@@ -1281,13 +2011,13 @@ static void
free_crypt (Crypt *args)
{
g_free (args->input);
- g_free (args->mech.pParameter);
+ gp11_mechanism_unref (args->mech);
g_free (args->result);
g_free (args);
}
static guchar*
-crypt_sync (GP11Session *self, GP11Object *key, GP11Mechanism *mech_args, const guchar *input,
+crypt_sync (GP11Session *self, GP11Object *key, GP11Mechanism *mechanism, const guchar *input,
gsize n_input, gsize *n_result, GCancellable *cancellable, GError **err,
CK_C_EncryptInit init_func, CK_C_Encrypt complete_func)
{
@@ -1295,18 +2025,16 @@ crypt_sync (GP11Session *self, GP11Object *key, GP11Mechanism *mech_args, const
GP11Slot *slot;
g_return_val_if_fail (GP11_IS_OBJECT (key), NULL);
- g_return_val_if_fail (mech_args, NULL);
+ g_return_val_if_fail (mechanism, NULL);
g_return_val_if_fail (init_func, NULL);
g_return_val_if_fail (complete_func, NULL);
memset (&args, 0, sizeof (args));
g_object_get (key, "handle", &args.key, NULL);
g_return_val_if_fail (args.key != 0, NULL);
-
- args.mech.mechanism = mech_args->type;
- args.mech.pParameter = mech_args->parameter;
- args.mech.ulParameterLen = mech_args->n_parameter;
-
+
+ args.mech = mechanism;
+
/* No need to copy in this case */
args.input = (guchar*)input;
args.n_input = n_input;
@@ -1328,7 +2056,7 @@ crypt_sync (GP11Session *self, GP11Object *key, GP11Mechanism *mech_args, const
}
static void
-crypt_async (GP11Session *self, GP11Object *key, GP11Mechanism *mech_args, const guchar *input,
+crypt_async (GP11Session *self, GP11Object *key, GP11Mechanism *mechanism, const guchar *input,
gsize n_input, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data,
CK_C_EncryptInit init_func, CK_C_Encrypt complete_func)
{
@@ -1336,18 +2064,15 @@ crypt_async (GP11Session *self, GP11Object *key, GP11Mechanism *mech_args, const
GP11Slot *slot;
g_return_if_fail (GP11_IS_OBJECT (key));
- g_return_if_fail (mech_args);
+ g_return_if_fail (mechanism);
g_return_if_fail (init_func);
g_return_if_fail (complete_func);
g_object_get (key, "handle", &args->key, NULL);
g_return_if_fail (args->key != 0);
- args->mech.mechanism = mech_args->type;
- args->mech.pParameter = mech_args->parameter && mech_args->n_parameter ?
- g_memdup (mech_args->parameter, mech_args->n_parameter) : NULL;
- args->mech.ulParameterLen = mech_args->n_parameter;
-
+ args->mech = gp11_mechanism_ref (mechanism);
+
args->input = input && n_input ? g_memdup (input, n_input) : NULL;
args->n_input = n_input;
@@ -1403,15 +2128,15 @@ guchar*
gp11_session_encrypt (GP11Session *self, GP11Object *key, gulong mech_type, const guchar *input,
gsize n_input, gsize *n_result, GError **err)
{
- GP11Mechanism mech_args = { mech_type, NULL, 0 };
- return gp11_session_encrypt_full (self, key, &mech_args, input, n_input, n_result, NULL, err);
+ GP11Mechanism mechanism = { mech_type, NULL, 0 };
+ return gp11_session_encrypt_full (self, key, &mechanism, input, n_input, n_result, NULL, err);
}
/**
* gp11_session_encrypt_full:
* @self: The session.
* @key: The key to encrypt with.
- * @mech_args: The mechanism type and parameters to use for encryption.
+ * @mechanism: The mechanism type and parameters to use for encryption.
* @input: The data to encrypt.
* @n_input: The length of the data to encrypt.
* @n_result: A location to store the length of the result data.
@@ -1424,7 +2149,7 @@ gp11_session_encrypt (GP11Session *self, GP11Object *key, gulong mech_type, cons
* Returns: The data that was encrypted, or NULL if an error occured.
*/
guchar*
-gp11_session_encrypt_full (GP11Session *self, GP11Object *key, GP11Mechanism *mech_args,
+gp11_session_encrypt_full (GP11Session *self, GP11Object *key, GP11Mechanism *mechanism,
const guchar *input, gsize n_input, gsize *n_result,
GCancellable *cancellable, GError **err)
{
@@ -1438,7 +2163,7 @@ gp11_session_encrypt_full (GP11Session *self, GP11Object *key, GP11Mechanism *me
funcs = gp11_module_get_functions (module);
g_return_val_if_fail (module != NULL, NULL);
- ret = crypt_sync (self, key, mech_args, input, n_input, n_result, cancellable, err,
+ ret = crypt_sync (self, key, mechanism, input, n_input, n_result, cancellable, err,
funcs->C_EncryptInit, funcs->C_Encrypt);
g_object_unref (module);
@@ -1449,7 +2174,7 @@ gp11_session_encrypt_full (GP11Session *self, GP11Object *key, GP11Mechanism *me
* gp11_session_encrypt_async:
* @self: The session.
* @key: The key to encrypt with.
- * @mech_args: The mechanism type and parameters to use for encryption.
+ * @mechanism: The mechanism type and parameters to use for encryption.
* @input: The data to encrypt.
* @n_input: The length of the data to encrypt.
* @cancellable: A GCancellable which can be used to cancel the operation.
@@ -1458,11 +2183,9 @@ gp11_session_encrypt_full (GP11Session *self, GP11Object *key, GP11Mechanism *me
*
* Encrypt data in a mechanism specific manner. This call will
* return immediately and complete asynchronously.
- *
- * Returns: The data that was encrypted.
- */
+ **/
void
-gp11_session_encrypt_async (GP11Session *self, GP11Object *key, GP11Mechanism *mech_args,
+gp11_session_encrypt_async (GP11Session *self, GP11Object *key, GP11Mechanism *mechanism,
const guchar *input, gsize n_input, GCancellable *cancellable,
GAsyncReadyCallback callback, gpointer user_data)
{
@@ -1475,7 +2198,7 @@ gp11_session_encrypt_async (GP11Session *self, GP11Object *key, GP11Mechanism *m
funcs = gp11_module_get_functions (module);
g_return_if_fail (module != NULL);
- crypt_async (self, key, mech_args, input, n_input, cancellable, callback, user_data,
+ crypt_async (self, key, mechanism, input, n_input, cancellable, callback, user_data,
funcs->C_EncryptInit, funcs->C_Encrypt);
g_object_unref (module);
@@ -1522,15 +2245,15 @@ guchar*
gp11_session_decrypt (GP11Session *self, GP11Object *key, gulong mech_type, const guchar *input,
gsize n_input, gsize *n_result, GError **err)
{
- GP11Mechanism mech_args = { mech_type, NULL, 0 };
- return gp11_session_decrypt_full (self, key, &mech_args, input, n_input, n_result, NULL, err);
+ GP11Mechanism mechanism = { mech_type, NULL, 0 };
+ return gp11_session_decrypt_full (self, key, &mechanism, input, n_input, n_result, NULL, err);
}
/**
* gp11_session_decrypt_full:
* @self: The session.
* @key: The key to decrypt with.
- * @mech_args: The mechanism type and parameters to use for decryption.
+ * @mechanism: The mechanism type and parameters to use for decryption.
* @input: The data to decrypt.
* @n_input: The length of the data to decrypt.
* @n_result: A location to store the length of the result data.
@@ -1543,7 +2266,7 @@ gp11_session_decrypt (GP11Session *self, GP11Object *key, gulong mech_type, cons
* Returns: The data that was decrypted, or NULL if an error occured.
*/
guchar*
-gp11_session_decrypt_full (GP11Session *self, GP11Object *key, GP11Mechanism *mech_args,
+gp11_session_decrypt_full (GP11Session *self, GP11Object *key, GP11Mechanism *mechanism,
const guchar *input, gsize n_input, gsize *n_result,
GCancellable *cancellable, GError **err)
{
@@ -1557,7 +2280,7 @@ gp11_session_decrypt_full (GP11Session *self, GP11Object *key, GP11Mechanism *me
funcs = gp11_module_get_functions (module);
g_return_val_if_fail (module != NULL, NULL);
- ret = crypt_sync (self, key, mech_args, input, n_input, n_result, cancellable, err,
+ ret = crypt_sync (self, key, mechanism, input, n_input, n_result, cancellable, err,
funcs->C_DecryptInit, funcs->C_Decrypt);
g_object_unref (module);
return ret;
@@ -1567,7 +2290,7 @@ gp11_session_decrypt_full (GP11Session *self, GP11Object *key, GP11Mechanism *me
* gp11_session_decrypt_async:
* @self: The session.
* @key: The key to decrypt with.
- * @mech_args: The mechanism type and parameters to use for decryption.
+ * @mechanism: The mechanism type and parameters to use for decryption.
* @input: The data to decrypt.
* @n_input: The length of the data to decrypt.
* @cancellable: A GCancellable which can be used to cancel the operation.
@@ -1576,11 +2299,9 @@ gp11_session_decrypt_full (GP11Session *self, GP11Object *key, GP11Mechanism *me
*
* Decrypt data in a mechanism specific manner. This call will
* return immediately and complete asynchronously.
- *
- * Returns: The data that was decrypted.
*/
void
-gp11_session_decrypt_async (GP11Session *self, GP11Object *key, GP11Mechanism *mech_args,
+gp11_session_decrypt_async (GP11Session *self, GP11Object *key, GP11Mechanism *mechanism,
const guchar *input, gsize n_input, GCancellable *cancellable,
GAsyncReadyCallback callback, gpointer user_data)
{
@@ -1593,7 +2314,7 @@ gp11_session_decrypt_async (GP11Session *self, GP11Object *key, GP11Mechanism *m
funcs = gp11_module_get_functions (module);
g_return_if_fail (module != NULL);
- crypt_async (self, key, mech_args, input, n_input, cancellable, callback, user_data,
+ crypt_async (self, key, mechanism, input, n_input, cancellable, callback, user_data,
funcs->C_DecryptInit, funcs->C_Decrypt);
g_object_unref (module);
}
@@ -1639,15 +2360,15 @@ guchar*
gp11_session_sign (GP11Session *self, GP11Object *key, gulong mech_type, const guchar *input,
gsize n_input, gsize *n_result, GError **err)
{
- GP11Mechanism mech_args = { mech_type, NULL, 0 };
- return gp11_session_sign_full (self, key, &mech_args, input, n_input, n_result, NULL, err);
+ GP11Mechanism mechanism = { mech_type, NULL, 0 };
+ return gp11_session_sign_full (self, key, &mechanism, input, n_input, n_result, NULL, err);
}
/**
* gp11_session_sign_full:
* @self: The session.
* @key: The key to sign with.
- * @mech_args: The mechanism type and parameters to use for signing.
+ * @mechanism: The mechanism type and parameters to use for signing.
* @input: The data to sign.
* @n_input: The length of the data to sign.
* @n_result: A location to store the length of the result data.
@@ -1660,7 +2381,7 @@ gp11_session_sign (GP11Session *self, GP11Object *key, gulong mech_type, const g
* Returns: The data that was signed, or NULL if an error occured.
*/
guchar*
-gp11_session_sign_full (GP11Session *self, GP11Object *key, GP11Mechanism *mech_args,
+gp11_session_sign_full (GP11Session *self, GP11Object *key, GP11Mechanism *mechanism,
const guchar *input, gsize n_input, gsize *n_result,
GCancellable *cancellable, GError **err)
{
@@ -1674,7 +2395,7 @@ gp11_session_sign_full (GP11Session *self, GP11Object *key, GP11Mechanism *mech_
funcs = gp11_module_get_functions (module);
g_return_val_if_fail (module != NULL, NULL);
- ret = crypt_sync (self, key, mech_args, input, n_input, n_result, cancellable, err,
+ ret = crypt_sync (self, key, mechanism, input, n_input, n_result, cancellable, err,
funcs->C_SignInit, funcs->C_Sign);
g_object_unref (module);
return ret;
@@ -1684,7 +2405,7 @@ gp11_session_sign_full (GP11Session *self, GP11Object *key, GP11Mechanism *mech_
* gp11_session_sign_async:
* @self: The session.
* @key: The key to sign with.
- * @mech_args: The mechanism type and parameters to use for signing.
+ * @mechanism: The mechanism type and parameters to use for signing.
* @input: The data to sign.
* @n_input: The length of the data to sign.
* @cancellable: A GCancellable which can be used to cancel the operation.
@@ -1693,11 +2414,9 @@ gp11_session_sign_full (GP11Session *self, GP11Object *key, GP11Mechanism *mech_
*
* Sign data in a mechanism specific manner. This call will
* return immediately and complete asynchronously.
- *
- * Returns: The data that was signed.
*/
void
-gp11_session_sign_async (GP11Session *self, GP11Object *key, GP11Mechanism *mech_args,
+gp11_session_sign_async (GP11Session *self, GP11Object *key, GP11Mechanism *mechanism,
const guchar *input, gsize n_input, GCancellable *cancellable,
GAsyncReadyCallback callback, gpointer user_data)
{
@@ -1710,7 +2429,7 @@ gp11_session_sign_async (GP11Session *self, GP11Object *key, GP11Mechanism *mech
funcs = gp11_module_get_functions (module);
g_return_if_fail (module != NULL);
- crypt_async (self, key, mech_args, input, n_input, cancellable, callback, user_data,
+ crypt_async (self, key, mechanism, input, n_input, cancellable, callback, user_data,
funcs->C_SignInit, funcs->C_Sign);
g_object_unref (module);
}
@@ -1745,7 +2464,7 @@ typedef struct _Verify {
/* Input */
CK_OBJECT_HANDLE key;
- CK_MECHANISM mech;
+ GP11Mechanism *mech;
guchar *input;
CK_ULONG n_input;
guchar *signature;
@@ -1759,7 +2478,7 @@ perform_verify (Verify *args)
CK_RV rv;
/* Initialize the crypt operation */
- rv = (args->base.pkcs11->C_VerifyInit) (args->base.handle, &args->mech, args->key);
+ rv = (args->base.pkcs11->C_VerifyInit) (args->base.handle, (CK_MECHANISM_PTR)args->mech, args->key);
if (rv != CKR_OK)
return rv;
@@ -1787,7 +2506,7 @@ free_verify (Verify *args)
{
g_free (args->input);
g_free (args->signature);
- g_free (args->mech.pParameter);
+ gp11_mechanism_unref (args->mech);
g_free (args);
}
@@ -1811,8 +2530,8 @@ gboolean
gp11_session_verify (GP11Session *self, GP11Object *key, gulong mech_type, const guchar *input,
gsize n_input, const guchar *signature, gsize n_signature, GError **err)
{
- GP11Mechanism mech_args = { mech_type, NULL, 0 };
- return gp11_session_verify_full (self, key, &mech_args, input, n_input,
+ GP11Mechanism mechanism = { mech_type, NULL, 0 };
+ return gp11_session_verify_full (self, key, &mechanism, input, n_input,
signature, n_signature, NULL, err);
}
@@ -1820,7 +2539,7 @@ gp11_session_verify (GP11Session *self, GP11Object *key, gulong mech_type, const
* gp11_session_verify_full:
* @self: The session.
* @key: The key to verify with.
- * @mech_args: The mechanism type and parameters to use for signing.
+ * @mechanism: The mechanism type and parameters to use for signing.
* @input: The data to verify.
* @n_input: The length of the data to verify.
* @signature: The signature.
@@ -1834,7 +2553,7 @@ gp11_session_verify (GP11Session *self, GP11Object *key, gulong mech_type, const
* Returns: TRUE if the data verified correctly, otherwise a failure or error occurred.
*/
gboolean
-gp11_session_verify_full (GP11Session *self, GP11Object *key, GP11Mechanism *mech_args,
+gp11_session_verify_full (GP11Session *self, GP11Object *key, GP11Mechanism *mechanism,
const guchar *input, gsize n_input, const guchar *signature,
gsize n_signature, GCancellable *cancellable, GError **err)
{
@@ -1842,16 +2561,14 @@ gp11_session_verify_full (GP11Session *self, GP11Object *key, GP11Mechanism *mec
GP11Slot *slot;
g_return_val_if_fail (GP11_IS_OBJECT (key), FALSE);
- g_return_val_if_fail (mech_args, FALSE);
+ g_return_val_if_fail (mechanism, FALSE);
memset (&args, 0, sizeof (args));
g_object_get (key, "handle", &args.key, NULL);
g_return_val_if_fail (args.key != 0, FALSE);
-
- args.mech.mechanism = mech_args->type;
- args.mech.pParameter = mech_args->parameter;
- args.mech.ulParameterLen = mech_args->n_parameter;
-
+
+ args.mech = mechanism;
+
/* No need to copy in this case */
args.input = (guchar*)input;
args.n_input = n_input;
@@ -1869,7 +2586,7 @@ gp11_session_verify_full (GP11Session *self, GP11Object *key, GP11Mechanism *mec
* gp11_session_verify_async:
* @self: The session.
* @key: The key to verify with.
- * @mech_args: The mechanism type and parameters to use for signing.
+ * @mechanism: The mechanism type and parameters to use for signing.
* @input: The data to verify.
* @n_input: The length of the data to verify.
* @signature: The signature.
@@ -1882,7 +2599,7 @@ gp11_session_verify_full (GP11Session *self, GP11Object *key, GP11Mechanism *mec
* immediately and completes asynchronously.
*/
void
-gp11_session_verify_async (GP11Session *self, GP11Object *key, GP11Mechanism *mech_args,
+gp11_session_verify_async (GP11Session *self, GP11Object *key, GP11Mechanism *mechanism,
const guchar *input, gsize n_input, const guchar *signature,
gsize n_signature, GCancellable *cancellable,
GAsyncReadyCallback callback, gpointer user_data)
@@ -1891,16 +2608,13 @@ gp11_session_verify_async (GP11Session *self, GP11Object *key, GP11Mechanism *me
GP11Slot *slot;
g_return_if_fail (GP11_IS_OBJECT (key));
- g_return_if_fail (mech_args);
+ g_return_if_fail (mechanism);
g_object_get (key, "handle", &args->key, NULL);
g_return_if_fail (args->key != 0);
- args->mech.mechanism = mech_args->type;
- args->mech.pParameter = mech_args->parameter && mech_args->n_parameter ?
- g_memdup (mech_args->parameter, mech_args->n_parameter) : NULL;
- args->mech.ulParameterLen = mech_args->n_parameter;
-
+ args->mech = gp11_mechanism_ref (mechanism);
+
args->input = input && n_input ? g_memdup (input, n_input) : NULL;
args->n_input = n_input;
args->signature = signature && n_signature ? g_memdup (signature, n_signature) : NULL;
diff --git a/gp11/gp11.h b/gp11/gp11.h
index 3cd9f37..009ef38 100644
--- a/gp11/gp11.h
+++ b/gp11/gp11.h
@@ -57,6 +57,16 @@ typedef struct GP11Mechanism {
gulong n_parameter;
} GP11Mechanism;
+GP11Mechanism* gp11_mechanism_new (gulong type);
+
+GP11Mechanism* gp11_mechanism_new_with_param (gulong type,
+ gconstpointer parameter,
+ gulong n_parameter);
+
+GP11Mechanism* gp11_mechanism_ref (GP11Mechanism* mech);
+
+void gp11_mechanism_unref (GP11Mechanism* mech);
+
typedef struct GP11Attribute {
gulong type;
guchar *value;
@@ -714,25 +724,32 @@ GP11Object* gp11_session_generate_key_finish (GP11Session *self,
GError **err,
...) GP11_INVALID_TERMINATED;
-gboolean gp11_session_generate_key_pair (GP11Session *self,
+#endif /* UNIMPLEMENTED */
+
+gboolean gp11_session_generate_key_pair_full (GP11Session *self,
GP11Mechanism *mechanism,
+ GP11Attributes *public_attrs,
+ GP11Attributes *private_attrs,
GP11Object **public_key,
GP11Object **private_key,
- GError **err,
- ...) GP11_INVALID_TERMINATED;
+ GCancellable *cancellable,
+ GError **err);
void gp11_session_generate_key_pair_async (GP11Session *self,
GP11Mechanism *mechanism,
+ GP11Attributes *public_attrs,
+ GP11Attributes *private_attrs,
+ GCancellable *cancellable,
GAsyncReadyCallback callback,
- gpointer user_data,
- ...) GP11_INVALID_TERMINATED;
+ gpointer user_data);
gboolean gp11_session_generate_key_pair_finish (GP11Session *self,
GAsyncResult *result,
GP11Object **public_key,
GP11Object **private_key,
- GError **err,
- ...) GP11_INVALID_TERMINATED;
+ GError **err);
+
+#ifdef UNIMPLEMENTED
gboolean gp11_session_seed_random (GP11Session *self,
const guchar *seed,
@@ -774,7 +791,7 @@ guchar* gp11_session_encrypt (GP11Session *self,
guchar* gp11_session_encrypt_full (GP11Session *self,
GP11Object *key,
- GP11Mechanism *mech_args,
+ GP11Mechanism *mechanism,
const guchar *input,
gsize n_input,
gsize *n_result,
@@ -783,7 +800,7 @@ guchar* gp11_session_encrypt_full (GP11Session *self,
void gp11_session_encrypt_async (GP11Session *self,
GP11Object *key,
- GP11Mechanism *mech_args,
+ GP11Mechanism *mechanism,
const guchar *input,
gsize n_input,
GCancellable *cancellable,
@@ -799,13 +816,13 @@ guchar* gp11_session_encrypt_finish (GP11Session *self,
GP11Processor* gp11_session_batch_encrypt (GP11Session *self,
GP11Object *key,
- GP11Mechanism *mech_args,
+ GP11Mechanism *mechanism,
GCancellable *cancellable,
GError **err);
void gp11_session_batch_encrypt_async (GP11Session *self,
GP11Object *key,
- GP11Mechanism *mech_args,
+ GP11Mechanism *mechanism,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
@@ -827,7 +844,7 @@ guchar* gp11_session_decrypt (GP11Session *self,
guchar* gp11_session_decrypt_full (GP11Session *self,
GP11Object *key,
- GP11Mechanism *mech_args,
+ GP11Mechanism *mechanism,
const guchar *input,
gsize n_input,
gsize *n_result,
@@ -836,7 +853,7 @@ guchar* gp11_session_decrypt_full (GP11Session *self,
void gp11_session_decrypt_async (GP11Session *self,
GP11Object *key,
- GP11Mechanism *mech_args,
+ GP11Mechanism *mechanism,
const guchar *input,
gsize n_input,
GCancellable *cancellable,
@@ -852,13 +869,13 @@ guchar* gp11_session_decrypt_finish (GP11Session *self,
GP11Processor* gp11_session_batch_decrypt (GP11Session *self,
GP11Object *key,
- GP11Mechanism *mech_args,
+ GP11Mechanism *mechanism,
GCancellable *cancellable,
GError **err);
void gp11_session_batch_decrypt_async (GP11Session *self,
GP11Object *key,
- GP11Mechanism *mech_args,
+ GP11Mechanism *mechanism,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
@@ -875,7 +892,7 @@ guchar* gp11_session_digest (GP11Session *self,
GError **err);
guchar* gp11_session_digest_full (GP11Session *self,
- GP11Mechanism *mech_args,
+ GP11Mechanism *mechanism,
const guchar *input,
gsize n_input,
gsize *n_result,
@@ -883,7 +900,7 @@ guchar* gp11_session_digest_full (GP11Session *self,
GError **err);
void gp11_session_digest_async (GP11Session *self,
- GP11Mechanism *mech_args,
+ GP11Mechanism *mechanism,
const guchar *input,
gsize n_input,
GCancellable *cancellable,
@@ -896,12 +913,12 @@ guchar* gp11_session_digest_finish (GP11Session *self,
GError **err);
GP11Processor* gp11_session_batch_digest (GP11Session *self,
- GP11Mechanism *mech_args,
+ GP11Mechanism *mechanism,
GCancellable *cancellable,
GError **err);
void gp11_session_batch_digest_async (GP11Session *self,
- GP11Mechanism *mech_args,
+ GP11Mechanism *mechanism,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
@@ -979,7 +996,7 @@ guchar* gp11_session_sign (GP11Session *self,
guchar* gp11_session_sign_full (GP11Session *self,
GP11Object *key,
- GP11Mechanism *mech_args,
+ GP11Mechanism *mechanism,
const guchar *input,
gsize n_input,
gsize *n_result,
@@ -988,7 +1005,7 @@ guchar* gp11_session_sign_full (GP11Session *self,
void gp11_session_sign_async (GP11Session *self,
GP11Object *key,
- GP11Mechanism *mech_args,
+ GP11Mechanism *mechanism,
const guchar *input,
gsize n_input,
GCancellable *cancellable,
@@ -1004,13 +1021,13 @@ guchar* gp11_session_sign_finish (GP11Session *self,
GP11Processor* gp11_session_batch_sign (GP11Session *self,
GP11Object *key,
- GP11Mechanism *mech_args,
+ GP11Mechanism *mechanism,
GCancellable *cancellable,
GError **err);
void gp11_session_batch_sign_async (GP11Session *self,
GP11Object *key,
- GP11Mechanism *mech_args,
+ GP11Mechanism *mechanism,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
@@ -1048,7 +1065,7 @@ guchar* gp11_session_sign_recover (GP11Session *self,
guchar* gp11_session_sign_recover_full (GP11Session *self,
GP11Object *key,
- GP11Mechanism *mech_args,
+ GP11Mechanism *mechanism,
const guchar *input,
gsize n_input,
gsize *n_result,
@@ -1057,7 +1074,7 @@ guchar* gp11_session_sign_recover_full (GP11Session *self,
void gp11_session_sign_recover_async (GP11Session *self,
GP11Object *key,
- GP11Mechanism *mech_args,
+ GP11Mechanism *mechanism,
const guchar *input,
gsize n_input,
GCancellable *cancellable,
@@ -1082,7 +1099,7 @@ gboolean gp11_session_verify (GP11Session *self,
gboolean gp11_session_verify_full (GP11Session *self,
GP11Object *key,
- GP11Mechanism *mech_args,
+ GP11Mechanism *mechanism,
const guchar *input,
gsize n_input,
const guchar *signature,
@@ -1118,7 +1135,7 @@ GkrProcessor* gp11_session_batch_verify (GP11Session *self,
void gp11_session_batch_verify_async (GP11Session *self,
GP11Object *key,
- GP11Mechanism *mech_args,
+ GP11Mechanism *mechanism,
const guchar *input,
gsize n_input,
GCancellable *cancellable,
@@ -1139,7 +1156,7 @@ guchar* gp11_session_verify_recover (GP11Session *self,
guchar* gp11_session_verify_recover_full (GP11Session *self,
GP11Object *key,
- GP11Mechanism *mech_args,
+ GP11Mechanism *mechanism,
const guchar *input,
gsize n_input,
gsize *n_result,
@@ -1148,7 +1165,7 @@ guchar* gp11_session_verify_recover_full (GP11Session *self,
void gp11_session_verify_recover_async (GP11Session *self,
GP11Object *key,
- GP11Mechanism *mech_args,
+ GP11Mechanism *mechanism,
const guchar *input,
gsize n_input,
GCancellable *cancellable,
@@ -1160,93 +1177,92 @@ guchar* gp11_session_verify_recover_finish (GP11Session *self,
gsize *n_result,
GError **err);
-guchar* gp11_session_wrap (GP11Session *self,
- GP11Object *key,
+#endif /* UNIMPLEMENTED */
+
+gpointer gp11_session_wrap_key (GP11Session *self,
+ GP11Object *wrapper,
gulong mech_type,
- GP11Object *wrapped_key,
+ GP11Object *wrapped,
gsize *n_result,
GError **err);
-guchar* gp11_session_wrap (GP11Session *self,
- GP11Object *key,
- GP11Mechanism *mech_args,
- GP11Object *wrapped_key,
+gpointer gp11_session_wrap_key_full (GP11Session *self,
+ GP11Object *wrapper,
+ GP11Mechanism *mechanism,
+ GP11Object *wrapped,
gsize *n_result,
GCancellable *cancellable,
GError **err);
-void gp11_session_wrap_async (GP11Session *self,
- GP11Object *key,
- GP11Mechanism *mech_args,
- GP11Object *wrapped_key,
+void gp11_session_wrap_key_async (GP11Session *self,
+ GP11Object *wrapper,
+ GP11Mechanism *mechanism,
+ GP11Object *wrapped,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
-guchar* gp11_session_wrap_finish (GP11Session *self,
+gpointer gp11_session_wrap_key_finish (GP11Session *self,
GAsyncResult *result,
gsize *n_result,
GError **err);
-GP11Object* gp11_session_unwrap (GP11Session *self,
- GP11Object *key,
+GP11Object* gp11_session_unwrap_key (GP11Session *self,
+ GP11Object *wrapper,
gulong mech_type,
- const guchar *input,
+ gconstpointer input,
gsize n_input,
GError **err,
...) GP11_INVALID_TERMINATED;
-GP11Object* gp11_session_unwrap (GP11Session *self,
- GP11Object *key,
- GP11Mechanism *mech_args,
- const guchar *input,
+GP11Object* gp11_session_unwrap_key_full (GP11Session *self,
+ GP11Object *wrapper,
+ GP11Mechanism *mechanism,
+ gconstpointer input,
gsize n_input,
+ GP11Attributes *attrs,
GCancellable *cancellable,
- GError **err,
- ...) GP11_INVALID_TERMINATED;
+ GError **err);
-void gp11_session_unwrap_async (GP11Session *self,
- GP11Object *key,
- GP11Mechanism *mech_args,
- const guchar *input,
+void gp11_session_unwrap_key_async (GP11Session *self,
+ GP11Object *wrapper,
+ GP11Mechanism *mechanism,
+ gconstpointer input,
gsize n_input,
+ GP11Attributes *attrs,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
- ...) GP11_INVALID_TERMINATED;
-GP11Object* gp11_session_unwrap_finish (GP11Session *self,
+GP11Object* gp11_session_unwrap_key_finish (GP11Session *self,
GAsyncResult *result,
GError **err);
-GP11Object* gp11_session_derive (GP11Session *self,
- GP11Object *key,
+GP11Object* gp11_session_derive_key (GP11Session *self,
+ GP11Object *base,
gulong mech_type,
GError **err,
...) GP11_INVALID_TERMINATED;
-GP11Object* gp11_session_derive_full (GP11Session *self,
- GP11Object *key,
- GP11Mechanism *mech_args,
+GP11Object* gp11_session_derive_key_full (GP11Session *self,
+ GP11Object *base,
+ GP11Mechanism *mechanism,
+ GP11Attributes *attrs,
GCancellable *cancellable,
- GError **err,
- ...) GP11_INVALID_TERMINATED;
+ GError **err);
-void gp11_session_derive_async (GP11Session *self,
- GP11Object *key,
- GP11Mechanism *mech_args,
+void gp11_session_derive_key_async (GP11Session *self,
+ GP11Object *base,
+ GP11Mechanism *mechanism,
+ GP11Attributes *attrs,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
- ...) GP11_INVALID_TERMINATED;
-GP11Object* gp11_session_derive_finish (GP11Session *self,
+GP11Object* gp11_session_derive_key_finish (GP11Session *self,
GAsyncResult *result,
GError **err);
-#endif /* UNIMPLEMENTED */
-
-
/* ------------------------------------------------------------------------
* OBJECT
*/
diff --git a/gp11/tests/Makefile.am b/gp11/tests/Makefile.am
index 6cd06fb..9b0b4c1 100644
--- a/gp11/tests/Makefile.am
+++ b/gp11/tests/Makefile.am
@@ -2,6 +2,7 @@
# Keep these in the order they should be tested
UNIT_AUTO = \
unit-test-gp11-attributes.c \
+ test-gp11-mechanism.c \
unit-test-gp11-module.c \
unit-test-gp11-slot.c \
unit-test-gp11-session.c \
diff --git a/gp11/tests/gp11-test-module.c b/gp11/tests/gp11-test-module.c
index b4ff426..41980b7 100644
--- a/gp11/tests/gp11-test-module.c
+++ b/gp11/tests/gp11-test-module.c
@@ -75,6 +75,16 @@ free_session (gpointer data)
g_free (sess);
}
+static GP11Attributes*
+lookup_object (Session *session, CK_OBJECT_HANDLE hObject)
+{
+ GP11Attributes *attrs;
+ attrs = g_hash_table_lookup (the_objects, GUINT_TO_POINTER (hObject));
+ if (!attrs)
+ attrs = g_hash_table_lookup (session->objects, GUINT_TO_POINTER (hObject));
+ return attrs;
+}
+
static CK_RV
test_C_Initialize (CK_VOID_PTR pInitArgs)
{
@@ -136,6 +146,10 @@ test_C_Initialize (CK_VOID_PTR pInitArgs)
CKA_ALLOWED_MECHANISMS, sizeof (value), &value,
CKA_DECRYPT, GP11_BOOLEAN, TRUE,
CKA_PRIVATE, GP11_BOOLEAN, TRUE,
+ CKA_WRAP, GP11_BOOLEAN, TRUE,
+ CKA_UNWRAP, GP11_BOOLEAN, TRUE,
+ CKA_DERIVE, GP11_BOOLEAN, TRUE,
+ CKA_VALUE, GP11_STRING, "value",
GP11_INVALID);
g_hash_table_insert (the_objects, GUINT_TO_POINTER (PRIVATE_KEY_CAPITALIZE), attrs);
@@ -146,6 +160,7 @@ test_C_Initialize (CK_VOID_PTR pInitArgs)
CKA_ALLOWED_MECHANISMS, sizeof (value), &value,
CKA_ENCRYPT, GP11_BOOLEAN, TRUE,
CKA_PRIVATE, GP11_BOOLEAN, FALSE,
+ CKA_VALUE, GP11_STRING, "value",
GP11_INVALID);
g_hash_table_insert (the_objects, GUINT_TO_POINTER (PUBLIC_KEY_CAPITALIZE), attrs);
@@ -157,6 +172,7 @@ test_C_Initialize (CK_VOID_PTR pInitArgs)
CKA_SIGN, GP11_BOOLEAN, TRUE,
CKA_PRIVATE, GP11_BOOLEAN, TRUE,
CKA_ALWAYS_AUTHENTICATE, GP11_BOOLEAN, TRUE,
+ CKA_VALUE, GP11_STRING, "value",
GP11_INVALID);
g_hash_table_insert (the_objects, GUINT_TO_POINTER (PRIVATE_KEY_PREFIX), attrs);
@@ -167,6 +183,7 @@ test_C_Initialize (CK_VOID_PTR pInitArgs)
CKA_ALLOWED_MECHANISMS, sizeof (value), &value,
CKA_VERIFY, GP11_BOOLEAN, TRUE,
CKA_PRIVATE, GP11_BOOLEAN, FALSE,
+ CKA_VALUE, GP11_STRING, "value",
GP11_INVALID);
g_hash_table_insert (the_objects, GUINT_TO_POINTER (PUBLIC_KEY_PREFIX), attrs);
@@ -613,10 +630,8 @@ test_C_DestroyObject (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
g_assert (session != NULL && "No such session found");
if (!session)
return CKR_SESSION_HANDLE_INVALID;
-
- attrs = g_hash_table_lookup (the_objects, GUINT_TO_POINTER (hObject));
- if (!attrs)
- attrs = g_hash_table_lookup (session->objects, GUINT_TO_POINTER (hObject));
+
+ attrs = lookup_object (session, hObject);
if (!attrs) {
g_assert_not_reached (); /* "no such object found" */
return CKR_OBJECT_HANDLE_INVALID;
@@ -654,9 +669,7 @@ test_C_GetAttributeValue (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
if (!session)
return CKR_SESSION_HANDLE_INVALID;
- attrs = g_hash_table_lookup (the_objects, GUINT_TO_POINTER (hObject));
- if (!attrs)
- attrs = g_hash_table_lookup (session->objects, GUINT_TO_POINTER (hObject));
+ attrs = lookup_object (session, hObject);
if (!attrs) {
g_assert_not_reached (); /* "invalid object handle passed" */
return CKR_OBJECT_HANDLE_INVALID;
@@ -703,9 +716,7 @@ test_C_SetAttributeValue (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
if (!session)
return CKR_SESSION_HANDLE_INVALID;
- attrs = g_hash_table_lookup (the_objects, GUINT_TO_POINTER (hObject));
- if (!attrs)
- attrs = g_hash_table_lookup (session->objects, GUINT_TO_POINTER (hObject));
+ attrs = lookup_object (session, hObject);
if (!attrs) {
g_assert_not_reached (); /* "invalid object handle passed" */
return CKR_OBJECT_HANDLE_INVALID;
@@ -1340,21 +1351,123 @@ test_C_GenerateKey (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
static CK_RV
test_C_GenerateKeyPair (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
- CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount,
- CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount,
- CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey)
+ CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount,
+ CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount,
+ CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey)
{
- g_assert_not_reached (); /* Not yet used by library */
- return CKR_FUNCTION_NOT_SUPPORTED;
+ GP11Attributes *attrs;
+ Session *session;
+ gboolean token;
+ CK_ULONG i;
+
+ session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
+ g_assert (session != NULL && "No such session found");
+ if (!session)
+ return CKR_SESSION_HANDLE_INVALID;
+
+ g_assert (pMechanism);
+ g_assert (pPublicKeyTemplate);
+ g_assert (ulPublicKeyAttributeCount);
+ g_assert (pPrivateKeyTemplate);
+ g_assert (phPublicKey);
+ g_assert (phPrivateKey);
+
+ if (pMechanism->mechanism != CKM_GENERATE)
+ return CKR_MECHANISM_INVALID;
+
+ if (!pMechanism->pParameter || pMechanism->ulParameterLen != 9 ||
+ memcmp (pMechanism->pParameter, "generate", 9) != 0) {
+ g_assert_not_reached ();
+ return CKR_MECHANISM_PARAM_INVALID;
+ }
+
+ attrs = gp11_attributes_new ();
+ gp11_attributes_add_string (attrs, CKA_VALUE, "generated");
+ for (i = 0; i < ulPublicKeyAttributeCount; ++i)
+ gp11_attributes_add_data (attrs, pPublicKeyTemplate[i].type,
+ pPublicKeyTemplate[i].pValue,
+ pPublicKeyTemplate[i].ulValueLen);
+ *phPublicKey = ++unique_identifier;
+ if (gp11_attributes_find_boolean (attrs, CKA_TOKEN, &token) && token)
+ g_hash_table_insert (the_objects, GUINT_TO_POINTER (*phPublicKey), attrs);
+ else
+ g_hash_table_insert (session->objects, GUINT_TO_POINTER (*phPublicKey), attrs);
+
+ attrs = gp11_attributes_new ();
+ gp11_attributes_add_string (attrs, CKA_VALUE, "generated");
+ for (i = 0; i < ulPrivateKeyAttributeCount; ++i)
+ gp11_attributes_add_data (attrs, pPrivateKeyTemplate[i].type,
+ pPrivateKeyTemplate[i].pValue,
+ pPrivateKeyTemplate[i].ulValueLen);
+ *phPrivateKey = ++unique_identifier;
+ if (gp11_attributes_find_boolean (attrs, CKA_TOKEN, &token) && token)
+ g_hash_table_insert (the_objects, GUINT_TO_POINTER (*phPrivateKey), attrs);
+ else
+ g_hash_table_insert (session->objects, GUINT_TO_POINTER (*phPrivateKey), attrs);
+ return CKR_OK;
}
static CK_RV
test_C_WrapKey (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey,
- CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen)
+ CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey,
+ CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen)
{
- g_assert_not_reached (); /* Not yet used by library */
- return CKR_FUNCTION_NOT_SUPPORTED;
+ GP11Attributes *attrs;
+ GP11Attribute *attr;
+ Session *session;
+
+ session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
+ if (!session) {
+ g_assert_not_reached ();
+ return CKR_SESSION_HANDLE_INVALID;
+ }
+
+ g_assert (pMechanism);
+ g_assert (hWrappingKey);
+ g_assert (hKey);
+ g_assert (pulWrappedKeyLen);
+
+ attrs = lookup_object (session, hWrappingKey);
+ if (!attrs) {
+ g_assert_not_reached ();
+ return CKR_WRAPPING_KEY_HANDLE_INVALID;
+ }
+
+ attrs = lookup_object (session, hKey);
+ if (!attrs) {
+ g_assert_not_reached ();
+ return CKR_WRAPPED_KEY_INVALID;
+ }
+
+ if (pMechanism->mechanism != CKM_WRAP)
+ return CKR_MECHANISM_INVALID;
+
+ if (pMechanism->pParameter) {
+ if (pMechanism->ulParameterLen != 4 ||
+ memcmp (pMechanism->pParameter, "wrap", 4) != 0) {
+ g_assert_not_reached ();
+ return CKR_MECHANISM_PARAM_INVALID;
+ }
+ }
+
+ attr = gp11_attributes_find (attrs, CKA_VALUE);
+ if (attr == NULL)
+ return CKR_WRAPPED_KEY_INVALID;
+
+ if (!pWrappedKey) {
+ *pulWrappedKeyLen = attr->length;
+ return CKR_OK;
+ }
+
+ if (*pulWrappedKeyLen < attr->length) {
+ *pulWrappedKeyLen = attr->length;
+ return CKR_BUFFER_TOO_SMALL;
+ }
+
+ memcpy (pWrappedKey, attr->value, attr->length);
+ *pulWrappedKeyLen = attr->length;
+
+ return CKR_OK;
}
static CK_RV
@@ -1363,8 +1476,56 @@ test_C_UnwrapKey (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
CK_ULONG pulWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate,
CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey)
{
- g_assert_not_reached (); /* Not yet used by library */
- return CKR_FUNCTION_NOT_SUPPORTED;
+ GP11Attributes *attrs;
+ Session *session;
+ gboolean token;
+ CK_ULONG i;
+
+ session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
+ if (!session) {
+ g_assert_not_reached ();
+ return CKR_SESSION_HANDLE_INVALID;
+ }
+
+ g_assert (pMechanism);
+ g_assert (pUnwrappingKey);
+ g_assert (pWrappedKey);
+ g_assert (pulWrappedKeyLen);
+ g_assert (phKey);
+ g_assert (ulCount);
+ g_assert (pTemplate);
+ g_assert (phKey);
+
+ attrs = lookup_object (session, pUnwrappingKey);
+ if (!attrs) {
+ g_assert_not_reached ();
+ return CKR_WRAPPING_KEY_HANDLE_INVALID;
+ }
+
+ if (pMechanism->mechanism != CKM_WRAP)
+ return CKR_MECHANISM_INVALID;
+
+ if (pMechanism->pParameter) {
+ if (pMechanism->ulParameterLen != 4 ||
+ memcmp (pMechanism->pParameter, "wrap", 4) != 0) {
+ g_assert_not_reached ();
+ return CKR_MECHANISM_PARAM_INVALID;
+ }
+ }
+
+ attrs = gp11_attributes_new ();
+ gp11_attributes_add_data (attrs, CKA_VALUE, pWrappedKey, pulWrappedKeyLen);
+ for (i = 0; i < ulCount; ++i)
+ gp11_attributes_add_data (attrs, pTemplate[i].type,
+ pTemplate[i].pValue,
+ pTemplate[i].ulValueLen);
+ *phKey = ++unique_identifier;
+ if (gp11_attributes_find_boolean (attrs, CKA_TOKEN, &token) && token)
+ g_hash_table_insert (the_objects, GUINT_TO_POINTER (*phKey), attrs);
+ else
+ g_hash_table_insert (session->objects, GUINT_TO_POINTER (*phKey), attrs);
+
+ return CKR_OK;
}
static CK_RV
@@ -1372,8 +1533,54 @@ test_C_DeriveKey (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate,
CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey)
{
- g_assert_not_reached (); /* Not yet used by library */
- return CKR_FUNCTION_NOT_SUPPORTED;
+ GP11Attributes *attrs, *copy;
+ Session *session;
+ gboolean token;
+ CK_ULONG i;
+
+ session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
+ if (!session) {
+ g_assert_not_reached ();
+ return CKR_SESSION_HANDLE_INVALID;
+ }
+
+ g_assert (pMechanism);
+ g_assert (ulCount);
+ g_assert (pTemplate);
+ g_assert (phKey);
+
+ attrs = lookup_object (session, hBaseKey);
+ if (!attrs) {
+ g_assert_not_reached ();
+ return CKR_WRAPPING_KEY_HANDLE_INVALID;
+ }
+
+ if (pMechanism->mechanism != CKM_DERIVE)
+ return CKR_MECHANISM_INVALID;
+
+ if (pMechanism->pParameter) {
+ if (pMechanism->ulParameterLen != 6 ||
+ memcmp (pMechanism->pParameter, "derive", 6) != 0) {
+ g_assert_not_reached ();
+ return CKR_MECHANISM_PARAM_INVALID;
+ }
+ }
+
+ copy = gp11_attributes_new ();
+ gp11_attributes_add_string (copy, CKA_VALUE, "derived");
+ for (i = 0; i < ulCount; ++i)
+ gp11_attributes_add_data (copy, pTemplate[i].type,
+ pTemplate[i].pValue,
+ pTemplate[i].ulValueLen);
+ for (i = 0; i < gp11_attributes_count (attrs); ++i)
+ gp11_attributes_add (copy, gp11_attributes_at (attrs, i));
+ *phKey = ++unique_identifier;
+ if (gp11_attributes_find_boolean (copy, CKA_TOKEN, &token) && token)
+ g_hash_table_insert (the_objects, GUINT_TO_POINTER (*phKey), copy);
+ else
+ g_hash_table_insert (session->objects, GUINT_TO_POINTER (*phKey), copy);
+
+ return CKR_OK;
}
static CK_RV
diff --git a/gp11/tests/gp11-test.h b/gp11/tests/gp11-test.h
index 4592e20..013ef0d 100644
--- a/gp11/tests/gp11-test.h
+++ b/gp11/tests/gp11-test.h
@@ -29,9 +29,22 @@
* CKM_PREFIX (sign/verify)
* sign prefixes data with key label
* verify unprefixes data with key label.
+ *
+ * CKM_GENERATE (generate-pair)
+ * generates a pair of keys, mechanism param should be 'generate'
+ *
+ * CKM_WRAP (wrap key)
+ * wraps key by returning value, mechanism param should be 'wrap'
+ *
+ * CKM_DERIVE (derive-key)
+ * derives key by setting value to 'derived'.
+ * mechanism param should be 'derive'
*/
#define CKM_CAPITALIZE (CKM_VENDOR_DEFINED | 1)
#define CKM_PREFIX (CKM_VENDOR_DEFINED | 2)
+#define CKM_GENERATE (CKM_VENDOR_DEFINED | 3)
+#define CKM_WRAP (CKM_VENDOR_DEFINED | 4)
+#define CKM_DERIVE (CKM_VENDOR_DEFINED | 5)
#endif /*TESTGP11HELPERS_H_*/
diff --git a/gp11/tests/test-gp11-mechanism.c b/gp11/tests/test-gp11-mechanism.c
new file mode 100644
index 0000000..68543a2
--- /dev/null
+++ b/gp11/tests/test-gp11-mechanism.c
@@ -0,0 +1,60 @@
+
+#include <glib.h>
+#include <string.h>
+
+#include "run-auto-test.h"
+#include "gp11-test.h"
+
+#define MECH_TYPE 55
+#define MECH_DATA "TEST DATA"
+#define N_MECH_DATA ((gsize)9)
+
+DEFINE_TEST(mech_new)
+{
+ GP11Mechanism *mech;
+
+ mech = gp11_mechanism_new (MECH_TYPE);
+
+ g_assert (mech);
+ g_assert (mech->type == MECH_TYPE);
+ g_assert (mech->parameter == NULL);
+ g_assert (mech->n_parameter == 0);
+
+ gp11_mechanism_unref (mech);
+}
+
+DEFINE_TEST(mech_new_with_param)
+{
+ GP11Mechanism *mech;
+ gpointer parameter = MECH_DATA;
+
+ mech = gp11_mechanism_new_with_param (MECH_TYPE, parameter, N_MECH_DATA);
+
+ g_assert (mech);
+ g_assert (mech->type == MECH_TYPE);
+ g_assert (mech->parameter != NULL);
+ g_assert (mech->parameter != parameter); /* Copied */
+ g_assert (mech->n_parameter == N_MECH_DATA);
+ g_assert (memcmp (mech->parameter, MECH_DATA, N_MECH_DATA) == 0);
+
+ gp11_mechanism_unref (mech);
+}
+
+DEFINE_TEST(mech_ref_unref)
+{
+ GP11Mechanism *mech, *check;
+
+ mech = gp11_mechanism_new (MECH_TYPE);
+ g_assert (mech);
+
+ check = gp11_mechanism_ref (mech);
+ g_assert (check == mech);
+
+ gp11_mechanism_unref (check);
+ gp11_mechanism_unref (mech);
+}
+
+DEFINE_TEST(mech_unref_null)
+{
+ gp11_mechanism_unref (NULL);
+}
diff --git a/gp11/tests/unit-test-gp11-crypto.c b/gp11/tests/unit-test-gp11-crypto.c
index a6bf68e..90a0438 100644
--- a/gp11/tests/unit-test-gp11-crypto.c
+++ b/gp11/tests/unit-test-gp11-crypto.c
@@ -59,22 +59,61 @@ find_key (GP11Session *session, CK_ATTRIBUTE_TYPE method, CK_MECHANISM_TYPE mech
for (l = objects; l; l = g_list_next (l)) {
gp11_object_set_session (l->data, session);
- mechs = gp11_object_get_data (l->data, CKA_ALLOWED_MECHANISMS, &n_mechs, NULL);
- g_assert (mechs);
- g_assert (n_mechs == sizeof (CK_MECHANISM_TYPE));
-
- /* We know all of them only have one allowed mech */
- if (*mechs == mech) {
- object = l->data;
- g_object_ref (object);
- break;
+ if (mech) {
+ mechs = gp11_object_get_data (l->data, CKA_ALLOWED_MECHANISMS, &n_mechs, NULL);
+ g_assert (mechs);
+ g_assert (n_mechs == sizeof (CK_MECHANISM_TYPE));
+ /* We know all of them only have one allowed mech */
+ if (*mechs != mech)
+ continue;
}
+ object = l->data;
+ g_object_ref (object);
+ break;
}
gp11_list_unref_free (objects);
return object;
}
+static GP11Object*
+find_key_with_value (GP11Session *session, const gchar *value)
+{
+ GList *objects;
+ GP11Object *object;
+
+ objects = gp11_session_find_objects (session, NULL, CKA_VALUE, GP11_STRING, value, GP11_INVALID);
+ g_assert (objects);
+
+ object = g_object_ref (objects->data);
+ gp11_list_unref_free (objects);
+ return object;
+}
+
+static void
+check_key_with_value (GP11Session *session, GP11Object *key, CK_OBJECT_CLASS klass, const gchar *value)
+{
+ GP11Attributes *attrs;
+ GP11Attribute *attr;
+ gulong check;
+
+ gp11_object_set_session (key, session);
+ attrs = gp11_object_get (key, NULL, CKA_CLASS, CKA_VALUE, GP11_INVALID);
+ g_assert (attrs);
+
+ if (!gp11_attributes_find_ulong (attrs, CKA_CLASS, &check))
+ g_assert_not_reached ();
+ g_assert (check == klass);
+
+ attr = gp11_attributes_find (attrs, CKA_VALUE);
+ g_assert (attr);
+ g_assert (!gp11_attribute_is_invalid (attr));
+ g_assert_cmpsize (attr->length, ==, strlen (value));
+ g_assert (memcmp (attr->value, value, attr->length) == 0);
+
+ gp11_attributes_unref (attrs);
+}
+
static gboolean
authenticate_object (GP11Slot *module, GP11Object *object, gchar *label, gchar **password)
{
@@ -89,16 +128,14 @@ authenticate_object (GP11Slot *module, GP11Object *object, gchar *label, gchar *
DEFINE_TEST(encrypt)
{
- GP11Mechanism mech;
+ GP11Mechanism *mech;
GError *error = NULL;
GAsyncResult *result = NULL;
GP11Object *key;
guchar *output;
gsize n_output;
- mech.type = CKM_CAPITALIZE;
- mech.n_parameter = 0;
- mech.parameter = NULL;
+ mech = gp11_mechanism_new (CKM_CAPITALIZE);
/* Find the right key */
key = find_key (session, CKA_ENCRYPT, CKM_CAPITALIZE);
@@ -112,14 +149,14 @@ DEFINE_TEST(encrypt)
g_free (output);
/* Full one */
- output = gp11_session_encrypt_full (session, key, &mech, (const guchar*)"blah blah", 10, &n_output, NULL, &error);
+ output = gp11_session_encrypt_full (session, key, mech, (const guchar*)"blah blah", 10, &n_output, NULL, &error);
SUCCESS_RES (output, error);
g_assert (n_output == 10);
g_assert_cmpstr ((gchar*)output, ==, "BLAH BLAH");
g_free (output);
/* Asynchronous one */
- gp11_session_encrypt_async (session, key, &mech, (const guchar*)"second chance", 14, NULL, fetch_async_result, &result);
+ gp11_session_encrypt_async (session, key, mech, (const guchar*)"second chance", 14, NULL, fetch_async_result, &result);
WAIT_UNTIL (result);
g_assert (result != NULL);
@@ -131,22 +168,21 @@ DEFINE_TEST(encrypt)
g_assert_cmpstr ((gchar*)output, ==, "SECOND CHANCE");
g_free (output);
+ gp11_mechanism_unref (mech);
g_object_unref (result);
g_object_unref (key);
}
DEFINE_TEST(decrypt)
{
- GP11Mechanism mech;
+ GP11Mechanism *mech;
GError *error = NULL;
GAsyncResult *result = NULL;
GP11Object *key;
guchar *output;
gsize n_output;
- mech.type = CKM_CAPITALIZE;
- mech.n_parameter = 0;
- mech.parameter = NULL;
+ mech = gp11_mechanism_new (CKM_CAPITALIZE);
/* Find the right key */
key = find_key (session, CKA_DECRYPT, CKM_CAPITALIZE);
@@ -160,14 +196,14 @@ DEFINE_TEST(decrypt)
g_free (output);
/* Full one */
- output = gp11_session_decrypt_full (session, key, &mech, (const guchar*)"TENNIS instructor", 18, &n_output, NULL, &error);
+ output = gp11_session_decrypt_full (session, key, mech, (const guchar*)"TENNIS instructor", 18, &n_output, NULL, &error);
SUCCESS_RES (output, error);
g_assert (n_output == 18);
g_assert_cmpstr ((gchar*)output, ==, "tennis instructor");
g_free (output);
/* Asynchronous one */
- gp11_session_decrypt_async (session, key, &mech, (const guchar*)"FAT CHANCE", 11, NULL, fetch_async_result, &result);
+ gp11_session_decrypt_async (session, key, mech, (const guchar*)"FAT CHANCE", 11, NULL, fetch_async_result, &result);
WAIT_UNTIL (result);
g_assert (result != NULL);
@@ -179,6 +215,7 @@ DEFINE_TEST(decrypt)
g_assert_cmpstr ((gchar*)output, ==, "fat chance");
g_free (output);
+ gp11_mechanism_unref (mech);
g_object_unref (result);
g_object_unref (key);
}
@@ -207,17 +244,15 @@ DEFINE_TEST(login_context_specific)
DEFINE_TEST(sign)
{
- GP11Mechanism mech;
+ GP11Mechanism *mech;
GError *error = NULL;
GAsyncResult *result = NULL;
GP11Object *key;
guchar *output;
gsize n_output;
- mech.type = CKM_PREFIX;
- mech.n_parameter = 10;
- mech.parameter = "my-prefix:";
-
+ mech = gp11_mechanism_new_with_param (CKM_PREFIX, "my-prefix:", 10);
+
/* Enable auto-login on this session, see previous test */
gp11_module_set_auto_authenticate (module, TRUE);
g_signal_connect (module, "authenticate-object", G_CALLBACK (authenticate_object), NULL);
@@ -234,14 +269,14 @@ DEFINE_TEST(sign)
g_free (output);
/* Full one */
- output = gp11_session_sign_full (session, key, &mech, (const guchar*)"Labarbara", 10, &n_output, NULL, &error);
+ output = gp11_session_sign_full (session, key, mech, (const guchar*)"Labarbara", 10, &n_output, NULL, &error);
SUCCESS_RES (output, error);
g_assert_cmpuint (n_output, ==, 20);
g_assert_cmpstr ((gchar*)output, ==, "my-prefix:Labarbara");
g_free (output);
/* Asynchronous one */
- gp11_session_sign_async (session, key, &mech, (const guchar*)"Conrad", 7, NULL, fetch_async_result, &result);
+ gp11_session_sign_async (session, key, mech, (const guchar*)"Conrad", 7, NULL, fetch_async_result, &result);
WAIT_UNTIL (result);
g_assert (result != NULL);
@@ -253,22 +288,21 @@ DEFINE_TEST(sign)
g_assert_cmpstr ((gchar*)output, ==, "my-prefix:Conrad");
g_free (output);
+ gp11_mechanism_unref (mech);
g_object_unref (result);
g_object_unref (key);
}
DEFINE_TEST(verify)
{
- GP11Mechanism mech;
+ GP11Mechanism *mech;
GError *error = NULL;
GAsyncResult *result = NULL;
GP11Object *key;
gboolean ret;
- mech.type = CKM_PREFIX;
- mech.n_parameter = 10;
- mech.parameter = "my-prefix:";
-
+ mech = gp11_mechanism_new_with_param (CKM_PREFIX, "my-prefix:", 10);
+
/* Enable auto-login on this session, shouldn't be needed */
gp11_module_set_auto_authenticate (module, TRUE);
g_signal_connect (module, "authenticate-object", G_CALLBACK (authenticate_object), NULL);
@@ -283,17 +317,17 @@ DEFINE_TEST(verify)
SUCCESS_RES (ret, error);
/* Full one */
- ret = gp11_session_verify_full (session, key, &mech, (const guchar*)"Labarbara", 10,
+ ret = gp11_session_verify_full (session, key, mech, (const guchar*)"Labarbara", 10,
(const guchar*)"my-prefix:Labarbara", 20, NULL, &error);
SUCCESS_RES (ret, error);
/* Failure one */
- ret = gp11_session_verify_full (session, key, &mech, (const guchar*)"Labarbara", 10,
+ ret = gp11_session_verify_full (session, key, mech, (const guchar*)"Labarbara", 10,
(const guchar*)"my-prefix:Loborboro", 20, NULL, &error);
FAIL_RES (ret, error);
/* Asynchronous one */
- gp11_session_verify_async (session, key, &mech, (const guchar*)"Labarbara", 10,
+ gp11_session_verify_async (session, key, mech, (const guchar*)"Labarbara", 10,
(const guchar*)"my-prefix:Labarbara", 20, NULL, fetch_async_result, &result);
WAIT_UNTIL (result);
g_assert (result != NULL);
@@ -303,7 +337,7 @@ DEFINE_TEST(verify)
/* Asynchronous failure */
result = NULL;
- gp11_session_verify_async (session, key, &mech, (const guchar*)"Labarbara", 10,
+ gp11_session_verify_async (session, key, mech, (const guchar*)"Labarbara", 10,
(const guchar*)"my-prefix:Labarxoro", 20, NULL, fetch_async_result, &result);
WAIT_UNTIL (result);
g_assert (result != NULL);
@@ -311,5 +345,250 @@ DEFINE_TEST(verify)
FAIL_RES (ret, error);
g_object_unref (result);
+ gp11_mechanism_unref (mech);
g_object_unref (key);
}
+
+DEFINE_TEST(generate_key_pair)
+{
+ GP11Attributes *pub_attrs, *prv_attrs;
+ GP11Mechanism *mech;
+ GError *error = NULL;
+ GAsyncResult *result = NULL;
+ GP11Object *pub_key, *prv_key;
+ gboolean ret;
+
+ mech = gp11_mechanism_new_with_param (CKM_GENERATE, "generate", 9);
+
+ pub_attrs = gp11_attributes_new ();
+ gp11_attributes_add_ulong (pub_attrs, CKA_CLASS, CKO_PUBLIC_KEY);
+ prv_attrs = gp11_attributes_new ();
+ gp11_attributes_add_ulong (prv_attrs, CKA_CLASS, CKO_PRIVATE_KEY);
+
+ /* Full One*/
+ ret = gp11_session_generate_key_pair_full (session, mech, pub_attrs, prv_attrs,
+ &pub_key, &prv_key, NULL, &error);
+ SUCCESS_RES (ret, error);
+ g_object_unref (pub_key);
+ g_object_unref (prv_key);
+
+ /* Failure one */
+ mech->type = 0;
+ pub_key = prv_key = NULL;
+ ret = gp11_session_generate_key_pair_full (session, mech, pub_attrs, prv_attrs,
+ &pub_key, &prv_key, NULL, &error);
+ FAIL_RES (ret, error);
+ g_assert (pub_key == NULL);
+ g_assert (prv_key == NULL);
+
+ /* Asynchronous one */
+ mech->type = CKM_GENERATE;
+ gp11_session_generate_key_pair_async (session, mech, pub_attrs, prv_attrs, NULL, fetch_async_result, &result);
+ WAIT_UNTIL (result);
+ g_assert (result != NULL);
+ ret = gp11_session_generate_key_pair_finish (session, result, &pub_key, &prv_key, &error);
+ SUCCESS_RES (ret, error);
+ g_object_unref (result);
+ g_object_unref (pub_key);
+ g_object_unref (prv_key);
+
+ /* Asynchronous failure */
+ result = NULL;
+ mech->type = 0;
+ pub_key = prv_key = NULL;
+ gp11_session_generate_key_pair_async (session, mech, pub_attrs, prv_attrs, NULL, fetch_async_result, &result);
+ WAIT_UNTIL (result);
+ g_assert (result != NULL);
+ ret = gp11_session_generate_key_pair_finish (session, result, &pub_key, &prv_key, &error);
+ FAIL_RES (ret, error);
+ g_object_unref (result);
+ g_assert (pub_key == NULL);
+ g_assert (prv_key == NULL);
+
+ gp11_mechanism_unref (mech);
+ gp11_attributes_unref (pub_attrs);
+ gp11_attributes_unref (prv_attrs);
+}
+
+DEFINE_TEST(wrap_key)
+{
+ GP11Mechanism *mech;
+ GError *error = NULL;
+ GAsyncResult *result = NULL;
+ GP11Object *wrapper, *wrapped;
+ gpointer output;
+ gsize n_output;
+
+ mech = gp11_mechanism_new_with_param (CKM_WRAP, "wrap", 4);
+ wrapper = find_key (session, CKA_WRAP, 0);
+ wrapped = find_key_with_value (session, "value");
+
+ /* Simple One */
+ output = gp11_session_wrap_key (session, wrapper, CKM_WRAP, wrapped, &n_output, &error);
+ SUCCESS_RES (output, error);
+ g_assert (output);
+ g_assert_cmpsize (n_output, ==, 5);
+ g_assert (memcmp (output, "value", 5) == 0);
+ g_free (output);
+
+ /* Full One*/
+ output = gp11_session_wrap_key_full (session, wrapper, mech, wrapped, &n_output, NULL, &error);
+ SUCCESS_RES (output, error);
+ g_assert_cmpsize (n_output, ==, 5);
+ g_assert (memcmp (output, "value", 5) == 0);
+ g_free (output);
+
+ /* Failure one */
+ mech->type = 0;
+ n_output = 0;
+ output = gp11_session_wrap_key_full (session, wrapper, mech, wrapped, &n_output, NULL, &error);
+ FAIL_RES (output, error);
+ g_assert_cmpsize (n_output, ==, 0);
+
+ /* Asynchronous one */
+ mech->type = CKM_WRAP;
+ gp11_session_wrap_key_async (session, wrapper, mech, wrapped, NULL, fetch_async_result, &result);
+ WAIT_UNTIL (result);
+ g_assert (result != NULL);
+ output = gp11_session_wrap_key_finish (session, result, &n_output, &error);
+ SUCCESS_RES (output, error);
+ g_assert_cmpsize (n_output, ==, 5);
+ g_assert (memcmp (output, "value", 5) == 0);
+ g_object_unref (result);
+ g_free (output);
+
+ /* Asynchronous failure */
+ result = NULL;
+ mech->type = 0;
+ n_output = 0;
+ gp11_session_wrap_key_async (session, wrapper, mech, wrapped, NULL, fetch_async_result, &result);
+ WAIT_UNTIL (result);
+ g_assert (result != NULL);
+ output = gp11_session_wrap_key_finish (session, result, &n_output, &error);
+ FAIL_RES (output, error);
+ g_assert_cmpsize (n_output, ==, 0);
+ g_object_unref (result);
+
+ g_object_unref (wrapper);
+ g_object_unref (wrapped);
+ gp11_mechanism_unref (mech);
+}
+
+DEFINE_TEST(unwrap_key)
+{
+ GP11Mechanism *mech;
+ GError *error = NULL;
+ GAsyncResult *result = NULL;
+ GP11Object *wrapper, *unwrapped;
+ GP11Attributes *attrs;
+
+ mech = gp11_mechanism_new_with_param (CKM_WRAP, "wrap", 4);
+ wrapper = find_key (session, CKA_UNWRAP, 0);
+ attrs = gp11_attributes_newv (CKA_CLASS, GP11_ULONG, CKO_SECRET_KEY, GP11_INVALID);
+
+ /* Simple One */
+ unwrapped = gp11_session_unwrap_key (session, wrapper, CKM_WRAP, "special", 7, &error,
+ CKA_CLASS, GP11_ULONG, CKO_SECRET_KEY, GP11_INVALID);
+ SUCCESS_RES (unwrapped, error);
+ g_assert (GP11_IS_OBJECT (unwrapped));
+ check_key_with_value (session, unwrapped, CKO_SECRET_KEY, "special");
+ g_object_unref (unwrapped);
+
+ /* Full One*/
+ unwrapped = gp11_session_unwrap_key_full (session, wrapper, mech, "special", 7, attrs, NULL, &error);
+ SUCCESS_RES (unwrapped, error);
+ g_assert (GP11_IS_OBJECT (unwrapped));
+ check_key_with_value (session, unwrapped, CKO_SECRET_KEY, "special");
+ g_object_unref (unwrapped);
+
+ /* Failure one */
+ mech->type = 0;
+ unwrapped = gp11_session_unwrap_key_full (session, wrapper, mech, "special", 7, attrs, NULL, &error);
+ FAIL_RES (unwrapped, error);
+
+ /* Asynchronous one */
+ mech->type = CKM_WRAP;
+ gp11_session_unwrap_key_async (session, wrapper, mech, "special", 7, attrs, NULL, fetch_async_result, &result);
+ WAIT_UNTIL (result);
+ g_assert (result != NULL);
+ unwrapped = gp11_session_unwrap_key_finish (session, result, &error);
+ SUCCESS_RES (unwrapped, error);
+ g_assert (GP11_IS_OBJECT (unwrapped));
+ check_key_with_value (session, unwrapped, CKO_SECRET_KEY, "special");
+ g_object_unref (unwrapped);
+ g_object_unref (result);
+
+ /* Asynchronous failure */
+ result = NULL;
+ mech->type = 0;
+ gp11_session_unwrap_key_async (session, wrapper, mech, "special", 6, attrs, NULL, fetch_async_result, &result);
+ WAIT_UNTIL (result);
+ g_assert (result != NULL);
+ unwrapped = gp11_session_unwrap_key_finish (session, result, &error);
+ FAIL_RES (unwrapped, error);
+ g_object_unref (result);
+
+ g_object_unref (wrapper);
+ gp11_attributes_unref (attrs);
+ gp11_mechanism_unref (mech);
+}
+
+DEFINE_TEST(derive_key)
+{
+ GP11Mechanism *mech;
+ GError *error = NULL;
+ GAsyncResult *result = NULL;
+ GP11Object *wrapper, *derived;
+ GP11Attributes *attrs;
+
+ mech = gp11_mechanism_new_with_param (CKM_DERIVE, "derive", 6);
+ wrapper = find_key (session, CKA_DERIVE, 0);
+ attrs = gp11_attributes_newv (CKA_CLASS, GP11_ULONG, CKO_SECRET_KEY, GP11_INVALID);
+
+ /* Simple One */
+ derived = gp11_session_derive_key (session, wrapper, CKM_DERIVE, &error,
+ CKA_CLASS, GP11_ULONG, CKO_SECRET_KEY, GP11_INVALID);
+ SUCCESS_RES (derived, error);
+ g_assert (GP11_IS_OBJECT (derived));
+g_printerr ("derived is: %lu", gp11_object_get_handle (derived));
+ check_key_with_value (session, derived, CKO_SECRET_KEY, "derived");
+ g_object_unref (derived);
+
+ /* Full One*/
+ derived = gp11_session_derive_key_full (session, wrapper, mech, attrs, NULL, &error);
+ SUCCESS_RES (derived, error);
+ g_assert (GP11_IS_OBJECT (derived));
+ check_key_with_value (session, derived, CKO_SECRET_KEY, "derived");
+ g_object_unref (derived);
+
+ /* Failure one */
+ mech->type = 0;
+ derived = gp11_session_derive_key_full (session, wrapper, mech, attrs, NULL, &error);
+ FAIL_RES (derived, error);
+
+ /* Asynchronous one */
+ mech->type = CKM_DERIVE;
+ gp11_session_derive_key_async (session, wrapper, mech, attrs, NULL, fetch_async_result, &result);
+ WAIT_UNTIL (result);
+ g_assert (result != NULL);
+ derived = gp11_session_derive_key_finish (session, result, &error);
+ SUCCESS_RES (derived, error);
+ g_assert (GP11_IS_OBJECT (derived));
+ check_key_with_value (session, derived, CKO_SECRET_KEY, "derived");
+ g_object_unref (derived);
+ g_object_unref (result);
+
+ /* Asynchronous failure */
+ result = NULL;
+ mech->type = 0;
+ gp11_session_derive_key_async (session, wrapper, mech, attrs, NULL, fetch_async_result, &result);
+ WAIT_UNTIL (result);
+ g_assert (result != NULL);
+ derived = gp11_session_derive_key_finish (session, result, &error);
+ FAIL_RES (derived, error);
+ g_object_unref (result);
+
+ g_object_unref (wrapper);
+ gp11_attributes_unref (attrs);
+ gp11_mechanism_unref (mech);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]