1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /* gck-object.c - the GObject PKCS#11 wrapper library
3 
4    Copyright (C) 2008, Stefan Walter
5 
6    The Gnome Keyring Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Library General Public License as
8    published by the Free Software Foundation; either version 2 of the
9    License, or (at your option) any later version.
10 
11    The Gnome Keyring Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Library General Public License for more details.
15 
16    You should have received a copy of the GNU Library General Public
17    License along with the Gnome Library; see the file COPYING.LIB.  If not,
18    see <http://www.gnu.org/licenses/>.
19 
20    Author: Stef Walter <nielsen@memberwebs.com>
21 */
22 
23 #include "config.h"
24 
25 #include "gck.h"
26 #include "gck-private.h"
27 
28 #include <string.h>
29 
30 /**
31  * SECTION:gck-object
32  * @title: GckObject
33  * @short_description: Represents a PKCS11 object such as a key or certificate.
34  *
35  * A GckObject holds a handle to a PKCS11 object such as a key or certificate. Token objects
36  * are stored on the token persistently. Others are transient and are called session objects.
37  */
38 
39 /**
40  * GckObject:
41  *
42  * Represents a PKCS11 object handle such as a key or certifiacte.
43  */
44 
45 /**
46  * GckObjectClass:
47  * @parent: derived from this
48  *
49  * The class for a #GckObject.
50  *
51  * If the @attribute_types field is set by a derived class, then the a
52  * #GckEnumerator which has been setup using gck_enumerator_set_object_type()
53  * with this derived type will retrieve these attributes when enumerating. In
54  * this case the class must implement an 'attributes' property of boxed type
55  * GCK_TYPE_ATTRIBUTES.
56  */
57 
58 /*
59  * MT safe -- Nothing in GckObjectData changes between
60  * init and finalize. All GckObjectPrivate access between init
61  * and finalize is locked.
62  */
63 
64 enum {
65 	PROP_0,
66 	PROP_MODULE,
67 	PROP_SESSION,
68 	PROP_HANDLE
69 };
70 
71 struct _GckObjectPrivate {
72 	GckModule *module;
73 	GckSession *session;
74 	CK_OBJECT_HANDLE handle;
75 };
76 
77 G_DEFINE_TYPE_WITH_PRIVATE (GckObject, gck_object, G_TYPE_OBJECT);
78 
79 /* ----------------------------------------------------------------------------
80  * OBJECT
81  */
82 
83 static void
gck_object_init(GckObject * self)84 gck_object_init (GckObject *self)
85 {
86 	self->pv = gck_object_get_instance_private (self);
87 }
88 
89 static void
gck_object_get_property(GObject * obj,guint prop_id,GValue * value,GParamSpec * pspec)90 gck_object_get_property (GObject *obj, guint prop_id, GValue *value,
91                           GParamSpec *pspec)
92 {
93 	GckObject *self = GCK_OBJECT (obj);
94 
95 	switch (prop_id) {
96 	case PROP_MODULE:
97 		g_value_take_object (value, gck_object_get_module (self));
98 		break;
99 	case PROP_SESSION:
100 		g_value_take_object (value, gck_object_get_session (self));
101 		break;
102 	case PROP_HANDLE:
103 		g_value_set_ulong (value, gck_object_get_handle (self));
104 		break;
105 	}
106 }
107 
108 static void
gck_object_set_property(GObject * obj,guint prop_id,const GValue * value,GParamSpec * pspec)109 gck_object_set_property (GObject *obj, guint prop_id, const GValue *value,
110                          GParamSpec *pspec)
111 {
112 	GckObject *self = GCK_OBJECT (obj);
113 
114 	/* The sets to data below are only allowed during construction */
115 
116 	switch (prop_id) {
117 	case PROP_MODULE:
118 		g_return_if_fail (!self->pv->module);
119 		self->pv->module = g_value_get_object (value);
120 		g_return_if_fail (self->pv->module);
121 		g_object_ref (self->pv->module);
122 		break;
123 	case PROP_SESSION:
124 		g_return_if_fail (!self->pv->session);
125 		self->pv->session = g_value_get_object (value);
126 		g_return_if_fail (self->pv->session);
127 		g_object_ref (self->pv->session);
128 		break;
129 	case PROP_HANDLE:
130 		g_return_if_fail (!self->pv->handle);
131 		self->pv->handle = g_value_get_ulong (value);
132 		break;
133 	}
134 }
135 
136 static void
gck_object_finalize(GObject * obj)137 gck_object_finalize (GObject *obj)
138 {
139 	GckObject *self = GCK_OBJECT (obj);
140 
141 	if (self->pv->session)
142 		g_object_unref (self->pv->session);
143 	self->pv->session = NULL;
144 
145 	if (self->pv->module)
146 		g_object_unref (self->pv->module);
147 	self->pv->module = NULL;
148 
149 	self->pv->handle = 0;
150 
151 	G_OBJECT_CLASS (gck_object_parent_class)->finalize (obj);
152 }
153 
154 
155 static void
gck_object_class_init(GckObjectClass * klass)156 gck_object_class_init (GckObjectClass *klass)
157 {
158 	GObjectClass *gobject_class = (GObjectClass*)klass;
159 	gck_object_parent_class = g_type_class_peek_parent (klass);
160 
161 	gobject_class->get_property = gck_object_get_property;
162 	gobject_class->set_property = gck_object_set_property;
163 	gobject_class->finalize = gck_object_finalize;
164 
165 	/**
166 	 * GckObject:module:
167 	 *
168 	 * The GckModule that this object belongs to.
169 	 */
170 	g_object_class_install_property (gobject_class, PROP_MODULE,
171 		g_param_spec_object ("module", "Module", "PKCS11 Module",
172 		                     GCK_TYPE_MODULE,
173 		                     G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
174 
175 	/**
176 	 * GckObject:handle:
177 	 *
178 	 * The raw PKCS11 handle for this object.
179 	 */
180 	g_object_class_install_property (gobject_class, PROP_HANDLE,
181 		g_param_spec_ulong ("handle", "Object Handle", "PKCS11 Object Handle",
182 		                   0, G_MAXULONG, 0,
183 		                   G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
184 
185 	/**
186 	 * GckObject:session:
187 	 *
188 	 * The PKCS11 session to make calls on when this object needs to
189 	 * perform operations on itself.
190 	 *
191 	 * If this is NULL then a new session is opened for each operation,
192 	 * such as gck_object_get(), gck_object_set() or gck_object_destroy().
193 	 */
194 	g_object_class_install_property (gobject_class, PROP_SESSION,
195 		g_param_spec_object ("session", "session", "PKCS11 Session to make calls on",
196 		                     GCK_TYPE_SESSION,
197 		                     G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
198 }
199 
200 /* ----------------------------------------------------------------------------
201  * PUBLIC
202  */
203 
204 /**
205  * gck_object_from_handle:
206  * @session: The session through which this object is accessed or created.
207  * @object_handle: The raw CK_OBJECT_HANDLE of the object.
208  *
209  * Initialize a GckObject from a raw PKCS\#11 handle. Normally you would use
210  * gck_session_create_object() or gck_session_find_objects() to access objects.
211  *
212  * Return value: (transfer full): The new GckObject. You should use
213  *               g_object_unref() when done with this object.
214  **/
215 GckObject *
gck_object_from_handle(GckSession * session,gulong object_handle)216 gck_object_from_handle (GckSession *session,
217                         gulong object_handle)
218 {
219 	GckModule *module = NULL;
220 	GckObject *object;
221 
222 	g_return_val_if_fail (GCK_IS_SESSION (session), NULL);
223 
224 	module = gck_session_get_module (session);
225 	object = g_object_new (GCK_TYPE_OBJECT,
226 	                       "module", module,
227 	                       "handle", object_handle,
228 	                       "session", session,
229 	                       NULL);
230 	g_object_unref (module);
231 
232 	return object;
233 }
234 
235 /**
236  * gck_objects_from_handle_array:
237  * @session: The session for these objects
238  * @object_handles: (array length=n_object_handles): The raw object handles.
239  * @n_object_handles: The number of raw object handles.
240  *
241  * Initialize a list of GckObject from raw PKCS\#11 handles. The handles argument must contain
242  * contiguous CK_OBJECT_HANDLE handles in an array.
243  *
244  * Returns: (transfer full) (element-type Gck.Object): The list of #GckObject
245  *          objects. You should use gck_list_unref_free() when done with this
246  *          list.
247  **/
248 GList *
gck_objects_from_handle_array(GckSession * session,gulong * object_handles,gulong n_object_handles)249 gck_objects_from_handle_array (GckSession *session,
250                                gulong *object_handles,
251                                gulong n_object_handles)
252 {
253 	GList *results = NULL;
254 	CK_ULONG i;
255 
256 	g_return_val_if_fail (GCK_IS_SESSION (session), NULL);
257 	g_return_val_if_fail (n_object_handles == 0 || object_handles != NULL, NULL);
258 
259 	for (i = 0; i < n_object_handles; ++i)
260 		results = g_list_prepend (results, gck_object_from_handle (session, object_handles[i]));
261 	return g_list_reverse (results);
262 }
263 
264 /**
265  * gck_object_equal:
266  * @object1: (type Gck.Object): a pointer to the first #GckObject
267  * @object2: (type Gck.Object): a pointer to the second #GckObject
268  *
269  * Checks equality of two objects. Two GckObject objects can point to the same
270  * underlying PKCS\#11 object.
271  *
272  * Return value: %TRUE if object1 and object2 are equal.
273  *               %FALSE if either is not a GckObject.
274  **/
275 gboolean
gck_object_equal(gconstpointer object1,gconstpointer object2)276 gck_object_equal (gconstpointer object1, gconstpointer object2)
277 {
278 	GckObject *obj1, *obj2;
279 	GckSlot *slot1, *slot2;
280 	gboolean ret;
281 
282 	if (object1 == object2)
283 		return TRUE;
284 	if (!GCK_IS_OBJECT (object1) || !GCK_IS_OBJECT (object2))
285 		return FALSE;
286 
287 	obj1 = GCK_OBJECT (object1);
288 	obj2 = GCK_OBJECT (object2);
289 
290 	slot1 = gck_session_get_slot (obj1->pv->session);
291 	slot2 = gck_session_get_slot (obj2->pv->session);
292 
293 	ret = obj1->pv->handle == obj2->pv->handle &&
294 	      gck_slot_equal (slot1, slot2);
295 
296 	g_object_unref (slot1);
297 	g_object_unref (slot2);
298 
299 	return ret;
300 }
301 
302 /**
303  * gck_object_hash:
304  * @object: (type Gck.Object): a pointer to a #GckObject
305  *
306  * Create a hash value for the GckObject.
307  *
308  * This function is intended for easily hashing a GckObject to add to
309  * a GHashTable or similar data structure.
310  *
311  * Return value: An integer that can be used as a hash value, or 0 if invalid.
312  **/
313 guint
gck_object_hash(gconstpointer object)314 gck_object_hash (gconstpointer object)
315 {
316 	GckObject *self;
317 	GckSlot *slot;
318 	guint hash;
319 
320 	g_return_val_if_fail (GCK_IS_OBJECT (object), 0);
321 
322 	self = GCK_OBJECT (object);
323 	slot = gck_session_get_slot (self->pv->session);
324 
325 	hash = _gck_ulong_hash (&self->pv->handle) ^
326 	       gck_slot_hash (slot);
327 
328 	g_object_unref (slot);
329 
330 	return hash;
331 }
332 
333 
334 /**
335  * gck_object_get_handle:
336  * @self: The object.
337  *
338  * Get the raw PKCS\#11 handle of a GckObject.
339  *
340  * Return value: the raw CK_OBJECT_HANDLE object handle
341  **/
342 gulong
gck_object_get_handle(GckObject * self)343 gck_object_get_handle (GckObject *self)
344 {
345 	g_return_val_if_fail (GCK_IS_OBJECT (self), (CK_OBJECT_HANDLE)-1);
346 	return self->pv->handle;
347 }
348 
349 /**
350  * gck_object_get_module:
351  * @self: The object.
352  *
353  * Get the PKCS\#11 module to which this object belongs.
354  *
355  * Returns: (transfer full): the module, which should be unreffed after use
356  **/
357 GckModule *
gck_object_get_module(GckObject * self)358 gck_object_get_module (GckObject *self)
359 {
360 	g_return_val_if_fail (GCK_IS_OBJECT (self), NULL);
361 	g_return_val_if_fail (GCK_IS_MODULE (self->pv->module), NULL);
362 	return g_object_ref (self->pv->module);
363 }
364 
365 
366 /**
367  * gck_object_get_session:
368  * @self: The object
369  *
370  * Get the PKCS\#11 session assigned to make calls on when operating
371  * on this object.
372  *
373  * This will only return a session if it was set explitly on this
374  * object. By default an object will open and close sessions
375  * appropriate for its calls.
376  *
377  * Returns: (transfer full): the assigned session, which must be unreffed after use
378  **/
379 GckSession *
gck_object_get_session(GckObject * self)380 gck_object_get_session (GckObject *self)
381 {
382 	g_return_val_if_fail (GCK_IS_OBJECT (self), NULL);
383 	g_return_val_if_fail (GCK_IS_SESSION (self->pv->session), NULL);
384 	return g_object_ref (self->pv->session);
385 }
386 
387 /* --------------------------------------------------------------------------------------
388  * DESTROY
389  */
390 
391 typedef struct _Destroy {
392 	GckArguments base;
393 	CK_OBJECT_HANDLE object;
394 } Destroy;
395 
396 static CK_RV
perform_destroy(Destroy * args)397 perform_destroy (Destroy *args)
398 {
399 	g_assert (args);
400 	return (args->base.pkcs11->C_DestroyObject) (args->base.handle, args->object);
401 }
402 
403 /**
404  * gck_object_destroy:
405  * @self: The object to destroy.
406  * @cancellable: Optional cancellable object, or %NULL to ignore.
407  * @error: A location to return an error.
408  *
409  * Destroy a PKCS\#11 object, deleting it from storage or the session.
410  * This call may block for an indefinite period.
411  *
412  * Return value: Whether the call was successful or not.
413  **/
414 gboolean
gck_object_destroy(GckObject * self,GCancellable * cancellable,GError ** error)415 gck_object_destroy (GckObject *self, GCancellable *cancellable, GError **error)
416 {
417 	Destroy args = { GCK_ARGUMENTS_INIT, 0 };
418 
419 	g_return_val_if_fail (GCK_IS_OBJECT (self), FALSE);
420 	g_return_val_if_fail (GCK_IS_SESSION (self->pv->session), FALSE);
421 	g_return_val_if_fail (!error || !*error, FALSE);
422 
423 	args.object = self->pv->handle;
424 	return _gck_call_sync (self->pv->session, perform_destroy, NULL, &args, cancellable, error);
425 }
426 
427 /**
428  * gck_object_destroy_async:
429  * @self: The object to destroy.
430  * @cancellable: Optional cancellable object, or %NULL to ignore.
431  * @callback: Callback which is called when operation completes.
432  * @user_data: Data to pass to the callback.
433  *
434  * Destroy a PKCS\#11 object, deleting it from storage or the session.
435  * This call will return immediately and complete asynchronously.
436  **/
437 void
gck_object_destroy_async(GckObject * self,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)438 gck_object_destroy_async (GckObject *self, GCancellable *cancellable,
439                            GAsyncReadyCallback callback, gpointer user_data)
440 {
441 	GckCall *call;
442 	Destroy* args;
443 
444 	g_return_if_fail (GCK_IS_OBJECT (self));
445 	g_return_if_fail (GCK_IS_SESSION (self->pv->session));
446 
447 	call = _gck_call_async_prep (self->pv->session, perform_destroy, NULL, sizeof (*args), NULL);
448 	args = _gck_call_get_arguments (call);
449 	args->object = self->pv->handle;
450 
451 	_gck_call_async_ready_go (call, self, cancellable, callback, user_data);
452 }
453 
454 /**
455  * gck_object_destroy_finish:
456  * @self: The object being destroyed.
457  * @result: The result of the destory operation passed to the callback.
458  * @error: A location to store an error.
459  *
460  * Get the status of the operation to destroy a PKCS\#11 object, begun with
461  * gck_object_destroy_async().
462  *
463  * Return value: Whether the object was destroyed successfully or not.
464  */
465 gboolean
gck_object_destroy_finish(GckObject * self,GAsyncResult * result,GError ** error)466 gck_object_destroy_finish (GckObject *self, GAsyncResult *result, GError **error)
467 {
468 	g_return_val_if_fail (GCK_IS_OBJECT (self), FALSE);
469 	g_return_val_if_fail (G_IS_TASK (result), FALSE);
470 	return _gck_call_basic_finish (result, error);
471 }
472 
473 /* --------------------------------------------------------------------------------------
474  * SET ATTRIBUTES
475  */
476 
477 typedef struct _SetAttributes {
478 	GckArguments base;
479 	GckAttributes *attrs;
480 	CK_OBJECT_HANDLE object;
481 } SetAttributes;
482 
483 static CK_RV
perform_set_attributes(SetAttributes * args)484 perform_set_attributes (SetAttributes *args)
485 {
486 	CK_ATTRIBUTE_PTR attrs;
487 	CK_ULONG n_attrs;
488 
489 	g_assert (args);
490 	attrs = _gck_attributes_commit_out (args->attrs, &n_attrs);
491 
492 	return (args->base.pkcs11->C_SetAttributeValue) (args->base.handle, args->object,
493 	                                                 attrs, n_attrs);
494 }
495 
496 static void
free_set_attributes(SetAttributes * args)497 free_set_attributes (SetAttributes *args)
498 {
499 	g_assert (args);
500 	gck_attributes_unref (args->attrs);
501 	g_free (args);
502 }
503 
504 /**
505  * gck_object_set:
506  * @self: The object to set attributes on.
507  * @attrs: The attributes to set on the object.
508  * @cancellable: Optional cancellable object, or %NULL to ignore.
509  * @error: A location to return an error.
510  *
511  * Set PKCS\#11 attributes on an object. This call may block for an indefinite period.
512  *
513  * If the @attrs #GckAttributes is floating, it is consumed.
514  *
515  * Return value: Whether the call was successful or not.
516  **/
517 gboolean
gck_object_set(GckObject * self,GckAttributes * attrs,GCancellable * cancellable,GError ** error)518 gck_object_set (GckObject *self, GckAttributes *attrs,
519                 GCancellable *cancellable, GError **error)
520 {
521 	SetAttributes args;
522 	gboolean ret = FALSE;
523 
524 	g_return_val_if_fail (GCK_IS_OBJECT (self), FALSE);
525 	g_return_val_if_fail (attrs != NULL, FALSE);
526 	g_return_val_if_fail (!error || !*error, FALSE);
527 
528 	memset (&args, 0, sizeof (args));
529 	args.attrs = attrs;
530 	args.object = self->pv->handle;
531 
532 	gck_attributes_ref_sink (attrs);
533 
534 	ret = _gck_call_sync (self->pv->session, perform_set_attributes, NULL, &args, cancellable, error);
535 
536 	gck_attributes_unref (attrs);
537 
538 	return ret;
539 }
540 
541 /**
542  * gck_object_set_async:
543  * @self: The object to set attributes on.
544  * @attrs: The attributes to set on the object.
545  * @cancellable: Optional cancellable object, or %NULL to ignore.
546  * @callback: Callback which is called when operation completes.
547  * @user_data: Data to pass to the callback.
548  *
549  * Set PKCS\#11 attributes on an object. This call will return
550  * immediately and completes asynchronously.
551  *
552  * If the @attrs #GckAttributes is floating, it is consumed.
553  **/
554 void
gck_object_set_async(GckObject * self,GckAttributes * attrs,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)555 gck_object_set_async (GckObject *self, GckAttributes *attrs, GCancellable *cancellable,
556                        GAsyncReadyCallback callback, gpointer user_data)
557 {
558 	GckCall *call;
559 	SetAttributes *args;
560 
561 	g_return_if_fail (GCK_IS_OBJECT (self));
562 	g_return_if_fail (attrs != NULL);
563 
564 	call = _gck_call_async_prep (self->pv->session, perform_set_attributes,
565 	                             NULL, sizeof (*args), free_set_attributes);
566 
567 	args = _gck_call_get_arguments (call);
568 	args->attrs = gck_attributes_ref_sink (attrs);
569 	args->object = self->pv->handle;
570 
571 	_gck_call_async_ready_go (call, self, cancellable, callback, user_data);
572 }
573 
574 /**
575  * gck_object_set_finish:
576  * @self: The object to set attributes on.
577  * @result: The result of the destory operation passed to the callback.
578  * @error: A location to store an error.
579  *
580  * Get the status of the operation to set attributes on a PKCS\#11 object,
581  * begun with gck_object_set_async().
582  *
583  * Return value: Whether the attributes were successfully set on the object or not.
584  */
585 gboolean
gck_object_set_finish(GckObject * self,GAsyncResult * result,GError ** error)586 gck_object_set_finish (GckObject *self, GAsyncResult *result, GError **error)
587 {
588 	SetAttributes *args;
589 
590 	g_return_val_if_fail (GCK_IS_OBJECT (self), FALSE);
591 	g_return_val_if_fail (G_IS_TASK (result), FALSE);
592 	g_return_val_if_fail (!error || !*error, FALSE);
593 
594 	/* Unlock the attributes we were using */
595 	args = _gck_call_async_result_arguments (result, SetAttributes);
596 	g_assert (args->attrs);
597 
598 	return _gck_call_basic_finish (result, error);
599 }
600 
601 /* ------------------------------------------------------------------------------------
602  * GET ATTRIBUTES
603  */
604 
605 typedef struct _GetAttributes {
606 	GckArguments base;
607 	CK_OBJECT_HANDLE object;
608 	GckBuilder builder;
609 } GetAttributes;
610 
611 static CK_RV
perform_get_attributes(GetAttributes * args)612 perform_get_attributes (GetAttributes *args)
613 {
614 	CK_ATTRIBUTE_PTR attrs;
615 	CK_ULONG n_attrs;
616 	CK_RV rv;
617 
618 	g_assert (args != NULL);
619 
620 	/* Prepare all the attributes */
621 	attrs = _gck_builder_prepare_in (&args->builder, &n_attrs);
622 
623 	/* Get the size of each value */
624 	rv = (args->base.pkcs11->C_GetAttributeValue) (args->base.handle, args->object,
625 	                                               attrs, n_attrs);
626 	if (!GCK_IS_GET_ATTRIBUTE_RV_OK (rv))
627 		return rv;
628 
629 	/* Allocate memory for each value */
630 	attrs = _gck_builder_commit_in (&args->builder, &n_attrs);
631 
632 	/* Now get the actual values */
633 	rv = (args->base.pkcs11->C_GetAttributeValue) (args->base.handle, args->object,
634 	                                               attrs, n_attrs);
635 
636 	if (GCK_IS_GET_ATTRIBUTE_RV_OK (rv))
637 		rv = CKR_OK;
638 
639 	return rv;
640 }
641 
642 static void
free_get_attributes(GetAttributes * args)643 free_get_attributes (GetAttributes *args)
644 {
645 	g_assert (args != NULL);
646 	gck_builder_clear (&args->builder);
647 	g_free (args);
648 }
649 
650 
651 /**
652  * gck_object_get:
653  * @self: The object to get attributes from.
654  * @cancellable: A #GCancellable or %NULL
655  * @error: A location to store an error.
656  * @...: The attribute types to get.
657  *
658  * Get the specified attributes from the object. This call may
659  * block for an indefinite period.
660  *
661  * Returns: (transfer full): the resulting PKCS\#11 attributes, or %NULL if an
662  *          error occurred; the result must be unreffed when you're finished
663  *          with it
664  **/
665 GckAttributes *
gck_object_get(GckObject * self,GCancellable * cancellable,GError ** error,...)666 gck_object_get (GckObject *self, GCancellable *cancellable, GError **error, ...)
667 {
668 	GckAttributes *attrs;
669 	GArray *array;
670 	va_list va;
671 	gulong type;
672 
673 	g_return_val_if_fail (GCK_IS_OBJECT (self), NULL);
674 	g_return_val_if_fail (!error || !*error, NULL);
675 
676 	array = g_array_new (FALSE, TRUE, sizeof (gulong));
677 	va_start (va, error);
678 	for (;;) {
679 		type = va_arg (va, gulong);
680 		if (type == GCK_INVALID)
681 			break;
682 		g_array_append_val (array, type);
683 	}
684 	va_end (va);
685 
686 	attrs = gck_object_get_full (self, (gulong*)array->data, array->len, cancellable, error);
687 	g_array_free (array, TRUE);
688 
689 	return attrs;
690 }
691 
692 /**
693  * gck_object_get_full:
694  * @self: The object to get attributes from.
695  * @attr_types: (array length=n_attr_types): the types of the attributes to get
696  * @n_attr_types: the number of attr_types
697  * @cancellable: optional cancellation object, or %NULL
698  * @error: A location to store an error.
699  *
700  * Get the specified attributes from the object. This call may
701  * block for an indefinite period.
702  *
703  * No extra references are added to the returned attributes pointer.
704  * During this call you may not access the attributes in any way.
705  *
706  * Returns: (transfer full): a pointer to the filled in attributes if successful,
707  *          or %NULL if not
708  **/
709 GckAttributes *
gck_object_get_full(GckObject * self,const gulong * attr_types,guint n_attr_types,GCancellable * cancellable,GError ** error)710 gck_object_get_full (GckObject *self,
711                      const gulong *attr_types,
712                      guint n_attr_types,
713                      GCancellable *cancellable,
714                      GError **error)
715 {
716 	GetAttributes args;
717 	gboolean ret;
718 	guint i;
719 
720 	g_return_val_if_fail (GCK_IS_OBJECT (self), NULL);
721 	g_return_val_if_fail (!error || !*error, NULL);
722 
723 	memset (&args, 0, sizeof (args));
724 
725 	gck_builder_init (&args.builder);
726 	for (i = 0; i < n_attr_types; ++i)
727 		gck_builder_add_empty (&args.builder, attr_types[i]);
728 
729 	args.object = self->pv->handle;
730 
731 	ret = _gck_call_sync (self->pv->session, perform_get_attributes, NULL, &args, cancellable, error);
732 
733 	if (ret) {
734 		return gck_attributes_ref_sink (gck_builder_end (&args.builder));
735 	} else {
736 		gck_builder_clear (&args.builder);
737 		return NULL;
738 	}
739 }
740 
741 /**
742  * gck_object_get_async:
743  * @self: The object to get attributes from.
744  * @attr_types: (array length=n_attr_types): the types of the attributes to get
745  * @n_attr_types: the number of attr_types
746  * @cancellable: optional cancellation object, or %NULL
747  * @callback: A callback which is called when the operation completes.
748  * @user_data: Data to be passed to the callback.
749  *
750  * Get the specified attributes from the object. The attributes will be cleared
751  * of their current values, and new attributes will be stored. The attributes
752  * should not be accessed in any way except for referencing and unreferencing
753  * them until gck_object_get_finish() is called.
754  *
755  * This call returns immediately and completes asynchronously.
756  **/
757 void
gck_object_get_async(GckObject * self,const gulong * attr_types,guint n_attr_types,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)758 gck_object_get_async (GckObject *self,
759                       const gulong *attr_types,
760                       guint n_attr_types,
761                       GCancellable *cancellable,
762                       GAsyncReadyCallback callback,
763                       gpointer user_data)
764 {
765 	GckCall *call;
766 	GetAttributes *args;
767 	guint i;
768 
769 	g_return_if_fail (GCK_IS_OBJECT (self));
770 
771 	call = _gck_call_async_prep (self->pv->session, perform_get_attributes,
772 	                             NULL, sizeof (*args), free_get_attributes);
773 
774 	args = _gck_call_get_arguments (call);
775 	gck_builder_init (&args->builder);
776 	for (i = 0; i < n_attr_types; ++i)
777 		gck_builder_add_empty (&args->builder, attr_types[i]);
778 
779 	args->object = self->pv->handle;
780 
781 	_gck_call_async_ready_go (call, self, cancellable, callback, user_data);
782 }
783 
784 /**
785  * gck_object_get_finish:
786  * @self: The object to get attributes from.
787  * @result: The result passed to the callback.
788  * @error: A location to store an error.
789  *
790  * Get the result of a get operation and return specified attributes from
791  * the object.
792  *
793  * No extra references are added to the returned attributes pointer.
794  *
795  * Return value: The filled in attributes structure if successful or
796  * %NULL if not successful.
797  **/
798 GckAttributes*
gck_object_get_finish(GckObject * self,GAsyncResult * result,GError ** error)799 gck_object_get_finish (GckObject *self, GAsyncResult *result, GError **error)
800 {
801 	GetAttributes *args;
802 
803 	g_return_val_if_fail (GCK_IS_OBJECT (self), NULL);
804 	g_return_val_if_fail (G_IS_TASK (result), NULL);
805 	g_return_val_if_fail (!error || !*error, NULL);
806 
807 	args = _gck_call_async_result_arguments (result, GetAttributes);
808 
809 	if (!_gck_call_basic_finish (result, error))
810 		return NULL;
811 
812 	return gck_attributes_ref_sink (gck_builder_end (&args->builder));
813 }
814 
815 /* ---------------------------------------------------------------------------------
816  * GET ATTRIBUTE DATA
817  */
818 
819 typedef struct _GetAttributeData {
820 	GckArguments base;
821 	CK_OBJECT_HANDLE object;
822 	CK_ATTRIBUTE_TYPE type;
823 	GckAllocator allocator;
824 	guchar *result;
825 	gsize n_result;
826 } GetAttributeData;
827 
828 static CK_RV
perform_get_attribute_data(GetAttributeData * args)829 perform_get_attribute_data (GetAttributeData *args)
830 {
831 	CK_ATTRIBUTE attr;
832 	CK_RV rv;
833 
834 	g_assert (args);
835 	g_assert (args->allocator);
836 
837 	attr.type = args->type;
838 	attr.ulValueLen = 0;
839 	attr.pValue = 0;
840 
841 	/* Get the size of the value */
842 	rv = (args->base.pkcs11->C_GetAttributeValue) (args->base.handle, args->object,
843 	                                               &attr, 1);
844 	if (rv != CKR_OK)
845 		return rv;
846 
847 	/* Allocate memory for the value */
848 	args->result = (args->allocator) (NULL, attr.ulValueLen + 1);
849 	g_assert (args->result);
850 	attr.pValue = args->result;
851 
852 	/* Now get the actual value */
853 	rv = (args->base.pkcs11->C_GetAttributeValue) (args->base.handle, args->object,
854 	                                               &attr, 1);
855 
856 	if (rv == CKR_OK) {
857 		args->n_result = attr.ulValueLen;
858 		args->result[args->n_result] = 0;
859 	}
860 
861 	return rv;
862 }
863 
864 static void
free_get_attribute_data(GetAttributeData * args)865 free_get_attribute_data (GetAttributeData *args)
866 {
867 	g_assert (args);
868 	g_free (args->result);
869 	g_free (args);
870 }
871 
872 /**
873  * gck_object_get_data:
874  * @self: The object to get attribute data from.
875  * @attr_type: The attribute to get data for.
876  * @cancellable: A #GCancellable or %NULL
877  * @n_data: The length of the resulting data.
878  * @error: A location to store an error.
879  *
880  * Get the data for the specified attribute from the object. For convenience
881  * the returned data has a null terminator.
882  *
883  * This call may block for an indefinite period.
884  *
885  * Returns: (transfer full) (array length=n_data): the resulting PKCS\#11
886  *          attribute data, or %NULL if an error occurred
887  **/
888 guchar *
gck_object_get_data(GckObject * self,gulong attr_type,GCancellable * cancellable,gsize * n_data,GError ** error)889 gck_object_get_data (GckObject *self,
890                      gulong attr_type,
891                      GCancellable *cancellable,
892                      gsize *n_data,
893                      GError **error)
894 {
895 	g_return_val_if_fail (GCK_IS_OBJECT (self), NULL);
896 	g_return_val_if_fail (n_data, NULL);
897 	g_return_val_if_fail (!error || !*error, NULL);
898 
899 	return gck_object_get_data_full (self, attr_type, g_realloc, cancellable, n_data, error);
900 }
901 
902 /**
903  * gck_object_get_data_full: (skip)
904  * @self: The object to get attribute data from.
905  * @attr_type: The attribute to get data for.
906  * @allocator: An allocator with which to allocate memory for the data, or %NULL for default.
907  * @cancellable: Optional cancellation object, or %NULL.
908  * @n_data: The length of the resulting data.
909  * @error: A location to store an error.
910  *
911  * Get the data for the specified attribute from the object. For convenience
912  * the returned data has an extra null terminator, not included in the returned length.
913  *
914  * This call may block for an indefinite period.
915  *
916  * Returns: (transfer full) (array length=n_data): The resulting PKCS\#11
917  *          attribute data, or %NULL if an error occurred.
918  **/
919 guchar *
gck_object_get_data_full(GckObject * self,gulong attr_type,GckAllocator allocator,GCancellable * cancellable,gsize * n_data,GError ** error)920 gck_object_get_data_full (GckObject *self, gulong attr_type, GckAllocator allocator,
921                            GCancellable *cancellable, gsize *n_data, GError **error)
922 {
923 	GetAttributeData args;
924 	gboolean ret;
925 
926 	g_return_val_if_fail (GCK_IS_OBJECT (self), NULL);
927 	g_return_val_if_fail (n_data, NULL);
928 	g_return_val_if_fail (!error || !*error, NULL);
929 
930 	if (!allocator)
931 		allocator = g_realloc;
932 
933 	memset (&args, 0, sizeof (args));
934 	args.allocator = allocator;
935 	args.object = self->pv->handle;
936 	args.type = attr_type;
937 
938 	ret = _gck_call_sync (self->pv->session, perform_get_attribute_data, NULL, &args, cancellable, error);
939 
940 	/* Free any value if failed */
941 	if (!ret) {
942 		if (args.result)
943 			(allocator) (args.result, 0);
944 		return NULL;
945 	}
946 
947 	*n_data = args.n_result;
948 	return args.result;
949 }
950 
951 /**
952  * gck_object_get_data_async:
953  * @self: The object to get attribute data from.
954  * @attr_type: The attribute to get data for.
955  * @allocator: (skip): An allocator with which to allocate memory for the data, or %NULL for default.
956  * @cancellable: Optional cancellation object, or %NULL.
957  * @callback: Called when the operation completes.
958  * @user_data: Data to be passed to the callback.
959  *
960  * Get the data for the specified attribute from the object.
961  *
962  * This call will return immediately and complete asynchronously.
963  **/
964 void
gck_object_get_data_async(GckObject * self,gulong attr_type,GckAllocator allocator,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)965 gck_object_get_data_async (GckObject *self, gulong attr_type, GckAllocator allocator,
966                             GCancellable *cancellable, GAsyncReadyCallback callback,
967                             gpointer user_data)
968 {
969 	GckCall *call;
970 	GetAttributeData *args;
971 
972 	g_return_if_fail (GCK_IS_OBJECT (self));
973 
974 	if (!allocator)
975 		allocator = g_realloc;
976 
977 	call = _gck_call_async_prep (self->pv->session, perform_get_attribute_data,
978 	                             NULL, sizeof (*args), free_get_attribute_data);
979 
980 	args = _gck_call_get_arguments (call);
981 	args->allocator = allocator;
982 	args->object = self->pv->handle;
983 	args->type = attr_type;
984 
985 	_gck_call_async_ready_go (call, self, cancellable, callback, user_data);
986 }
987 
988 /**
989  * gck_object_get_data_finish:
990  * @self: The object to get an attribute from.
991  * @result: The result passed to the callback.
992  * @n_data: The length of the resulting data.
993  * @error: A location to store an error.
994  *
995  * Get the result of an operation to get attribute data from
996  * an object. For convenience the returned data has an extra null terminator,
997  * not included in the returned length.
998  *
999  * Returns: (transfer full) (array length=n_data): The PKCS\#11 attribute data
1000  *          or %NULL if an error occurred.
1001  **/
1002 guchar *
gck_object_get_data_finish(GckObject * self,GAsyncResult * result,gsize * n_data,GError ** error)1003 gck_object_get_data_finish (GckObject *self,
1004                             GAsyncResult *result,
1005                             gsize *n_data,
1006                             GError **error)
1007 {
1008 	GetAttributeData *args;
1009 	guchar *data;
1010 
1011 	g_return_val_if_fail (GCK_IS_OBJECT (self), NULL);
1012 	g_return_val_if_fail (G_IS_TASK (result), NULL);
1013 	g_return_val_if_fail (n_data, NULL);
1014 	g_return_val_if_fail (!error || !*error, NULL);
1015 
1016 	if (!_gck_call_basic_finish (result, error))
1017 		return NULL;
1018 
1019 	args = _gck_call_async_result_arguments (result, GetAttributeData);
1020 
1021 	*n_data = args->n_result;
1022 	data = args->result;
1023 	args->result = NULL;
1024 
1025 	return data;
1026 }
1027 
1028 /* ---------------------------------------------------------------------------------------
1029  * SET TEMPLATE
1030  */
1031 
1032 typedef struct _set_template_args {
1033 	GckArguments base;
1034 	CK_OBJECT_HANDLE object;
1035 	CK_ATTRIBUTE_TYPE type;
1036 	GckAttributes *attrs;
1037 } set_template_args;
1038 
1039 static CK_RV
perform_set_template(set_template_args * args)1040 perform_set_template (set_template_args *args)
1041 {
1042 	CK_ATTRIBUTE attr;
1043 	CK_ULONG n_attrs;
1044 
1045 	g_assert (args);
1046 
1047 	attr.type = args->type;
1048 	attr.pValue = _gck_attributes_commit_out (args->attrs, &n_attrs);
1049 	attr.ulValueLen = n_attrs * sizeof (CK_ATTRIBUTE);
1050 
1051 	return (args->base.pkcs11->C_SetAttributeValue) (args->base.handle, args->object, &attr, 1);
1052 }
1053 
1054 static void
free_set_template(set_template_args * args)1055 free_set_template (set_template_args *args)
1056 {
1057 	g_assert (args);
1058 	gck_attributes_unref (args->attrs);
1059 	g_free (args);
1060 }
1061 
1062 /**
1063  * gck_object_set_template:
1064  * @self: The object to set an attribute template on.
1065  * @attr_type: The attribute template type.
1066  * @attrs: The attribute template.
1067  * @cancellable: Optional cancellation object, or %NULL.
1068  * @error: A location to store an error.
1069  *
1070  * Set an attribute template on the object. The attr_type must be for
1071  * an attribute which contains a template.
1072  *
1073  * If the @attrs #GckAttributes is floating, it is consumed.
1074  *
1075  * This call may block for an indefinite period.
1076  *
1077  * Return value: %TRUE if the operation succeeded.
1078  **/
1079 gboolean
gck_object_set_template(GckObject * self,gulong attr_type,GckAttributes * attrs,GCancellable * cancellable,GError ** error)1080 gck_object_set_template (GckObject *self, gulong attr_type, GckAttributes *attrs,
1081                          GCancellable *cancellable, GError **error)
1082 {
1083 	set_template_args args;
1084 	gboolean ret = FALSE;
1085 
1086 	g_return_val_if_fail (GCK_IS_OBJECT (self), FALSE);
1087 	g_return_val_if_fail (attrs, FALSE);
1088 	g_return_val_if_fail (!error || !*error, FALSE);
1089 
1090 	memset (&args, 0, sizeof (args));
1091 	args.attrs = attrs;
1092 	args.type = attr_type;
1093 	args.object = self->pv->handle;
1094 
1095 	gck_attributes_ref_sink (attrs);
1096 
1097 	ret = _gck_call_sync (self->pv->session, perform_set_template, NULL, &args, cancellable, error);
1098 
1099 	gck_attributes_unref (attrs);
1100 
1101 	return ret;
1102 }
1103 
1104 /**
1105  * gck_object_set_template_async:
1106  * @self: The object to set an attribute template on.
1107  * @attr_type: The attribute template type.
1108  * @attrs: The attribute template.
1109  * @cancellable: Optional cancellation object, or %NULL.
1110  * @callback: Called when the operation completes.
1111  * @user_data: Data to be passed to the callback.
1112  *
1113  * Set an attribute template on the object. The attr_type must be for
1114  * an attribute which contains a template.
1115  *
1116  * If the @attrs #GckAttributes is floating, it is consumed.
1117  *
1118  * This call will return immediately and complete asynchronously.
1119  **/
1120 void
gck_object_set_template_async(GckObject * self,gulong attr_type,GckAttributes * attrs,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1121 gck_object_set_template_async (GckObject *self, gulong attr_type, GckAttributes *attrs,
1122                                 GCancellable *cancellable, GAsyncReadyCallback callback,
1123                                 gpointer user_data)
1124 {
1125 	GckCall *call;
1126 	set_template_args *args;
1127 
1128 	g_return_if_fail (GCK_IS_OBJECT (self));
1129 	g_return_if_fail (attrs);
1130 
1131 	call = _gck_call_async_prep (self->pv->session, perform_set_template,
1132 	                             NULL, sizeof (*args), free_set_template);
1133 
1134 	args = _gck_call_get_arguments (call);
1135 	args->attrs = gck_attributes_ref_sink (attrs);
1136 	args->type = attr_type;
1137 	args->object = self->pv->handle;
1138 
1139 	_gck_call_async_ready_go (call, self, cancellable, callback, user_data);
1140 }
1141 
1142 /**
1143  * gck_object_set_template_finish:
1144  * @self: The object to set an attribute template on.
1145  * @result: The result passed to the callback.
1146  * @error: A location to store an error.
1147  *
1148  * Get the result of an operation to set attribute template on
1149  * an object.
1150  *
1151  * Return value: %TRUE if the operation succeeded.
1152  **/
1153 gboolean
gck_object_set_template_finish(GckObject * self,GAsyncResult * result,GError ** error)1154 gck_object_set_template_finish (GckObject *self, GAsyncResult *result, GError **error)
1155 {
1156 	set_template_args *args;
1157 
1158 	g_return_val_if_fail (GCK_IS_OBJECT (self), FALSE);
1159 	g_return_val_if_fail (G_IS_TASK (result), FALSE);
1160 	g_return_val_if_fail (!error || !*error, FALSE);
1161 
1162 	/* Unlock the attributes we were using */
1163 	args = _gck_call_async_result_arguments (result, set_template_args);
1164 	g_assert (args->attrs);
1165 
1166 	return _gck_call_basic_finish (result, error);
1167 }
1168 
1169 /* ---------------------------------------------------------------------------------------
1170  * GET TEMPLATE
1171  */
1172 
1173 typedef struct _get_template_args {
1174 	GckArguments base;
1175 	CK_OBJECT_HANDLE object;
1176 	CK_ATTRIBUTE_TYPE type;
1177 	GckBuilder builder;
1178 } get_template_args;
1179 
1180 static CK_RV
perform_get_template(get_template_args * args)1181 perform_get_template (get_template_args *args)
1182 {
1183 	CK_ATTRIBUTE attr;
1184 	CK_ULONG n_attrs, i;
1185 	CK_RV rv;
1186 
1187 	g_assert (args);
1188 
1189 	gck_builder_init (&args->builder);
1190 	attr.type = args->type;
1191 	attr.ulValueLen = 0;
1192 	attr.pValue = 0;
1193 
1194 	/* Get the length of the entire template */
1195 	rv = (args->base.pkcs11->C_GetAttributeValue) (args->base.handle, args->object, &attr, 1);
1196 	if (rv != CKR_OK)
1197 		return rv;
1198 
1199 	/* Number of attributes, rounded down */
1200 	n_attrs = (attr.ulValueLen / sizeof (CK_ATTRIBUTE));
1201 	for (i = 0; i < n_attrs; ++i)
1202 		gck_builder_add_empty (&args->builder, 0);
1203 
1204 	/* Prepare all the attributes */
1205 	attr.pValue = _gck_builder_prepare_in (&args->builder, &n_attrs);
1206 
1207 	/* Get the size of each value */
1208 	rv = (args->base.pkcs11->C_GetAttributeValue) (args->base.handle, args->object, &attr, 1);
1209 	if (rv != CKR_OK)
1210 		return rv;
1211 
1212 	/* Allocate memory for each value */
1213 	attr.pValue = _gck_builder_commit_in (&args->builder, &n_attrs);
1214 
1215 	/* Now get the actual values */
1216 	return (args->base.pkcs11->C_GetAttributeValue) (args->base.handle, args->object, &attr, 1);
1217 }
1218 
1219 static void
free_get_template(get_template_args * args)1220 free_get_template (get_template_args *args)
1221 {
1222 	g_assert (args != NULL);
1223 	gck_builder_clear (&args->builder);
1224 	g_free (args);
1225 }
1226 
1227 /**
1228  * gck_object_get_template:
1229  * @self: The object to get an attribute template from.
1230  * @attr_type: The template attribute type.
1231  * @cancellable: Optional cancellation object, or %NULL.
1232  * @error: A location to store an error.
1233  *
1234  * Get an attribute template from the object. The attr_type must be for
1235  * an attribute which returns a template.
1236  *
1237  * This call may block for an indefinite period.
1238  *
1239  * Returns: (transfer full): the resulting PKCS\#11 attribute template, or %NULL
1240  *          if an error occurred
1241  **/
1242 GckAttributes *
gck_object_get_template(GckObject * self,gulong attr_type,GCancellable * cancellable,GError ** error)1243 gck_object_get_template (GckObject *self, gulong attr_type,
1244                          GCancellable *cancellable, GError **error)
1245 {
1246 	get_template_args args;
1247 	gboolean ret;
1248 
1249 	g_return_val_if_fail (GCK_IS_OBJECT (self), NULL);
1250 	g_return_val_if_fail (!error || !*error, NULL);
1251 
1252 	memset (&args, 0, sizeof (args));
1253 	args.object = self->pv->handle;
1254 	args.type = attr_type;
1255 
1256 	ret = _gck_call_sync (self->pv->session, perform_get_template, NULL, &args, cancellable, error);
1257 
1258 	/* Free any value if failed */
1259 	if (!ret) {
1260 		gck_builder_clear (&args.builder);
1261 		return NULL;
1262 	}
1263 
1264 	return gck_attributes_ref_sink (gck_builder_end (&args.builder));
1265 }
1266 
1267 /**
1268  * gck_object_get_template_async:
1269  * @self: The object to get an attribute template from.
1270  * @attr_type: The template attribute type.
1271  * @cancellable: Optional cancellation object, or %NULL.
1272  * @callback: Called when the operation completes.
1273  * @user_data: Data to be passed to the callback.
1274  *
1275  * Get an attribute template from the object. The attr_type must be for
1276  * an attribute which returns a template.
1277  *
1278  * This call will return immediately and complete asynchronously.
1279  **/
1280 void
gck_object_get_template_async(GckObject * self,gulong attr_type,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)1281 gck_object_get_template_async (GckObject *self, gulong attr_type,
1282                                 GCancellable *cancellable, GAsyncReadyCallback callback,
1283                                 gpointer user_data)
1284 {
1285 	GckCall *call;
1286 	get_template_args *args;
1287 
1288 	g_return_if_fail (GCK_IS_OBJECT (self));
1289 
1290 	call = _gck_call_async_prep (self->pv->session, perform_get_template,
1291 	                             NULL, sizeof (*args), free_get_template);
1292 
1293 	args = _gck_call_get_arguments (call);
1294 	args->object = self->pv->handle;
1295 	args->type = attr_type;
1296 
1297 	_gck_call_async_ready_go (call, self, cancellable, callback, user_data);
1298 }
1299 
1300 /**
1301  * gck_object_get_template_finish:
1302  * @self: The object to get an attribute from.
1303  * @result: The result passed to the callback.
1304  * @error: A location to store an error.
1305  *
1306  * Get the result of an operation to get attribute template from
1307  * an object.
1308  *
1309  * Returns: (transfer full): the resulting PKCS\#11 attribute template, or %NULL
1310  *          if an error occurred
1311  **/
1312 GckAttributes *
gck_object_get_template_finish(GckObject * self,GAsyncResult * result,GError ** error)1313 gck_object_get_template_finish (GckObject *self, GAsyncResult *result,
1314                                 GError **error)
1315 {
1316 	get_template_args *args;
1317 
1318 	g_return_val_if_fail (GCK_IS_OBJECT (self), NULL);
1319 	g_return_val_if_fail (G_IS_TASK (result), NULL);
1320 	g_return_val_if_fail (!error || !*error, NULL);
1321 
1322 	if (!_gck_call_basic_finish (result, error))
1323 		return NULL;
1324 
1325 	args = _gck_call_async_result_arguments (result, get_template_args);
1326 	return gck_attributes_ref_sink (gck_builder_end (&args->builder));
1327 }
1328