summaryrefslogtreecommitdiff
path: root/gck/gck-module.c
diff options
context:
space:
mode:
authorStef Walter <stefw@collabora.co.uk>2011-10-06 12:51:08 +0200
committerStef Walter <stefw@collabora.co.uk>2011-10-06 13:22:43 +0200
commitf28d3d768f0e4057f727e8c3b93ba50c19f5db24 (patch)
tree288ef581590dfccbfddcad3c87d98ce3a4ed0a97 /gck/gck-module.c
parent626eef363c0ece57713c5be5939677784e8115cc (diff)
downloadgnome-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.c748
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&num;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&num;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&num;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&num;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;
-}