1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2 /* gck-module.c - the GObject PKCS#11 wrapper library
4 Copyright (C) 2008, Stefan Walter
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.
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.
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 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
21 Author: Stef Walter <nielsen@memberwebs.com>
27 #include "gck-private.h"
28 #include "gck-marshal.h"
30 #include <glib/gi18n-lib.h>
32 #include <p11-kit/p11-kit.h>
39 * @short_description: A loaded and initialized PKCS\#11 module.
41 * A GckModule object holds a loaded PKCS\#11 module. A PKCS\#11 module is a shared library.
43 * You can load and initialize a PKCS\#11 module with the gck_module_initialize() call. If you already
44 * have a loaded and initialized module that you'd like to use with the various gck functions, then
45 * you can use gck_module_new().
51 * Holds a loaded and initialized PKCS\#11 module.
56 * @pkcs11_version_major: The major version of the module.
57 * @pkcs11_version_minor: The minor version of the module.
58 * @manufacturer_id: The module manufacturer.
59 * @flags: The module PKCS#11 flags.
60 * @library_description: The module description.
61 * @library_version_major: The major version of the library.
62 * @library_version_minor: The minor version of the library.
64 * Holds information about the PKCS#11 module.
66 * This structure corresponds to CK_MODULE_INFO in the PKCS\#11 standard. The
67 * strings are NULL terminated for easier use.
69 * Use gck_module_info_free() to release this structure when done with it.
75 * The only thing that can change after object initialization in
76 * a GckModule is the finalized flag, which can be set
92 struct _GckModulePrivate {
96 CK_FUNCTION_LIST_PTR funcs;
97 CK_C_INITIALIZE_ARGS init_args;
99 /* Modified atomically */
103 G_DEFINE_TYPE (GckModule, gck_module, G_TYPE_OBJECT);
105 static guint signals[LAST_SIGNAL] = { 0 };
107 /* ----------------------------------------------------------------------------
112 gck_module_real_authenticate_slot (GckModule *module, GckSlot *self, gchar *label, gchar **password)
118 gck_module_real_authenticate_object (GckModule *module, GckObject *object, gchar *label, gchar **password)
124 gck_module_init (GckModule *self)
126 self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCK_TYPE_MODULE, GckModulePrivate);
130 gck_module_get_property (GObject *obj, guint prop_id, GValue *value,
133 GckModule *self = GCK_MODULE (obj);
137 g_value_set_string (value, gck_module_get_path (self));
140 g_value_set_pointer (value, gck_module_get_functions (self));
146 gck_module_set_property (GObject *obj, guint prop_id, const GValue *value,
149 GckModule *self = GCK_MODULE (obj);
151 /* Only allowed during initialization */
154 g_return_if_fail (!self->pv->path);
155 self->pv->path = g_value_dup_string (value);
158 g_return_if_fail (!self->pv->funcs);
159 self->pv->funcs = g_value_get_pointer (value);
165 gck_module_dispose (GObject *obj)
167 GckModule *self = GCK_MODULE (obj);
168 gboolean finalize = FALSE;
171 if (self->pv->initialized && self->pv->funcs) {
172 if (g_atomic_int_compare_and_exchange (&self->pv->finalized, 0, 1))
176 /* Must be careful when accessing funcs */
178 rv = p11_kit_finalize_module (self->pv->funcs);
180 g_warning ("C_Finalize on module '%s' failed: %s",
181 self->pv->path, gck_message_from_rv (rv));
185 G_OBJECT_CLASS (gck_module_parent_class)->dispose (obj);
189 gck_module_finalize (GObject *obj)
191 GckModule *self = GCK_MODULE (obj);
193 self->pv->funcs = NULL;
195 if (self->pv->module) {
196 if (!g_module_close (self->pv->module))
197 g_warning ("failed to close the pkcs11 module: %s",
199 self->pv->module = NULL;
202 g_free (self->pv->path);
203 self->pv->path = NULL;
205 G_OBJECT_CLASS (gck_module_parent_class)->finalize (obj);
210 gck_module_class_init (GckModuleClass *klass)
212 GObjectClass *gobject_class = (GObjectClass*)klass;
213 gck_module_parent_class = g_type_class_peek_parent (klass);
215 gobject_class->get_property = gck_module_get_property;
216 gobject_class->set_property = gck_module_set_property;
217 gobject_class->dispose = gck_module_dispose;
218 gobject_class->finalize = gck_module_finalize;
220 klass->authenticate_object = gck_module_real_authenticate_object;
221 klass->authenticate_slot = gck_module_real_authenticate_slot;
226 * The PKCS#11 module file path.
228 * This may be set to NULL if this object was created from an already
229 * initialized module via the gck_module_new() function.
231 g_object_class_install_property (gobject_class, PROP_PATH,
232 g_param_spec_string ("path", "Module Path", "Path to the PKCS11 Module",
233 NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
236 * GckModule:functions:
238 * The raw PKCS#11 function list for the module.
240 * This points to a CK_FUNCTION_LIST structure.
242 g_object_class_install_property (gobject_class, PROP_FUNCTIONS,
243 g_param_spec_pointer ("functions", "Function List", "PKCS11 Function List",
244 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
247 * GckModule::authenticate-slot:
248 * @module: The module
249 * @slot: The slot to be authenticated.
250 * @string: A displayable label which describes the object.
251 * @password: A gchar** where a password should be returned.
253 * Use gck_session_set_interaction() instead of connecting to this signal.
255 * Deprecated: Since 3.4
257 signals[AUTHENTICATE_SLOT] = g_signal_new ("authenticate-slot", GCK_TYPE_MODULE,
258 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GckModuleClass, authenticate_slot),
259 g_signal_accumulator_true_handled, NULL, _gck_marshal_BOOLEAN__OBJECT_STRING_POINTER,
260 G_TYPE_BOOLEAN, 3, GCK_TYPE_SLOT, G_TYPE_STRING, G_TYPE_POINTER);
263 * GckModule::authenticate-object:
264 * @module: The module.
265 * @object: The object to be authenticated.
266 * @label: A displayable label which describes the object.
267 * @password: A gchar** where a password should be returned.
269 * Use gck_session_set_interaction() instead of connecting to this signal.
271 * Deprecated: Since 3.4
273 signals[AUTHENTICATE_OBJECT] = g_signal_new ("authenticate-object", GCK_TYPE_MODULE,
274 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GckModuleClass, authenticate_object),
275 g_signal_accumulator_true_handled, NULL, _gck_marshal_BOOLEAN__OBJECT_STRING_POINTER,
276 G_TYPE_BOOLEAN, 3, GCK_TYPE_OBJECT, G_TYPE_STRING, G_TYPE_POINTER);
278 g_type_class_add_private (gobject_class, sizeof (GckModulePrivate));
282 gck_module_info_get_type (void)
284 static volatile gsize initialized = 0;
285 static GType type = 0;
286 if (g_once_init_enter (&initialized)) {
287 type = g_boxed_type_register_static ("GckModuleInfo",
288 (GBoxedCopyFunc)gck_module_info_copy,
289 (GBoxedFreeFunc)gck_module_info_free);
290 g_once_init_leave (&initialized, 1);
296 * gck_module_info_copy:
297 * @module_info: a module info
299 * Make a copy of the module info.
301 * Returns: (transfer full): a newly allocated copy module info
304 gck_module_info_copy (GckModuleInfo *module_info)
306 if (module_info == NULL)
309 module_info = g_memdup (module_info, sizeof (GckModuleInfo));
310 module_info->manufacturer_id = g_strdup (module_info->manufacturer_id);
311 module_info->library_description = g_strdup (module_info->library_description);
317 * gck_module_info_free:
318 * @module_info: The module info to free, or NULL.
320 * Free a GckModuleInfo structure.
323 gck_module_info_free (GckModuleInfo *module_info)
327 g_free (module_info->library_description);
328 g_free (module_info->manufacturer_id);
329 g_free (module_info);
340 perform_initialize (Initialize *args)
342 CK_C_GetFunctionList get_function_list;
343 CK_FUNCTION_LIST_PTR funcs;
348 /* Load the actual module */
349 module = g_module_open (args->path, 0);
351 g_set_error (&args->error, GCK_ERROR, (int)CKR_GCK_MODULE_PROBLEM,
352 _("Error loading PKCS#11 module: %s"), g_module_error ());
353 return CKR_GCK_MODULE_PROBLEM;
356 /* Get the entry point */
357 if (!g_module_symbol (module, "C_GetFunctionList", (void**)&get_function_list)) {
358 g_set_error (&args->error, GCK_ERROR, (int)CKR_GCK_MODULE_PROBLEM,
359 _("Invalid PKCS#11 module: %s"), g_module_error ());
360 g_module_close (module);
361 return CKR_GCK_MODULE_PROBLEM;
364 /* Get the function list */
365 rv = (get_function_list) (&funcs);
367 g_set_error (&args->error, GCK_ERROR, rv,
368 _("Couldn't setup PKCS#11 module: %s"),
369 gck_message_from_rv (rv));
370 g_module_close (module);
374 result = g_object_new (GCK_TYPE_MODULE,
378 result->pv->module = module;
380 /* Now initialize the module */
381 rv = p11_kit_initialize_module (funcs);
383 g_set_error (&args->error, GCK_ERROR, rv,
384 _("Couldn't initialize PKCS#11 module: %s"),
385 gck_message_from_rv (rv));
386 g_object_unref (result);
390 result->pv->initialized = TRUE;
391 args->result = result;
396 free_initialize (Initialize *args)
399 g_clear_error (&args->error);
400 g_clear_object (&args->result);
405 * gck_module_initialize:
406 * @path: The file system path to the PKCS\#11 module to load.
407 * @cancellable: (allow-none): optional cancellation object
408 * @error: A location to store an error resulting from a failed load.
410 * Load and initialize a PKCS\#11 module represented by a GckModule object.
412 * Return value: (transfer full): The loaded PKCS\#11 module or %NULL if failed.
415 gck_module_initialize (const gchar *path,
416 GCancellable *cancellable,
419 Initialize args = { GCK_ARGUMENTS_INIT, 0, };
421 g_return_val_if_fail (path != NULL, NULL);
422 g_return_val_if_fail (!error || !*error, NULL);
424 args.path = g_strdup (path);
426 if (!_gck_call_sync (NULL, perform_initialize, NULL, &args, cancellable, error)) {
428 /* A custom error from perform_initialize */
430 g_clear_error (error);
431 g_propagate_error (error, args.error);
437 g_clear_error (&args.error);
442 * gck_module_initialize_async:
443 * @path: the file system path to the PKCS\#11 module to load
444 * @cancellable: (allow-none): optional cancellation object
445 * @callback: a callback which will be called when the operation completes
446 * @user_data: data to pass to the callback
448 * Asynchronously load and initialize a PKCS\#11 module represented by a
452 gck_module_initialize_async (const gchar *path,
453 GCancellable *cancellable,
454 GAsyncReadyCallback callback,
459 g_return_if_fail (path != NULL);
461 args = _gck_call_async_prep (NULL, NULL, perform_initialize, NULL,
462 sizeof (*args), free_initialize);
463 args->path = g_strdup (path);
465 _gck_call_async_ready_go (args, cancellable, callback, user_data);
469 * gck_module_initialize_finish:
470 * @result: the asynchronous result
471 * @error: location to place an error on failure
473 * Finishes the asynchronous initialize operation.
475 * Returns: (transfer full) (allow-none): The initialized module, or NULL
478 gck_module_initialize_finish (GAsyncResult *result,
481 GckModule *module = NULL;
484 args = _gck_call_arguments (result, Initialize);
485 if (_gck_call_basic_finish (result, error)) {
486 module = args->result;
490 /* A custom error from perform_initialize */
492 g_clear_error (error);
493 g_propagate_error (error, args->error);
502 * gck_module_new: (skip)
503 * @funcs: Initialized PKCS\#11 function list pointer
505 * Create a GckModule representing a PKCS\#11 module. It is assumed that
506 * this the module is already initialized. In addition it will not be
507 * finalized when complete.
509 * Return value: The new PKCS\#11 module.
512 gck_module_new (CK_FUNCTION_LIST_PTR funcs)
514 g_return_val_if_fail (funcs != NULL, NULL);
515 return g_object_new (GCK_TYPE_MODULE, "functions", funcs, NULL);
519 _gck_module_new_initialized (CK_FUNCTION_LIST_PTR funcs)
521 GckModule *module = gck_module_new (funcs);
522 module->pv->initialized = TRUE; /* As if we initialized it */
528 * @module1: (type Gck.Module): a pointer to the first #GckModule
529 * @module2: (type Gck.Module): a pointer to the second #GckModule
531 * Checks equality of two modules. Two GckModule objects can point to the same
532 * underlying PKCS\#11 module.
534 * Return value: TRUE if module1 and module2 are equal. FALSE if either is not a GckModule.
537 gck_module_equal (gconstpointer module1, gconstpointer module2)
539 GckModule *mod1, *mod2;
541 if (module1 == module2)
543 if (!GCK_IS_MODULE (module1) || !GCK_IS_MODULE (module2))
546 mod1 = GCK_MODULE (module1);
547 mod2 = GCK_MODULE (module2);
549 return mod1->pv->funcs == mod2->pv->funcs;
554 * @module: (type Gck.Module): a pointer to a #GckModule
556 * Create a hash value for the GckModule.
558 * This function is intended for easily hashing a GckModule to add to
559 * a GHashTable or similar data structure.
561 * Return value: An integer that can be used as a hash value, or 0 if invalid.
564 gck_module_hash (gconstpointer module)
568 g_return_val_if_fail (GCK_IS_MODULE (module), 0);
569 self = GCK_MODULE (module);
570 return g_direct_hash (self->pv->funcs);
574 _gck_module_info_from_pkcs11 (CK_INFO_PTR info)
576 GckModuleInfo *modinfo;
578 modinfo = g_new0 (GckModuleInfo, 1);
579 modinfo->flags = info->flags;
580 modinfo->library_description = gck_string_from_chars (info->libraryDescription,
581 sizeof (info->libraryDescription));
582 modinfo->manufacturer_id = gck_string_from_chars (info->manufacturerID,
583 sizeof (info->manufacturerID));
584 modinfo->library_version_major = info->libraryVersion.major;
585 modinfo->library_version_minor = info->libraryVersion.minor;
586 modinfo->pkcs11_version_major = info->cryptokiVersion.major;
587 modinfo->pkcs11_version_minor = info->cryptokiVersion.minor;
593 _gck_module_info_to_pkcs11 (GckModuleInfo* module_info, CK_INFO_PTR info)
595 info->flags = module_info->flags;
596 if (!gck_string_to_chars (info->libraryDescription,
597 sizeof (info->libraryDescription),
598 module_info->library_description))
599 g_return_if_reached ();
600 if (!gck_string_to_chars (info->manufacturerID,
601 sizeof (info->manufacturerID),
602 module_info->manufacturer_id))
603 g_return_if_reached ();
605 info->libraryVersion.major = module_info->library_version_major;
606 info->libraryVersion.minor = module_info->library_version_minor;
607 info->cryptokiVersion.major = module_info->pkcs11_version_major;
608 info->cryptokiVersion.minor = module_info->pkcs11_version_minor;
612 * gck_module_get_info:
613 * @self: The module to get info for.
615 * Get the info about a PKCS\#11 module.
617 * Returns: (transfer full): the module info; release this with gck_module_info_free()
620 gck_module_get_info (GckModule *self)
625 g_return_val_if_fail (GCK_IS_MODULE (self), NULL);
626 g_return_val_if_fail (self->pv->funcs, NULL);
628 memset (&info, 0, sizeof (info));
629 rv = (self->pv->funcs->C_GetInfo (&info));
631 g_warning ("couldn't get module info: %s", gck_message_from_rv (rv));
635 return _gck_module_info_from_pkcs11 (&info);
639 * gck_module_get_slots:
640 * @self: The module for which to get the slots.
641 * @token_present: Whether to limit only to slots with a token present.
643 * Get the GckSlot objects for a given module.
645 * Return value: (element-type Gck.Slot) (transfer full): The possibly empty
646 * list of slots. Release this with gck_list_unref_free().
649 gck_module_get_slots (GckModule *self, gboolean token_present)
651 CK_SLOT_ID_PTR slot_list;
656 g_return_val_if_fail (GCK_IS_MODULE (self), NULL);
657 g_return_val_if_fail (self->pv->funcs, NULL);
659 rv = (self->pv->funcs->C_GetSlotList) (token_present ? CK_TRUE : CK_FALSE, NULL, &count);
661 g_warning ("couldn't get slot count: %s", gck_message_from_rv (rv));
668 slot_list = g_new (CK_SLOT_ID, count);
669 rv = (self->pv->funcs->C_GetSlotList) (token_present ? CK_TRUE : CK_FALSE, slot_list, &count);
671 g_warning ("couldn't get slot list: %s", gck_message_from_rv (rv));
677 for (i = 0; i < count; ++i) {
678 result = g_list_prepend (result, g_object_new (GCK_TYPE_SLOT,
679 "handle", slot_list[i],
680 "module", self, NULL));
684 return g_list_reverse (result);
688 * gck_module_get_path:
689 * @self: The module for which to get the path.
691 * Get the file path of this module. This may not be an absolute path, and
692 * usually reflects the path passed to gck_module_initialize().
694 * Return value: The path, do not modify or free this value.
697 gck_module_get_path (GckModule *self)
699 g_return_val_if_fail (GCK_IS_MODULE (self), NULL);
700 return self->pv->path;
704 * gck_module_get_functions: (skip)
705 * @self: The module for which to get the function list.
707 * Get the PKCS\#11 function list for the module.
709 * Return value: The function list, do not modify this structure.
712 gck_module_get_functions (GckModule *self)
714 g_return_val_if_fail (GCK_IS_MODULE (self), NULL);
715 return self->pv->funcs;
720 * @self: the module to match
721 * @uri: the uri to match against the module
723 * Check whether the PKCS\#11 URI matches the module
725 * Returns: whether the URI matches or not
728 gck_module_match (GckModule *self,
731 gboolean match = TRUE;
734 g_return_val_if_fail (GCK_IS_MODULE (self), FALSE);
735 g_return_val_if_fail (uri != NULL, FALSE);
737 if (uri->any_unrecognized)
740 if (match && uri->module_info) {
741 info = gck_module_get_info (self);
742 match = _gck_module_info_match (uri->module_info, info);
743 gck_module_info_free (info);