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