summaryrefslogtreecommitdiff
path: root/gck/gck-object.c
diff options
context:
space:
mode:
Diffstat (limited to 'gck/gck-object.c')
-rw-r--r--gck/gck-object.c1326
1 files changed, 0 insertions, 1326 deletions
diff --git a/gck/gck-object.c b/gck/gck-object.c
deleted file mode 100644
index 7798db20..00000000
--- a/gck/gck-object.c
+++ /dev/null
@@ -1,1326 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* gck-object.c - the GObject PKCS#11 wrapper library
-
- Copyright (C) 2008, Stefan Walter
-
- The Gnome Keyring Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The Gnome Keyring Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the Gnome Library; see the file COPYING.LIB. If not,
- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
-
- Author: Stef Walter <nielsen@memberwebs.com>
-*/
-
-#include "config.h"
-
-#include "gck.h"
-#include "gck-private.h"
-
-#include <string.h>
-
-/**
- * SECTION:gck-object
- * @title: GckObject
- * @short_description: Represents a PKCS11 object such as a key or certificate.
- *
- * A GckObject holds a handle to a PKCS11 object such as a key or certificate. Token objects
- * are stored on the token persistently. Others are transient and are called session objects.
- */
-
-/**
- * GckObject:
- * @parent: derived from this.
- *
- * Represents a PKCS11 object handle such as a key or certifiacte.
- */
-
-/*
- * MT safe -- Nothing in GckObjectData changes between
- * init and finalize. All GckObjectPrivate access between init
- * and finalize is locked.
- */
-
-enum {
- PROP_0,
- PROP_MODULE,
- PROP_SESSION,
- PROP_HANDLE
-};
-
-struct _GckObjectPrivate {
- GckModule *module;
- GckSession *session;
- CK_OBJECT_HANDLE handle;
-};
-
-G_DEFINE_TYPE (GckObject, gck_object, G_TYPE_OBJECT);
-
-/* ----------------------------------------------------------------------------
- * OBJECT
- */
-
-static void
-gck_object_init (GckObject *self)
-{
- self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCK_TYPE_OBJECT, GckObjectPrivate);
-}
-
-static void
-gck_object_get_property (GObject *obj, guint prop_id, GValue *value,
- GParamSpec *pspec)
-{
- GckObject *self = GCK_OBJECT (obj);
-
- switch (prop_id) {
- case PROP_MODULE:
- g_value_take_object (value, gck_object_get_module (self));
- break;
- case PROP_SESSION:
- g_value_take_object (value, gck_object_get_session (self));
- break;
- case PROP_HANDLE:
- g_value_set_ulong (value, gck_object_get_handle (self));
- break;
- }
-}
-
-static void
-gck_object_set_property (GObject *obj, guint prop_id, const GValue *value,
- GParamSpec *pspec)
-{
- GckObject *self = GCK_OBJECT (obj);
-
- /* The sets to data below are only allowed during construction */
-
- switch (prop_id) {
- case PROP_MODULE:
- g_return_if_fail (!self->pv->module);
- self->pv->module = g_value_get_object (value);
- g_return_if_fail (self->pv->module);
- g_object_ref (self->pv->module);
- break;
- case PROP_SESSION:
- g_return_if_fail (!self->pv->session);
- self->pv->session = g_value_get_object (value);
- g_return_if_fail (self->pv->session);
- g_object_ref (self->pv->session);
- break;
- case PROP_HANDLE:
- g_return_if_fail (!self->pv->handle);
- self->pv->handle = g_value_get_ulong (value);
- break;
- }
-}
-
-static void
-gck_object_finalize (GObject *obj)
-{
- GckObject *self = GCK_OBJECT (obj);
-
- if (self->pv->session)
- g_object_unref (self->pv->session);
- self->pv->session = NULL;
-
- if (self->pv->module)
- g_object_unref (self->pv->module);
- self->pv->module = NULL;
-
- self->pv->handle = 0;
-
- G_OBJECT_CLASS (gck_object_parent_class)->finalize (obj);
-}
-
-
-static void
-gck_object_class_init (GckObjectClass *klass)
-{
- GObjectClass *gobject_class = (GObjectClass*)klass;
- gck_object_parent_class = g_type_class_peek_parent (klass);
-
- gobject_class->get_property = gck_object_get_property;
- gobject_class->set_property = gck_object_set_property;
- gobject_class->finalize = gck_object_finalize;
-
- /**
- * GckObject:module:
- *
- * The GckModule that this object belongs to.
- */
- g_object_class_install_property (gobject_class, PROP_MODULE,
- g_param_spec_object ("module", "Module", "PKCS11 Module",
- GCK_TYPE_MODULE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- /**
- * GckObject:handle:
- *
- * The raw PKCS11 handle for this object.
- */
- g_object_class_install_property (gobject_class, PROP_HANDLE,
- g_param_spec_ulong ("handle", "Object Handle", "PKCS11 Object Handle",
- 0, G_MAXULONG, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- /**
- * GckObject:session:
- *
- * The PKCS11 session to make calls on when this object needs to
- * perform operations on itself.
- *
- * If this is NULL then a new session is opened for each operation,
- * such as gck_object_get(), gck_object_set() or gck_object_destroy().
- */
- g_object_class_install_property (gobject_class, PROP_SESSION,
- g_param_spec_object ("session", "session", "PKCS11 Session to make calls on",
- GCK_TYPE_SESSION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_type_class_add_private (klass, sizeof (GckObjectPrivate));
-}
-
-/* ----------------------------------------------------------------------------
- * PUBLIC
- */
-
-/**
- * gck_object_from_handle:
- * @session: The session through which this object is accessed or created.
- * @object_handle: The raw CK_OBJECT_HANDLE of the object.
- *
- * Initialize a GckObject from a raw PKCS\#11 handle. Normally you would use
- * gck_session_create_object() or gck_session_find_objects() to access objects.
- *
- * Return value: (transfer full): The new GckObject. You should use
- * g_object_unref() when done with this object.
- **/
-GckObject *
-gck_object_from_handle (GckSession *session,
- gulong object_handle)
-{
- GckModule *module = NULL;
- GckObject *object;
-
- g_return_val_if_fail (GCK_IS_SESSION (session), NULL);
-
- module = gck_session_get_module (session);
- object = g_object_new (GCK_TYPE_OBJECT,
- "module", module,
- "handle", object_handle,
- "session", session,
- NULL);
- g_object_unref (module);
-
- return object;
-}
-
-/**
- * gck_objects_from_handle_array:
- * @session: The session for these objects
- * @object_handles: (array length=n_object_handles): The raw object handles.
- * @n_object_handles: The number of raw object handles.
- *
- * Initialize a list of GckObject from raw PKCS\#11 handles. The handles argument must contain
- * contiguous CK_OBJECT_HANDLE handles in an array.
- *
- * Returns: (transfer full) (element-type Gck.Object): The list of #GckObject
- * objects. You should use gck_list_unref_free() when done with this
- * list.
- **/
-GList *
-gck_objects_from_handle_array (GckSession *session,
- gulong *object_handles,
- gulong n_object_handles)
-{
- GList *results = NULL;
- CK_ULONG i;
-
- g_return_val_if_fail (GCK_IS_SESSION (session), NULL);
- g_return_val_if_fail (n_object_handles == 0 || object_handles != NULL, NULL);
-
- for (i = 0; i < n_object_handles; ++i)
- results = g_list_prepend (results, gck_object_from_handle (session, object_handles[i]));
- return g_list_reverse (results);
-}
-
-/**
- * gck_object_equal:
- * @object1: (type Gck.Object): a pointer to the first #GckObject
- * @object2: (type Gck.Object): a pointer to the second #GckObject
- *
- * Checks equality of two objects. Two GckObject objects can point to the same
- * underlying PKCS\#11 object.
- *
- * Return value: TRUE if object1 and object2 are equal. FALSE if either is not a GckObject.
- **/
-gboolean
-gck_object_equal (gconstpointer object1, gconstpointer object2)
-{
- GckObject *obj1, *obj2;
- GckSlot *slot1, *slot2;
- gboolean ret;
-
- if (object1 == object2)
- return TRUE;
- if (!GCK_IS_OBJECT (object1) || !GCK_IS_OBJECT (object2))
- return FALSE;
-
- obj1 = GCK_OBJECT (object1);
- obj2 = GCK_OBJECT (object2);
-
- slot1 = gck_session_get_slot (obj1->pv->session);
- slot2 = gck_session_get_slot (obj2->pv->session);
-
- ret = obj1->pv->handle == obj2->pv->handle &&
- gck_slot_equal (slot1, slot2);
-
- g_object_unref (slot1);
- g_object_unref (slot2);
-
- return ret;
-}
-
-/**
- * gck_object_hash:
- * @object: (type Gck.Object): a pointer to a #GckObject
- *
- * Create a hash value for the GckObject.
- *
- * This function is intended for easily hashing a GckObject to add to
- * a GHashTable or similar data structure.
- *
- * Return value: An integer that can be used as a hash value, or 0 if invalid.
- **/
-guint
-gck_object_hash (gconstpointer object)
-{
- GckObject *self;
- GckSlot *slot;
- guint hash;
-
- g_return_val_if_fail (GCK_IS_OBJECT (object), 0);
-
- self = GCK_OBJECT (object);
- slot = gck_session_get_slot (self->pv->session);
-
- hash = _gck_ulong_hash (&self->pv->handle) ^
- gck_slot_hash (slot);
-
- g_object_unref (slot);
-
- return hash;
-}
-
-
-/**
- * gck_object_get_handle:
- * @self: The object.
- *
- * Get the raw PKCS\#11 handle of a GckObject.
- *
- * Return value: the raw CK_OBJECT_HANDLE object handle
- **/
-gulong
-gck_object_get_handle (GckObject *self)
-{
- g_return_val_if_fail (GCK_IS_OBJECT (self), (CK_OBJECT_HANDLE)-1);
- return self->pv->handle;
-}
-
-/**
- * gck_object_get_module:
- * @self: The object.
- *
- * Get the PKCS\#11 module to which this object belongs.
- *
- * Returns: (transfer full): the module, which should be unreffed after use
- **/
-GckModule *
-gck_object_get_module (GckObject *self)
-{
- g_return_val_if_fail (GCK_IS_OBJECT (self), NULL);
- g_return_val_if_fail (GCK_IS_MODULE (self->pv->module), NULL);
- return g_object_ref (self->pv->module);
-}
-
-
-/**
- * gck_object_get_session:
- * @self: The object
- *
- * Get the PKCS\#11 session assigned to make calls on when operating
- * on this object.
- *
- * This will only return a session if it was set explitly on this
- * object. By default an object will open and close sessions
- * appropriate for its calls.
- *
- * Returns: (transfer full): the assigned session, which must be unreffed after use
- **/
-GckSession *
-gck_object_get_session (GckObject *self)
-{
- g_return_val_if_fail (GCK_IS_OBJECT (self), NULL);
- g_return_val_if_fail (GCK_IS_SESSION (self->pv->session), NULL);
- return g_object_ref (self->pv->session);
-}
-
-/* --------------------------------------------------------------------------------------
- * DESTROY
- */
-
-typedef struct _Destroy {
- GckArguments base;
- CK_OBJECT_HANDLE object;
-} Destroy;
-
-static CK_RV
-perform_destroy (Destroy *args)
-{
- g_assert (args);
- return (args->base.pkcs11->C_DestroyObject) (args->base.handle, args->object);
-}
-
-/**
- * gck_object_destroy:
- * @self: The object to destroy.
- * @cancellable: Optional cancellable object, or NULL to ignore.
- * @error: A location to return an error.
- *
- * Destroy a PKCS\#11 object, deleting it from storage or the session.
- * This call may block for an indefinite period.
- *
- * Return value: Whether the call was successful or not.
- **/
-gboolean
-gck_object_destroy (GckObject *self, GCancellable *cancellable, GError **error)
-{
- Destroy args = { GCK_ARGUMENTS_INIT, 0 };
-
- g_return_val_if_fail (GCK_IS_OBJECT (self), FALSE);
- g_return_val_if_fail (GCK_IS_SESSION (self->pv->session), FALSE);
- g_return_val_if_fail (!error || !*error, FALSE);
-
- args.object = self->pv->handle;
- return _gck_call_sync (self->pv->session, perform_destroy, NULL, &args, cancellable, error);
-}
-
-/**
- * gck_object_destroy_async:
- * @self: The object to destroy.
- * @cancellable: Optional cancellable object, or NULL to ignore.
- * @callback: Callback which is called when operation completes.
- * @user_data: Data to pass to the callback.
- *
- * Destroy a PKCS\#11 object, deleting it from storage or the session.
- * This call will return immediately and complete asynchronously.
- **/
-void
-gck_object_destroy_async (GckObject *self, GCancellable *cancellable,
- GAsyncReadyCallback callback, gpointer user_data)
-{
- Destroy* args;
-
- g_return_if_fail (GCK_IS_OBJECT (self));
- g_return_if_fail (GCK_IS_SESSION (self->pv->session));
-
- args = _gck_call_async_prep (self->pv->session, self, perform_destroy, NULL, sizeof (*args), NULL);
- args->object = self->pv->handle;
-
- _gck_call_async_ready_go (args, cancellable, callback, user_data);
-}
-
-/**
- * gck_object_destroy_finish:
- * @self: The object being destroyed.
- * @result: The result of the destory operation passed to the callback.
- * @error: A location to store an error.
- *
- * Get the status of the operation to destroy a PKCS\#11 object, begun with
- * gck_object_destroy_async().
- *
- * Return value: Whether the object was destroyed successfully or not.
- */
-gboolean
-gck_object_destroy_finish (GckObject *self, GAsyncResult *result, GError **error)
-{
- g_return_val_if_fail (GCK_IS_OBJECT (self), FALSE);
- g_return_val_if_fail (GCK_IS_CALL (result), FALSE);
- return _gck_call_basic_finish (result, error);
-}
-
-/* --------------------------------------------------------------------------------------
- * SET ATTRIBUTES
- */
-
-typedef struct _SetAttributes {
- GckArguments base;
- GckAttributes *attrs;
- CK_OBJECT_HANDLE object;
-} SetAttributes;
-
-static CK_RV
-perform_set_attributes (SetAttributes *args)
-{
- CK_ATTRIBUTE_PTR attrs;
- CK_ULONG n_attrs;
-
- g_assert (args);
- attrs = _gck_attributes_commit_out (args->attrs, &n_attrs);
-
- return (args->base.pkcs11->C_SetAttributeValue) (args->base.handle, args->object,
- attrs, n_attrs);
-}
-
-static void
-free_set_attributes (SetAttributes *args)
-{
- g_assert (args);
- gck_attributes_unref (args->attrs);
- g_free (args);
-}
-
-/**
- * gck_object_set:
- * @self: The object to set attributes on.
- * @attrs: The attributes to set on the object.
- * @cancellable: Optional cancellable object, or NULL to ignore.
- * @error: A location to return an error.
- *
- * Set PKCS\#11 attributes on an object. This call may block for an indefinite period.
- *
- * Return value: Whether the call was successful or not.
- **/
-gboolean
-gck_object_set (GckObject *self, GckAttributes *attrs,
- GCancellable *cancellable, GError **error)
-{
- SetAttributes args;
- gboolean ret = FALSE;
-
- g_return_val_if_fail (GCK_IS_OBJECT (self), FALSE);
- g_return_val_if_fail (attrs != NULL, FALSE);
- g_return_val_if_fail (!error || !*error, FALSE);
-
- _gck_attributes_lock (attrs);
-
- memset (&args, 0, sizeof (args));
- args.attrs = attrs;
- args.object = self->pv->handle;
-
- ret = _gck_call_sync (self->pv->session, perform_set_attributes, NULL, &args, cancellable, error);
-
- _gck_attributes_unlock (attrs);
- return ret;
-}
-
-/**
- * gck_object_set_async:
- * @self: The object to set attributes on.
- * @attrs: The attributes to set on the object.
- * @cancellable: Optional cancellable object, or NULL to ignore.
- * @callback: Callback which is called when operation completes.
- * @user_data: Data to pass to the callback.
- *
- * Set PKCS\#11 attributes on an object. This call will return
- * immediately and completes asynchronously.
- **/
-void
-gck_object_set_async (GckObject *self, GckAttributes *attrs, GCancellable *cancellable,
- GAsyncReadyCallback callback, gpointer user_data)
-{
- SetAttributes *args;
-
- g_return_if_fail (GCK_IS_OBJECT (self));
- g_return_if_fail (attrs != NULL);
-
- args = _gck_call_async_prep (self->pv->session, self, perform_set_attributes,
- NULL, sizeof (*args), free_set_attributes);
-
- _gck_attributes_lock (attrs);
- args->attrs = gck_attributes_ref (attrs);
- args->object = self->pv->handle;
-
- _gck_call_async_ready_go (args, cancellable, callback, user_data);
-}
-
-/**
- * gck_object_set_finish:
- * @self: The object to set attributes on.
- * @result: The result of the destory operation passed to the callback.
- * @error: A location to store an error.
- *
- * Get the status of the operation to set attributes on a PKCS\#11 object,
- * begun with gck_object_set_async().
- *
- * Return value: Whether the attributes were successfully set on the object or not.
- */
-gboolean
-gck_object_set_finish (GckObject *self, GAsyncResult *result, GError **error)
-{
- SetAttributes *args;
-
- g_return_val_if_fail (GCK_IS_OBJECT (self), FALSE);
- g_return_val_if_fail (GCK_IS_CALL (result), FALSE);
- g_return_val_if_fail (!error || !*error, FALSE);
-
- /* Unlock the attributes we were using */
- args = _gck_call_arguments (result, SetAttributes);
- g_assert (args->attrs);
- _gck_attributes_unlock (args->attrs);
-
- return _gck_call_basic_finish (result, error);
-}
-
-/* ------------------------------------------------------------------------------------
- * GET ATTRIBUTES
- */
-
-typedef struct _GetAttributes {
- GckArguments base;
- CK_OBJECT_HANDLE object;
- GckAttributes *attrs;
-} GetAttributes;
-
-/*
- * Certain failure return values only apply to individual attributes
- * being retrieved. These are ignored, since the attribute should
- * already have -1 set as the length.
- */
-static gboolean
-is_ok_get_attributes_rv (CK_RV rv)
-{
- switch (rv) {
- case CKR_OK:
- case CKR_ATTRIBUTE_SENSITIVE:
- case CKR_ATTRIBUTE_TYPE_INVALID:
- return TRUE;
- default:
- return FALSE;
- }
-}
-
-static CK_RV
-perform_get_attributes (GetAttributes *args)
-{
- CK_ATTRIBUTE_PTR attrs;
- CK_ULONG n_attrs;
- CK_RV rv;
-
- g_assert (args);
- g_assert (args->attrs);
-
- /* Prepare all the attributes */
- attrs = _gck_attributes_prepare_in (args->attrs, &n_attrs);
-
- /* 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))
- return rv;
-
- /* Allocate memory for each value */
- attrs = _gck_attributes_commit_in (args->attrs, &n_attrs);
-
- /* Now get the actual values */
- rv = (args->base.pkcs11->C_GetAttributeValue) (args->base.handle, args->object,
- attrs, n_attrs);
-
- if (is_ok_get_attributes_rv (rv))
- rv = CKR_OK;
-
- return rv;
-}
-
-static void
-free_get_attributes (GetAttributes *args)
-{
- g_assert (args);
- g_assert (args->attrs);
- gck_attributes_unref (args->attrs);
- g_free (args);
-}
-
-
-/**
- * gck_object_get:
- * @self: The object to get attributes from.
- * @cancellable: A #GCancellable or %NULL
- * @error: A location to store an error.
- * @...: The attribute types to get.
- *
- * Get the specified attributes from the object. This call may
- * block for an indefinite period.
- *
- * Returns: (transfer full): the resulting PKCS\#11 attributes, or %NULL if an
- * error occurred; the result must be unreffed when you're finished
- * with it
- **/
-GckAttributes *
-gck_object_get (GckObject *self, GCancellable *cancellable, GError **error, ...)
-{
- GckAttributes *attrs;
- GArray *array;
- va_list va;
- gulong type;
-
- g_return_val_if_fail (GCK_IS_OBJECT (self), NULL);
- g_return_val_if_fail (!error || !*error, NULL);
-
- array = g_array_new (FALSE, TRUE, sizeof (gulong));
- va_start (va, error);
- for (;;) {
- type = va_arg (va, gulong);
- if (type == GCK_INVALID)
- break;
- g_array_append_val (array, type);
- }
- va_end (va);
-
- attrs = gck_object_get_full (self, (gulong*)array->data, array->len, cancellable, error);
- g_array_free (array, TRUE);
-
- return attrs;
-}
-
-/**
- * gck_object_get_full:
- * @self: The object to get attributes from.
- * @attr_types: (array length=n_attr_types): the types of the attributes to get
- * @n_attr_types: the number of attr_types
- * @cancellable: optional cancellation object, or %NULL
- * @error: A location to store an error.
- *
- * Get the specified attributes from the object. This call may
- * block for an indefinite period.
- *
- * No extra references are added to the returned attributes pointer.
- * During this call you may not access the attributes in any way.
- *
- * Returns: (transfer full): a pointer to the filled in attributes if successful,
- * or %NULL if not
- **/
-GckAttributes *
-gck_object_get_full (GckObject *self, gulong *attr_types, guint n_attr_types,
- GCancellable *cancellable, GError **error)
-{
- GetAttributes args;
- GckAttributes *attrs;
- gboolean ret;
- guint i;
-
- g_return_val_if_fail (GCK_IS_OBJECT (self), NULL);
- g_return_val_if_fail (!error || !*error, NULL);
-
- attrs = gck_attributes_new ();
- for (i = 0; i < n_attr_types; ++i)
- gck_attributes_add_empty (attrs, attr_types[i]);
-
- _gck_attributes_lock (attrs);
-
- memset (&args, 0, sizeof (args));
- args.attrs = attrs;
- args.object = self->pv->handle;
-
- ret = _gck_call_sync (self->pv->session, perform_get_attributes, NULL, &args, cancellable, error);
- _gck_attributes_unlock (attrs);
-
- if (!ret) {
- gck_attributes_unref (attrs);
- attrs = NULL;
- }
-
- return attrs;
-}
-
-/**
- * gck_object_get_async:
- * @self: The object to get attributes from.
- * @attr_types: (array length=n_attr_types): the types of the attributes to get
- * @n_attr_types: the number of attr_types
- * @cancellable: optional cancellation object, or %NULL
- * @callback: A callback which is called when the operation completes.
- * @user_data: Data to be passed to the callback.
- *
- * Get the specified attributes from the object. The attributes will be cleared
- * of their current values, and new attributes will be stored. The attributes
- * should not be accessed in any way except for referencing and unreferencing
- * them until gck_object_get_finish() is called.
- *
- * This call returns immediately and completes asynchronously.
- **/
-void
-gck_object_get_async (GckObject *self, gulong *attr_types, guint n_attr_types, GCancellable *cancellable,
- GAsyncReadyCallback callback, gpointer user_data)
-{
- GckAttributes *attrs;
- GetAttributes *args;
- guint i;
-
- g_return_if_fail (GCK_IS_OBJECT (self));
-
- attrs = gck_attributes_new ();
- for (i = 0; i < n_attr_types; ++i)
- gck_attributes_add_empty (attrs, attr_types[i]);
-
- args = _gck_call_async_prep (self->pv->session, self, perform_get_attributes,
- NULL, sizeof (*args), free_get_attributes);
-
- _gck_attributes_lock (attrs);
- args->attrs = attrs;
- args->object = self->pv->handle;
-
- _gck_call_async_ready_go (args, cancellable, callback, user_data);
-}
-
-/**
- * gck_object_get_finish:
- * @self: The object to get attributes from.
- * @result: The result passed to the callback.
- * @error: A location to store an error.
- *
- * Get the result of a get operation and return specified attributes from
- * the object.
- *
- * No extra references are added to the returned attributes pointer.
- *
- * Return value: The filled in attributes structure if successful or
- * NULL if not successful.
- **/
-GckAttributes*
-gck_object_get_finish (GckObject *self, GAsyncResult *result, GError **error)
-{
- GetAttributes *args;
- GckAttributes *attrs;
-
- g_return_val_if_fail (GCK_IS_OBJECT (self), NULL);
- g_return_val_if_fail (GCK_IS_CALL (result), NULL);
- g_return_val_if_fail (!error || !*error, NULL);
-
- args = _gck_call_arguments (result, GetAttributes);
- _gck_attributes_unlock (args->attrs);
- attrs = gck_attributes_ref (args->attrs);
-
- if (!_gck_call_basic_finish (result, error)) {
- gck_attributes_unref (attrs);
- attrs = NULL;
- }
-
- return attrs;
-}
-
-/* ---------------------------------------------------------------------------------
- * GET ATTRIBUTE DATA
- */
-
-typedef struct _GetAttributeData {
- GckArguments base;
- CK_OBJECT_HANDLE object;
- CK_ATTRIBUTE_TYPE type;
- GckAllocator allocator;
- guchar *result;
- gsize n_result;
-} GetAttributeData;
-
-static CK_RV
-perform_get_attribute_data (GetAttributeData *args)
-{
- CK_ATTRIBUTE attr;
- CK_RV rv;
-
- g_assert (args);
- g_assert (args->allocator);
-
- attr.type = args->type;
- attr.ulValueLen = 0;
- attr.pValue = 0;
-
- /* Get the size of the value */
- rv = (args->base.pkcs11->C_GetAttributeValue) (args->base.handle, args->object,
- &attr, 1);
- if (rv != CKR_OK)
- return rv;
-
- /* Allocate memory for the value */
- args->result = (args->allocator) (NULL, attr.ulValueLen + 1);
- g_assert (args->result);
- attr.pValue = args->result;
-
- /* Now get the actual value */
- rv = (args->base.pkcs11->C_GetAttributeValue) (args->base.handle, args->object,
- &attr, 1);
-
- if (rv == CKR_OK) {
- args->n_result = attr.ulValueLen;
- args->result[args->n_result] = 0;
- }
-
- return rv;
-}
-
-static void
-free_get_attribute_data (GetAttributeData *args)
-{
- g_assert (args);
- g_free (args->result);
- g_free (args);
-}
-
-/**
- * gck_object_get_data:
- * @self: The object to get attribute data from.
- * @attr_type: The attribute to get data for.
- * @cancellable: A #GCancellable or %NULL
- * @n_data: The length of the resulting data.
- * @error: A location to store an error.
- *
- * Get the data for the specified attribute from the object. For convenience
- * the returned data has a null terminator.
- *
- * This call may block for an indefinite period.
- *
- * Returns: (transfer full) (array length=n_data): the resulting PKCS\#11
- * attribute data, or %NULL if an error occurred
- **/
-guchar *
-gck_object_get_data (GckObject *self,
- gulong attr_type,
- GCancellable *cancellable,
- gsize *n_data,
- GError **error)
-{
- g_return_val_if_fail (GCK_IS_OBJECT (self), NULL);
- g_return_val_if_fail (n_data, NULL);
- g_return_val_if_fail (!error || !*error, NULL);
-
- return gck_object_get_data_full (self, attr_type, g_realloc, cancellable, n_data, error);
-}
-
-/**
- * gck_object_get_data_full: (skip)
- * @self: The object to get attribute data from.
- * @attr_type: The attribute to get data for.
- * @allocator: An allocator with which to allocate memory for the data, or NULL for default.
- * @cancellable: Optional cancellation object, or NULL.
- * @n_data: The length of the resulting data.
- * @error: A location to store an error.
- *
- * Get the data for the specified attribute from the object. For convenience
- * the returned data has an extra null terminator, not included in the returned length.
- *
- * This call may block for an indefinite period.
- *
- * Returns: (transfer full) (array length=n_data): The resulting PKCS\#11
- * attribute data, or %NULL if an error occurred.
- **/
-guchar *
-gck_object_get_data_full (GckObject *self, gulong attr_type, GckAllocator allocator,
- GCancellable *cancellable, gsize *n_data, GError **error)
-{
- GetAttributeData args;
- gboolean ret;
-
- g_return_val_if_fail (GCK_IS_OBJECT (self), NULL);
- g_return_val_if_fail (n_data, NULL);
- g_return_val_if_fail (!error || !*error, NULL);
-
- if (!allocator)
- allocator = g_realloc;
-
- memset (&args, 0, sizeof (args));
- args.allocator = allocator;
- args.object = self->pv->handle;
- args.type = attr_type;
-
- ret = _gck_call_sync (self->pv->session, perform_get_attribute_data, NULL, &args, cancellable, error);
-
- /* Free any value if failed */
- if (!ret) {
- if (args.result)
- (allocator) (args.result, 0);
- return NULL;
- }
-
- *n_data = args.n_result;
- return args.result;
-}
-
-/**
- * gck_object_get_data_async:
- * @self: The object to get attribute data from.
- * @attr_type: The attribute to get data for.
- * @allocator: (skip): An allocator with which to allocate memory for the data, or NULL for default.
- * @cancellable: Optional cancellation object, or NULL.
- * @callback: Called when the operation completes.
- * @user_data: Data to be passed to the callback.
- *
- * Get the data for the specified attribute from the object.
- *
- * This call will return immediately and complete asynchronously.
- **/
-void
-gck_object_get_data_async (GckObject *self, gulong attr_type, GckAllocator allocator,
- GCancellable *cancellable, GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GetAttributeData *args;
-
- g_return_if_fail (GCK_IS_OBJECT (self));
-
- if (!allocator)
- allocator = g_realloc;
-
- args = _gck_call_async_prep (self->pv->session, self, perform_get_attribute_data,
- NULL, sizeof (*args), free_get_attribute_data);
-
- args->allocator = allocator;
- args->object = self->pv->handle;
- args->type = attr_type;
-
- _gck_call_async_ready_go (args, cancellable, callback, user_data);
-}
-
-/**
- * gck_object_get_data_finish:
- * @self: The object to get an attribute from.
- * @result: The result passed to the callback.
- * @n_data: The length of the resulting data.
- * @error: A location to store an error.
- *
- * Get the result of an operation to get attribute data from
- * an object. For convenience the returned data has an extra null terminator,
- * not included in the returned length.
- *
- * Returns: (transfer full) (array length=n_data): The PKCS\#11 attribute data
- * or %NULL if an error occurred.
- **/
-guchar *
-gck_object_get_data_finish (GckObject *self,
- GAsyncResult *result,
- gsize *n_data,
- GError **error)
-{
- GetAttributeData *args;
- guchar *data;
-
- g_return_val_if_fail (GCK_IS_OBJECT (self), NULL);
- g_return_val_if_fail (GCK_IS_CALL (result), NULL);
- g_return_val_if_fail (n_data, NULL);
- g_return_val_if_fail (!error || !*error, NULL);
-
- if (!_gck_call_basic_finish (result, error))
- return NULL;
-
- args = _gck_call_arguments (result, GetAttributeData);
-
- *n_data = args->n_result;
- data = args->result;
- args->result = NULL;
-
- return data;
-}
-
-/* ---------------------------------------------------------------------------------------
- * SET TEMPLATE
- */
-
-typedef struct _set_template_args {
- GckArguments base;
- CK_OBJECT_HANDLE object;
- CK_ATTRIBUTE_TYPE type;
- GckAttributes *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 = _gck_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);
- gck_attributes_unref (args->attrs);
- g_free (args);
-}
-
-/**
- * gck_object_set_template:
- * @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.
- * @error: 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
-gck_object_set_template (GckObject *self, gulong attr_type, GckAttributes *attrs,
- GCancellable *cancellable, GError **error)
-{
- set_template_args args;
- gboolean ret = FALSE;
-
- g_return_val_if_fail (GCK_IS_OBJECT (self), FALSE);
- g_return_val_if_fail (attrs, FALSE);
- g_return_val_if_fail (!error || !*error, FALSE);
-
- _gck_attributes_lock (attrs);
-
- memset (&args, 0, sizeof (args));
- args.attrs = attrs;
- args.type = attr_type;
- args.object = self->pv->handle;
-
- ret = _gck_call_sync (self->pv->session, perform_set_template, NULL, &args, cancellable, error);
-
- _gck_attributes_unlock (attrs);
- return ret;
-}
-
-/**
- * gck_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
-gck_object_set_template_async (GckObject *self, gulong attr_type, GckAttributes *attrs,
- GCancellable *cancellable, GAsyncReadyCallback callback,
- gpointer user_data)
-{
- set_template_args *args;
-
- g_return_if_fail (GCK_IS_OBJECT (self));
- g_return_if_fail (attrs);
-
- args = _gck_call_async_prep (self->pv->session, self, perform_set_template,
- NULL, sizeof (*args), free_set_template);
-
- _gck_attributes_lock (attrs);
- args->attrs = gck_attributes_ref (attrs);
- args->type = attr_type;
- args->object = self->pv->handle;
-
- _gck_call_async_ready_go (args, cancellable, callback, user_data);
-}
-
-/**
- * gck_object_set_template_finish:
- * @self: The object to set an attribute template on.
- * @result: The result passed to the callback.
- * @error: 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
-gck_object_set_template_finish (GckObject *self, GAsyncResult *result, GError **error)
-{
- set_template_args *args;
-
- g_return_val_if_fail (GCK_IS_OBJECT (self), FALSE);
- g_return_val_if_fail (GCK_IS_CALL (result), FALSE);
- g_return_val_if_fail (!error || !*error, FALSE);
-
- /* Unlock the attributes we were using */
- args = _gck_call_arguments (result, set_template_args);
- g_assert (args->attrs);
- _gck_attributes_unlock (args->attrs);
-
- return _gck_call_basic_finish (result, error);
-}
-
-/* ---------------------------------------------------------------------------------------
- * GET TEMPLATE
- */
-
-typedef struct _get_template_args {
- GckArguments base;
- CK_OBJECT_HANDLE object;
- CK_ATTRIBUTE_TYPE type;
- GckAttributes *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 = gck_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)
- gck_attributes_add_empty (args->attrs, 0);
-
- /* Prepare all the attributes */
- _gck_attributes_lock (args->attrs);
- attr.pValue = _gck_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 = _gck_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);
- gck_attributes_unref (args->attrs);
- g_free (args);
-}
-
-/**
- * gck_object_get_template:
- * @self: The object to get an attribute template from.
- * @attr_type: The template attribute type.
- * @cancellable: Optional cancellation object, or NULL.
- * @error: 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.
- *
- * Returns: (transfer full): the resulting PKCS\#11 attribute template, or %NULL
- * if an error occurred
- **/
-GckAttributes *
-gck_object_get_template (GckObject *self, gulong attr_type,
- GCancellable *cancellable, GError **error)
-{
- get_template_args args;
- gboolean ret;
-
- g_return_val_if_fail (GCK_IS_OBJECT (self), NULL);
- g_return_val_if_fail (!error || !*error, NULL);
-
- memset (&args, 0, sizeof (args));
- args.object = self->pv->handle;
- args.type = attr_type;
-
- ret = _gck_call_sync (self->pv->session, perform_get_template, NULL, &args, cancellable, error);
-
- _gck_attributes_unlock (args.attrs);
-
- /* Free any value if failed */
- if (!ret) {
- gck_attributes_unref (args.attrs);
- args.attrs = NULL;
- }
-
- return args.attrs;
-}
-
-/**
- * gck_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
-gck_object_get_template_async (GckObject *self, gulong attr_type,
- GCancellable *cancellable, GAsyncReadyCallback callback,
- gpointer user_data)
-{
- get_template_args *args;
-
- g_return_if_fail (GCK_IS_OBJECT (self));
-
- args = _gck_call_async_prep (self->pv->session, self, perform_get_template,
- NULL, sizeof (*args), free_get_template);
-
- args->object = self->pv->handle;
- args->type = attr_type;
-
- _gck_call_async_ready_go (args, cancellable, callback, user_data);
-}
-
-/**
- * gck_object_get_template_finish:
- * @self: The object to get an attribute from.
- * @result: The result passed to the callback.
- * @error: A location to store an error.
- *
- * Get the result of an operation to get attribute template from
- * an object.
- *
- * Returns: (transfer full): the resulting PKCS\#11 attribute template, or %NULL
- * if an error occurred
- **/
-GckAttributes *
-gck_object_get_template_finish (GckObject *self, GAsyncResult *result,
- GError **error)
-{
- get_template_args *args;
-
- g_return_val_if_fail (GCK_IS_OBJECT (self), NULL);
- g_return_val_if_fail (GCK_IS_CALL (result), NULL);
- g_return_val_if_fail (!error || !*error, NULL);
-
- if (!_gck_call_basic_finish (result, error))
- return NULL;
-
- args = _gck_call_arguments (result, get_template_args);
- _gck_attributes_unlock (args->attrs);
- return gck_attributes_ref (args->attrs);
-}