diff options
author | Stefan Walter <stefw@src.gnome.org> | 2009-01-10 01:17:01 +0000 |
---|---|---|
committer | Stefan Walter <stefw@src.gnome.org> | 2009-01-10 01:17:01 +0000 |
commit | 05984117f3a262b95fb7b976f566c947177bc931 (patch) | |
tree | c21f198f7b5bdb3e7ade3b2356e35ad777f4aa40 | |
parent | 15204a793cc3cc168a2db50616af07a4314d79b1 (diff) |
Add plex-layer and integrate 'roots-store' component into the PKCS#11
* daemon/Makefile.am:
* daemon/pkcs11/gkr-pkcs11-daemon.c:
* pkcs11/Makefile.am:
* pkcs11/pkcs11g.h:
* pkcs11/gck-manager.c:
* pkcs11/gck-module.c:
* pkcs11/gck-object.c:
* pkcs11/gck-object.h:
* pkcs11/gck-session.c:
* pkcs11/plex-layer/gck-plex-layer.c: (added)
* pkcs11/plex-layer/gck-plex-layer.h: (added)
* pkcs11/plex-layer/Makefile.am: (added)
* pkcs11/roots-store/gck-roots-certificate.c:
* pkcs11/roots-store/gck-roots-module.c:
* pkcs11/roots-store/gck-roots-module.h:
* pkcs11/roots-store/gck-roots-standalone.c:
* pkcs11/roots-store/gck-roots-store.h:
* pkcs11/roots-store/Makefile.am:
* pkcs11/rpc-layer/gck-rpc-layer.h:
* configure.in: Add plex-layer and integrate 'roots-store' component into
the PKCS#11 stack.
svn path=/trunk/; revision=1455
-rw-r--r-- | ChangeLog | 24 | ||||
-rw-r--r-- | configure.in | 1 | ||||
-rw-r--r-- | daemon/Makefile.am | 2 | ||||
-rw-r--r-- | daemon/pkcs11/gkr-pkcs11-daemon.c | 25 | ||||
-rw-r--r-- | pkcs11/Makefile.am | 7 | ||||
-rw-r--r-- | pkcs11/gck/gck-manager.c | 18 | ||||
-rw-r--r-- | pkcs11/gck/gck-module.c | 4 | ||||
-rw-r--r-- | pkcs11/gck/gck-object.c | 17 | ||||
-rw-r--r-- | pkcs11/gck/gck-object.h | 4 | ||||
-rw-r--r-- | pkcs11/gck/gck-session.c | 17 | ||||
-rw-r--r-- | pkcs11/pkcs11g.h | 4 | ||||
-rw-r--r-- | pkcs11/plex-layer/Makefile.am | 22 | ||||
-rw-r--r-- | pkcs11/plex-layer/gck-plex-layer.c | 1021 | ||||
-rw-r--r-- | pkcs11/plex-layer/gck-plex-layer.h | 31 | ||||
-rw-r--r-- | pkcs11/roots-store/Makefile.am | 13 | ||||
-rw-r--r-- | pkcs11/roots-store/gck-roots-certificate.c | 21 | ||||
-rw-r--r-- | pkcs11/roots-store/gck-roots-module.c | 16 | ||||
-rw-r--r-- | pkcs11/roots-store/gck-roots-module.h | 2 | ||||
-rw-r--r-- | pkcs11/roots-store/gck-roots-standalone.c | 6 | ||||
-rw-r--r-- | pkcs11/roots-store/gck-roots-store.h | 29 | ||||
-rw-r--r-- | pkcs11/rpc-layer/gck-rpc-layer.h | 6 |
21 files changed, 1223 insertions, 67 deletions
@@ -1,5 +1,29 @@ 2009-01-09 Stef Walter <stef@memberwebs.com> + * daemon/Makefile.am: + * daemon/pkcs11/gkr-pkcs11-daemon.c: + * pkcs11/Makefile.am: + * pkcs11/pkcs11g.h: + * pkcs11/gck-manager.c: + * pkcs11/gck-module.c: + * pkcs11/gck-object.c: + * pkcs11/gck-object.h: + * pkcs11/gck-session.c: + * pkcs11/plex-layer/gck-plex-layer.c: (added) + * pkcs11/plex-layer/gck-plex-layer.h: (added) + * pkcs11/plex-layer/Makefile.am: (added) + * pkcs11/roots-store/gck-roots-certificate.c: + * pkcs11/roots-store/gck-roots-module.c: + * pkcs11/roots-store/gck-roots-module.h: + * pkcs11/roots-store/gck-roots-standalone.c: + * pkcs11/roots-store/gck-roots-store.h: + * pkcs11/roots-store/Makefile.am: + * pkcs11/rpc-layer/gck-rpc-layer.h: + * configure.in: Add plex-layer and integrate 'roots-store' component into + the PKCS#11 stack. + +2009-01-09 Stef Walter <stef@memberwebs.com> + * pkcs11/roots-store/: (rename from roots/) * pkcs11/Makefile.am: * configure.in: Rename 'roots' component to 'roots-store' diff --git a/configure.in b/configure.in index 473e449d..084ac3c2 100644 --- a/configure.in +++ b/configure.in @@ -507,6 +507,7 @@ pam/tests/Makefile pkcs11/Makefile pkcs11/gck/Makefile pkcs11/gck/tests/Makefile +pkcs11/plex-layer/Makefile pkcs11/roots-store/Makefile pkcs11/roots-store/tests/Makefile pkcs11/rpc-layer/Makefile diff --git a/daemon/Makefile.am b/daemon/Makefile.am index 0d30ce6a..f47abd79 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -43,6 +43,8 @@ gnome_keyring_daemon_LDADD = \ $(top_builddir)/daemon/keyrings/libgkr-keyrings.la \ $(top_builddir)/daemon/ui/libgkr-ui.la \ $(top_builddir)/library/libgnome-keyring-common.la \ + $(top_builddir)/pkcs11/plex-layer/libgck-plex-layer.la \ + $(top_builddir)/pkcs11/roots-store/libgck-roots-store.la \ $(top_builddir)/pkcs11/rpc-layer/libgck-rpc-layer.la \ $(top_builddir)/pkcs11/ssh-agent/libgck-ssh-agent.la \ $(top_builddir)/pkcs11/ssh-store/libgck-ssh-store.la \ diff --git a/daemon/pkcs11/gkr-pkcs11-daemon.c b/daemon/pkcs11/gkr-pkcs11-daemon.c index d404b250..e9fb99e6 100644 --- a/daemon/pkcs11/gkr-pkcs11-daemon.c +++ b/daemon/pkcs11/gkr-pkcs11-daemon.c @@ -24,9 +24,11 @@ #include "gkr-pkcs11-auth.h" #include "gkr-pkcs11-daemon.h" -#include "pkcs11/ssh-store/gck-ssh-store.h" +#include "pkcs11/plex-layer/gck-plex-layer.h" +#include "pkcs11/roots-store/gck-roots-store.h" #include "pkcs11/rpc-layer/gck-rpc-layer.h" #include "pkcs11/ssh-agent/gck-ssh-agent.h" +#include "pkcs11/ssh-store/gck-ssh-store.h" #include "common/gkr-async.h" #include "common/gkr-daemon-util.h" @@ -69,21 +71,32 @@ pkcs11_daemon_cleanup (gpointer unused) gboolean gkr_pkcs11_daemon_initialize (void) { + CK_FUNCTION_LIST_PTR plex_layer; + CK_FUNCTION_LIST_PTR roots_store; CK_FUNCTION_LIST_PTR ssh_store; CK_RV rv; /* Now initialize them all */ gkr_async_begin_concurrent (); - /* Initialize the SSH storage */ + /* Connect SSH storage */ ssh_store = gck_ssh_store_get_functions (); - - /* TODO: More will come here, but currently this is it */ - + + /* Connect Root certificates */ + roots_store = gck_roots_store_get_functions (); + + /* Add all of those into the multiplexing layer */ + gck_plex_layer_add_module (ssh_store); +#ifdef ROOT_CERTIFICATES + gck_plex_layer_add_module (roots_store); +#endif + plex_layer = gck_plex_layer_get_functions (); + /* The auth component is the top component */ - gkr_pkcs11_auth_chain_functions (ssh_store); + gkr_pkcs11_auth_chain_functions (plex_layer); pkcs11_roof = gkr_pkcs11_auth_get_functions (); + /* Initialize the whole caboodle */ rv = (pkcs11_roof->C_Initialize) (NULL); gkr_async_end_concurrent (); diff --git a/pkcs11/Makefile.am b/pkcs11/Makefile.am index a43e9550..a084193b 100644 --- a/pkcs11/Makefile.am +++ b/pkcs11/Makefile.am @@ -9,12 +9,6 @@ inc_HEADERS = \ EXTRA_DIST = \ pkcs11.h -if WITH_ROOT_CERTS -ROOTS_DIR = roots-store -else -ROOTS_DIR = -endif - if WITH_TESTS TESTS_DIR = tests else @@ -23,6 +17,7 @@ endif SUBDIRS = . \ gck \ + roots-store \ rpc-layer \ plex-layer \ ssh-agent \ diff --git a/pkcs11/gck/gck-manager.c b/pkcs11/gck/gck-manager.c index d25421a5..2b305dc2 100644 --- a/pkcs11/gck/gck-manager.c +++ b/pkcs11/gck/gck-manager.c @@ -216,8 +216,13 @@ read_value (GckObject *object, const gchar *property, CK_ATTRIBUTE_PTR *result) return FALSE; }; - *result = g_slice_new (CK_ATTRIBUTE); - memcpy (*result, &attr, sizeof (CK_ATTRIBUTE)); + if (attr.pValue) { + *result = g_slice_new (CK_ATTRIBUTE); + memcpy (*result, &attr, sizeof (CK_ATTRIBUTE)); + } else { + *result = NULL; + } + g_value_unset (&value); return TRUE; } @@ -398,12 +403,13 @@ add_object (GckManager *self, GckObject *object) handle = gck_object_get_handle (object); if (!handle) { /* Make a new handle */ - handle = (gck_util_next_handle () & GCK_OBJECT_HANDLE_MASK); - if (self->pv->for_token) - handle |= GCK_OBJECT_IS_PERMANENT; + handle = gck_util_next_handle (); gck_object_set_handle (object, handle); } - + + /* Make the object know about its token state */ + g_object_set (object, "permanent", self->pv->for_token, NULL); + /* * We don't ref the objects or anything. They're expected to * unregister upon dispose. diff --git a/pkcs11/gck/gck-module.c b/pkcs11/gck/gck-module.c index ed985d8f..bc19fd8d 100644 --- a/pkcs11/gck/gck-module.c +++ b/pkcs11/gck/gck-module.c @@ -586,6 +586,10 @@ CK_ULONG gck_module_next_handle (GckModule *self) { g_return_val_if_fail (GCK_IS_MODULE (self), 0); + if (self->pv->handle_counter == CK_GNOME_MAX_HANDLE) { + g_warning ("handle counter wrapped"); + self->pv->handle_counter = 0; + } return (self->pv->handle_counter)++; } diff --git a/pkcs11/gck/gck-object.c b/pkcs11/gck/gck-object.c index 8fd9e7ae..51754a61 100644 --- a/pkcs11/gck/gck-object.c +++ b/pkcs11/gck/gck-object.c @@ -36,7 +36,8 @@ enum { PROP_HANDLE, PROP_MANAGER, PROP_STORE, - PROP_UNIQUE + PROP_UNIQUE, + PROP_PERMANENT }; enum { @@ -51,6 +52,7 @@ struct _GckObjectPrivate { GckManager *manager; GckStore *store; gchar *unique; + gboolean permanent; }; G_DEFINE_TYPE (GckObject, gck_object, G_TYPE_OBJECT); @@ -78,7 +80,7 @@ gck_object_real_get_attribute (GckObject *self, CK_ATTRIBUTE* attr) case CKA_PRIVATE: return gck_attribute_set_bool (attr, FALSE); case CKA_TOKEN: - return gck_attribute_set_bool (attr, (self->pv->handle & GCK_OBJECT_IS_PERMANENT) ? TRUE : FALSE); + return gck_attribute_set_bool (attr, self->pv->permanent); case CKA_GNOME_UNIQUE: if (self->pv->unique) return gck_attribute_set_string (attr, self->pv->unique); @@ -238,6 +240,10 @@ gck_object_set_property (GObject *obj, guint prop_id, const GValue *value, g_return_if_fail (!self->pv->unique); self->pv->unique = g_value_dup_string (value); break; + case PROP_PERMANENT: + self->pv->permanent = g_value_get_boolean (value); + g_object_notify (G_OBJECT (self), "permanent"); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); break; @@ -263,6 +269,9 @@ gck_object_get_property (GObject *obj, guint prop_id, GValue *value, case PROP_UNIQUE: g_value_set_string (value, gck_object_get_unique (self)); break; + case PROP_PERMANENT: + g_value_set_boolean (value, self->pv->permanent); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec); break; @@ -303,6 +312,10 @@ gck_object_class_init (GckObjectClass *klass) g_param_spec_string ("unique", "Unique Identifer", "Machine unique identifier", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (gobject_class, PROP_PERMANENT, + g_param_spec_boolean ("permanent", "Is Permanent Object", "Is permanent token object", + FALSE, G_PARAM_READWRITE)); + signals[NOTIFY_ATTRIBUTE] = g_signal_new ("notify-attribute", GCK_TYPE_OBJECT, G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GckObjectClass, notify_attribute), NULL, NULL, g_cclosure_marshal_VOID__ULONG, diff --git a/pkcs11/gck/gck-object.h b/pkcs11/gck/gck-object.h index 71f0d1d6..cb5b12da 100644 --- a/pkcs11/gck/gck-object.h +++ b/pkcs11/gck/gck-object.h @@ -28,10 +28,6 @@ #include "gck-types.h" -#define GCK_OBJECT_HANDLE_MASK 0x0FFFFFFF -#define GCK_OBJECT_IS_PERMANENT 0x10000000 -#define GCK_OBJECT_IS_TEMPORARY 0x00000000 - #define GCK_TYPE_OBJECT (gck_object_get_type ()) #define GCK_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCK_TYPE_OBJECT, GckObject)) #define GCK_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GCK_TYPE_OBJECT, GckObjectClass)) diff --git a/pkcs11/gck/gck-session.c b/pkcs11/gck/gck-session.c index a7d440f1..ffef8c15 100644 --- a/pkcs11/gck/gck-session.c +++ b/pkcs11/gck/gck-session.c @@ -233,20 +233,23 @@ lookup_object_from_handle (GckSession *self, CK_OBJECT_HANDLE handle, if (handle == 0) return CKR_OBJECT_HANDLE_INVALID; + + /* Try looking up in the token manager */ + manager = gck_module_get_manager (self->pv->module); + object = gck_manager_find_by_handle (manager, handle); + is_token = TRUE; - if (handle & GCK_OBJECT_IS_PERMANENT) { - manager = gck_module_get_manager (self->pv->module); - is_token = TRUE; - } else { + /* Try looking up in the session manager */ + if (object == NULL) { manager = gck_session_get_manager (self); + object = gck_manager_find_by_handle (manager, handle); is_token = FALSE; } - g_return_val_if_fail (manager, CKR_GENERAL_ERROR); - - object = gck_manager_find_by_handle (manager, handle); if (object == NULL) return CKR_OBJECT_HANDLE_INVALID; + + g_return_val_if_fail (manager, CKR_GENERAL_ERROR); /* * Check that we're not accessing private objects on a diff --git a/pkcs11/pkcs11g.h b/pkcs11/pkcs11g.h index babc2d38..244c62f2 100644 --- a/pkcs11/pkcs11g.h +++ b/pkcs11/pkcs11g.h @@ -66,8 +66,8 @@ */ #define CK_GNOME_MAX_SLOT (0x000003FF) -#define CK_GNOME_MAX_APP ((CK_ULONG)-1) >> 10) -#define CK_GNOME_MAX_HANDLE ((CK_ULONG)-1) >> 10) +#define CK_GNOME_MAX_APP (((CK_ULONG)-1) >> 10) +#define CK_GNOME_MAX_HANDLE (((CK_ULONG)-1) >> 10) /* ------------------------------------------------------------------- diff --git a/pkcs11/plex-layer/Makefile.am b/pkcs11/plex-layer/Makefile.am new file mode 100644 index 00000000..06afd4f0 --- /dev/null +++ b/pkcs11/plex-layer/Makefile.am @@ -0,0 +1,22 @@ + +noinst_LTLIBRARIES = \ + libgck-plex-layer.la + +INCLUDES = -I. \ + -I$(top_srcdir) \ + -I$(top_builddir) + +# ------------------------------------------------------------------------------ +# The code + +libgck_plex_layer_la_SOURCES = \ + gck-plex-layer.c gck-plex-layer.h + +libgck_plex_layer_la_LIBADD = \ + $(GTHREAD_LIBS) \ + $(GLIB_LIBS) + +libgck_plex_layer_la_CFLAGS = \ + $(GTHREAD_CFLAGS) \ + $(GLIB_CFLAGS) +
\ No newline at end of file diff --git a/pkcs11/plex-layer/gck-plex-layer.c b/pkcs11/plex-layer/gck-plex-layer.c new file mode 100644 index 00000000..70261180 --- /dev/null +++ b/pkcs11/plex-layer/gck-plex-layer.c @@ -0,0 +1,1021 @@ +/* + * gnome-keyring + * + * Copyright (C) 2008 Stefan Walter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program 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 + * Lesser General License for more details. + * + * You should have received a copy of the GNU Lesser General + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#include "config.h" + +#include "gck-plex-layer.h" + +#include "pkcs11/pkcs11.h" +#include "pkcs11/pkcs11g.h" + +#include <glib.h> + +#include <string.h> + +typedef struct _Mapping { + CK_SLOT_ID plex_slot; + CK_SLOT_ID real_slot; + CK_FUNCTION_LIST_PTR funcs; +} Mapping; + +G_LOCK_DEFINE_STATIC (plex_layer); + +static GList *plex_modules = NULL; +static Mapping *plex_mappings = NULL; +static guint n_plex_mappings = 0; + +#define MANUFACTURER_ID "GNOME Keyring " +#define LIBRARY_DESCRIPTION "GNOME Keyring Daemon Core " +#define LIBRARY_VERSION_MAJOR 1 +#define LIBRARY_VERSION_MINOR 1 + +/* Start plex slots slightly higher for testing */ +#define PLEX_MAPPING_OFFSET 0x10 + +#define HANDLE_SLOT_BITS ((sizeof (CK_ULONG) * 8) - 10) +#define HANDLE_REAL_MASK (((CK_ULONG)-1) >> 10) + + +static gboolean +map_slot_down (CK_SLOT_ID_PTR slot, Mapping *mapping) +{ + CK_SLOT_ID id = CK_GNOME_APPARTMENT_SLOT (*slot); + gboolean ret = TRUE; + + if (id < PLEX_MAPPING_OFFSET) + return FALSE; + id -= PLEX_MAPPING_OFFSET; + + g_assert (mapping); + + G_LOCK (plex_layer); + + if (id > n_plex_mappings) { + ret = FALSE; + } else { + memcpy (mapping, &plex_mappings[id], sizeof (Mapping)); + *slot = CK_GNOME_MAKE_APPARTMENT(mapping->real_slot, CK_GNOME_APPARTMENT_APP (*slot)); + } + + G_UNLOCK (plex_layer); + + return ret; +} + +#define MAP_SLOT_UP(slot, map) G_STMT_START { \ + + + +#define MAP_SLOT_DOWN(slot, map) G_STMT_START { \ + if (!map_slot_down (&slot, &map)) \ + return CKR_SLOT_ID_INVALID; \ + } G_STMT_END + +#define MAP_SESSION_UP(map, session) G_STMT_START { \ + g_return_val_if_fail ((session) < CK_GNOME_MAX_HANDLE, CKR_GENERAL_ERROR); \ + session = ((session) | ((map.plex_slot) << HANDLE_SLOT_BITS)); \ + } G_STMT_END + +#define MAP_SESSION_DOWN(session, map) G_STMT_START { \ + CK_SLOT_ID slot = (session >> HANDLE_SLOT_BITS); \ + if (!map_slot_down (&slot, &map)) \ + return CKR_SESSION_HANDLE_INVALID; \ + session &= HANDLE_REAL_MASK; \ + } G_STMT_END + +#define MAP_OBJECT_UP(map, object) G_STMT_START { \ + g_return_val_if_fail ((object) < CK_GNOME_MAX_HANDLE, CKR_GENERAL_ERROR); \ + object = ((object) | ((map.plex_slot) << HANDLE_SLOT_BITS)); \ + } G_STMT_END + +#define MAP_SESSION_OBJECT_DOWN(session, object, map) G_STMT_START { \ + CK_SLOT_ID slot = (session >> HANDLE_SLOT_BITS); \ + if (!map_slot_down (&slot, &map)) \ + return CKR_SESSION_HANDLE_INVALID; \ + session &= HANDLE_REAL_MASK; \ + object &= HANDLE_REAL_MASK; \ + } G_STMT_END + + +static CK_RV +plex_C_Initialize (CK_VOID_PTR init_args) +{ + CK_FUNCTION_LIST_PTR funcs; + GArray *mappings = NULL; + CK_SLOT_ID_PTR slots; + Mapping mapping; + CK_ULONG i, count; + CK_RV rv = CKR_OK; + GList *l; + + mappings = g_array_new (FALSE, TRUE, sizeof (Mapping)); + + G_LOCK (plex_layer); + + if (plex_mappings) + rv = CKR_CRYPTOKI_ALREADY_INITIALIZED; + + for (l = plex_modules; rv == CKR_OK && l != NULL; l = g_list_next (l)) { + funcs = l->data; + + /* Initialize each module */ + rv = (funcs->C_Initialize) (init_args); + if (rv == CKR_CRYPTOKI_ALREADY_INITIALIZED) + rv = CKR_OK; + if (rv != CKR_OK) + break; + + /* And then ask it for its slots */ + rv = (funcs->C_GetSlotList) (FALSE, NULL, &count); + if (rv != CKR_OK) + break; + if (!count) + continue; + slots = g_new0 (CK_SLOT_ID, count); + rv = (funcs->C_GetSlotList) (FALSE, slots, &count); + if (rv != CKR_OK) { + g_free (slots); + break; + } + + /* And now add a mapping for each of those slots */ + for (i = 0; i < count; ++i) { + memset (&mapping, 0, sizeof (mapping)); + mapping.plex_slot = mappings->len + PLEX_MAPPING_OFFSET; + mapping.real_slot = slots[i]; + mapping.funcs = funcs; + g_array_append_val (mappings, mapping); + } + + g_free (slots); + } + + /* If failed, then finalize all the ones that succeeded */ + if (rv != CKR_OK && l != NULL) { + for (l = g_list_previous (l); l; l = g_list_previous (l)) { + funcs = l->data; + (funcs->C_Finalize) (NULL); + } + } + + /* If succeeded then swap in mappings */ + if (rv == CKR_OK) { + g_assert (!plex_mappings); + n_plex_mappings = mappings->len; + plex_mappings = (Mapping*)g_array_free (mappings, FALSE); + mappings = NULL; + } + + G_UNLOCK (plex_layer); + + /* If failed or somehow unused then free */ + if (mappings) + g_array_free (mappings, TRUE); + + return rv; +} + +static CK_RV +plex_C_Finalize (CK_VOID_PTR reserved) +{ + guint i; + + G_LOCK (plex_layer); + + for (i = 0; i < n_plex_mappings; ++i) + (plex_mappings[i].funcs->C_Finalize) (NULL); + g_free (plex_mappings); + plex_mappings = NULL; + + G_UNLOCK (plex_layer); + + return CKR_OK; +} + +static CK_RV +plex_C_GetInfo (CK_INFO_PTR info) +{ + if (info == NULL) + return CKR_ARGUMENTS_BAD; + + info->cryptokiVersion.major = CRYPTOKI_VERSION_MAJOR; + info->cryptokiVersion.minor = CRYPTOKI_VERSION_MINOR; + info->libraryVersion.major = LIBRARY_VERSION_MAJOR; + info->libraryVersion.minor = LIBRARY_VERSION_MINOR; + info->flags = CKF_GNOME_APPARTMENTS; + strncpy ((char*)info->manufacturerID, MANUFACTURER_ID, 32); + strncpy ((char*)info->libraryDescription, LIBRARY_DESCRIPTION, 32); + return CKR_OK; +} + +static CK_RV +plex_C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list) +{ + if (!list) + return CKR_ARGUMENTS_BAD; + *list = gck_plex_layer_get_functions (); + return CKR_OK; +} + +static CK_RV +plex_C_GetSlotList (CK_BBOOL token_present, CK_SLOT_ID_PTR slot_list, CK_ULONG_PTR count) +{ + CK_SLOT_INFO info; + Mapping *mapping; + CK_ULONG index; + CK_RV rv; + + guint i; + + if (!count) + return CKR_ARGUMENTS_BAD; + + G_LOCK (plex_layer); + + rv = CKR_OK; + index = 0; + + /* Go through and build up a map */ + for (i = 0; i < n_plex_mappings; ++i) { + mapping = &plex_mappings[i]; + + /* Skip ones without a token if requested */ + if (token_present) { + rv = (mapping->funcs->C_GetSlotInfo) (mapping->real_slot, &info); + if (rv != CKR_OK) + break; + if (!(info.flags & CKF_TOKEN_PRESENT)) + continue; + } + + /* Fill in the slot if we can */ + if (slot_list && *count > index) + slot_list[index] = mapping->plex_slot; + + ++index; + } + + if (slot_list && *count < index) + rv = CKR_BUFFER_TOO_SMALL; + + *count = index; + + G_UNLOCK (plex_layer); + + return rv; +} + +static CK_RV +plex_C_GetSlotInfo (CK_SLOT_ID id, CK_SLOT_INFO_PTR info) +{ + Mapping map; + MAP_SLOT_DOWN (id, map); + return (map.funcs->C_GetSlotInfo) (id, info); +} + +static CK_RV +plex_C_GetTokenInfo (CK_SLOT_ID id, CK_TOKEN_INFO_PTR info) +{ + Mapping map; + MAP_SLOT_DOWN (id, map); + return (map.funcs->C_GetTokenInfo) (id, info); +} + +static CK_RV +plex_C_GetMechanismList (CK_SLOT_ID id, CK_MECHANISM_TYPE_PTR mechanism_list, CK_ULONG_PTR count) +{ + Mapping map; + MAP_SLOT_DOWN (id, map); + return (map.funcs->C_GetMechanismList) (id, mechanism_list, count); +} + +static CK_RV +plex_C_GetMechanismInfo (CK_SLOT_ID id, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR info) +{ + Mapping map; + MAP_SLOT_DOWN (id, map); + return (map.funcs->C_GetMechanismInfo) (id, type, info); +} + +static CK_RV +plex_C_InitToken (CK_SLOT_ID id, CK_UTF8CHAR_PTR pin, CK_ULONG pin_len, CK_UTF8CHAR_PTR label) +{ + Mapping map; + MAP_SLOT_DOWN (id, map); + return (map.funcs->C_InitToken) (id, pin, pin_len, label); +} + +static CK_RV +plex_C_WaitForSlotEvent (CK_FLAGS flags, CK_SLOT_ID_PTR slot, CK_VOID_PTR reserved) +{ + /* TODO: We could implement this by polling, esp. the nonblock case. */ + return CKR_NO_EVENT; +} + +static CK_RV +plex_C_OpenSession (CK_SLOT_ID id, CK_FLAGS flags, CK_VOID_PTR user_data, CK_NOTIFY callback, CK_SESSION_HANDLE_PTR handle) +{ + Mapping map; + CK_RV rv; + + if (handle == NULL) + return CKR_ARGUMENTS_BAD; + + MAP_SLOT_DOWN (id, map); + rv = (map.funcs->C_OpenSession) (id, flags, user_data, callback, handle); + MAP_SESSION_UP (map, *handle); + + return rv; +} + +static CK_RV +plex_C_CloseSession (CK_SESSION_HANDLE handle) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_CloseSession) (handle); +} + +static CK_RV +plex_C_CloseAllSessions (CK_SLOT_ID id) +{ + Mapping map; + MAP_SLOT_DOWN (id, map); + return (map.funcs->C_CloseAllSessions) (id); +} + +static CK_RV +plex_C_GetFunctionStatus (CK_SESSION_HANDLE handle) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_GetFunctionStatus) (handle); +} + +static CK_RV +plex_C_CancelFunction (CK_SESSION_HANDLE handle) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_CancelFunction) (handle); +} + +static CK_RV +plex_C_GetSessionInfo (CK_SESSION_HANDLE handle, CK_SESSION_INFO_PTR info) +{ + Mapping map; + CK_RV rv; + + if (info == NULL) + return CKR_ARGUMENTS_BAD; + + MAP_SESSION_DOWN (handle, map); + rv = (map.funcs->C_GetSessionInfo) (handle, info); + if (rv == CKR_OK) + info->slotID = map.plex_slot; + + return rv; +} + +static CK_RV +plex_C_InitPIN (CK_SESSION_HANDLE handle, CK_UTF8CHAR_PTR pin, CK_ULONG pin_len) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_InitPIN) (handle, pin, pin_len); +} + +static CK_RV +plex_C_SetPIN (CK_SESSION_HANDLE handle, CK_UTF8CHAR_PTR old_pin, CK_ULONG old_pin_len, CK_UTF8CHAR_PTR new_pin, CK_ULONG new_pin_len) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_SetPIN) (handle, old_pin, old_pin_len, new_pin, new_pin_len); +} + +static CK_RV +plex_C_GetOperationState (CK_SESSION_HANDLE handle, CK_BYTE_PTR operation_state, CK_ULONG_PTR operation_state_len) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_GetOperationState) (handle, operation_state, operation_state_len); +} + +static CK_RV +plex_C_SetOperationState (CK_SESSION_HANDLE handle, CK_BYTE_PTR operation_state, + CK_ULONG operation_state_len, CK_OBJECT_HANDLE encryption_key, + CK_OBJECT_HANDLE authentication_key) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_SetOperationState) (handle, operation_state, operation_state_len, encryption_key, authentication_key); +} + +static CK_RV +plex_C_Login (CK_SESSION_HANDLE handle, CK_USER_TYPE user_type, + CK_UTF8CHAR_PTR pin, CK_ULONG pin_len) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_Login) (handle, user_type, pin, pin_len); +} + +static CK_RV +plex_C_Logout (CK_SESSION_HANDLE handle) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_Logout) (handle); +} + +static CK_RV +plex_C_CreateObject (CK_SESSION_HANDLE handle, CK_ATTRIBUTE_PTR template, + CK_ULONG count, CK_OBJECT_HANDLE_PTR new_object) +{ + Mapping map; + CK_RV rv; + + if (new_object == NULL) + return CKR_ARGUMENTS_BAD; + + MAP_SESSION_DOWN (handle, map); + rv = (map.funcs->C_CreateObject) (handle, template, count, new_object); + if (rv == CKR_OK) + MAP_OBJECT_UP (map, *new_object); + + return rv; +} + +static CK_RV +plex_C_CopyObject (CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE object, + CK_ATTRIBUTE_PTR template, CK_ULONG count, + CK_OBJECT_HANDLE_PTR new_object) +{ + Mapping map; + CK_RV rv; + + if (new_object == NULL) + return CKR_ARGUMENTS_BAD; + + MAP_SESSION_OBJECT_DOWN (handle, object, map); + rv = (map.funcs->C_CopyObject) (handle, object, template, count, new_object); + if (rv == CKR_OK) + MAP_OBJECT_UP (map, *new_object); + + return rv; +} + +static CK_RV +plex_C_DestroyObject (CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE object) +{ + Mapping map; + MAP_SESSION_OBJECT_DOWN (handle, object, map); + return (map.funcs->C_DestroyObject) (handle, object); +} + +static CK_RV +plex_C_GetObjectSize (CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE object, + CK_ULONG_PTR size) +{ + Mapping map; + MAP_SESSION_OBJECT_DOWN (handle, object, map); + return (map.funcs->C_GetObjectSize) (handle, object, size); +} + +static CK_RV +plex_C_GetAttributeValue (CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE object, + CK_ATTRIBUTE_PTR template, CK_ULONG count) +{ + Mapping map; + MAP_SESSION_OBJECT_DOWN (handle, object, map); + return (map.funcs->C_GetAttributeValue) (handle, object, template, count); +} + +static CK_RV +plex_C_SetAttributeValue (CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE object, + CK_ATTRIBUTE_PTR template, CK_ULONG count) +{ + Mapping map; + MAP_SESSION_OBJECT_DOWN (handle, object, map); + return (map.funcs->C_SetAttributeValue) (handle, object, template, count); +} + +static CK_RV +plex_C_FindObjectsInit (CK_SESSION_HANDLE handle, CK_ATTRIBUTE_PTR template, + CK_ULONG count) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_FindObjectsInit) (handle, template, count); +} + +static CK_RV +plex_C_FindObjects (CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE_PTR objects, + CK_ULONG max_count, CK_ULONG_PTR count) +{ + Mapping map; + CK_ULONG i; + CK_RV rv; + + if (count == NULL) + return CKR_ARGUMENTS_BAD; + + MAP_SESSION_DOWN (handle, map); + + rv = (map.funcs->C_FindObjects) (handle, objects, max_count, count); + if (rv == CKR_OK && objects) { + for (i = 0; i < *count; ++i) + MAP_OBJECT_UP (map, objects[i]); + } + + return rv; +} + +static CK_RV +plex_C_FindObjectsFinal (CK_SESSION_HANDLE handle) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_FindObjectsFinal) (handle); +} + +static CK_RV +plex_C_EncryptInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key) +{ + Mapping map; + MAP_SESSION_OBJECT_DOWN (handle, key, map); + return (map.funcs->C_EncryptInit) (handle, mechanism, key); +} + +static CK_RV +plex_C_Encrypt (CK_SESSION_HANDLE handle, CK_BYTE_PTR data, CK_ULONG data_len, + CK_BYTE_PTR encrypted_data, CK_ULONG_PTR encrypted_data_len) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_Encrypt) (handle, data, data_len, encrypted_data, encrypted_data_len); +} + +static CK_RV +plex_C_EncryptUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR part, + CK_ULONG part_len, CK_BYTE_PTR encrypted_part, + CK_ULONG_PTR encrypted_part_len) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_EncryptUpdate) (handle, part, part_len, encrypted_part, encrypted_part_len); +} + +static CK_RV +plex_C_EncryptFinal (CK_SESSION_HANDLE handle, CK_BYTE_PTR last_part, + CK_ULONG_PTR last_part_len) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_EncryptFinal) (handle, last_part, last_part_len); +} + +static CK_RV +plex_C_DecryptInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key) +{ + Mapping map; + MAP_SESSION_OBJECT_DOWN (handle, key, map); + return (map.funcs->C_DecryptInit) (handle, mechanism, key); +} + +static CK_RV +plex_C_Decrypt (CK_SESSION_HANDLE handle, CK_BYTE_PTR enc_data, + CK_ULONG enc_data_len, CK_BYTE_PTR data, CK_ULONG_PTR data_len) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_Decrypt) (handle, enc_data, enc_data_len, data, data_len); +} + +static CK_RV +plex_C_DecryptUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR enc_part, + CK_ULONG enc_part_len, CK_BYTE_PTR part, CK_ULONG_PTR part_len) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_DecryptUpdate) (handle, enc_part, enc_part_len, part, part_len); +} + +static CK_RV +plex_C_DecryptFinal (CK_SESSION_HANDLE handle, CK_BYTE_PTR last_part, + CK_ULONG_PTR last_part_len) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_DecryptFinal) (handle, last_part, last_part_len); +} + +static CK_RV +plex_C_DigestInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_DigestInit) (handle, mechanism); +} + +static CK_RV +plex_C_Digest (CK_SESSION_HANDLE handle, CK_BYTE_PTR data, CK_ULONG data_len, + CK_BYTE_PTR digest, CK_ULONG_PTR digest_len) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_Digest) (handle, data, data_len, digest, digest_len); +} + +static CK_RV +plex_C_DigestUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR part, CK_ULONG part_len) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_DigestUpdate) (handle, part, part_len); +} + +static CK_RV +plex_C_DigestKey (CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE key) +{ + Mapping map; + MAP_SESSION_OBJECT_DOWN (handle, key, map); + return (map.funcs->C_DigestKey) (handle, key); +} + +static CK_RV +plex_C_DigestFinal (CK_SESSION_HANDLE handle, CK_BYTE_PTR digest, + CK_ULONG_PTR digest_len) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_DigestFinal) (handle, digest, digest_len); +} + +static CK_RV +plex_C_SignInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key) +{ + Mapping map; + MAP_SESSION_OBJECT_DOWN (handle, key, map); + return (map.funcs->C_SignInit) (handle, mechanism, key); +} + +static CK_RV +plex_C_Sign (CK_SESSION_HANDLE handle, CK_BYTE_PTR data, CK_ULONG data_len, + CK_BYTE_PTR signature, CK_ULONG_PTR signature_len) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_Sign) (handle, data, data_len, signature, signature_len); +} + +static CK_RV +plex_C_SignUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR part, CK_ULONG part_len) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_SignUpdate) (handle, part, part_len); +} + +static CK_RV +plex_C_SignFinal (CK_SESSION_HANDLE handle, CK_BYTE_PTR signature, + CK_ULONG_PTR signature_len) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_SignFinal) (handle, signature, signature_len); +} + +static CK_RV +plex_C_SignRecoverInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key) +{ + Mapping map; + MAP_SESSION_OBJECT_DOWN (handle, key, map); + return (map.funcs->C_SignRecoverInit) (handle, mechanism, key); +} + +static CK_RV +plex_C_SignRecover (CK_SESSION_HANDLE handle, CK_BYTE_PTR data, CK_ULONG data_len, + CK_BYTE_PTR signature, CK_ULONG_PTR signature_len) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_SignRecover) (handle, data, data_len, signature, signature_len); +} + +static CK_RV +plex_C_VerifyInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key) +{ + Mapping map; + MAP_SESSION_OBJECT_DOWN (handle, key, map); + return (map.funcs->C_VerifyInit) (handle, mechanism, key); +} + +static CK_RV +plex_C_Verify (CK_SESSION_HANDLE handle, CK_BYTE_PTR data, CK_ULONG data_len, + CK_BYTE_PTR signature, CK_ULONG signature_len) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_Verify) (handle, data, data_len, signature, signature_len); +} + +static CK_RV +plex_C_VerifyUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR part, CK_ULONG part_len) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_VerifyUpdate) (handle, part, part_len); +} + +static CK_RV +plex_C_VerifyFinal (CK_SESSION_HANDLE handle, CK_BYTE_PTR signature, + CK_ULONG signature_len) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_VerifyFinal) (handle, signature, signature_len); +} + +static CK_RV +plex_C_VerifyRecoverInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key) +{ + Mapping map; + MAP_SESSION_OBJECT_DOWN (handle, key, map); + return (map.funcs->C_VerifyRecoverInit) (handle, mechanism, key); +} + +static CK_RV +plex_C_VerifyRecover (CK_SESSION_HANDLE handle, CK_BYTE_PTR signature, + CK_ULONG signature_len, CK_BYTE_PTR data, CK_ULONG_PTR data_len) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_VerifyRecover) (handle, signature, signature_len, data, data_len); +} + +static CK_RV +plex_C_DigestEncryptUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR part, + CK_ULONG part_len, CK_BYTE_PTR enc_part, + CK_ULONG_PTR enc_part_len) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_DigestEncryptUpdate) (handle, part, part_len, enc_part, enc_part_len); +} + +static CK_RV +plex_C_DecryptDigestUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR enc_part, + CK_ULONG enc_part_len, CK_BYTE_PTR part, + CK_ULONG_PTR part_len) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_DecryptDigestUpdate) (handle, enc_part, enc_part_len, part, part_len); +} + +static CK_RV +plex_C_SignEncryptUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR part, + CK_ULONG part_len, CK_BYTE_PTR enc_part, + CK_ULONG_PTR enc_part_len) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_SignEncryptUpdate) (handle, part, part_len, enc_part, enc_part_len); +} + +static CK_RV +plex_C_DecryptVerifyUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR enc_part, + CK_ULONG enc_part_len, CK_BYTE_PTR part, + CK_ULONG_PTR part_len) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_DecryptVerifyUpdate) (handle, enc_part, enc_part_len, part, part_len); +} + +static CK_RV +plex_C_GenerateKey (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism, + CK_ATTRIBUTE_PTR template, CK_ULONG count, + CK_OBJECT_HANDLE_PTR key) +{ + Mapping map; + CK_RV rv; + + if (key == NULL) + return CKR_ARGUMENTS_BAD; + + MAP_SESSION_DOWN (handle, map); + rv = (map.funcs->C_GenerateKey) (handle, mechanism, template, count, key); + if (rv == CKR_OK) + MAP_OBJECT_UP (map, *key); + + return rv; +} + +static CK_RV +plex_C_GenerateKeyPair (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism, + CK_ATTRIBUTE_PTR pub_template, CK_ULONG pub_count, + CK_ATTRIBUTE_PTR priv_template, CK_ULONG priv_count, + CK_OBJECT_HANDLE_PTR pub_key, CK_OBJECT_HANDLE_PTR priv_key) +{ + Mapping map; + CK_RV rv; + + if (priv_key == NULL || pub_key == NULL) + return CKR_ARGUMENTS_BAD; + + rv = (map.funcs->C_GenerateKeyPair) (handle, mechanism, pub_template, pub_count, priv_template, priv_count, pub_key, priv_key); + if (rv == CKR_OK) { + MAP_OBJECT_UP (map, *pub_key); + MAP_OBJECT_UP (map, *priv_key); + } + + return rv; +} + +static CK_RV +plex_C_WrapKey (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE wrapping_key, CK_OBJECT_HANDLE key, + CK_BYTE_PTR wrapped_key, CK_ULONG_PTR wrapped_key_len) +{ + Mapping map; + MAP_SESSION_OBJECT_DOWN (handle, key, map); + return (map.funcs->C_WrapKey) (handle, mechanism, wrapping_key, key, wrapped_key, wrapped_key_len); +} + +static CK_RV +plex_C_UnwrapKey (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE unwrapping_key, CK_BYTE_PTR wrapped_key, + CK_ULONG wrapped_key_len, CK_ATTRIBUTE_PTR template, + CK_ULONG count, CK_OBJECT_HANDLE_PTR key) +{ + Mapping map; + CK_RV rv; + + if (key == NULL) + return CKR_ARGUMENTS_BAD; + + rv = (map.funcs->C_UnwrapKey) (handle, mechanism, unwrapping_key, wrapped_key, wrapped_key_len, template, count, key); + if (rv == CKR_OK) + MAP_OBJECT_UP (map, *key); + + return rv; +} + +static CK_RV +plex_C_DeriveKey (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE base_key, CK_ATTRIBUTE_PTR template, + CK_ULONG count, CK_OBJECT_HANDLE_PTR key) +{ + Mapping map; + CK_RV rv; + + if (key == NULL) + return CKR_ARGUMENTS_BAD; + + rv = (map.funcs->C_DeriveKey) (handle, mechanism, base_key, template, count, key); + if (rv == CKR_OK) + MAP_OBJECT_UP (map, *key); + + return rv; +} + +static CK_RV +plex_C_SeedRandom (CK_SESSION_HANDLE handle, CK_BYTE_PTR seed, CK_ULONG seed_len) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_SeedRandom) (handle, seed, seed_len); +} + +static CK_RV +plex_C_GenerateRandom (CK_SESSION_HANDLE handle, CK_BYTE_PTR random_data, + CK_ULONG random_len) +{ + Mapping map; + MAP_SESSION_DOWN (handle, map); + return (map.funcs->C_GenerateRandom) (handle, random_data, random_len); +} + +/* -------------------------------------------------------------------- + * MODULE ENTRY POINT + */ + +static CK_FUNCTION_LIST plex_function_list = { + { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR }, /* version */ + plex_C_Initialize, + plex_C_Finalize, + plex_C_GetInfo, + plex_C_GetFunctionList, + plex_C_GetSlotList, + plex_C_GetSlotInfo, + plex_C_GetTokenInfo, + plex_C_GetMechanismList, + plex_C_GetMechanismInfo, + plex_C_InitToken, + plex_C_InitPIN, + plex_C_SetPIN, + plex_C_OpenSession, + plex_C_CloseSession, + plex_C_CloseAllSessions, + plex_C_GetSessionInfo, + plex_C_GetOperationState, + plex_C_SetOperationState, + plex_C_Login, + plex_C_Logout, + plex_C_CreateObject, + plex_C_CopyObject, + plex_C_DestroyObject, + plex_C_GetObjectSize, + plex_C_GetAttributeValue, + plex_C_SetAttributeValue, + plex_C_FindObjectsInit, + plex_C_FindObjects, + plex_C_FindObjectsFinal, + plex_C_EncryptInit, + plex_C_Encrypt, + plex_C_EncryptUpdate, + plex_C_EncryptFinal, + plex_C_DecryptInit, + plex_C_Decrypt, + plex_C_DecryptUpdate, + plex_C_DecryptFinal, + plex_C_DigestInit, + plex_C_Digest, + plex_C_DigestUpdate, + plex_C_DigestKey, + plex_C_DigestFinal, + plex_C_SignInit, + plex_C_Sign, + plex_C_SignUpdate, + plex_C_SignFinal, + plex_C_SignRecoverInit, + plex_C_SignRecover, + plex_C_VerifyInit, + plex_C_Verify, + plex_C_VerifyUpdate, + plex_C_VerifyFinal, + plex_C_VerifyRecoverInit, + plex_C_VerifyRecover, + plex_C_DigestEncryptUpdate, + plex_C_DecryptDigestUpdate, + plex_C_SignEncryptUpdate, + plex_C_DecryptVerifyUpdate, + plex_C_GenerateKey, + plex_C_GenerateKeyPair, + plex_C_WrapKey, + plex_C_UnwrapKey, + plex_C_DeriveKey, + plex_C_SeedRandom, + plex_C_GenerateRandom, + plex_C_GetFunctionStatus, + plex_C_CancelFunction, + plex_C_WaitForSlotEvent +}; + +/* ----------------------------------------------------------------------------------------- + * PUBLIC FUNCTIONS + */ + +CK_FUNCTION_LIST_PTR +gck_plex_layer_get_functions (void) +{ + return &plex_function_list; +} + +void +gck_plex_layer_add_module (CK_FUNCTION_LIST_PTR funcs) +{ + g_assert (funcs); + + G_LOCK (plex_layer); + + plex_modules = g_list_append (plex_modules, funcs); + + G_UNLOCK (plex_layer); +} diff --git a/pkcs11/plex-layer/gck-plex-layer.h b/pkcs11/plex-layer/gck-plex-layer.h new file mode 100644 index 00000000..6bb880b8 --- /dev/null +++ b/pkcs11/plex-layer/gck-plex-layer.h @@ -0,0 +1,31 @@ +/* + * gnome-keyring + * + * Copyright (C) 2008 Stefan Walter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef __GCK_PLEX_LAYER_H__ +#define __GCK_PLEX_LAYER_H__ + +#include "pkcs11/pkcs11.h" + +CK_FUNCTION_LIST_PTR gck_plex_layer_get_functions (void); + +void gck_plex_layer_add_module (CK_FUNCTION_LIST_PTR funcs); + +#endif /* __GCK_PLEX_LAYER_H__ */ diff --git a/pkcs11/roots-store/Makefile.am b/pkcs11/roots-store/Makefile.am index 1dd6d9f8..3fed6916 100644 --- a/pkcs11/roots-store/Makefile.am +++ b/pkcs11/roots-store/Makefile.am @@ -12,9 +12,10 @@ INCLUDES = \ # The roots component code noinst_LTLIBRARIES = \ - libgck-roots.la + libgck-roots-store.la -libgck_roots_la_SOURCES = \ +libgck_roots_store_la_SOURCES = \ + gck-roots-store.h \ gck-roots-module.c gck-roots-module.h \ gck-roots-certificate.c gck-roots-certificate.h @@ -24,16 +25,16 @@ libgck_roots_la_SOURCES = \ moduledir = $(libdir)/gnome-keyring/standalone/ module_LTLIBRARIES = \ - gck-roots-module.la + gck-roots-store-standalone.la -gck_roots_module_la_LDFLAGS = \ +gck_roots_store_standalone_la_LDFLAGS = \ -module -avoid-version \ -no-undefined -export-symbols-regex 'C_GetFunctionList' -gck_roots_module_la_SOURCES = \ +gck_roots_store_standalone_la_SOURCES = \ gck-roots-standalone.c -gck_roots_module_la_LIBADD = \ +gck_roots_store_standalone_la_LIBADD = \ libgck-roots.la \ $(top_builddir)/pkcs11/gck/libgck.la \ $(top_builddir)/common/libgkr-common-buffer.la \ diff --git a/pkcs11/roots-store/gck-roots-certificate.c b/pkcs11/roots-store/gck-roots-certificate.c index 0188a76b..8a6153e6 100644 --- a/pkcs11/roots-store/gck-roots-certificate.c +++ b/pkcs11/roots-store/gck-roots-certificate.c @@ -33,14 +33,12 @@ enum { PROP_0, - PROP_UNIQUE, PROP_PATH, }; struct _GckRootsCertificate { GckCertificate parent; gchar *path; - gchar *unique; }; G_DEFINE_TYPE (GckRootsCertificate, gck_roots_certificate, GCK_TYPE_CERTIFICATE); @@ -89,10 +87,6 @@ gck_roots_certificate_set_property (GObject *obj, guint prop_id, const GValue *v GckRootsCertificate *self = GCK_ROOTS_CERTIFICATE (obj); switch (prop_id) { - case PROP_UNIQUE: - g_return_if_fail (!self->unique); - self->unique = g_value_dup_string (value); - break; case PROP_PATH: g_return_if_fail (!self->path); self->path = g_value_dup_string (value); @@ -110,9 +104,6 @@ gck_roots_certificate_get_property (GObject *obj, guint prop_id, GValue *value, GckRootsCertificate *self = GCK_ROOTS_CERTIFICATE (obj); switch (prop_id) { - case PROP_UNIQUE: - g_value_set_string (value, gck_roots_certificate_get_unique (self)); - break; case PROP_PATH: g_value_set_string (value, gck_roots_certificate_get_path (self)); break; @@ -128,7 +119,6 @@ gck_roots_certificate_finalize (GObject *obj) GckRootsCertificate *self = GCK_ROOTS_CERTIFICATE (obj); g_free (self->path); - g_free (self->unique); G_OBJECT_CLASS (gck_roots_certificate_parent_class)->finalize (obj); } @@ -145,10 +135,6 @@ gck_roots_certificate_class_init (GckRootsCertificateClass *klass) gck_class->get_attribute = gck_roots_certificate_get_attribute; - g_object_class_install_property (gobject_class, PROP_UNIQUE, - g_param_spec_string ("unique", "Unique", "Certificate hash plus path", - "", G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (gobject_class, PROP_PATH, g_param_spec_string ("path", "Path", "Certificate origin path", "", G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); @@ -165,13 +151,6 @@ gck_roots_certificate_new (const gchar *unique, const gchar *path) } const gchar* -gck_roots_certificate_get_unique (GckRootsCertificate *self) -{ - g_return_val_if_fail (GCK_IS_ROOTS_CERTIFICATE (self), ""); - return self->unique; -} - -const gchar* gck_roots_certificate_get_path (GckRootsCertificate *self) { g_return_val_if_fail (GCK_IS_ROOTS_CERTIFICATE (self), ""); diff --git a/pkcs11/roots-store/gck-roots-module.c b/pkcs11/roots-store/gck-roots-module.c index 046e82bf..d209246f 100644 --- a/pkcs11/roots-store/gck-roots-module.c +++ b/pkcs11/roots-store/gck-roots-module.c @@ -21,6 +21,7 @@ #include "config.h" +#include "gck-roots-store.h" #include "gck-roots-module.h" #include "gck-roots-certificate.h" @@ -254,7 +255,9 @@ static CK_RV gck_roots_module_real_refresh_token (GckModule *base) { GckRootsModule *self = GCK_ROOTS_MODULE (base); +#ifdef ROOT_CERTIFICATES gck_file_tracker_refresh (self->tracker, FALSE); +#endif return CKR_OK; } @@ -266,12 +269,14 @@ gck_roots_module_constructor (GType type, guint n_props, GObjectConstructParam * g_return_val_if_fail (self, NULL); +#ifdef ROOT_CERTIFICATES if (!self->directory) self->directory = g_strdup (ROOT_CERTIFICATES); self->tracker = gck_file_tracker_new (self->directory, "*", "*.0"); g_signal_connect (self->tracker, "file-added", G_CALLBACK (file_load), self); g_signal_connect (self->tracker, "file-changed", G_CALLBACK (file_load), self); g_signal_connect (self->tracker, "file-removed", G_CALLBACK (file_remove), self); +#endif manager = gck_module_get_manager (GCK_MODULE (self)); gck_manager_add_property_index (manager, "unique", TRUE); @@ -333,3 +338,14 @@ gck_roots_module_class_init (GckRootsModuleClass *klass) module_class->slot_info = &gck_roots_module_slot_info; module_class->token_info = &gck_roots_module_token_info; } + +/* --------------------------------------------------------------------------------------- + * PUBLIC + */ + +CK_FUNCTION_LIST_PTR +gck_roots_store_get_functions (void) +{ + gck_crypto_initialize (); + return gck_roots_module_function_list; +} diff --git a/pkcs11/roots-store/gck-roots-module.h b/pkcs11/roots-store/gck-roots-module.h index 4f1edb6a..29f73e7b 100644 --- a/pkcs11/roots-store/gck-roots-module.h +++ b/pkcs11/roots-store/gck-roots-module.h @@ -40,8 +40,6 @@ struct _GckRootsModuleClass { GckModuleClass parent_class; }; -GCK_DECLARE_MODULE (gck_roots_module); - GType gck_roots_module_get_type (void); #endif /* __GCK_ROOTS_MODULE_H__ */ diff --git a/pkcs11/roots-store/gck-roots-standalone.c b/pkcs11/roots-store/gck-roots-standalone.c index 11b9db6f..f81ceb32 100644 --- a/pkcs11/roots-store/gck-roots-standalone.c +++ b/pkcs11/roots-store/gck-roots-standalone.c @@ -23,12 +23,14 @@ #include "config.h" -#include "gck-roots-module.h" +#include "gck-roots-store.h" #include "gck/gck-crypto.h" #include "common/gkr-secure-memory.h" +#include <glib-object.h> + #include "pkcs11/pkcs11.h" /* Module callbacks for secure memory */ @@ -53,6 +55,6 @@ C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list) gck_crypto_initialize (); - *list = gck_roots_module_function_list; + *list = gck_roots_store_get_functions (); return CKR_OK; } diff --git a/pkcs11/roots-store/gck-roots-store.h b/pkcs11/roots-store/gck-roots-store.h new file mode 100644 index 00000000..f49d796a --- /dev/null +++ b/pkcs11/roots-store/gck-roots-store.h @@ -0,0 +1,29 @@ +/* + * gnome-keyring + * + * Copyright (C) 2008 Stefan Walter + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This program 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + +#ifndef __GCK_ROOTS_STORE_H__ +#define __GCK_ROOTS_STORE_H__ + +#include "pkcs11/pkcs11.h" + +CK_FUNCTION_LIST_PTR gck_roots_store_get_functions (void); + +#endif /* __GCK_ROOTS_STORE_H__ */ diff --git a/pkcs11/rpc-layer/gck-rpc-layer.h b/pkcs11/rpc-layer/gck-rpc-layer.h index 9eed5bfd..74861939 100644 --- a/pkcs11/rpc-layer/gck-rpc-layer.h +++ b/pkcs11/rpc-layer/gck-rpc-layer.h @@ -1,5 +1,5 @@ -#ifndef GCKRPC_H_ -#define GCKRPC_H_ +#ifndef GCKRPC_LAYER_H_ +#define GCKRPC_LAYER_H_ #include "pkcs11/pkcs11.h" @@ -17,4 +17,4 @@ void gck_rpc_layer_uninitialize (void); /* Accept a new connection. Should be called when above fd has read */ void gck_rpc_layer_accept (void); -#endif /* GCKRPC_H_ */ +#endif /* GCKRPC_LAYER_H_ */ |