[gp11] Support for getting and setting object template style attrs.
authorStef Walter <stef@memberwebs.com>
Sun, 20 Dec 2009 17:18:49 +0000 (17:18 +0000)
committerStef Walter <stef@memberwebs.com>
Mon, 1 Feb 2010 02:32:44 +0000 (02:32 +0000)
These are attributes like CKA_WRAP_TEMPLATE etc...

gp11/gp11-object.c
gp11/gp11.h

index 29995a9..08e894f 100644 (file)
@@ -861,10 +861,8 @@ perform_get_attributes (GetAttributes *args)
        /* Get the size of each value */
        rv = (args->base.pkcs11->C_GetAttributeValue) (args->base.handle, args->object,
                                                       attrs, n_attrs);
-       if (!is_ok_get_attributes_rv (rv)) {
-               g_free (attrs);
+       if (!is_ok_get_attributes_rv (rv))
                return rv;
-       }
 
        /* Allocate memory for each value */
        attrs = _gp11_attributes_commit_in (args->attrs, &n_attrs);
@@ -1255,3 +1253,359 @@ gp11_object_get_data_finish (GP11Object *self, GAsyncResult *result,
 
        return data;
 }
+
+/* ---------------------------------------------------------------------------------------
+ * SET TEMPLATE
+ */
+
+typedef struct _set_template_args {
+       GP11Arguments base;
+       CK_OBJECT_HANDLE object;
+       CK_ATTRIBUTE_TYPE type;
+       GP11Attributes *attrs;
+} set_template_args;
+
+static CK_RV
+perform_set_template (set_template_args *args)
+{
+       CK_ATTRIBUTE attr;
+       CK_ULONG n_attrs;
+
+       g_assert (args);
+
+       attr.type = args->type;
+       attr.pValue = _gp11_attributes_commit_out (args->attrs, &n_attrs);
+       attr.ulValueLen = n_attrs * sizeof (CK_ATTRIBUTE);
+
+       return (args->base.pkcs11->C_SetAttributeValue) (args->base.handle, args->object, &attr, 1);
+}
+
+static void
+free_set_template (set_template_args *args)
+{
+       g_assert (args);
+       gp11_attributes_unref (args->attrs);
+       g_free (args);
+}
+
+/**
+ * gp11_object_set_template:
+ * @self: The object to set an attribute template on.
+ * @attr_type: The attribute template type.
+ * @attrs: The attribute template.
+ * @err: A location to store an error.
+ *
+ * Set an attribute template on the object. The attr_type must be for
+ * an attribute which contains a template.
+ *
+ * This call may block for an indefinite period.
+ *
+ * Return value: TRUE if the operation succeeded.
+ **/
+gboolean
+gp11_object_set_template (GP11Object *self, gulong attr_type, GP11Attributes *attrs,
+                          GError **err)
+{
+       g_return_val_if_fail (GP11_IS_OBJECT (self), FALSE);
+       g_return_val_if_fail (!err || !*err, FALSE);
+       return gp11_object_set_template_full (self, attr_type, attrs, NULL, err);
+}
+
+/**
+ * gp11_object_set_template_full:
+ * @self: The object to set an attribute template on.
+ * @attr_type: The attribute template type.
+ * @attrs: The attribute template.
+ * @cancellable: Optional cancellation object, or NULL.
+ * @err: A location to store an error.
+ *
+ * Set an attribute template on the object. The attr_type must be for
+ * an attribute which contains a template.
+ *
+ * This call may block for an indefinite period.
+ *
+ * Return value: TRUE if the operation succeeded.
+ **/
+gboolean
+gp11_object_set_template_full (GP11Object *self, gulong attr_type, GP11Attributes *attrs,
+                               GCancellable *cancellable, GError **err)
+{
+       GP11ObjectData *data = GP11_OBJECT_GET_DATA (self);
+       set_template_args args;
+       GP11Session *session;
+       gboolean ret = FALSE;
+
+       g_return_val_if_fail (GP11_IS_OBJECT (self), FALSE);
+       g_return_val_if_fail (attrs, FALSE);
+       g_return_val_if_fail (!err || !*err, FALSE);
+
+       _gp11_attributes_lock (attrs);
+
+       memset (&args, 0, sizeof (args));
+       args.attrs = attrs;
+       args.type = attr_type;
+       args.object = data->handle;
+
+       session = require_session_sync (self, CKF_RW_SESSION, err);
+       if (session)
+               ret = _gp11_call_sync (session, perform_set_attributes, NULL, &args, cancellable, err);
+
+       _gp11_attributes_unlock (attrs);
+       g_object_unref (session);
+       return ret;
+}
+
+/**
+ * gp11_object_set_template_async:
+ * @self: The object to set an attribute template on.
+ * @attr_type: The attribute template type.
+ * @attrs: The attribute template.
+ * @cancellable: Optional cancellation object, or NULL.
+ * @callback: Called when the operation completes.
+ * @user_data: Data to be passed to the callback.
+ *
+ * Set an attribute template on the object. The attr_type must be for
+ * an attribute which contains a template.
+ *
+ * This call will return immediately and complete asynchronously.
+ **/
+void
+gp11_object_set_template_async (GP11Object *self, gulong attr_type, GP11Attributes *attrs,
+                                GCancellable *cancellable, GAsyncReadyCallback callback,
+                                gpointer user_data)
+{
+       GP11ObjectData *data = GP11_OBJECT_GET_DATA (self);
+       set_template_args *args;
+       GP11Call *call;
+
+       g_return_if_fail (GP11_IS_OBJECT (self));
+       g_return_if_fail (attrs);
+
+       args = _gp11_call_async_prep (data->slot, self, perform_set_template,
+                                     NULL, sizeof (*args), free_set_template);
+
+       _gp11_attributes_lock (attrs);
+       args->attrs = gp11_attributes_ref (attrs);
+       args->type = attr_type;
+       args->object = data->handle;
+
+       call = _gp11_call_async_ready (args, cancellable, callback, user_data);
+       require_session_async (self, call, CKF_RW_SESSION, cancellable);
+}
+
+/**
+ * gp11_object_set_template_finish:
+ * @self: The object to set an attribute template on.
+ * @result: The result passed to the callback.
+ * @err: A location to store an error.
+ *
+ * Get the result of an operation to set attribute template on
+ * an object.
+ *
+ * Return value: TRUE if the operation succeeded.
+ **/
+gboolean
+gp11_object_set_template_finish (GP11Object *self, GAsyncResult *result, GError **err)
+{
+       set_template_args *args;
+
+       g_return_val_if_fail (GP11_IS_OBJECT (self), FALSE);
+       g_return_val_if_fail (GP11_IS_CALL (result), FALSE);
+       g_return_val_if_fail (!err || !*err, FALSE);
+
+       /* Unlock the attributes we were using */
+       args = _gp11_call_arguments (result, set_template_args);
+       g_assert (args->attrs);
+       _gp11_attributes_unlock (args->attrs);
+
+       return _gp11_call_basic_finish (result, err);
+}
+
+/* ---------------------------------------------------------------------------------------
+ * GET TEMPLATE
+ */
+
+typedef struct _get_template_args {
+       GP11Arguments base;
+       CK_OBJECT_HANDLE object;
+       CK_ATTRIBUTE_TYPE type;
+       GP11Attributes *attrs;
+} get_template_args;
+
+static CK_RV
+perform_get_template (get_template_args *args)
+{
+       CK_ATTRIBUTE attr;
+       CK_ULONG n_attrs, i;
+       CK_RV rv;
+
+       g_assert (args);
+       g_assert (!args->attrs);
+
+       args->attrs = gp11_attributes_new ();
+       attr.type = args->type;
+       attr.ulValueLen = 0;
+       attr.pValue = 0;
+
+       /* Get the length of the entire template */
+       rv = (args->base.pkcs11->C_GetAttributeValue) (args->base.handle, args->object, &attr, 1);
+       if (rv != CKR_OK)
+               return rv;
+
+       /* Number of attributes, rounded down */
+       n_attrs = (attr.ulValueLen / sizeof (CK_ATTRIBUTE));
+       for (i = 0; i < n_attrs; ++i)
+               gp11_attributes_add_empty (args->attrs, 0);
+
+       /* Prepare all the attributes */
+       attr.pValue = _gp11_attributes_prepare_in (args->attrs, &n_attrs);
+
+       /* Get the size of each value */
+       rv = (args->base.pkcs11->C_GetAttributeValue) (args->base.handle, args->object, &attr, 1);
+       if (rv != CKR_OK)
+               return rv;
+
+       /* Allocate memory for each value */
+       attr.pValue = _gp11_attributes_commit_in (args->attrs, &n_attrs);
+
+       /* Now get the actual values */
+       return (args->base.pkcs11->C_GetAttributeValue) (args->base.handle, args->object, &attr, 1);
+}
+
+static void
+free_get_template (get_template_args *args)
+{
+       g_assert (args);
+       gp11_attributes_unref (args->attrs);
+       g_free (args);
+}
+
+/**
+ * gp11_object_get_template:
+ * @self: The object to get an attribute template from.
+ * @attr_type: The attribute template type.
+ * @err: A location to store an error.
+ *
+ * Get an attribute template from the object. The attr_type must be for
+ * an attribute which returns a template.
+ *
+ * This call may block for an indefinite period.
+ *
+ * Return value: The resulting PKCS#11 attribute template, or NULL if an error occurred.
+ **/
+GP11Attributes*
+gp11_object_get_template (GP11Object *self, gulong attr_type, GError **err)
+{
+       g_return_val_if_fail (GP11_IS_OBJECT (self), NULL);
+       g_return_val_if_fail (!err || !*err, NULL);
+
+       return gp11_object_get_template_full (self, attr_type, NULL, err);
+}
+
+/**
+ * gp11_object_get_template_full:
+ * @self: The object to get an attribute template from.
+ * @attr_type: The template attribute type.
+ * @cancellable: Optional cancellation object, or NULL.
+ * @err: A location to store an error.
+ *
+ * Get an attribute template from the object. The attr_type must be for
+ * an attribute which returns a template.
+ *
+ * This call may block for an indefinite period.
+ *
+ * Return value: The resulting PKCS#11 attribute template, or NULL if an error occurred.
+ **/
+GP11Attributes*
+gp11_object_get_template_full (GP11Object *self, gulong attr_type,
+                               GCancellable *cancellable, GError **err)
+{
+       GP11ObjectData *data = GP11_OBJECT_GET_DATA (self);
+       get_template_args args;
+       GP11Session *session;
+       gboolean ret;
+
+       g_return_val_if_fail (GP11_IS_OBJECT (self), NULL);
+       g_return_val_if_fail (!err || !*err, NULL);
+
+       session = require_session_sync (self, 0, err);
+       if (!session)
+               return NULL;
+
+       memset (&args, 0, sizeof (args));
+       args.object = data->handle;
+       args.type = attr_type;
+
+       ret = _gp11_call_sync (session, perform_get_template, NULL, &args, cancellable, err);
+       g_object_unref (session);
+
+       /* Free any value if failed */
+       if (!ret) {
+               gp11_attributes_unref (args.attrs);
+               args.attrs = NULL;
+       }
+
+       return args.attrs;
+}
+
+/**
+ * gp11_object_get_template_async:
+ * @self: The object to get an attribute template from.
+ * @attr_type: The template attribute type.
+ * @cancellable: Optional cancellation object, or NULL.
+ * @callback: Called when the operation completes.
+ * @user_data: Data to be passed to the callback.
+ *
+ * Get an attribute template from the object. The attr_type must be for
+ * an attribute which returns a template.
+ *
+ * This call will return immediately and complete asynchronously.
+ **/
+void
+gp11_object_get_template_async (GP11Object *self, gulong attr_type,
+                                GCancellable *cancellable, GAsyncReadyCallback callback,
+                                gpointer user_data)
+{
+       GP11ObjectData *data = GP11_OBJECT_GET_DATA (self);
+       get_template_args *args;
+       GP11Call *call;
+
+       g_return_if_fail (GP11_IS_OBJECT (self));
+
+       args = _gp11_call_async_prep (data->slot, self, perform_get_template,
+                                     NULL, sizeof (*args), free_get_template);
+
+       args->object = data->handle;
+       args->type = attr_type;
+
+       call = _gp11_call_async_ready (args, cancellable, callback, user_data);
+       require_session_async (self, call, 0, cancellable);
+}
+
+/**
+ * gp11_object_get_template_finish:
+ * @self: The object to get an attribute from.
+ * @result: The result passed to the callback.
+ * @err: A location to store an error.
+ *
+ * Get the result of an operation to get attribute template from
+ * an object.
+ *
+ * Return value: The resulting PKCS#11 attribute template, or NULL if an error occurred.
+ **/
+GP11Attributes*
+gp11_object_get_template_finish (GP11Object *self, GAsyncResult *result,
+                                 GError **err)
+{
+       get_template_args *args;
+
+       g_return_val_if_fail (GP11_IS_OBJECT (self), NULL);
+       g_return_val_if_fail (GP11_IS_CALL (result), NULL);
+       g_return_val_if_fail (!err || !*err, NULL);
+
+       if (!_gp11_call_basic_finish (result, err))
+               return NULL;
+
+       args = _gp11_call_arguments (result, get_template_args);
+       return gp11_attributes_ref (args->attrs);
+}
index 0338769..6994996 100644 (file)
@@ -1439,6 +1439,46 @@ gpointer            gp11_object_get_data_finish             (GP11Object *self,
                                                              gsize *n_data,
                                                              GError **err);
 
+gboolean            gp11_object_set_template                (GP11Object *self,
+                                                             gulong attr_type,
+                                                             GP11Attributes *attrs,
+                                                             GError **err);
+
+gboolean            gp11_object_set_template_full           (GP11Object *self,
+                                                             gulong attr_type,
+                                                             GP11Attributes *attrs,
+                                                             GCancellable *cancellable,
+                                                             GError **err);
+
+void                gp11_object_set_template_async          (GP11Object *self,
+                                                             gulong attr_type,
+                                                             GP11Attributes *attrs,
+                                                             GCancellable *cancellable,
+                                                             GAsyncReadyCallback callback,
+                                                             gpointer user_data);
+
+gboolean            gp11_object_set_template_finish         (GP11Object *self,
+                                                             GAsyncResult *result,
+                                                             GError **err);
+
+GP11Attributes*     gp11_object_get_template                (GP11Object *self,
+                                                             gulong attr_type,
+                                                             GError **err);
+
+GP11Attributes*     gp11_object_get_template_full           (GP11Object *self,
+                                                             gulong attr_type,
+                                                             GCancellable *cancellable,
+                                                             GError **err);
+
+void                gp11_object_get_template_async          (GP11Object *self,
+                                                             gulong attr_type,
+                                                             GCancellable *cancellable,
+                                                             GAsyncReadyCallback callback,
+                                                             gpointer user_data);
+
+GP11Attributes*     gp11_object_get_template_finish         (GP11Object *self,
+                                                             GAsyncResult *result,
+                                                             GError **err);
 
 /* ----------------------------------------------------------------------
  * PROCESSOR