diff options
author | Stef Walter <stefw@collabora.co.uk> | 2011-10-06 12:51:08 +0200 |
---|---|---|
committer | Stef Walter <stefw@collabora.co.uk> | 2011-10-06 13:22:43 +0200 |
commit | f28d3d768f0e4057f727e8c3b93ba50c19f5db24 (patch) | |
tree | 288ef581590dfccbfddcad3c87d98ce3a4ed0a97 /gck/gck-module.c | |
parent | 626eef363c0ece57713c5be5939677784e8115cc (diff) | |
download | gnome-keyring-split.tar.gz |
Split Gcr and Gck libraries out of gnome-keyringsplit
Diffstat (limited to 'gck/gck-module.c')
-rw-r--r-- | gck/gck-module.c | 748 |
1 files changed, 0 insertions, 748 deletions
diff --git a/gck/gck-module.c b/gck/gck-module.c deleted file mode 100644 index cdd9d451..00000000 --- a/gck/gck-module.c +++ /dev/null @@ -1,748 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* gck-module.c - the GObject PKCS#11 wrapper library - - Copyright (C) 2008, Stefan Walter - - The Gnome Keyring Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Keyring Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Author: Stef Walter <nielsen@memberwebs.com> -*/ - -#include "config.h" - -#include "gck.h" -#include "gck-private.h" -#include "gck-marshal.h" - -#include <glib/gi18n.h> - -#include <p11-kit/p11-kit.h> - -#include <string.h> - -/** - * SECTION:gck-module - * @title: GckModule - * @short_description: A loaded and initialized PKCS\#11 module. - * - * A GckModule object holds a loaded PKCS\#11 module. A PKCS\#11 module is a shared library. - * - * You can load and initialize a PKCS\#11 module with the gck_module_initialize() call. If you already - * have a loaded and initialized module that you'd like to use with the various gck functions, then - * you can use gck_module_new(). - */ - -/** - * GckModule: - * @parent: derived from this. - * - * Holds a loaded and initialized PKCS\#11 module. - */ - -/** - * GckModuleInfo: - * @pkcs11_version_major: The major version of the module. - * @pkcs11_version_minor: The minor version of the module. - * @manufacturer_id: The module manufacturer. - * @flags: The module PKCS#11 flags. - * @library_description: The module description. - * @library_version_major: The major version of the library. - * @library_version_minor: The minor version of the library. - * - * Holds information about the PKCS#11 module. - * - * This structure corresponds to CK_MODULE_INFO in the PKCS\#11 standard. The - * strings are NULL terminated for easier use. - * - * Use gck_module_info_free() to release this structure when done with it. - */ - -/* - * MT safe - * - * The only thing that can change after object initialization in - * a GckModule is the finalized flag, which can be set - * to 1 in dispose. - */ - -enum { - PROP_0, - PROP_PATH, - PROP_FUNCTIONS -}; - -enum { - AUTHENTICATE_SLOT, - AUTHENTICATE_OBJECT, - LAST_SIGNAL -}; - -struct _GckModulePrivate { - GModule *module; - gchar *path; - gboolean initialized; - CK_FUNCTION_LIST_PTR funcs; - CK_C_INITIALIZE_ARGS init_args; - - /* Modified atomically */ - gint finalized; -}; - -G_DEFINE_TYPE (GckModule, gck_module, G_TYPE_OBJECT); - -static guint signals[LAST_SIGNAL] = { 0 }; - -/* ---------------------------------------------------------------------------- - * OBJECT - */ - -static gboolean -gck_module_real_authenticate_slot (GckModule *module, GckSlot *self, gchar *label, gchar **password) -{ - return FALSE; -} - -static gboolean -gck_module_real_authenticate_object (GckModule *module, GckObject *object, gchar *label, gchar **password) -{ - return FALSE; -} - -static void -gck_module_init (GckModule *self) -{ - self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCK_TYPE_MODULE, GckModulePrivate); -} - -static void -gck_module_get_property (GObject *obj, guint prop_id, GValue *value, - GParamSpec *pspec) -{ - GckModule *self = GCK_MODULE (obj); - - switch (prop_id) { - case PROP_PATH: - g_value_set_string (value, gck_module_get_path (self)); - break; - case PROP_FUNCTIONS: - g_value_set_pointer (value, gck_module_get_functions (self)); - break; - } -} - -static void -gck_module_set_property (GObject *obj, guint prop_id, const GValue *value, - GParamSpec *pspec) -{ - GckModule *self = GCK_MODULE (obj); - - /* Only allowed during initialization */ - switch (prop_id) { - case PROP_PATH: - g_return_if_fail (!self->pv->path); - self->pv->path = g_value_dup_string (value); - break; - case PROP_FUNCTIONS: - g_return_if_fail (!self->pv->funcs); - self->pv->funcs = g_value_get_pointer (value); - break; - } -} - -static void -gck_module_dispose (GObject *obj) -{ - GckModule *self = GCK_MODULE (obj); - gboolean finalize = FALSE; - CK_RV rv; - - if (self->pv->initialized && self->pv->funcs) { - if (g_atomic_int_compare_and_exchange (&self->pv->finalized, 0, 1)) - finalize = TRUE; - } - - /* Must be careful when accessing funcs */ - if (finalize) { - rv = p11_kit_finalize_module (self->pv->funcs); - if (rv != CKR_OK) { - g_warning ("C_Finalize on module '%s' failed: %s", - self->pv->path, gck_message_from_rv (rv)); - } - } - - G_OBJECT_CLASS (gck_module_parent_class)->dispose (obj); -} - -static void -gck_module_finalize (GObject *obj) -{ - GckModule *self = GCK_MODULE (obj); - - self->pv->funcs = NULL; - - if (self->pv->module) { - if (!g_module_close (self->pv->module)) - g_warning ("failed to close the pkcs11 module: %s", - g_module_error ()); - self->pv->module = NULL; - } - - g_free (self->pv->path); - self->pv->path = NULL; - - G_OBJECT_CLASS (gck_module_parent_class)->finalize (obj); -} - - -static void -gck_module_class_init (GckModuleClass *klass) -{ - GObjectClass *gobject_class = (GObjectClass*)klass; - gck_module_parent_class = g_type_class_peek_parent (klass); - - gobject_class->get_property = gck_module_get_property; - gobject_class->set_property = gck_module_set_property; - gobject_class->dispose = gck_module_dispose; - gobject_class->finalize = gck_module_finalize; - - klass->authenticate_object = gck_module_real_authenticate_object; - klass->authenticate_slot = gck_module_real_authenticate_slot; - - /** - * GckModule:path: - * - * The PKCS#11 module file path. - * - * This may be set to NULL if this object was created from an already - * initialized module via the gck_module_new() function. - */ - g_object_class_install_property (gobject_class, PROP_PATH, - g_param_spec_string ("path", "Module Path", "Path to the PKCS11 Module", - NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - /** - * GckModule:functions: - * - * The raw PKCS#11 function list for the module. - * - * This points to a CK_FUNCTION_LIST structure. - */ - g_object_class_install_property (gobject_class, PROP_FUNCTIONS, - g_param_spec_pointer ("functions", "Function List", "PKCS11 Function List", - G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - /** - * GckModule::authenticate-slot: - * @module: The module - * @slot: The slot to be authenticated. - * @string: A displayable label which describes the object. - * @password: A gchar** where a password should be returned. - * - * Use gck_slot_set_interaction() instead of connecting to this signal. - * - * Deprecated: Since 3.4 - */ - signals[AUTHENTICATE_SLOT] = g_signal_new ("authenticate-slot", GCK_TYPE_MODULE, - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GckModuleClass, authenticate_slot), - g_signal_accumulator_true_handled, NULL, _gck_marshal_BOOLEAN__OBJECT_STRING_POINTER, - G_TYPE_BOOLEAN, 3, GCK_TYPE_SLOT, G_TYPE_STRING, G_TYPE_POINTER); - - /** - * GckModule::authenticate-object: - * @module: The module. - * @object: The object to be authenticated. - * @label: A displayable label which describes the object. - * @password: A gchar** where a password should be returned. - * - * Use gck_slot_set_interaction() instead of connecting to this signal. - * - * Deprecated: Since 3.4 - */ - signals[AUTHENTICATE_OBJECT] = g_signal_new ("authenticate-object", GCK_TYPE_MODULE, - G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GckModuleClass, authenticate_object), - g_signal_accumulator_true_handled, NULL, _gck_marshal_BOOLEAN__OBJECT_STRING_POINTER, - G_TYPE_BOOLEAN, 3, GCK_TYPE_OBJECT, G_TYPE_STRING, G_TYPE_POINTER); - - g_type_class_add_private (gobject_class, sizeof (GckModulePrivate)); -} - -GType -gck_module_info_get_type (void) -{ - static volatile gsize initialized = 0; - static GType type = 0; - if (g_once_init_enter (&initialized)) { - type = g_boxed_type_register_static ("GckModuleInfo", - (GBoxedCopyFunc)gck_module_info_copy, - (GBoxedFreeFunc)gck_module_info_free); - g_once_init_leave (&initialized, 1); - } - return type; -} - -/** - * gck_module_info_copy: - * @module_info: a module info - * - * Make a copy of the module info. - * - * Returns: (transfer full): a newly allocated copy module info - */ -GckModuleInfo * -gck_module_info_copy (GckModuleInfo *module_info) -{ - if (module_info == NULL) - return NULL; - - module_info = g_memdup (module_info, sizeof (GckModuleInfo)); - module_info->manufacturer_id = g_strdup (module_info->manufacturer_id); - module_info->library_description = g_strdup (module_info->library_description); - return module_info; - -} - -/** - * gck_module_info_free: - * @module_info: The module info to free, or NULL. - * - * Free a GckModuleInfo structure. - **/ -void -gck_module_info_free (GckModuleInfo *module_info) -{ - if (!module_info) - return; - g_free (module_info->library_description); - g_free (module_info->manufacturer_id); - g_free (module_info); -} - -typedef struct { - GckArguments base; - gchar *path; - GckModule *result; - GError *error; -} Initialize; - -static CK_RV -perform_initialize (Initialize *args) -{ - CK_C_GetFunctionList get_function_list; - CK_FUNCTION_LIST_PTR funcs; - GModule *module; - GckModule *result; - CK_RV rv; - - /* Load the actual module */ - module = g_module_open (args->path, 0); - if (!module) { - g_set_error (&args->error, GCK_ERROR, (int)CKR_GCK_MODULE_PROBLEM, - _("Error loading PKCS#11 module: %s"), g_module_error ()); - return CKR_GCK_MODULE_PROBLEM; - } - - /* Get the entry point */ - if (!g_module_symbol (module, "C_GetFunctionList", (void**)&get_function_list)) { - g_set_error (&args->error, GCK_ERROR, (int)CKR_GCK_MODULE_PROBLEM, - _("Invalid PKCS#11 module: %s"), g_module_error ()); - g_module_close (module); - return CKR_GCK_MODULE_PROBLEM; - } - - /* Get the function list */ - rv = (get_function_list) (&funcs); - if (rv != CKR_OK) { - g_set_error (&args->error, GCK_ERROR, rv, - _("Couldn't setup PKCS#11 module: %s"), - gck_message_from_rv (rv)); - g_module_close (module); - return rv; - } - - result = g_object_new (GCK_TYPE_MODULE, - "functions", funcs, - "path", args->path, - NULL); - result->pv->module = module; - - /* Now initialize the module */ - rv = p11_kit_initialize_module (funcs); - if (rv != CKR_OK) { - g_set_error (&args->error, GCK_ERROR, rv, - _("Couldn't initialize PKCS#11 module: %s"), - gck_message_from_rv (rv)); - g_object_unref (result); - return rv; - } - - result->pv->initialized = TRUE; - args->result = result; - return CKR_OK; -} - -static void -free_initialize (Initialize *args) -{ - g_free (args->path); - g_clear_error (&args->error); - g_clear_object (&args->result); - g_free (args); -} - -/** - * gck_module_initialize: - * @path: The file system path to the PKCS\#11 module to load. - * @cancellable: (allow-none): optional cancellation object - * @error: A location to store an error resulting from a failed load. - * - * Load and initialize a PKCS\#11 module represented by a GckModule object. - * - * Return value: (transfer full): The loaded PKCS\#11 module or %NULL if failed. - **/ -GckModule* -gck_module_initialize (const gchar *path, - GCancellable *cancellable, - GError **error) -{ - Initialize args = { GCK_ARGUMENTS_INIT, 0, }; - - g_return_val_if_fail (path != NULL, NULL); - g_return_val_if_fail (!error || !*error, NULL); - - args.path = g_strdup (path); - - if (!_gck_call_sync (NULL, perform_initialize, NULL, &args, cancellable, error)) { - - /* A custom error from perform_initialize */ - if (args.error) { - g_clear_error (error); - g_propagate_error (error, args.error); - args.error = NULL; - } - } - - g_free (args.path); - g_clear_error (&args.error); - return args.result; -} - -/** - * gck_module_initialize_async: - * @path: the file system path to the PKCS\#11 module to load - * @cancellable: (allow-none): optional cancellation object - * @callback: a callback which will be called when the operation completes - * @user_data: data to pass to the callback - * - * Asynchronously load and initialize a PKCS\#11 module represented by a - * #GckModule object. - **/ -void -gck_module_initialize_async (const gchar *path, - GCancellable *cancellable, - GAsyncReadyCallback callback, - gpointer user_data) -{ - Initialize *args; - - g_return_if_fail (path != NULL); - - args = _gck_call_async_prep (NULL, NULL, perform_initialize, NULL, - sizeof (*args), free_initialize); - args->path = g_strdup (path); - - _gck_call_async_ready_go (args, cancellable, callback, user_data); -} - -/** - * gck_module_initialize_finish: - * @result: the asynchronous result - * @error: location to place an error on failure - * - * Finishes the asynchronous initialize operation. - * - * Returns: (transfer full) (allow-none): The initialized module, or NULL - */ -GckModule * -gck_module_initialize_finish (GAsyncResult *result, - GError **error) -{ - GckModule *module = NULL; - Initialize *args; - - args = _gck_call_arguments (result, Initialize); - if (_gck_call_basic_finish (result, error)) { - module = args->result; - args->result = NULL; - - } else { - /* A custom error from perform_initialize */ - if (args->error) { - g_clear_error (error); - g_propagate_error (error, args->error); - args->error = NULL; - } - } - - return module; -} - -/** - * gck_module_new: (skip) - * @funcs: Initialized PKCS\#11 function list pointer - * - * Create a GckModule representing a PKCS\#11 module. It is assumed that - * this the module is already initialized. In addition it will not be - * finalized when complete. - * - * Return value: The new PKCS\#11 module. - **/ -GckModule* -gck_module_new (CK_FUNCTION_LIST_PTR funcs) -{ - g_return_val_if_fail (funcs != NULL, NULL); - return g_object_new (GCK_TYPE_MODULE, "functions", funcs, NULL); -} - -GckModule* -_gck_module_new_initialized (CK_FUNCTION_LIST_PTR funcs) -{ - GckModule *module = gck_module_new (funcs); - module->pv->initialized = TRUE; /* As if we initialized it */ - return module; -} - -/** - * gck_module_equal: - * @module1: (type Gck.Module): a pointer to the first #GckModule - * @module2: (type Gck.Module): a pointer to the second #GckModule - * - * Checks equality of two modules. Two GckModule objects can point to the same - * underlying PKCS\#11 module. - * - * Return value: TRUE if module1 and module2 are equal. FALSE if either is not a GckModule. - **/ -gboolean -gck_module_equal (gconstpointer module1, gconstpointer module2) -{ - GckModule *mod1, *mod2; - - if (module1 == module2) - return TRUE; - if (!GCK_IS_MODULE (module1) || !GCK_IS_MODULE (module2)) - return FALSE; - - mod1 = GCK_MODULE (module1); - mod2 = GCK_MODULE (module2); - - return mod1->pv->funcs == mod2->pv->funcs; -} - -/** - * gck_module_hash: - * @module: (type Gck.Module): a pointer to a #GckModule - * - * Create a hash value for the GckModule. - * - * This function is intended for easily hashing a GckModule to add to - * a GHashTable or similar data structure. - * - * Return value: An integer that can be used as a hash value, or 0 if invalid. - **/ -guint -gck_module_hash (gconstpointer module) -{ - GckModule *self; - - g_return_val_if_fail (GCK_IS_MODULE (module), 0); - self = GCK_MODULE (module); - return g_direct_hash (self->pv->funcs); -} - -GckModuleInfo* -_gck_module_info_from_pkcs11 (CK_INFO_PTR info) -{ - GckModuleInfo *modinfo; - - modinfo = g_new0 (GckModuleInfo, 1); - modinfo->flags = info->flags; - modinfo->library_description = gck_string_from_chars (info->libraryDescription, - sizeof (info->libraryDescription)); - modinfo->manufacturer_id = gck_string_from_chars (info->manufacturerID, - sizeof (info->manufacturerID)); - modinfo->library_version_major = info->libraryVersion.major; - modinfo->library_version_minor = info->libraryVersion.minor; - modinfo->pkcs11_version_major = info->cryptokiVersion.major; - modinfo->pkcs11_version_minor = info->cryptokiVersion.minor; - - return modinfo; -} - -void -_gck_module_info_to_pkcs11 (GckModuleInfo* module_info, CK_INFO_PTR info) -{ - info->flags = module_info->flags; - if (!gck_string_to_chars (info->libraryDescription, - sizeof (info->libraryDescription), - module_info->library_description)) - g_return_if_reached (); - if (!gck_string_to_chars (info->manufacturerID, - sizeof (info->manufacturerID), - module_info->manufacturer_id)) - g_return_if_reached (); - - info->libraryVersion.major = module_info->library_version_major; - info->libraryVersion.minor = module_info->library_version_minor; - info->cryptokiVersion.major = module_info->pkcs11_version_major; - info->cryptokiVersion.minor = module_info->pkcs11_version_minor; -} - -/** - * gck_module_get_info: - * @self: The module to get info for. - * - * Get the info about a PKCS\#11 module. - * - * Returns: (transfer full): the module info; release this with gck_module_info_free() - **/ -GckModuleInfo* -gck_module_get_info (GckModule *self) -{ - CK_INFO info; - CK_RV rv; - - g_return_val_if_fail (GCK_IS_MODULE (self), NULL); - g_return_val_if_fail (self->pv->funcs, NULL); - - memset (&info, 0, sizeof (info)); - rv = (self->pv->funcs->C_GetInfo (&info)); - if (rv != CKR_OK) { - g_warning ("couldn't get module info: %s", gck_message_from_rv (rv)); - return NULL; - } - - return _gck_module_info_from_pkcs11 (&info); -} - -/** - * gck_module_get_slots: - * @self: The module for which to get the slots. - * @token_present: Whether to limit only to slots with a token present. - * - * Get the GckSlot objects for a given module. - * - * Return value: (element-type Gck.Slot) (transfer full): The possibly empty - * list of slots. Release this with gck_list_unref_free(). - */ -GList* -gck_module_get_slots (GckModule *self, gboolean token_present) -{ - CK_SLOT_ID_PTR slot_list; - CK_ULONG count, i; - GList *result; - CK_RV rv; - - g_return_val_if_fail (GCK_IS_MODULE (self), NULL); - g_return_val_if_fail (self->pv->funcs, NULL); - - rv = (self->pv->funcs->C_GetSlotList) (token_present ? CK_TRUE : CK_FALSE, NULL, &count); - if (rv != CKR_OK) { - g_warning ("couldn't get slot count: %s", gck_message_from_rv (rv)); - return NULL; - } - - if (!count) - return NULL; - - slot_list = g_new (CK_SLOT_ID, count); - rv = (self->pv->funcs->C_GetSlotList) (token_present ? CK_TRUE : CK_FALSE, slot_list, &count); - if (rv != CKR_OK) { - g_warning ("couldn't get slot list: %s", gck_message_from_rv (rv)); - g_free (slot_list); - return NULL; - } - - result = NULL; - for (i = 0; i < count; ++i) { - result = g_list_prepend (result, g_object_new (GCK_TYPE_SLOT, - "handle", slot_list[i], - "module", self, NULL)); - } - - g_free (slot_list); - return g_list_reverse (result); -} - -/** - * gck_module_get_path: - * @self: The module for which to get the path. - * - * Get the file path of this module. This may not be an absolute path, and - * usually reflects the path passed to gck_module_initialize(). - * - * Return value: The path, do not modify or free this value. - **/ -const gchar* -gck_module_get_path (GckModule *self) -{ - g_return_val_if_fail (GCK_IS_MODULE (self), NULL); - return self->pv->path; -} - -/** - * gck_module_get_functions: (skip) - * @self: The module for which to get the function list. - * - * Get the PKCS\#11 function list for the module. - * - * Return value: The function list, do not modify this structure. - **/ -CK_FUNCTION_LIST_PTR -gck_module_get_functions (GckModule *self) -{ - g_return_val_if_fail (GCK_IS_MODULE (self), NULL); - return self->pv->funcs; -} - -/** - * gck_module_match: - * @self: the module to match - * @uri: the uri to match against the module - * - * Check whether the PKCS\#11 URI matches the module - * - * Returns: whether the URI matches or not - */ -gboolean -gck_module_match (GckModule *self, - GckUriData *uri) -{ - gboolean match = TRUE; - GckModuleInfo *info; - - g_return_val_if_fail (GCK_IS_MODULE (self), FALSE); - g_return_val_if_fail (uri != NULL, FALSE); - - if (uri->any_unrecognized) - match = FALSE; - - if (match && uri->module_info) { - info = gck_module_get_info (self); - match = _gck_module_info_match (uri->module_info, info); - gck_module_info_free (info); - } - - return match; -} |