[gnome-keyring/gck-work] [gck] Rework testing and make mock module.



commit cb44b86f44a184738d6815d035a589594cdedf14
Author: Stef Walter <stef memberwebs com>
Date:   Sat Sep 18 17:08:59 2010 +0000

    [gck] Rework testing and make mock module.
    
    Make mock Pkcs#11 module better modularized, and available to other
    tests of other modules. Add more test helpers.

 gck/Makefile.am                 |   22 +-
 gck/gck-mock.c                  | 1787 +++++++++++++++++++++++++++++++++++++++
 gck/gck-mock.h                  |  409 +++++++++
 gck/gck-test.c                  |  165 ++++
 gck/gck-test.h                  |   68 ++
 gck/tests/Makefile.am           |   14 +-
 gck/tests/gck-test-module.c     | 1693 -------------------------------------
 gck/tests/gck-test.h            |   38 +-
 gck/tests/mock-test-module.c    |   10 +
 gck/tests/test-gck-crypto.c     |   48 +-
 gck/tests/test-gck-enumerator.c |    2 +-
 gck/tests/test-gck-module.c     |    4 +-
 gck/tests/test-gck-modules.c    |    2 +-
 gck/tests/test-gck-object.c     |    4 +-
 gck/tests/test-gck-session.c    |    2 +-
 gck/tests/test-gck-slot.c       |    2 +-
 16 files changed, 2492 insertions(+), 1778 deletions(-)
---
diff --git a/gck/Makefile.am b/gck/Makefile.am
index cd93099..7c887bb 100644
--- a/gck/Makefile.am
+++ b/gck/Makefile.am
@@ -1,3 +1,15 @@
+
+if WITH_TESTS
+TESTS_DIR = tests
+TESTS_SOURCES = gck-mock.c gck-mock.h gck-test.c gck-test.h
+else
+TESTS_DIR =
+TESTS_SOURCES
+endif
+
+SUBDIRS = . \
+	$(TESTS_DIR)
+
 incdir = $(includedir)/gck
 
 inc_HEADERS = \
@@ -28,6 +40,7 @@ libgck_la_SOURCES = \
 	gck-session.c \
 	gck-slot.c \
 	gck-uri.c \
+	$(TESTS_SOURCES) \
 	$(BUILT_SOURCES)
 
 libgck_la_LDFLAGS = \
@@ -60,12 +73,3 @@ DISTCLEANFILES = \
 
 gck-$(GCK_MAJOR).pc: gck.pc
 	cp gck.pc gck-$(GCK_MAJOR).pc
-
-if WITH_TESTS
-TESTS_DIR = tests
-else
-TESTS_DIR =
-endif
-
-SUBDIRS = . \
-	$(TESTS_DIR)
diff --git a/gck/gck-mock.c b/gck/gck-mock.c
new file mode 100644
index 0000000..3887896
--- /dev/null
+++ b/gck/gck-mock.c
@@ -0,0 +1,1787 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2010 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.h"
+#include "gck-mock.h"
+
+#include "pkcs11/pkcs11.h"
+#include "pkcs11/pkcs11i.h"
+
+#include <glib.h>
+
+#include <string.h>
+
+/*
+ * This is *NOT* how you'd want to implement a PKCS#11 module. This
+ * fake module simply provides enough for gck library to test against.
+ * It doesn't pass any tests, or behave as expected from a PKCS#11 module.
+ */
+
+
+static gboolean initialized = FALSE;
+static gchar *the_pin = NULL;
+static gulong n_the_pin = 0;
+
+static gboolean logged_in = FALSE;
+static CK_USER_TYPE user_type = 0;
+static CK_FUNCTION_LIST functionList;
+
+typedef enum _Operation {
+	OP_FIND = 1,
+	OP_CRYPTO
+} Operation;
+
+typedef struct _Session {
+	CK_SESSION_HANDLE handle;
+	CK_SESSION_INFO info;
+	GHashTable *objects;
+
+	Operation operation;
+
+	/* For find operations */
+	GList *matches;
+
+	/* For crypto operations */
+	CK_OBJECT_HANDLE crypto_key;
+	CK_ATTRIBUTE_TYPE crypto_method;
+	CK_MECHANISM_TYPE crypto_mechanism;
+	CK_BBOOL want_context_login;
+
+	/* For 'signing' with CKM_MOCK_PREFIX */
+	CK_BYTE sign_prefix[128];
+	CK_ULONG n_sign_prefix;
+} Session;
+
+static guint unique_identifier = 100;
+static GHashTable *the_sessions = NULL;
+static GHashTable *the_objects = NULL;
+
+enum {
+	PRIVATE_KEY_CAPITALIZE = 3,
+	PUBLIC_KEY_CAPITALIZE = 4,
+	PRIVATE_KEY_PREFIX = 5,
+	PUBLIC_KEY_PREFIX = 6
+};
+
+#define SIGNED_PREFIX "signed-prefix:"
+
+static void
+free_session (gpointer data)
+{
+	Session *sess = (Session*)data;
+	if (sess)
+		g_hash_table_destroy (sess->objects);
+	g_free (sess);
+}
+
+static GckAttributes*
+lookup_object (Session *session, CK_OBJECT_HANDLE hObject)
+{
+	GckAttributes *attrs;
+	attrs = g_hash_table_lookup (the_objects, GUINT_TO_POINTER (hObject));
+	if (!attrs)
+		attrs = g_hash_table_lookup (session->objects, GUINT_TO_POINTER (hObject));
+	return attrs;
+}
+
+CK_OBJECT_HANDLE
+gck_mock_module_take_object (GckAttributes *attrs)
+{
+	gboolean token;
+	guint handle;
+
+	g_return_val_if_fail (the_objects, 0);
+
+	handle = ++unique_identifier;
+	if (gck_attributes_find_boolean (attrs, CKA_TOKEN, &token))
+		g_return_val_if_fail (token == TRUE, 0);
+	else
+		gck_attributes_add_boolean (attrs, CKA_TOKEN, TRUE);
+	g_hash_table_insert (the_objects, GUINT_TO_POINTER (handle), attrs);
+	return handle;
+}
+
+void
+gck_mock_module_enumerate_objects (CK_SESSION_HANDLE handle, GckMockEnumerator func,
+                                   gpointer user_data)
+{
+	GHashTableIter iter;
+	gpointer key;
+	gpointer value;
+	Session *session;
+
+	g_assert (the_objects);
+	g_assert (func);
+
+	/* Token objects */
+	g_hash_table_iter_init (&iter, the_objects);
+	while (g_hash_table_iter_next (&iter, &key, &value)) {
+		if (!(func) (GPOINTER_TO_UINT (key), value, user_data))
+			return;
+	}
+
+	/* session objects */
+	if (handle) {
+		session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (handle));
+		if (session) {
+			g_hash_table_iter_init (&iter, session->objects);
+			while (g_hash_table_iter_next (&iter, &key, &value)) {
+				if (!(func) (GPOINTER_TO_UINT (key), value, user_data))
+					return;
+			}
+		}
+	}
+}
+
+typedef struct _FindObject {
+	CK_ATTRIBUTE_PTR attrs;
+	CK_ULONG n_attrs;
+	CK_OBJECT_HANDLE object;
+} FindObject;
+
+static gboolean
+enumerate_and_find_object (CK_OBJECT_HANDLE object, GckAttributes *attrs, gpointer user_data)
+{
+	FindObject *ctx = user_data;
+	CK_ATTRIBUTE_PTR match;
+	GckAttribute *attr;
+	CK_ULONG i;
+
+	for (i = 0; i < ctx->n_attrs; ++i) {
+		match = ctx->attrs + i;
+		attr = gck_attributes_find (attrs, match->type);
+		if (!attr)
+			return TRUE; /* Continue */
+
+		if (attr->length != match->ulValueLen ||
+		    memcmp (attr->value, match->pValue, attr->length) != 0)
+			return TRUE; /* Continue */
+	}
+
+	ctx->object = object;
+	return FALSE; /* Stop iteration */
+}
+
+CK_OBJECT_HANDLE
+gck_mock_module_find_object (CK_SESSION_HANDLE session, CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
+{
+	FindObject ctx;
+
+	ctx.attrs = attrs;
+	ctx.n_attrs = n_attrs;
+	ctx.object = 0;
+
+	gck_mock_module_enumerate_objects (session, enumerate_and_find_object, &ctx);
+
+	return ctx.object;
+}
+
+static gboolean
+enumerate_and_count_objects (CK_OBJECT_HANDLE object, GckAttributes *attrs, gpointer user_data)
+{
+	guint *n_objects = user_data;
+	++(*n_objects);
+	return TRUE; /* Continue */
+}
+
+guint
+gck_mock_module_count_objects (CK_SESSION_HANDLE session)
+{
+	guint n_objects = 0;
+	gck_mock_module_enumerate_objects (session, enumerate_and_count_objects, &n_objects);
+	return n_objects;
+}
+
+void
+gck_mock_module_set_object (CK_OBJECT_HANDLE object, CK_ATTRIBUTE_PTR attrs,
+                            CK_ULONG n_attrs)
+{
+	CK_ULONG i;
+	GckAttributes *atts;
+	GckAttribute *attr;
+	CK_ATTRIBUTE_PTR set;
+
+	g_return_if_fail (object != 0);
+	g_return_if_fail (the_objects);
+
+	atts = g_hash_table_lookup (the_objects, GUINT_TO_POINTER (object));
+	g_return_if_fail (atts);
+
+	for (i = 0; i < n_attrs; ++i) {
+		set = attrs + i;
+		attr = gck_attributes_find (atts, set->type);
+		if (!attr) {
+			gck_attributes_add_data (atts, set->type, set->pValue, set->ulValueLen);
+		} else {
+			gck_attribute_clear (attr);
+			gck_attribute_init (attr, set->type, set->pValue, set->ulValueLen);
+		}
+	}
+}
+
+void
+gck_mock_module_set_pin (const gchar *password)
+{
+	g_free (the_pin);
+	the_pin = g_strdup (password);
+	n_the_pin = strlen (password);
+}
+
+CK_RV
+gck_mock_C_Initialize (CK_VOID_PTR pInitArgs)
+{
+	GckAttributes *attrs;
+	CK_ULONG value;
+	CK_C_INITIALIZE_ARGS_PTR args;
+
+	g_return_val_if_fail (initialized == FALSE, CKR_CRYPTOKI_ALREADY_INITIALIZED);
+
+	args = (CK_C_INITIALIZE_ARGS_PTR)pInitArgs;
+	if (args) {
+		g_return_val_if_fail(
+		              (args->CreateMutex == NULL && args->DestroyMutex == NULL &&
+		               args->LockMutex == NULL && args->UnlockMutex == NULL) ||
+		              (args->CreateMutex != NULL && args->DestroyMutex != NULL &&
+		               args->LockMutex != NULL && args->UnlockMutex != NULL),
+		               CKR_ARGUMENTS_BAD);
+
+		/* Flags should allow OS locking and os threads */
+		g_return_val_if_fail ((args->flags & CKF_OS_LOCKING_OK), CKR_CANT_LOCK);
+		g_return_val_if_fail ((args->flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS) == 0, CKR_NEED_TO_CREATE_THREADS);
+	}
+
+	the_pin = g_strdup ("booo");
+	n_the_pin = strlen (the_pin);
+	the_sessions = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, free_session);
+	the_objects = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)gck_attributes_unref);
+
+	/* Our token object */
+	attrs = gck_attributes_new ();
+	gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_DATA);
+	gck_attributes_add_string (attrs, CKA_LABEL, "TEST LABEL");
+	g_hash_table_insert (the_objects, GUINT_TO_POINTER (2), attrs);
+
+	/* Private capitalize key */
+	value = CKM_MOCK_CAPITALIZE;
+	attrs = gck_attributes_new ();
+	gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_PRIVATE_KEY);
+	gck_attributes_add_string (attrs, CKA_LABEL, "Private Capitalize Key");
+	gck_attributes_add_data (attrs, CKA_ALLOWED_MECHANISMS, &value, sizeof (value));
+	gck_attributes_add_boolean (attrs, CKA_DECRYPT, CK_TRUE);
+	gck_attributes_add_boolean (attrs, CKA_PRIVATE, CK_TRUE);
+	gck_attributes_add_boolean (attrs, CKA_WRAP, CK_TRUE);
+	gck_attributes_add_boolean (attrs, CKA_UNWRAP, CK_TRUE);
+	gck_attributes_add_boolean (attrs, CKA_DERIVE, CK_TRUE);
+	gck_attributes_add_string (attrs, CKA_VALUE, "value");
+	gck_attributes_add_string (attrs, CKA_GNOME_UNIQUE, "unique1");
+	g_hash_table_insert (the_objects, GUINT_TO_POINTER (PRIVATE_KEY_CAPITALIZE), attrs);
+
+	/* Public capitalize key */
+	value = CKM_MOCK_CAPITALIZE;
+	attrs = gck_attributes_new ();
+	gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_PUBLIC_KEY);
+	gck_attributes_add_string (attrs, CKA_LABEL, "Public Capitalize Key");
+	gck_attributes_add_data (attrs, CKA_ALLOWED_MECHANISMS, &value, sizeof (value));
+	gck_attributes_add_boolean (attrs, CKA_ENCRYPT, CK_TRUE);
+	gck_attributes_add_boolean (attrs, CKA_PRIVATE, CK_FALSE);
+	gck_attributes_add_string (attrs, CKA_VALUE, "value");
+	gck_attributes_add_string (attrs, CKA_GNOME_UNIQUE, "unique2");
+	g_hash_table_insert (the_objects, GUINT_TO_POINTER (PUBLIC_KEY_CAPITALIZE), attrs);
+
+	/* Private prefix key */
+	value = CKM_MOCK_PREFIX;
+	attrs = gck_attributes_new ();
+	gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_PRIVATE_KEY);
+	gck_attributes_add_string (attrs, CKA_LABEL, "Private prefix key");
+	gck_attributes_add_data (attrs, CKA_ALLOWED_MECHANISMS, &value, sizeof (value));
+	gck_attributes_add_boolean (attrs, CKA_SIGN, CK_TRUE);
+	gck_attributes_add_boolean (attrs, CKA_PRIVATE, CK_TRUE);
+	gck_attributes_add_boolean (attrs, CKA_ALWAYS_AUTHENTICATE, CK_TRUE);
+	gck_attributes_add_string (attrs, CKA_VALUE, "value");
+	gck_attributes_add_string (attrs, CKA_GNOME_UNIQUE, "unique3");
+	g_hash_table_insert (the_objects, GUINT_TO_POINTER (PRIVATE_KEY_PREFIX), attrs);
+
+	/* Private prefix key */
+	value = CKM_MOCK_PREFIX;
+	attrs = gck_attributes_new ();
+	gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_PUBLIC_KEY);
+	gck_attributes_add_string (attrs, CKA_LABEL, "Public prefix key");
+	gck_attributes_add_data (attrs, CKA_ALLOWED_MECHANISMS, &value, sizeof (value));
+	gck_attributes_add_boolean (attrs, CKA_VERIFY, CK_TRUE);
+	gck_attributes_add_boolean (attrs, CKA_PRIVATE, CK_FALSE);
+	gck_attributes_add_string (attrs, CKA_VALUE, "value");
+	gck_attributes_add_string (attrs, CKA_GNOME_UNIQUE, "unique4");
+	g_hash_table_insert (the_objects, GUINT_TO_POINTER (PUBLIC_KEY_PREFIX), attrs);
+
+	initialized = TRUE;
+	return CKR_OK;
+}
+
+CK_RV
+gck_mock_validate_and_C_Initialize (CK_VOID_PTR pInitArgs)
+{
+	CK_C_INITIALIZE_ARGS_PTR args;
+	void *mutex;
+	CK_RV rv;
+
+	args = (CK_C_INITIALIZE_ARGS_PTR)pInitArgs;
+	if (args) {
+		g_assert ((args->CreateMutex) (NULL) == CKR_ARGUMENTS_BAD && "CreateMutex succeeded wrong");
+		g_assert ((args->DestroyMutex) (NULL) == CKR_MUTEX_BAD && "DestroyMutex succeeded wrong");
+		g_assert ((args->LockMutex) (NULL) == CKR_MUTEX_BAD && "LockMutex succeeded wrong");
+		g_assert ((args->UnlockMutex) (NULL) == CKR_MUTEX_BAD && "UnlockMutex succeeded wrong");
+
+		/* Try to create an actual mutex */
+		rv = (args->CreateMutex) (&mutex);
+		g_assert (rv == CKR_OK && "CreateMutex g_assert_not_reacheded");
+		g_assert (mutex != NULL && "CreateMutex created null mutex");
+
+		/* Try and lock the mutex */
+		rv = (args->LockMutex) (mutex);
+		g_assert (rv == CKR_OK && "LockMutex g_assert_not_reacheded");
+
+		/* Try and unlock the mutex */
+		rv = (args->UnlockMutex) (mutex);
+		g_assert (rv == CKR_OK && "UnlockMutex g_assert_not_reacheded");
+
+		/* Try and destroy the mutex */
+		rv = (args->DestroyMutex) (mutex);
+		g_assert (rv == CKR_OK && "DestroyMutex g_assert_not_reacheded");
+	}
+
+	return gck_mock_C_Initialize (pInitArgs);
+}
+
+CK_RV
+gck_mock_C_Finalize (CK_VOID_PTR pReserved)
+{
+	g_return_val_if_fail (pReserved == NULL, CKR_ARGUMENTS_BAD);
+	g_return_val_if_fail (initialized == TRUE, CKR_CRYPTOKI_NOT_INITIALIZED);
+
+	initialized = FALSE;
+	logged_in = FALSE;
+	g_hash_table_destroy (the_objects);
+	the_objects = NULL;
+
+	g_hash_table_destroy (the_sessions);
+	the_sessions = NULL;
+
+	g_free (the_pin);
+	return CKR_OK;
+}
+
+static const CK_INFO TEST_INFO = {
+	{ CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR },
+	"TEST MANUFACTURER              ",
+	0,
+	"TEST LIBRARY                   ",
+	{ 45, 145 }
+};
+
+CK_RV
+gck_mock_C_GetInfo (CK_INFO_PTR pInfo)
+{
+	g_return_val_if_fail (pInfo, CKR_ARGUMENTS_BAD);
+	memcpy (pInfo, &TEST_INFO, sizeof (*pInfo));
+	return CKR_OK;
+}
+
+CK_RV
+gck_mock_C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list)
+{
+	g_return_val_if_fail (list, CKR_ARGUMENTS_BAD);
+	*list = &functionList;
+	return CKR_OK;
+}
+
+/*
+ * Two slots
+ *  ONE: token present
+ *  TWO: token not present
+ */
+
+CK_RV
+gck_mock_C_GetSlotList (CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount)
+{
+	CK_ULONG count;
+
+	g_return_val_if_fail (pulCount, CKR_ARGUMENTS_BAD);
+
+	count = tokenPresent ? 1 : 2;
+
+	/* Application only wants to know the number of slots. */
+	if (pSlotList == NULL) {
+		*pulCount = count;
+		return CKR_OK;
+	}
+
+	if (*pulCount < count)
+		g_return_val_if_reached (CKR_BUFFER_TOO_SMALL);
+
+	*pulCount = count;
+	pSlotList[0] = GCK_MOCK_SLOT_ONE_ID;
+	if (!tokenPresent)
+		pSlotList[1] = GCK_MOCK_SLOT_TWO_ID;
+
+	return CKR_OK;
+}
+
+/* Update gck-mock.h URIs when updating this */
+
+static const CK_SLOT_INFO TEST_INFO_ONE = {
+	"TEST SLOT                                                       ",
+	"TEST MANUFACTURER              ",
+	CKF_TOKEN_PRESENT | CKF_REMOVABLE_DEVICE,
+	{ 55, 155 },
+	{ 65, 165 },
+};
+
+/* Update gck-mock.h URIs when updating this */
+
+static const CK_SLOT_INFO TEST_INFO_TWO = {
+	"TEST SLOT                                                       ",
+	"TEST MANUFACTURER              ",
+	CKF_REMOVABLE_DEVICE,
+	{ 55, 155 },
+	{ 65, 165 },
+};
+
+CK_RV
+gck_mock_C_GetSlotInfo (CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
+{
+	g_return_val_if_fail (pInfo, CKR_ARGUMENTS_BAD);
+
+	if (slotID == GCK_MOCK_SLOT_ONE_ID) {
+		memcpy (pInfo, &TEST_INFO_ONE, sizeof (*pInfo));
+		return CKR_OK;
+	} else if (slotID == GCK_MOCK_SLOT_TWO_ID) {
+		memcpy (pInfo, &TEST_INFO_TWO, sizeof (*pInfo));
+		return CKR_OK;
+	} else {
+		g_return_val_if_reached (CKR_SLOT_ID_INVALID);
+	}
+}
+
+/* Update gck-mock.h URIs when updating this */
+
+static const CK_TOKEN_INFO TEST_TOKEN_ONE = {
+	"TEST LABEL                      ",
+	"TEST MANUFACTURER               ",
+	"TEST MODEL      ",
+	"TEST SERIAL     ",
+	CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED | CKF_CLOCK_ON_TOKEN | CKF_TOKEN_INITIALIZED,
+	1,
+	2,
+	3,
+	4,
+	5,
+	6,
+	7,
+	8,
+	9,
+	10,
+	{ 75, 175 },
+	{ 85, 185 },
+	{ '1', '9', '9', '9', '0', '5', '2', '5', '0', '9', '1', '9', '5', '9', '0', '0' }
+};
+
+CK_RV
+gck_mock_C_GetTokenInfo (CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
+{
+	g_return_val_if_fail (pInfo != NULL, CKR_ARGUMENTS_BAD);
+
+	if (slotID == GCK_MOCK_SLOT_ONE_ID) {
+		memcpy (pInfo, &TEST_TOKEN_ONE, sizeof (*pInfo));
+		return CKR_OK;
+	} else if (slotID == GCK_MOCK_SLOT_TWO_ID) {
+		return CKR_TOKEN_NOT_PRESENT;
+	} else {
+		g_return_val_if_reached (CKR_SLOT_ID_INVALID);
+	}
+}
+
+CK_RV
+gck_mock_fail_C_GetTokenInfo (CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
+{
+	return CKR_GENERAL_ERROR;
+}
+
+/*
+ * TWO mechanisms:
+ *  CKM_MOCK_CAPITALIZE
+ *  CKM_MOCK_PREFIX
+ */
+
+CK_RV
+gck_mock_C_GetMechanismList (CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList,
+                             CK_ULONG_PTR pulCount)
+{
+	g_return_val_if_fail (slotID == GCK_MOCK_SLOT_ONE_ID, CKR_SLOT_ID_INVALID);
+	g_return_val_if_fail (pulCount, CKR_ARGUMENTS_BAD);
+
+	/* Application only wants to know the number of slots. */
+	if (pMechanismList == NULL) {
+		*pulCount = 2;
+		return CKR_OK;
+	}
+
+	if (*pulCount != 2)
+		g_return_val_if_reached (CKR_BUFFER_TOO_SMALL);
+
+	pMechanismList[0] = CKM_MOCK_CAPITALIZE;
+	pMechanismList[1] = CKM_MOCK_PREFIX;
+	return CKR_OK;
+}
+
+static const CK_MECHANISM_INFO TEST_MECH_CAPITALIZE = {
+	512, 4096, 0
+};
+
+static const CK_MECHANISM_INFO TEST_MECH_PREFIX = {
+	2048, 2048, 0
+};
+
+CK_RV
+gck_mock_C_GetMechanismInfo (CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
+                             CK_MECHANISM_INFO_PTR pInfo)
+{
+	g_return_val_if_fail (slotID == GCK_MOCK_SLOT_ONE_ID, CKR_SLOT_ID_INVALID);
+	g_return_val_if_fail (pInfo, CKR_ARGUMENTS_BAD);
+
+	if (type == CKM_MOCK_CAPITALIZE) {
+		memcpy (pInfo, &TEST_MECH_CAPITALIZE, sizeof (*pInfo));
+		return CKR_OK;
+	} else if (type == CKM_MOCK_PREFIX) {
+		memcpy (pInfo, &TEST_MECH_PREFIX, sizeof (*pInfo));
+		return CKR_OK;
+	} else {
+		g_return_val_if_reached (CKR_MECHANISM_INVALID);
+	}
+}
+
+CK_RV
+gck_mock_specific_args_C_InitToken (CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen,
+                                    CK_UTF8CHAR_PTR pLabel)
+{
+	g_return_val_if_fail (slotID == GCK_MOCK_SLOT_ONE_ID, CKR_SLOT_ID_INVALID);
+
+	g_return_val_if_fail (pPin, CKR_PIN_INVALID);
+	g_return_val_if_fail (strlen ("TEST PIN") == ulPinLen, CKR_PIN_INVALID);
+	g_return_val_if_fail (strncmp ((gchar*)pPin, "TEST PIN", ulPinLen) == 0, CKR_PIN_INVALID);
+	g_return_val_if_fail (pLabel != NULL, CKR_PIN_INVALID);
+	g_return_val_if_fail (strcmp ((gchar*)pPin, "TEST LABEL") == 0, CKR_PIN_INVALID);
+
+	g_free (the_pin);
+	the_pin = g_strndup ((gchar*)pPin, ulPinLen);
+	n_the_pin = ulPinLen;
+	return CKR_OK;
+}
+
+CK_RV
+gck_mock_unsupported_C_WaitForSlotEvent (CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved)
+{
+	return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+gck_mock_C_OpenSession (CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication,
+                        CK_NOTIFY Notify, CK_SESSION_HANDLE_PTR phSession)
+{
+	Session *sess;
+
+	g_return_val_if_fail (slotID == GCK_MOCK_SLOT_ONE_ID || slotID == GCK_MOCK_SLOT_TWO_ID, CKR_SLOT_ID_INVALID);
+	g_return_val_if_fail (phSession != NULL, CKR_ARGUMENTS_BAD);
+	g_return_val_if_fail ((flags & CKF_SERIAL_SESSION) == CKF_SERIAL_SESSION, CKR_SESSION_PARALLEL_NOT_SUPPORTED);
+
+	sess = g_new0 (Session, 1);
+	sess->handle = ++unique_identifier;
+	sess->info.flags = flags;
+	sess->info.slotID = slotID;
+	sess->info.state = 0;
+	sess->info.ulDeviceError = 1414;
+	sess->objects = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)gck_attributes_unref);
+	*phSession = sess->handle;
+
+	g_hash_table_replace (the_sessions, GUINT_TO_POINTER (sess->handle), sess);
+	return CKR_OK;
+}
+
+CK_RV
+gck_mock_fail_C_OpenSession (CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication,
+                             CK_NOTIFY Notify, CK_SESSION_HANDLE_PTR phSession)
+{
+	return CKR_GENERAL_ERROR;
+}
+
+CK_RV
+gck_mock_C_CloseSession (CK_SESSION_HANDLE hSession)
+{
+	Session *session;
+
+	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
+	g_assert (session != NULL && "No such session found");
+	if (!session)
+		return CKR_SESSION_HANDLE_INVALID;
+
+	g_hash_table_remove (the_sessions, GUINT_TO_POINTER (hSession));
+	return CKR_OK;
+}
+
+CK_RV
+gck_mock_C_CloseAllSessions (CK_SLOT_ID slotID)
+{
+	g_return_val_if_fail (slotID == GCK_MOCK_SLOT_ONE_ID, CKR_SLOT_ID_INVALID);
+
+	g_hash_table_remove_all (the_sessions);
+	return CKR_OK;
+}
+
+CK_RV
+gck_mock_C_GetFunctionStatus (CK_SESSION_HANDLE hSession)
+{
+	return CKR_FUNCTION_NOT_PARALLEL;
+}
+
+CK_RV
+gck_mock_C_CancelFunction (CK_SESSION_HANDLE hSession)
+{
+	return CKR_FUNCTION_NOT_PARALLEL;
+}
+
+CK_RV
+gck_mock_C_GetSessionInfo (CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo)
+{
+	Session *session;
+
+	g_return_val_if_fail (pInfo != NULL, CKR_ARGUMENTS_BAD);
+
+	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
+	g_assert (session != NULL && "No such session found");
+	if (!session)
+		return CKR_SESSION_HANDLE_INVALID;
+
+	if (logged_in) {
+		if (session->info.flags & CKF_RW_SESSION)
+			session->info.state = CKS_RW_USER_FUNCTIONS;
+		else
+			session->info.state = CKS_RO_USER_FUNCTIONS;
+	} else {
+		if (session->info.flags & CKF_RW_SESSION)
+			session->info.state = CKS_RW_PUBLIC_SESSION;
+		else
+			session->info.state = CKS_RO_PUBLIC_SESSION;
+	}
+
+	memcpy (pInfo, &session->info, sizeof (*pInfo));
+	return CKR_OK;
+}
+
+CK_RV
+gck_mock_fail_C_GetSessionInfo (CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo)
+{
+	return CKR_GENERAL_ERROR;
+}
+
+CK_RV
+gck_mock_C_InitPIN (CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pPin,
+                    CK_ULONG ulPinLen)
+{
+	Session *session;
+
+	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
+	g_return_val_if_fail (session, CKR_SESSION_HANDLE_INVALID);
+
+	g_free (the_pin);
+	the_pin = g_strndup ((gchar*)pPin, ulPinLen);
+	n_the_pin = ulPinLen;
+	return CKR_OK;
+}
+
+CK_RV
+gck_mock_C_SetPIN (CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin,
+                   CK_ULONG ulOldLen, CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewLen)
+{
+	Session *session;
+	gchar *old;
+
+	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
+	g_return_val_if_fail (session, CKR_SESSION_HANDLE_INVALID);
+
+	old = g_strndup ((gchar*)pOldPin, ulOldLen);
+	if (!old || !g_str_equal (old, the_pin))
+		return CKR_PIN_INCORRECT;
+
+	g_free (the_pin);
+	the_pin = g_strndup ((gchar*)pNewPin, ulNewLen);
+	n_the_pin = ulNewLen;
+	return CKR_OK;
+}
+
+CK_RV
+gck_mock_unsupported_C_GetOperationState (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState,
+                                          CK_ULONG_PTR pulOperationStateLen)
+{
+	return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+gck_mock_unsupported_C_SetOperationState (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState,
+                                          CK_ULONG ulOperationStateLen, CK_OBJECT_HANDLE hEncryptionKey,
+                                          CK_OBJECT_HANDLE hAuthenticationKey)
+{
+	return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+gck_mock_C_Login (CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
+                  CK_UTF8CHAR_PTR pPin, CK_ULONG pPinLen)
+{
+	Session *session;
+
+	g_return_val_if_fail (userType == CKU_SO ||
+	                      userType == CKU_USER ||
+	                      userType == CKU_CONTEXT_SPECIFIC,
+	                      CKR_USER_TYPE_INVALID);
+
+	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
+	g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
+	g_return_val_if_fail (logged_in == FALSE, CKR_USER_ALREADY_LOGGED_IN);
+
+	if (!pPin)
+		return CKR_PIN_INCORRECT;
+
+	if (pPinLen != strlen (the_pin))
+		return CKR_PIN_INCORRECT;
+	if (strncmp ((gchar*)pPin, the_pin, pPinLen) != 0)
+		return CKR_PIN_INCORRECT;
+
+	if (userType == CKU_CONTEXT_SPECIFIC) {
+		g_return_val_if_fail (session->want_context_login == TRUE, CKR_OPERATION_NOT_INITIALIZED);
+		session->want_context_login = CK_FALSE;
+	} else {
+		logged_in = TRUE;
+		user_type = userType;
+	}
+
+	return CKR_OK;
+}
+
+CK_RV
+gck_mock_C_Logout (CK_SESSION_HANDLE hSession)
+{
+	Session *session;
+
+	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
+	g_assert (session != NULL && "No such session found");
+	if (!session)
+		return CKR_SESSION_HANDLE_INVALID;
+
+	g_assert (logged_in && "Not logged in");
+	logged_in = FALSE;
+	user_type = 0;
+	return CKR_OK;
+}
+
+CK_RV
+gck_mock_C_CreateObject (CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate,
+                         CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject)
+{
+	GckAttributes *attrs;
+	Session *session;
+	gboolean token, priv;
+	CK_OBJECT_CLASS klass;
+	CK_OBJECT_HANDLE object;
+	GckAttribute *attr;
+	CK_ULONG i;
+
+	g_return_val_if_fail (phObject, CKR_ARGUMENTS_BAD);
+
+	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
+	g_return_val_if_fail (session, CKR_SESSION_HANDLE_INVALID);
+
+	attrs = gck_attributes_new ();
+	for (i = 0; i < ulCount; ++i)
+		gck_attributes_add_data (attrs, pTemplate[i].type, pTemplate[i].pValue, pTemplate[i].ulValueLen);
+
+	if (gck_attributes_find_boolean (attrs, CKA_PRIVATE, &priv) && priv) {
+		if (!logged_in) {
+			gck_attributes_unref (attrs);
+			return CKR_USER_NOT_LOGGED_IN;
+		}
+	}
+
+	/* In order to create a credential we must check CK_VALUE */
+	if (gck_attributes_find_ulong (attrs, CKA_CLASS, &klass) && klass == CKO_G_CREDENTIAL) {
+		if (gck_attributes_find_ulong (attrs, CKA_G_OBJECT, &object)) {
+			attr = gck_attributes_find (attrs, CKA_VALUE);
+			if (!attr || attr->length != n_the_pin ||
+			    memcmp (attr->value, the_pin, attr->length) != 0) {
+				gck_attributes_unref (attrs);
+				return CKR_PIN_INCORRECT;
+			}
+		}
+	}
+
+	*phObject = ++unique_identifier;
+	if (gck_attributes_find_boolean (attrs, CKA_TOKEN, &token) && token)
+		g_hash_table_insert (the_objects, GUINT_TO_POINTER (*phObject), attrs);
+	else
+		g_hash_table_insert (session->objects, GUINT_TO_POINTER (*phObject), attrs);
+
+	return CKR_OK;
+}
+
+CK_RV
+gck_mock_unsupported_C_CopyObject (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
+                                   CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
+                                   CK_OBJECT_HANDLE_PTR phNewObject)
+{
+	return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+gck_mock_C_DestroyObject (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
+{
+	GckAttributes *attrs;
+	Session *session;
+	gboolean priv;
+
+	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
+	g_return_val_if_fail (session, CKR_SESSION_HANDLE_INVALID);
+
+	attrs = lookup_object (session, hObject);
+	g_return_val_if_fail (attrs, CKR_OBJECT_HANDLE_INVALID);
+
+	if (gck_attributes_find_boolean (attrs, CKA_PRIVATE, &priv) && priv) {
+		if (!logged_in)
+			return CKR_USER_NOT_LOGGED_IN;
+	}
+
+	g_hash_table_remove (the_objects, GUINT_TO_POINTER (hObject));
+	g_hash_table_remove (session->objects, GUINT_TO_POINTER (hObject));
+
+	return CKR_OK;
+}
+
+CK_RV
+gck_mock_unsupported_C_GetObjectSize (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
+                                      CK_ULONG_PTR pulSize)
+{
+	return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+gck_mock_C_GetAttributeValue (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
+                              CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
+{
+	CK_ATTRIBUTE_PTR result;
+	CK_RV ret = CKR_OK;
+	GckAttributes *attrs;
+	GckAttribute *attr;
+	Session *session;
+	CK_ULONG i;
+
+	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
+	g_return_val_if_fail (session, CKR_SESSION_HANDLE_INVALID);
+
+	attrs = lookup_object (session, hObject);
+	if (!attrs) {
+		g_assert_not_reached (); /* "invalid object handle passed" */
+		return CKR_OBJECT_HANDLE_INVALID;
+	}
+
+	for (i = 0; i < ulCount; ++i) {
+		result = pTemplate + i;
+		attr = gck_attributes_find (attrs, result->type);
+		if (!attr) {
+			result->ulValueLen = (CK_ULONG)-1;
+			ret = CKR_ATTRIBUTE_TYPE_INVALID;
+			continue;
+		}
+
+		if (!result->pValue) {
+			result->ulValueLen = attr->length;
+			continue;
+		}
+
+		if (result->ulValueLen >= attr->length) {
+			memcpy (result->pValue, attr->value, attr->length);
+			continue;
+		}
+
+		result->ulValueLen = (CK_ULONG)-1;
+		ret = CKR_BUFFER_TOO_SMALL;
+	}
+
+	return ret;
+}
+
+CK_RV
+gck_mock_C_SetAttributeValue (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
+                              CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
+{
+	Session *session;
+	GckAttributes *attrs;
+	CK_ATTRIBUTE_PTR set;
+	GckAttribute *attr;
+	CK_ULONG i;
+
+	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
+	g_return_val_if_fail (session, CKR_SESSION_HANDLE_INVALID);
+
+	attrs = lookup_object (session, hObject);
+	g_return_val_if_fail (attrs, CKR_OBJECT_HANDLE_INVALID);
+
+	for (i = 0; i < ulCount; ++i) {
+		set = pTemplate + i;
+		attr = gck_attributes_find (attrs, set->type);
+		if (!attr) {
+			gck_attributes_add_data (attrs, set->type, set->pValue, set->ulValueLen);
+		} else {
+			gck_attribute_clear (attr);
+			gck_attribute_init (attr, set->type, set->pValue, set->ulValueLen);
+		}
+	}
+
+	return CKR_OK;
+}
+
+typedef struct _FindObjects {
+	CK_ATTRIBUTE_PTR template;
+	CK_ULONG count;
+	Session *session;
+} FindObjects;
+
+static gboolean
+enumerate_and_find_objects (CK_OBJECT_HANDLE object, GckAttributes *attrs, gpointer user_data)
+{
+	FindObjects *ctx = user_data;
+	CK_ATTRIBUTE_PTR match;
+	GckAttribute *attr;
+	CK_ULONG i;
+
+	for (i = 0; i < ctx->count; ++i) {
+		match = ctx->template + i;
+		attr = gck_attributes_find (attrs, match->type);
+		if (!attr)
+			return TRUE; /* Continue */
+
+		if (attr->length != match->ulValueLen ||
+		    memcmp (attr->value, match->pValue, attr->length) != 0)
+			return TRUE; /* Continue */
+	}
+
+	ctx->session->matches = g_list_prepend (ctx->session->matches, GUINT_TO_POINTER (object));
+	return TRUE; /* Continue */
+}
+
+CK_RV
+gck_mock_C_FindObjectsInit (CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate,
+                            CK_ULONG ulCount)
+{
+	Session *session;
+	FindObjects ctx;
+
+	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
+	g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
+
+	/* Starting an operation, cancels any previous one */
+	if (session->operation != 0)
+		session->operation = 0;
+
+	session->operation = OP_FIND;
+
+	ctx.template = pTemplate;
+	ctx.count = ulCount;
+	ctx.session = session;
+
+	gck_mock_module_enumerate_objects (hSession, enumerate_and_find_objects, &ctx);
+	return CKR_OK;
+}
+
+CK_RV
+gck_mock_C_FindObjects (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject,
+                        CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount)
+{
+	Session *session;
+
+	g_return_val_if_fail (phObject, CKR_ARGUMENTS_BAD);
+	g_return_val_if_fail (pulObjectCount, CKR_ARGUMENTS_BAD);
+	g_return_val_if_fail (ulMaxObjectCount != 0, CKR_ARGUMENTS_BAD);
+
+	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
+	g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
+	g_return_val_if_fail (session->operation == OP_FIND, CKR_OPERATION_NOT_INITIALIZED);
+
+	*pulObjectCount = 0;
+	while (ulMaxObjectCount > 0 && session->matches) {
+		*phObject = GPOINTER_TO_UINT (session->matches->data);
+		++phObject;
+		--ulMaxObjectCount;
+		++(*pulObjectCount);
+		session->matches = g_list_remove (session->matches, session->matches->data);
+	}
+
+	return CKR_OK;
+}
+
+CK_RV
+gck_mock_C_FindObjectsFinal (CK_SESSION_HANDLE hSession)
+{
+
+	Session *session;
+
+	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
+	g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
+	g_return_val_if_fail (session->operation == OP_FIND, CKR_OPERATION_NOT_INITIALIZED);
+
+	session->operation = 0;
+	g_list_free (session->matches);
+	session->matches = NULL;
+
+	return CKR_OK;
+}
+
+CK_RV
+gck_mock_C_EncryptInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+                        CK_OBJECT_HANDLE hKey)
+{
+	Session *session;
+
+	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
+	g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
+
+	/* Starting an operation, cancels any previous one */
+	if (session->operation != 0)
+		session->operation = 0;
+
+	g_assert (pMechanism);
+	g_assert (pMechanism->mechanism == CKM_MOCK_CAPITALIZE);
+	g_assert (hKey == PUBLIC_KEY_CAPITALIZE);
+
+	session->operation = OP_CRYPTO;
+	session->crypto_method = CKA_ENCRYPT;
+	session->crypto_mechanism = CKM_MOCK_CAPITALIZE;
+	session->crypto_key = hKey;
+	return CKR_OK;
+}
+
+CK_RV
+gck_mock_C_Encrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
+                    CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen)
+{
+	Session *session;
+	CK_ULONG i;
+
+	g_return_val_if_fail (pData, CKR_DATA_INVALID);
+	g_return_val_if_fail (pulEncryptedDataLen, CKR_ARGUMENTS_BAD);
+
+	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
+	g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
+	g_return_val_if_fail (session->operation == OP_CRYPTO, CKR_OPERATION_NOT_INITIALIZED);
+	g_return_val_if_fail (session->crypto_method == CKA_ENCRYPT, CKR_OPERATION_NOT_INITIALIZED);
+
+	g_assert (session->crypto_mechanism == CKM_MOCK_CAPITALIZE);
+	g_assert (session->crypto_key == PUBLIC_KEY_CAPITALIZE);
+
+	if (!pEncryptedData) {
+		*pulEncryptedDataLen = ulDataLen;
+		return CKR_OK;
+	}
+
+	if (*pulEncryptedDataLen < ulDataLen) {
+		*pulEncryptedDataLen = ulDataLen;
+		return CKR_BUFFER_TOO_SMALL;
+	}
+
+	for (i = 0; i < ulDataLen; ++i)
+		pEncryptedData[i] = g_ascii_toupper (pData[i]);
+	*pulEncryptedDataLen = ulDataLen;
+
+	session->operation = 0;
+	session->crypto_method = 0;
+	session->crypto_mechanism = 0;
+	session->crypto_key = 0;
+
+	return CKR_OK;
+}
+
+CK_RV
+gck_mock_unsupported_C_EncryptUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
+                                      CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
+                                      CK_ULONG_PTR pulEncryptedPartLen)
+{
+	return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+gck_mock_unsupported_C_EncryptFinal (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastEncryptedPart,
+                                     CK_ULONG_PTR pulLastEncryptedPartLen)
+{
+	return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+gck_mock_C_DecryptInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+                        CK_OBJECT_HANDLE hKey)
+{
+	Session *session;
+
+	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
+	g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
+
+	/* Starting an operation, cancels any previous one */
+	if (session->operation != 0)
+		session->operation = 0;
+
+	g_assert (pMechanism);
+	g_assert (pMechanism->mechanism == CKM_MOCK_CAPITALIZE);
+	g_assert (hKey == PRIVATE_KEY_CAPITALIZE);
+
+	session->operation = OP_CRYPTO;
+	session->crypto_method = CKA_DECRYPT;
+	session->crypto_mechanism = CKM_MOCK_CAPITALIZE;
+	session->crypto_key = hKey;
+	return CKR_OK;
+}
+
+CK_RV
+gck_mock_C_Decrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData,
+                    CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
+{
+	Session *session;
+	CK_ULONG i;
+
+	g_return_val_if_fail (pEncryptedData, CKR_ENCRYPTED_DATA_INVALID);
+	g_return_val_if_fail (pulDataLen, CKR_ARGUMENTS_BAD);
+
+	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
+	g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
+	g_return_val_if_fail (session->operation == OP_CRYPTO, CKR_OPERATION_NOT_INITIALIZED);
+	g_return_val_if_fail (session->crypto_method == CKA_DECRYPT, CKR_OPERATION_NOT_INITIALIZED);
+
+	g_assert (session->crypto_method == CKA_DECRYPT);
+	g_assert (session->crypto_mechanism == CKM_MOCK_CAPITALIZE);
+	g_assert (session->crypto_key == PRIVATE_KEY_CAPITALIZE);
+
+	if (!pData) {
+		*pulDataLen = ulEncryptedDataLen;
+		return CKR_OK;
+	}
+
+	if (*pulDataLen < ulEncryptedDataLen) {
+		*pulDataLen = ulEncryptedDataLen;
+		return CKR_BUFFER_TOO_SMALL;
+	}
+
+	for (i = 0; i < ulEncryptedDataLen; ++i)
+		pData[i] = g_ascii_tolower (pEncryptedData[i]);
+	*pulDataLen = ulEncryptedDataLen;
+
+	session->operation = 0;
+	session->crypto_method = 0;
+	session->crypto_mechanism = 0;
+	session->crypto_key = 0;
+
+	return CKR_OK;
+}
+
+CK_RV
+gck_mock_unsupported_C_DecryptUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart,
+                                      CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen)
+{
+	return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+gck_mock_unsupported_C_DecryptFinal (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pLastPart,
+                                     CK_ULONG_PTR pulLastPartLen)
+{
+	return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+gck_mock_unsupported_C_DigestInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism)
+{
+	return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+gck_mock_unsupported_C_Digest (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
+                               CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen)
+{
+	return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+gck_mock_unsupported_C_DigestUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
+{
+	return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+gck_mock_unsupported_C_DigestKey (CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hKey)
+{
+	return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+gck_mock_unsupported_C_DigestFinal (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest,
+                                    CK_ULONG_PTR pulDigestLen)
+{
+	return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+gck_mock_C_SignInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+                     CK_OBJECT_HANDLE hKey)
+{
+	Session *session;
+
+	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
+	g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
+
+	/* Starting an operation, cancels any previous one */
+	if (session->operation != 0)
+		session->operation = 0;
+
+	g_assert (pMechanism);
+	g_assert (pMechanism->mechanism == CKM_MOCK_PREFIX);
+	g_assert (hKey == PRIVATE_KEY_PREFIX);
+
+	session->operation = OP_CRYPTO;
+	session->crypto_method = CKA_SIGN;
+	session->crypto_mechanism = CKM_MOCK_PREFIX;
+	session->crypto_key = hKey;
+
+	if (pMechanism->pParameter) {
+		g_assert (pMechanism->ulParameterLen < sizeof (session->sign_prefix));
+		memcpy (session->sign_prefix, pMechanism->pParameter, pMechanism->ulParameterLen);
+		session->n_sign_prefix = pMechanism->ulParameterLen;
+	} else {
+		g_assert (strlen (SIGNED_PREFIX) + 1 < sizeof (session->sign_prefix));
+		strcpy ((gchar*)session->sign_prefix, SIGNED_PREFIX);
+		session->n_sign_prefix = strlen (SIGNED_PREFIX);
+	}
+
+	/* The private key has CKA_ALWAYS_AUTHENTICATE above */
+	session->want_context_login = CK_TRUE;
+
+	return CKR_OK;
+}
+
+CK_RV
+gck_mock_C_Sign (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
+                 CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
+{
+	Session *session;
+	CK_ULONG length;
+
+	g_return_val_if_fail (pData, CKR_DATA_INVALID);
+	g_return_val_if_fail (pulSignatureLen, CKR_ARGUMENTS_BAD);
+
+	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
+	g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
+	g_return_val_if_fail (session->operation == OP_CRYPTO, CKR_OPERATION_NOT_INITIALIZED);
+	g_return_val_if_fail (session->crypto_method == CKA_SIGN, CKR_OPERATION_NOT_INITIALIZED);
+
+	if (session->want_context_login)
+		return CKR_USER_NOT_LOGGED_IN;
+
+	g_assert (session->crypto_method == CKA_SIGN);
+	g_assert (session->crypto_mechanism == CKM_MOCK_PREFIX);
+	g_assert (session->crypto_key == PRIVATE_KEY_PREFIX);
+
+	length = session->n_sign_prefix + ulDataLen;
+
+	if (!pSignature) {
+		*pulSignatureLen = length;
+		return CKR_OK;
+	}
+
+	if (*pulSignatureLen < length) {
+		*pulSignatureLen = length;
+		return CKR_BUFFER_TOO_SMALL;
+	}
+
+	memcpy (pSignature, session->sign_prefix, session->n_sign_prefix);
+	memcpy (pSignature + session->n_sign_prefix, pData, ulDataLen);
+	*pulSignatureLen = length;
+
+	session->operation = 0;
+	session->crypto_method = 0;
+	session->crypto_mechanism = 0;
+	session->crypto_key = 0;
+
+	return CKR_OK;
+}
+
+CK_RV
+gck_mock_unsupported_C_SignUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
+{
+	return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+gck_mock_unsupported_C_SignFinal (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature,
+                                  CK_ULONG_PTR pulSignatureLen)
+{
+	return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+gck_mock_unsupported_C_SignRecoverInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+                                        CK_OBJECT_HANDLE hKey)
+{
+	return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+gck_mock_unsupported_C_SignRecover (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
+                                    CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen)
+{
+	return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+gck_mock_C_VerifyInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+                       CK_OBJECT_HANDLE hKey)
+{
+	Session *session;
+
+	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
+	g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
+
+	/* Starting an operation, cancels any previous one */
+	if (session->operation != 0)
+		session->operation = 0;
+
+	g_assert (pMechanism);
+	g_assert (pMechanism->mechanism == CKM_MOCK_PREFIX);
+	g_assert (hKey == PUBLIC_KEY_PREFIX);
+
+	session->operation = OP_CRYPTO;
+	session->crypto_method = CKA_VERIFY;
+	session->crypto_mechanism = CKM_MOCK_PREFIX;
+	session->crypto_key = hKey;
+
+	if (pMechanism->pParameter) {
+		g_assert (pMechanism->ulParameterLen < sizeof (session->sign_prefix));
+		memcpy (session->sign_prefix, pMechanism->pParameter, pMechanism->ulParameterLen);
+		session->n_sign_prefix = pMechanism->ulParameterLen;
+	} else {
+		g_assert (strlen (SIGNED_PREFIX) + 1 < sizeof (session->sign_prefix));
+		strcpy ((gchar*)session->sign_prefix, SIGNED_PREFIX);
+		session->n_sign_prefix = strlen (SIGNED_PREFIX);
+	}
+
+	return CKR_OK;
+}
+
+CK_RV
+gck_mock_C_Verify (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen,
+                   CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen)
+{
+	Session *session;
+	CK_ULONG length;
+
+	g_return_val_if_fail (pData, CKR_DATA_INVALID);
+	g_return_val_if_fail (pSignature, CKR_ARGUMENTS_BAD);
+
+	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
+	g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
+	g_return_val_if_fail (session->operation == OP_CRYPTO, CKR_OPERATION_NOT_INITIALIZED);
+	g_return_val_if_fail (session->crypto_method == CKA_VERIFY, CKR_OPERATION_NOT_INITIALIZED);
+
+	g_assert (session->crypto_method == CKA_VERIFY);
+	g_assert (session->crypto_mechanism == CKM_MOCK_PREFIX);
+	g_assert (session->crypto_key == PUBLIC_KEY_PREFIX);
+
+	length = session->n_sign_prefix + ulDataLen;
+
+	if (ulSignatureLen < length) {
+		g_assert (FALSE);
+		return CKR_SIGNATURE_LEN_RANGE;
+	}
+
+	if (memcmp (pSignature, session->sign_prefix, session->n_sign_prefix) == 0 &&
+	    memcmp (pSignature + session->n_sign_prefix, pData, ulDataLen) == 0)
+		return CKR_OK;
+
+	return CKR_SIGNATURE_INVALID;
+}
+
+CK_RV
+gck_mock_unsupported_C_VerifyUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
+{
+	return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+gck_mock_unsupported_C_VerifyFinal (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature,
+                                    CK_ULONG pulSignatureLen)
+{
+	return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+gck_mock_unsupported_C_VerifyRecoverInit (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+                                          CK_OBJECT_HANDLE hKey)
+{
+	return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+gck_mock_unsupported_C_VerifyRecover (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature,
+                                      CK_ULONG pulSignatureLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
+{
+	return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+gck_mock_unsupported_C_DigestEncryptUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
+                                            CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
+                                            CK_ULONG_PTR ulEncryptedPartLen)
+{
+	return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+gck_mock_unsupported_C_DecryptDigestUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart,
+                                            CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart,
+                                            CK_ULONG_PTR pulPartLen)
+{
+	return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+gck_mock_unsupported_C_SignEncryptUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart,
+                                          CK_ULONG ulPartLen, CK_BYTE_PTR pEncryptedPart,
+                                          CK_ULONG_PTR ulEncryptedPartLen)
+{
+	return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+gck_mock_unsupported_C_DecryptVerifyUpdate (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart,
+                                            CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart,
+                                            CK_ULONG_PTR pulPartLen)
+{
+	return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+gck_mock_unsupported_C_GenerateKey (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+                                    CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
+                                    CK_OBJECT_HANDLE_PTR phKey)
+{
+	return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+gck_mock_unsupported_C_GenerateKeyPair (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+                                        CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount,
+                                        CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount,
+                                        CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey)
+{
+	GckAttributes *attrs;
+	Session *session;
+	gboolean token;
+	CK_ULONG i;
+
+	g_return_val_if_fail (pMechanism, CKR_MECHANISM_INVALID);
+	g_return_val_if_fail (pPublicKeyTemplate, CKR_TEMPLATE_INCOMPLETE);
+	g_return_val_if_fail (ulPublicKeyAttributeCount, CKR_TEMPLATE_INCOMPLETE);
+	g_return_val_if_fail (pPrivateKeyTemplate, CKR_TEMPLATE_INCOMPLETE);
+	g_return_val_if_fail (ulPrivateKeyAttributeCount, CKR_TEMPLATE_INCOMPLETE);
+	g_return_val_if_fail (phPublicKey, CKR_ARGUMENTS_BAD);
+	g_return_val_if_fail (phPrivateKey, CKR_ARGUMENTS_BAD);
+
+	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
+	g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
+
+	if (pMechanism->mechanism != CKM_MOCK_GENERATE)
+		return CKR_MECHANISM_INVALID;
+
+	if (!pMechanism->pParameter || pMechanism->ulParameterLen != 9 ||
+	    memcmp (pMechanism->pParameter, "generate", 9) != 0)
+		g_return_val_if_reached (CKR_MECHANISM_PARAM_INVALID);
+
+	attrs = gck_attributes_new ();
+	gck_attributes_add_string (attrs, CKA_VALUE, "generated");
+	for (i = 0; i < ulPublicKeyAttributeCount; ++i)
+		gck_attributes_add_data (attrs, pPublicKeyTemplate[i].type,
+		                         pPublicKeyTemplate[i].pValue,
+		                         pPublicKeyTemplate[i].ulValueLen);
+	*phPublicKey = ++unique_identifier;
+	if (gck_attributes_find_boolean (attrs, CKA_TOKEN, &token) && token)
+		g_hash_table_insert (the_objects, GUINT_TO_POINTER (*phPublicKey), attrs);
+	else
+		g_hash_table_insert (session->objects, GUINT_TO_POINTER (*phPublicKey), attrs);
+
+	attrs = gck_attributes_new ();
+	gck_attributes_add_string (attrs, CKA_VALUE, "generated");
+	for (i = 0; i < ulPrivateKeyAttributeCount; ++i)
+		gck_attributes_add_data (attrs, pPrivateKeyTemplate[i].type,
+		                         pPrivateKeyTemplate[i].pValue,
+		                         pPrivateKeyTemplate[i].ulValueLen);
+	*phPrivateKey = ++unique_identifier;
+	if (gck_attributes_find_boolean (attrs, CKA_TOKEN, &token) && token)
+		g_hash_table_insert (the_objects, GUINT_TO_POINTER (*phPrivateKey), attrs);
+	else
+		g_hash_table_insert (session->objects, GUINT_TO_POINTER (*phPrivateKey), attrs);
+	return CKR_OK;
+}
+
+CK_RV
+gck_mock_unsupported_C_WrapKey (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+                                CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey,
+                                CK_BYTE_PTR pWrappedKey, CK_ULONG_PTR pulWrappedKeyLen)
+{
+	GckAttributes *attrs;
+	GckAttribute *attr;
+	Session *session;
+
+	g_return_val_if_fail (pMechanism, CKR_MECHANISM_INVALID);
+	g_return_val_if_fail (hWrappingKey, CKR_OBJECT_HANDLE_INVALID);
+	g_return_val_if_fail (hKey, CKR_OBJECT_HANDLE_INVALID);
+	g_return_val_if_fail (pulWrappedKeyLen, CKR_WRAPPED_KEY_LEN_RANGE);
+
+	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
+	g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
+
+	attrs = lookup_object (session, hWrappingKey);
+	g_return_val_if_fail (attrs, CKR_WRAPPING_KEY_HANDLE_INVALID);
+
+	attrs = lookup_object (session, hKey);
+	g_return_val_if_fail (attrs, CKR_WRAPPED_KEY_INVALID);
+
+	if (pMechanism->mechanism != CKM_MOCK_WRAP)
+		return CKR_MECHANISM_INVALID;
+
+	if (pMechanism->pParameter) {
+		if (pMechanism->ulParameterLen != 4 ||
+		    memcmp (pMechanism->pParameter, "wrap", 4) != 0)
+			g_return_val_if_reached (CKR_MECHANISM_PARAM_INVALID);
+	}
+
+	attr = gck_attributes_find (attrs, CKA_VALUE);
+	if (attr == NULL)
+		return CKR_WRAPPED_KEY_INVALID;
+
+	if (!pWrappedKey) {
+		*pulWrappedKeyLen = attr->length;
+		return CKR_OK;
+	}
+
+	if (*pulWrappedKeyLen < attr->length) {
+		*pulWrappedKeyLen = attr->length;
+		return CKR_BUFFER_TOO_SMALL;
+	}
+
+	memcpy (pWrappedKey, attr->value, attr->length);
+	*pulWrappedKeyLen = attr->length;
+
+	return CKR_OK;
+}
+
+CK_RV
+gck_mock_unsupported_C_UnwrapKey (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+                                  CK_OBJECT_HANDLE hUnwrappingKey, CK_BYTE_PTR pWrappedKey,
+                                  CK_ULONG ulWrappedKeyLen, CK_ATTRIBUTE_PTR pTemplate,
+                                  CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey)
+{
+	GckAttributes *attrs;
+	Session *session;
+	gboolean token;
+	CK_ULONG i;
+
+	g_return_val_if_fail (pMechanism, CKR_MECHANISM_INVALID);
+	g_return_val_if_fail (hUnwrappingKey, CKR_WRAPPING_KEY_HANDLE_INVALID);
+	g_return_val_if_fail (pWrappedKey, CKR_WRAPPED_KEY_INVALID);
+	g_return_val_if_fail (ulWrappedKeyLen, CKR_WRAPPED_KEY_LEN_RANGE);
+	g_return_val_if_fail (phKey, CKR_ARGUMENTS_BAD);
+	g_return_val_if_fail (pTemplate, CKR_TEMPLATE_INCOMPLETE);
+	g_return_val_if_fail (ulCount, CKR_TEMPLATE_INCONSISTENT);
+
+	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
+	g_return_val_if_fail (session != NULL, CKR_SESSION_HANDLE_INVALID);
+
+	attrs = lookup_object (session, hUnwrappingKey);
+	g_return_val_if_fail (attrs, CKR_WRAPPING_KEY_HANDLE_INVALID);
+
+	if (pMechanism->mechanism != CKM_MOCK_WRAP)
+		return CKR_MECHANISM_INVALID;
+
+	if (pMechanism->pParameter) {
+		if (pMechanism->ulParameterLen != 4 ||
+		    memcmp (pMechanism->pParameter, "wrap", 4) != 0)
+			g_return_val_if_reached (CKR_MECHANISM_PARAM_INVALID);
+	}
+
+	attrs = gck_attributes_new ();
+	gck_attributes_add_data (attrs, CKA_VALUE, pWrappedKey, ulWrappedKeyLen);
+	for (i = 0; i < ulCount; ++i)
+		gck_attributes_add_data (attrs, pTemplate[i].type,
+		                         pTemplate[i].pValue,
+		                         pTemplate[i].ulValueLen);
+	*phKey = ++unique_identifier;
+	if (gck_attributes_find_boolean (attrs, CKA_TOKEN, &token) && token)
+		g_hash_table_insert (the_objects, GUINT_TO_POINTER (*phKey), attrs);
+	else
+		g_hash_table_insert (session->objects, GUINT_TO_POINTER (*phKey), attrs);
+
+	return CKR_OK;
+}
+
+CK_RV
+gck_mock_unsupported_C_DeriveKey (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+                                  CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate,
+                                  CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey)
+{
+	GckAttributes *attrs, *copy;
+	Session *session;
+	gboolean token;
+	CK_ULONG i;
+
+	g_return_val_if_fail (pMechanism, CKR_MECHANISM_INVALID);
+	g_return_val_if_fail (ulCount, CKR_TEMPLATE_INCOMPLETE);
+	g_return_val_if_fail (pTemplate, CKR_TEMPLATE_INCOMPLETE);
+	g_return_val_if_fail (phKey, CKR_ARGUMENTS_BAD);
+
+	session = g_hash_table_lookup (the_sessions, GUINT_TO_POINTER (hSession));
+	g_return_val_if_fail (session, CKR_SESSION_HANDLE_INVALID);
+
+	attrs = lookup_object (session, hBaseKey);
+	g_return_val_if_fail (attrs, CKR_KEY_HANDLE_INVALID);
+
+	if (pMechanism->mechanism != CKM_MOCK_DERIVE)
+		return CKR_MECHANISM_INVALID;
+
+	if (pMechanism->pParameter) {
+		if (pMechanism->ulParameterLen != 6 ||
+		    memcmp (pMechanism->pParameter, "derive", 6) != 0)
+			g_return_val_if_reached (CKR_MECHANISM_PARAM_INVALID);
+	}
+
+	copy = gck_attributes_new ();
+	gck_attributes_add_string (copy, CKA_VALUE, "derived");
+	for (i = 0; i < ulCount; ++i)
+		gck_attributes_add_data (copy, pTemplate[i].type,
+		                         pTemplate[i].pValue,
+		                         pTemplate[i].ulValueLen);
+	for (i = 0; i < gck_attributes_count (attrs); ++i)
+		gck_attributes_add (copy, gck_attributes_at (attrs, i));
+	*phKey = ++unique_identifier;
+	if (gck_attributes_find_boolean (copy, CKA_TOKEN, &token) && token)
+		g_hash_table_insert (the_objects, GUINT_TO_POINTER (*phKey), copy);
+	else
+		g_hash_table_insert (session->objects, GUINT_TO_POINTER (*phKey), copy);
+
+	return CKR_OK;
+}
+
+CK_RV
+gck_mock_unsupported_C_SeedRandom (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSeed, CK_ULONG ulSeedLen)
+{
+	return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+CK_RV
+gck_mock_unsupported_C_GenerateRandom (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pRandomData,
+                           CK_ULONG ulRandomLen)
+{
+	return CKR_FUNCTION_NOT_SUPPORTED;
+}
+
+static CK_FUNCTION_LIST functionList = {
+	{ 2, 11 },	/* version */
+	gck_mock_validate_and_C_Initialize,
+	gck_mock_C_Finalize,
+	gck_mock_C_GetInfo,
+	gck_mock_C_GetFunctionList,
+	gck_mock_C_GetSlotList,
+	gck_mock_C_GetSlotInfo,
+	gck_mock_C_GetTokenInfo,
+	gck_mock_C_GetMechanismList,
+	gck_mock_C_GetMechanismInfo,
+	gck_mock_specific_args_C_InitToken,
+	gck_mock_C_InitPIN,
+	gck_mock_C_SetPIN,
+	gck_mock_C_OpenSession,
+	gck_mock_C_CloseSession,
+	gck_mock_C_CloseAllSessions,
+	gck_mock_C_GetSessionInfo,
+	gck_mock_unsupported_C_GetOperationState,
+	gck_mock_unsupported_C_SetOperationState,
+	gck_mock_C_Login,
+	gck_mock_C_Logout,
+	gck_mock_C_CreateObject,
+	gck_mock_unsupported_C_CopyObject,
+	gck_mock_C_DestroyObject,
+	gck_mock_unsupported_C_GetObjectSize,
+	gck_mock_C_GetAttributeValue,
+	gck_mock_C_SetAttributeValue,
+	gck_mock_C_FindObjectsInit,
+	gck_mock_C_FindObjects,
+	gck_mock_C_FindObjectsFinal,
+	gck_mock_C_EncryptInit,
+	gck_mock_C_Encrypt,
+	gck_mock_unsupported_C_EncryptUpdate,
+	gck_mock_unsupported_C_EncryptFinal,
+	gck_mock_C_DecryptInit,
+	gck_mock_C_Decrypt,
+	gck_mock_unsupported_C_DecryptUpdate,
+	gck_mock_unsupported_C_DecryptFinal,
+	gck_mock_unsupported_C_DigestInit,
+	gck_mock_unsupported_C_Digest,
+	gck_mock_unsupported_C_DigestUpdate,
+	gck_mock_unsupported_C_DigestKey,
+	gck_mock_unsupported_C_DigestFinal,
+	gck_mock_C_SignInit,
+	gck_mock_C_Sign,
+	gck_mock_unsupported_C_SignUpdate,
+	gck_mock_unsupported_C_SignFinal,
+	gck_mock_unsupported_C_SignRecoverInit,
+	gck_mock_unsupported_C_SignRecover,
+	gck_mock_C_VerifyInit,
+	gck_mock_C_Verify,
+	gck_mock_unsupported_C_VerifyUpdate,
+	gck_mock_unsupported_C_VerifyFinal,
+	gck_mock_unsupported_C_VerifyRecoverInit,
+	gck_mock_unsupported_C_VerifyRecover,
+	gck_mock_unsupported_C_DigestEncryptUpdate,
+	gck_mock_unsupported_C_DecryptDigestUpdate,
+	gck_mock_unsupported_C_SignEncryptUpdate,
+	gck_mock_unsupported_C_DecryptVerifyUpdate,
+	gck_mock_unsupported_C_GenerateKey,
+	gck_mock_unsupported_C_GenerateKeyPair,
+	gck_mock_unsupported_C_WrapKey,
+	gck_mock_unsupported_C_UnwrapKey,
+	gck_mock_unsupported_C_DeriveKey,
+	gck_mock_unsupported_C_SeedRandom,
+	gck_mock_unsupported_C_GenerateRandom,
+	gck_mock_C_GetFunctionStatus,
+	gck_mock_C_CancelFunction,
+	gck_mock_unsupported_C_WaitForSlotEvent
+};
diff --git a/gck/gck-mock.h b/gck/gck-mock.h
new file mode 100644
index 0000000..b92c33c
--- /dev/null
+++ b/gck/gck-mock.h
@@ -0,0 +1,409 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2010 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.
+ */
+
+#include <glib.h>
+
+#include "gck.h"
+
+#include "pkcs11/pkcs11.h"
+#include "pkcs11/pkcs11i.h"
+
+#ifndef GCK_MOCK_H
+#define GCK_MOCK_H
+
+#ifdef WITH_TESTS
+
+CK_RV               gck_mock_C_Initialize                          (CK_VOID_PTR pInitArgs);
+
+CK_RV               gck_mock_validate_and_C_Initialize             (CK_VOID_PTR pInitArgs);
+
+CK_RV               gck_mock_C_Finalize                            (CK_VOID_PTR pReserved);
+
+CK_RV               gck_mock_C_GetInfo                             (CK_INFO_PTR pInfo);
+
+CK_RV               gck_mock_C_GetFunctionList                     (CK_FUNCTION_LIST_PTR_PTR list);
+
+CK_RV               gck_mock_C_GetSlotList                         (CK_BBOOL tokenPresent,
+                                                                    CK_SLOT_ID_PTR pSlotList,
+                                                                    CK_ULONG_PTR pulCount);
+
+CK_RV               gck_mock_C_GetSlotInfo                         (CK_SLOT_ID slotID,
+                                                                    CK_SLOT_INFO_PTR pInfo);
+
+CK_RV               gck_mock_C_GetTokenInfo                        (CK_SLOT_ID slotID,
+                                                                    CK_TOKEN_INFO_PTR pInfo);
+
+CK_RV               gck_mock_fail_C_GetTokenInfo                   (CK_SLOT_ID slotID,
+                                                                    CK_TOKEN_INFO_PTR pInfo);
+
+CK_RV               gck_mock_C_GetMechanismList                    (CK_SLOT_ID slotID,
+                                                                    CK_MECHANISM_TYPE_PTR pMechanismList,
+                                                                    CK_ULONG_PTR pulCount);
+
+CK_RV               gck_mock_C_GetMechanismInfo                    (CK_SLOT_ID slotID,
+                                                                    CK_MECHANISM_TYPE type,
+                                                                    CK_MECHANISM_INFO_PTR pInfo);
+
+CK_RV               gck_mock_specific_args_C_InitToken             (CK_SLOT_ID slotID,
+                                                                    CK_UTF8CHAR_PTR pPin,
+                                                                    CK_ULONG ulPinLen,
+                                                                    CK_UTF8CHAR_PTR pLabel);
+
+CK_RV               gck_mock_unsupported_C_WaitForSlotEvent        (CK_FLAGS flags,
+                                                                    CK_SLOT_ID_PTR pSlot,
+                                                                    CK_VOID_PTR pReserved);
+
+CK_RV               gck_mock_C_OpenSession                         (CK_SLOT_ID slotID,
+                                                                    CK_FLAGS flags,
+                                                                    CK_VOID_PTR pApplication,
+                                                                    CK_NOTIFY Notify,
+                                                                    CK_SESSION_HANDLE_PTR phSession);
+
+CK_RV               gck_mock_fail_C_OpenSession                    (CK_SLOT_ID slotID,
+                                                                    CK_FLAGS flags,
+                                                                    CK_VOID_PTR pApplication,
+                                                                    CK_NOTIFY Notify,
+                                                                    CK_SESSION_HANDLE_PTR phSession);
+
+CK_RV               gck_mock_C_CloseSession                        (CK_SESSION_HANDLE hSession);
+
+CK_RV               gck_mock_C_CloseAllSessions                    (CK_SLOT_ID slotID);
+
+CK_RV               gck_mock_C_GetFunctionStatus                   (CK_SESSION_HANDLE hSession);
+
+CK_RV               gck_mock_C_CancelFunction                      (CK_SESSION_HANDLE hSession);
+
+CK_RV               gck_mock_C_GetSessionInfo                      (CK_SESSION_HANDLE hSession,
+                                                                    CK_SESSION_INFO_PTR pInfo);
+
+CK_RV               gck_mock_fail_C_GetSessionInfo                 (CK_SESSION_HANDLE hSession,
+                                                                    CK_SESSION_INFO_PTR pInfo);
+
+CK_RV               gck_mock_C_InitPIN                             (CK_SESSION_HANDLE hSession,
+                                                                    CK_UTF8CHAR_PTR pPin,
+                                                                    CK_ULONG ulPinLen);
+
+CK_RV               gck_mock_C_SetPIN                              (CK_SESSION_HANDLE hSession,
+                                                                    CK_UTF8CHAR_PTR pOldPin,
+                                                                    CK_ULONG ulOldLen,
+                                                                    CK_UTF8CHAR_PTR pNewPin,
+                                                                    CK_ULONG ulNewLen);
+
+CK_RV               gck_mock_unsupported_C_GetOperationState       (CK_SESSION_HANDLE hSession,
+                                                                    CK_BYTE_PTR pOperationState,
+                                                                    CK_ULONG_PTR pulOperationStateLen);
+
+CK_RV               gck_mock_unsupported_C_SetOperationState       (CK_SESSION_HANDLE hSession,
+                                                                    CK_BYTE_PTR pOperationState,
+                                                                    CK_ULONG ulOperationStateLen,
+                                                                    CK_OBJECT_HANDLE hEncryptionKey,
+                                                                    CK_OBJECT_HANDLE hAuthenticationKey);
+
+CK_RV               gck_mock_C_Login                               (CK_SESSION_HANDLE hSession,
+                                                                    CK_USER_TYPE userType,
+                                                                    CK_UTF8CHAR_PTR pPin,
+                                                                    CK_ULONG pPinLen);
+
+CK_RV               gck_mock_C_Logout                              (CK_SESSION_HANDLE hSession);
+
+CK_RV               gck_mock_C_CreateObject                        (CK_SESSION_HANDLE hSession,
+                                                                    CK_ATTRIBUTE_PTR pTemplate,
+                                                                    CK_ULONG ulCount,
+                                                                    CK_OBJECT_HANDLE_PTR phObject);
+
+CK_RV               gck_mock_unsupported_C_CopyObject              (CK_SESSION_HANDLE hSession,
+                                                                    CK_OBJECT_HANDLE hObject,
+                                                                    CK_ATTRIBUTE_PTR pTemplate,
+                                                                    CK_ULONG ulCount,
+                                                                    CK_OBJECT_HANDLE_PTR phNewObject);
+
+CK_RV               gck_mock_C_DestroyObject                       (CK_SESSION_HANDLE hSession,
+                                                                    CK_OBJECT_HANDLE hObject);
+
+CK_RV               gck_mock_unsupported_C_GetObjectSize           (CK_SESSION_HANDLE hSession,
+                                                                    CK_OBJECT_HANDLE hObject,
+                                                                    CK_ULONG_PTR pulSize);
+
+CK_RV               gck_mock_C_GetAttributeValue                   (CK_SESSION_HANDLE hSession,
+                                                                    CK_OBJECT_HANDLE hObject,
+                                                                    CK_ATTRIBUTE_PTR pTemplate,
+                                                                    CK_ULONG ulCount);
+
+CK_RV               gck_mock_C_SetAttributeValue                   (CK_SESSION_HANDLE hSession,
+                                                                    CK_OBJECT_HANDLE hObject,
+                                                                    CK_ATTRIBUTE_PTR pTemplate,
+                                                                    CK_ULONG ulCount);
+
+CK_RV               gck_mock_C_FindObjectsInit                     (CK_SESSION_HANDLE hSession,
+                                                                    CK_ATTRIBUTE_PTR pTemplate,
+                                                                    CK_ULONG ulCount);
+
+CK_RV               gck_mock_C_FindObjects                         (CK_SESSION_HANDLE hSession,
+                                                                    CK_OBJECT_HANDLE_PTR phObject,
+                                                                    CK_ULONG ulMaxObjectCount,
+                                                                    CK_ULONG_PTR pulObjectCount);
+
+CK_RV               gck_mock_C_FindObjectsFinal                    (CK_SESSION_HANDLE hSession);
+
+CK_RV               gck_mock_C_EncryptInit                         (CK_SESSION_HANDLE hSession,
+                                                                    CK_MECHANISM_PTR pMechanism,
+                                                                    CK_OBJECT_HANDLE hKey);
+
+CK_RV               gck_mock_C_Encrypt                             (CK_SESSION_HANDLE hSession,
+                                                                    CK_BYTE_PTR pData,
+                                                                    CK_ULONG ulDataLen,
+                                                                    CK_BYTE_PTR pEncryptedData,
+                                                                    CK_ULONG_PTR pulEncryptedDataLen);
+
+CK_RV               gck_mock_unsupported_C_EncryptUpdate           (CK_SESSION_HANDLE hSession,
+                                                                    CK_BYTE_PTR pPart,
+                                                                    CK_ULONG ulPartLen,
+                                                                    CK_BYTE_PTR pEncryptedPart,
+                                                                    CK_ULONG_PTR pulEncryptedPartLen);
+
+CK_RV               gck_mock_unsupported_C_EncryptFinal            (CK_SESSION_HANDLE hSession,
+                                                                    CK_BYTE_PTR pLastEncryptedPart,
+                                                                    CK_ULONG_PTR pulLastEncryptedPartLen);
+
+CK_RV               gck_mock_C_DecryptInit                         (CK_SESSION_HANDLE hSession,
+                                                                    CK_MECHANISM_PTR pMechanism,
+                                                                    CK_OBJECT_HANDLE hKey);
+
+CK_RV               gck_mock_C_Decrypt                             (CK_SESSION_HANDLE hSession,
+                                                                    CK_BYTE_PTR pEncryptedData,
+                                                                    CK_ULONG ulEncryptedDataLen,
+                                                                    CK_BYTE_PTR pData,
+                                                                    CK_ULONG_PTR pulDataLen);
+
+CK_RV               gck_mock_unsupported_C_DecryptUpdate           (CK_SESSION_HANDLE hSession,
+                                                                    CK_BYTE_PTR pEncryptedPart,
+                                                                    CK_ULONG ulEncryptedPartLen,
+                                                                    CK_BYTE_PTR pPart,
+                                                                    CK_ULONG_PTR pulPartLen);
+
+CK_RV               gck_mock_unsupported_C_DecryptFinal            (CK_SESSION_HANDLE hSession,
+                                                                    CK_BYTE_PTR pLastPart,
+                                                                    CK_ULONG_PTR pulLastPartLen);
+
+CK_RV               gck_mock_unsupported_C_DigestInit              (CK_SESSION_HANDLE hSession,
+                                                                    CK_MECHANISM_PTR pMechanism);
+
+CK_RV               gck_mock_unsupported_C_Digest                  (CK_SESSION_HANDLE hSession,
+                                                                    CK_BYTE_PTR pData,
+                                                                    CK_ULONG ulDataLen,
+                                                                    CK_BYTE_PTR pDigest,
+                                                                    CK_ULONG_PTR pulDigestLen);
+
+CK_RV               gck_mock_unsupported_C_DigestUpdate            (CK_SESSION_HANDLE hSession,
+                                                                    CK_BYTE_PTR pPart,
+                                                                    CK_ULONG ulPartLen);
+
+CK_RV               gck_mock_unsupported_C_DigestKey               (CK_SESSION_HANDLE hSession,
+                                                                    CK_OBJECT_HANDLE hKey);
+
+CK_RV               gck_mock_unsupported_C_DigestFinal             (CK_SESSION_HANDLE hSession,
+                                                                    CK_BYTE_PTR pDigest,
+                                                                    CK_ULONG_PTR pulDigestLen);
+
+CK_RV               gck_mock_C_SignInit                            (CK_SESSION_HANDLE hSession,
+                                                                    CK_MECHANISM_PTR pMechanism,
+                                                                    CK_OBJECT_HANDLE hKey);
+
+CK_RV               gck_mock_C_Sign                                (CK_SESSION_HANDLE hSession,
+                                                                    CK_BYTE_PTR pData,
+                                                                    CK_ULONG ulDataLen,
+                                                                    CK_BYTE_PTR pSignature,
+                                                                    CK_ULONG_PTR pulSignatureLen);
+
+CK_RV               gck_mock_unsupported_C_SignUpdate              (CK_SESSION_HANDLE hSession,
+                                                                    CK_BYTE_PTR pPart,
+                                                                    CK_ULONG ulPartLen);
+
+CK_RV               gck_mock_unsupported_C_SignFinal               (CK_SESSION_HANDLE hSession,
+                                                                    CK_BYTE_PTR pSignature,
+                                                                    CK_ULONG_PTR pulSignatureLen);
+
+CK_RV               gck_mock_unsupported_C_SignRecoverInit         (CK_SESSION_HANDLE hSession,
+                                                                    CK_MECHANISM_PTR pMechanism,
+                                                                    CK_OBJECT_HANDLE hKey);
+
+CK_RV               gck_mock_unsupported_C_SignRecover             (CK_SESSION_HANDLE hSession,
+                                                                    CK_BYTE_PTR pData,
+                                                                    CK_ULONG ulDataLen,
+                                                                    CK_BYTE_PTR pSignature,
+                                                                    CK_ULONG_PTR pulSignatureLen);
+
+CK_RV               gck_mock_C_VerifyInit                          (CK_SESSION_HANDLE hSession,
+                                                                    CK_MECHANISM_PTR pMechanism,
+                                                                    CK_OBJECT_HANDLE hKey);
+
+CK_RV               gck_mock_C_Verify                              (CK_SESSION_HANDLE hSession,
+                                                                    CK_BYTE_PTR pData,
+                                                                    CK_ULONG ulDataLen,
+                                                                    CK_BYTE_PTR pSignature,
+                                                                    CK_ULONG ulSignatureLen);
+
+CK_RV               gck_mock_unsupported_C_VerifyUpdate            (CK_SESSION_HANDLE hSession,
+                                                                    CK_BYTE_PTR pPart,
+                                                                    CK_ULONG ulPartLen);
+
+CK_RV               gck_mock_unsupported_C_VerifyFinal             (CK_SESSION_HANDLE hSession,
+                                                                    CK_BYTE_PTR pSignature,
+                                                                    CK_ULONG pulSignatureLen);
+
+CK_RV               gck_mock_unsupported_C_VerifyRecoverInit       (CK_SESSION_HANDLE hSession,
+                                                                    CK_MECHANISM_PTR pMechanism,
+                                                                    CK_OBJECT_HANDLE hKey);
+
+CK_RV               gck_mock_unsupported_C_VerifyRecover           (CK_SESSION_HANDLE hSession,
+                                                                    CK_BYTE_PTR pSignature,
+                                                                    CK_ULONG pulSignatureLen,
+                                                                    CK_BYTE_PTR pData,
+                                                                    CK_ULONG_PTR pulDataLen);
+
+CK_RV               gck_mock_unsupported_C_DigestEncryptUpdate     (CK_SESSION_HANDLE hSession,
+                                                                    CK_BYTE_PTR pPart,
+                                                                    CK_ULONG ulPartLen,
+                                                                    CK_BYTE_PTR pEncryptedPart,
+                                                                    CK_ULONG_PTR ulEncryptedPartLen);
+
+CK_RV               gck_mock_unsupported_C_DecryptDigestUpdate     (CK_SESSION_HANDLE hSession,
+                                                                    CK_BYTE_PTR pEncryptedPart,
+                                                                    CK_ULONG ulEncryptedPartLen,
+                                                                    CK_BYTE_PTR pPart,
+                                                                    CK_ULONG_PTR pulPartLen);
+
+CK_RV               gck_mock_unsupported_C_SignEncryptUpdate       (CK_SESSION_HANDLE hSession,
+                                                                    CK_BYTE_PTR pPart,
+                                                                    CK_ULONG ulPartLen,
+                                                                    CK_BYTE_PTR pEncryptedPart,
+                                                                    CK_ULONG_PTR ulEncryptedPartLen);
+
+CK_RV               gck_mock_unsupported_C_DecryptVerifyUpdate     (CK_SESSION_HANDLE hSession,
+                                                                    CK_BYTE_PTR pEncryptedPart,
+                                                                    CK_ULONG ulEncryptedPartLen,
+                                                                    CK_BYTE_PTR pPart,
+                                                                    CK_ULONG_PTR pulPartLen);
+
+CK_RV               gck_mock_unsupported_C_GenerateKey             (CK_SESSION_HANDLE hSession,
+                                                                    CK_MECHANISM_PTR pMechanism,
+                                                                    CK_ATTRIBUTE_PTR pTemplate,
+                                                                    CK_ULONG ulCount,
+                                                                    CK_OBJECT_HANDLE_PTR phKey);
+
+CK_RV               gck_mock_unsupported_C_GenerateKeyPair         (CK_SESSION_HANDLE hSession,
+                                                                    CK_MECHANISM_PTR pMechanism,
+                                                                    CK_ATTRIBUTE_PTR pPublicKeyTemplate,
+                                                                    CK_ULONG ulPublicKeyAttributeCount,
+                                                                    CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
+                                                                    CK_ULONG ulPrivateKeyAttributeCount,
+                                                                    CK_OBJECT_HANDLE_PTR phPublicKey,
+                                                                    CK_OBJECT_HANDLE_PTR phPrivateKey);
+
+CK_RV               gck_mock_unsupported_C_WrapKey                 (CK_SESSION_HANDLE hSession,
+                                                                    CK_MECHANISM_PTR pMechanism,
+                                                                    CK_OBJECT_HANDLE hWrappingKey,
+                                                                    CK_OBJECT_HANDLE hKey,
+                                                                    CK_BYTE_PTR pWrappedKey,
+                                                                    CK_ULONG_PTR pulWrappedKeyLen);
+
+CK_RV               gck_mock_unsupported_C_UnwrapKey               (CK_SESSION_HANDLE hSession,
+                                                                    CK_MECHANISM_PTR pMechanism,
+                                                                    CK_OBJECT_HANDLE pUnwrappingKey,
+                                                                    CK_BYTE_PTR pWrappedKey,
+                                                                    CK_ULONG pulWrappedKeyLen,
+                                                                    CK_ATTRIBUTE_PTR pTemplate,
+                                                                    CK_ULONG ulCount,
+                                                                    CK_OBJECT_HANDLE_PTR phKey);
+
+CK_RV               gck_mock_unsupported_C_DeriveKey               (CK_SESSION_HANDLE hSession,
+                                                                    CK_MECHANISM_PTR pMechanism,
+                                                                    CK_OBJECT_HANDLE hBaseKey,
+                                                                    CK_ATTRIBUTE_PTR pTemplate,
+                                                                    CK_ULONG ulCount,
+                                                                    CK_OBJECT_HANDLE_PTR phKey);
+
+CK_RV               gck_mock_unsupported_C_SeedRandom              (CK_SESSION_HANDLE hSession,
+                                                                    CK_BYTE_PTR pSeed,
+                                                                    CK_ULONG ulSeedLen);
+
+CK_RV               gck_mock_unsupported_C_GenerateRandom          (CK_SESSION_HANDLE hSession,
+                                                                    CK_BYTE_PTR pRandomData,
+                                                                    CK_ULONG ulRandomLen);
+
+CK_OBJECT_HANDLE    gck_mock_module_find_object                    (CK_SESSION_HANDLE session,
+                                                                    CK_ATTRIBUTE_PTR attrs,
+                                                                    CK_ULONG n_attrs);
+
+guint               gck_mock_module_count_objects                  (CK_SESSION_HANDLE session);
+
+typedef gboolean    (*GckMockEnumerator)                           (CK_OBJECT_HANDLE handle,
+                                                                    GckAttributes *attrs,
+                                                                    gpointer user_data);
+
+void                gck_mock_module_enumerate_objects              (CK_SESSION_HANDLE session,
+                                                                    GckMockEnumerator func,
+                                                                    gpointer user_data);
+
+CK_OBJECT_HANDLE    gck_mock_module_take_object                    (GckAttributes *attrs);
+
+void                gck_mock_module_set_object                     (CK_OBJECT_HANDLE object,
+                                                                    CK_ATTRIBUTE_PTR attrs,
+                                                                    CK_ULONG n_attrs);
+
+void                gck_mock_module_set_pin                        (const gchar *password);
+
+/*
+ * Some dumb crypto mechanisms for simple testing.
+ *
+ * CKM_T_CAPITALIZE (encrypt/decrypt)
+ *     capitalizes to encrypt
+ *     lowercase to decrypt
+ *
+ * CKM_T_PREFIX (sign/verify)
+ *     sign prefixes data with key label
+ *     verify unprefixes data with key label.
+ *
+ * CKM_T_GENERATE (generate-pair)
+ *     generates a pair of keys, mechanism param should be 'generate'
+ *
+ * CKM_T_WRAP (wrap key)
+ *     wraps key by returning value, mechanism param should be 'wrap'
+ *
+ * CKM_T_DERIVE (derive-key)
+ *     derives key by setting value to 'derived'.
+ *     mechanism param should be 'derive'
+ */
+
+#define CKM_MOCK_CAPITALIZE    (CKM_VENDOR_DEFINED | 1)
+#define CKM_MOCK_PREFIX        (CKM_VENDOR_DEFINED | 2)
+#define CKM_MOCK_GENERATE      (CKM_VENDOR_DEFINED | 3)
+#define CKM_MOCK_WRAP          (CKM_VENDOR_DEFINED | 4)
+#define CKM_MOCK_DERIVE        (CKM_VENDOR_DEFINED | 5)
+
+#define GCK_MOCK_SLOT_ONE_ID  52
+#define GCK_MOCK_SLOT_TWO_ID  134
+
+#define GCK_MOCK_SLOT_ONE_URI "pkcs11:manufacturer=TEST%20MANUFACTURER;serial=TEST%20SERIAL"
+
+#endif /* WITH_TESTS */
+
+#endif /* TESTMODULE_H_ */
diff --git a/gck/gck-test.c b/gck/gck-test.c
new file mode 100644
index 0000000..ce59aeb
--- /dev/null
+++ b/gck/gck-test.c
@@ -0,0 +1,165 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2010 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-test.h"
+
+#include "pkcs11/pkcs11.h"
+
+#include <glib.h>
+
+#include <string.h>
+
+static const gchar*
+defined_rv_to_string (CK_RV rv)
+{
+	#define GKM_X(rv) case rv: return #rv;
+	switch (rv) {
+
+	/* These are not really errors, or not current */
+	GKM_X (CKR_OK)
+	GKM_X (CKR_NO_EVENT)
+	GKM_X (CKR_FUNCTION_NOT_PARALLEL)
+	GKM_X (CKR_SESSION_PARALLEL_NOT_SUPPORTED)
+	GKM_X (CKR_CANCEL)
+	GKM_X (CKR_FUNCTION_CANCELED)
+	GKM_X (CKR_HOST_MEMORY)
+	GKM_X (CKR_SLOT_ID_INVALID)
+	GKM_X (CKR_GENERAL_ERROR)
+	GKM_X (CKR_FUNCTION_FAILED)
+	GKM_X (CKR_ARGUMENTS_BAD)
+	GKM_X (CKR_NEED_TO_CREATE_THREADS)
+	GKM_X (CKR_CANT_LOCK)
+	GKM_X (CKR_ATTRIBUTE_READ_ONLY)
+	GKM_X (CKR_ATTRIBUTE_SENSITIVE)
+	GKM_X (CKR_ATTRIBUTE_TYPE_INVALID)
+	GKM_X (CKR_ATTRIBUTE_VALUE_INVALID)
+	GKM_X (CKR_DATA_INVALID)
+	GKM_X (CKR_DATA_LEN_RANGE)
+	GKM_X (CKR_DEVICE_ERROR)
+	GKM_X (CKR_DEVICE_MEMORY)
+	GKM_X (CKR_DEVICE_REMOVED)
+	GKM_X (CKR_ENCRYPTED_DATA_INVALID)
+	GKM_X (CKR_ENCRYPTED_DATA_LEN_RANGE)
+	GKM_X (CKR_FUNCTION_NOT_SUPPORTED)
+	GKM_X (CKR_KEY_HANDLE_INVALID)
+	GKM_X (CKR_KEY_SIZE_RANGE)
+	GKM_X (CKR_KEY_TYPE_INCONSISTENT)
+	GKM_X (CKR_KEY_NOT_NEEDED)
+	GKM_X (CKR_KEY_CHANGED)
+	GKM_X (CKR_KEY_NEEDED)
+	GKM_X (CKR_KEY_INDIGESTIBLE)
+	GKM_X (CKR_KEY_FUNCTION_NOT_PERMITTED)
+	GKM_X (CKR_KEY_NOT_WRAPPABLE)
+	GKM_X (CKR_KEY_UNEXTRACTABLE)
+	GKM_X (CKR_MECHANISM_INVALID)
+	GKM_X (CKR_MECHANISM_PARAM_INVALID)
+	GKM_X (CKR_OBJECT_HANDLE_INVALID)
+	GKM_X (CKR_OPERATION_ACTIVE)
+	GKM_X (CKR_OPERATION_NOT_INITIALIZED)
+	GKM_X (CKR_PIN_INCORRECT)
+	GKM_X (CKR_PIN_INVALID)
+	GKM_X (CKR_PIN_LEN_RANGE)
+	GKM_X (CKR_PIN_EXPIRED)
+	GKM_X (CKR_PIN_LOCKED)
+	GKM_X (CKR_SESSION_CLOSED)
+	GKM_X (CKR_SESSION_COUNT)
+	GKM_X (CKR_SESSION_HANDLE_INVALID)
+	GKM_X (CKR_SESSION_READ_ONLY)
+	GKM_X (CKR_SESSION_EXISTS)
+	GKM_X (CKR_SESSION_READ_ONLY_EXISTS)
+	GKM_X (CKR_SESSION_READ_WRITE_SO_EXISTS)
+	GKM_X (CKR_SIGNATURE_INVALID)
+	GKM_X (CKR_SIGNATURE_LEN_RANGE)
+	GKM_X (CKR_TEMPLATE_INCOMPLETE)
+	GKM_X (CKR_TEMPLATE_INCONSISTENT)
+	GKM_X (CKR_TOKEN_NOT_PRESENT)
+	GKM_X (CKR_TOKEN_NOT_RECOGNIZED)
+	GKM_X (CKR_TOKEN_WRITE_PROTECTED)
+	GKM_X (CKR_UNWRAPPING_KEY_HANDLE_INVALID)
+	GKM_X (CKR_UNWRAPPING_KEY_SIZE_RANGE)
+	GKM_X (CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT)
+	GKM_X (CKR_USER_ALREADY_LOGGED_IN)
+	GKM_X (CKR_USER_NOT_LOGGED_IN)
+	GKM_X (CKR_USER_PIN_NOT_INITIALIZED)
+	GKM_X (CKR_USER_TYPE_INVALID)
+	GKM_X (CKR_USER_ANOTHER_ALREADY_LOGGED_IN)
+	GKM_X (CKR_USER_TOO_MANY_TYPES)
+	GKM_X (CKR_WRAPPED_KEY_INVALID)
+	GKM_X (CKR_WRAPPED_KEY_LEN_RANGE)
+	GKM_X (CKR_WRAPPING_KEY_HANDLE_INVALID)
+	GKM_X (CKR_WRAPPING_KEY_SIZE_RANGE)
+	GKM_X (CKR_WRAPPING_KEY_TYPE_INCONSISTENT)
+	GKM_X (CKR_RANDOM_SEED_NOT_SUPPORTED)
+	GKM_X (CKR_RANDOM_NO_RNG)
+	GKM_X (CKR_DOMAIN_PARAMS_INVALID)
+	GKM_X (CKR_BUFFER_TOO_SMALL)
+	GKM_X (CKR_SAVED_STATE_INVALID)
+	GKM_X (CKR_INFORMATION_SENSITIVE)
+	GKM_X (CKR_STATE_UNSAVEABLE)
+	GKM_X (CKR_CRYPTOKI_NOT_INITIALIZED)
+	GKM_X (CKR_CRYPTOKI_ALREADY_INITIALIZED)
+	GKM_X (CKR_MUTEX_BAD)
+	GKM_X (CKR_MUTEX_NOT_LOCKED)
+	GKM_X (CKR_FUNCTION_REJECTED)
+	default:
+		return NULL;
+	}
+
+	#undef GKM_X
+}
+
+static gchar*
+rv_to_string (CK_RV rv)
+{
+	gchar *string = g_strdup (defined_rv_to_string (rv));
+	if (string == NULL)
+		string = g_strdup_printf ("0x%08lx", (gulong)rv);
+	return string;
+}
+
+void
+gck_assertion_message_cmprv (const gchar *domain, const gchar *file, gint line,
+                             const gchar *func, const gchar *expr,
+                             CK_RV arg1, const gchar *cmp, CK_RV arg2)
+{
+	gchar *a1, *a2, *s;
+	a1 = rv_to_string (arg1);
+	a2 = rv_to_string (arg2);
+	s = g_strdup_printf ("assertion failed (%s): (%s %s %s)", expr, a1, cmp, a2);
+	g_free (a1);
+	g_free (a2);
+	g_assertion_message (domain, file, line, func, s);
+	g_free (s);
+}
+
+void
+gck_assertion_message_cmpulong (const gchar *domain, const gchar *file, gint line,
+                                const gchar *func, const gchar *expr,
+                                CK_ULONG arg1, const gchar *cmp, CK_ULONG arg2)
+{
+	char *s = NULL;
+	s = g_strdup_printf ("assertion failed (%s): (0x%08llx %s 0x%08llx)", expr,
+	                     (long long unsigned)arg1, cmp, (long long unsigned)arg2);
+	g_assertion_message (domain, file, line, func, s);
+	g_free (s);
+}
diff --git a/gck/gck-test.h b/gck/gck-test.h
new file mode 100644
index 0000000..6f2e0fc
--- /dev/null
+++ b/gck/gck-test.h
@@ -0,0 +1,68 @@
+/*
+ * gnome-keyring
+ *
+ * Copyright (C) 2010 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.
+ */
+
+#include <glib.h>
+
+#include "gck/gck.h"
+
+#include "pkcs11/pkcs11.h"
+#include "pkcs11/pkcs11i.h"
+
+#ifndef GCK_TEST_H
+#define GCK_TEST_H
+
+#ifdef WITH_TESTS
+
+#define         gck_assert_cmprv(v1, cmp, v2) \
+		do { CK_RV __v1 = (v1), __v2 = (v2); \
+			if (__v1 cmp __v2) ; else \
+				gck_assertion_message_cmprv (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
+				                             #v1 " " #cmp " " #v2, __v1, #cmp, __v2); \
+		} while (0)
+
+#define         gck_assert_cmpulong(v1, cmp, v2) \
+		do { CK_RV __v1 = (v1), __v2 = (v2); \
+			if (__v1 cmp __v2) ; else \
+				gck_assertion_message_cmpulong (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
+				                                #v1 " " #cmp " " #v2, __v1, #cmp, __v2); \
+		} while (0)
+
+void            gck_assertion_message_cmprv        (const gchar *domain,
+                                                    const gchar *file,
+                                                    int line,
+                                                    const gchar *func,
+                                                    const gchar *expr,
+                                                    CK_RV arg1,
+                                                    const gchar *cmp,
+                                                    CK_RV arg2);
+
+void            gck_assertion_message_cmpulong     (const gchar *domain,
+                                                    const gchar *file,
+                                                    gint line,
+                                                    const gchar *func,
+                                                    const gchar *expr,
+                                                    CK_ULONG arg1,
+                                                    const gchar *cmp,
+                                                    CK_ULONG arg2);
+
+#endif /* WITH_TESTS */
+
+#endif /* GCK_TEST_H */
diff --git a/gck/tests/Makefile.am b/gck/tests/Makefile.am
index b2a319b..5ca392c 100644
--- a/gck/tests/Makefile.am
+++ b/gck/tests/Makefile.am
@@ -19,7 +19,7 @@ TESTING_FLAGS = \
 TESTING_LIBS = \
 	$(GIO_LIBS) \
 	$(top_builddir)/gck/libgck.la \
-	libgck-test-module.la
+	libmock-test-module.la
 
 EXTRA_DIST = \
 	gck-test.h
@@ -28,18 +28,18 @@ include $(top_srcdir)/testing/testing.make
 
 # ------------------------------------------------------------------------
 
-lib_LTLIBRARIES = libgck-test-module.la
+lib_LTLIBRARIES = libmock-test-module.la
 
-libgck_test_module_la_LDFLAGS = \
+libmock_test_module_la_LDFLAGS = \
 	-avoid-version
 
-libgck_test_module_la_CFLAGS = \
+libmock_test_module_la_CFLAGS = \
 	-I$(top_srcdir)/gck \
 	-I$(top_srcdir) \
 	$(GLIB_CFLAGS)
 
-libgck_test_module_la_SOURCES = \
-	gck-test-module.c
+libmock_test_module_la_SOURCES = \
+	mock-test-module.c
 
-libgck_test_module_la_LIBADD = \
+libmock_test_module_la_LIBADD = \
 	$(top_builddir)/gck/libgck.la
diff --git a/gck/tests/gck-test.h b/gck/tests/gck-test.h
index 4373cd4..1401d82 100644
--- a/gck/tests/gck-test.h
+++ b/gck/tests/gck-test.h
@@ -2,6 +2,7 @@
 #define GCK_TEST_H_
 
 #include "gck.h"
+#include "gck-mock.h"
 
 #define FAIL_RES(res, e) do { \
 	g_assert ((res) ? FALSE : TRUE); \
@@ -15,41 +16,4 @@
 	g_clear_error (&err); \
 	} while(0)
 
-/*
- * Some dumb crypto mechanisms for simple testing.
- *
- * CKM_CAPITALIZE (encrypt/decrypt)
- *     capitalizes to encrypt
- *     lowercase to decrypt
- *
- * CKM_PREFIX (sign/verify)
- *     sign prefixes data with key label
- *     verify unprefixes data with key label.
- *
- * CKM_GENERATE (generate-pair)
- *     generates a pair of keys, mechanism param should be 'generate'
- *
- * CKM_WRAP (wrap key)
- *     wraps key by returning value, mechanism param should be 'wrap'
- *
- * CKM_DERIVE (derive-key)
- *     derives key by setting value to 'derived'.
- *     mechanism param should be 'derive'
- */
-
-#define CKM_CAPITALIZE    (CKM_VENDOR_DEFINED | 1)
-#define CKM_PREFIX        (CKM_VENDOR_DEFINED | 2)
-#define CKM_GENERATE      (CKM_VENDOR_DEFINED | 3)
-#define CKM_WRAP          (CKM_VENDOR_DEFINED | 4)
-#define CKM_DERIVE        (CKM_VENDOR_DEFINED | 5)
-
-/*
- * Two slots
- *  ONE: token present
- *  TWO: token not present
- */
-
-#define GCK_TEST_SLOT_ONE  52
-#define GCK_TEST_SLOT_TWO  134
-
 #endif /* GCK_TEST_H_ */
diff --git a/gck/tests/mock-test-module.c b/gck/tests/mock-test-module.c
new file mode 100644
index 0000000..c5431e7
--- /dev/null
+++ b/gck/tests/mock-test-module.c
@@ -0,0 +1,10 @@
+#include "config.h"
+
+#include "gck-mock.h"
+#include "pkcs11.h"
+
+CK_RV
+C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list)
+{
+	return gck_mock_C_GetFunctionList (list);
+}
diff --git a/gck/tests/test-gck-crypto.c b/gck/tests/test-gck-crypto.c
index 95e5515..48ca597 100644
--- a/gck/tests/test-gck-crypto.c
+++ b/gck/tests/test-gck-crypto.c
@@ -20,7 +20,7 @@ DEFINE_SETUP(crypto_session)
 	GckSlot *slot;
 
 	/* Successful load */
-	module = gck_module_initialize (".libs/libgck-test-module.so", NULL, 0, &err);
+	module = gck_module_initialize (".libs/libmock-test-module.so", NULL, 0, &err);
 	SUCCESS_RES (module, err);
 
 	slots = gck_module_get_slots (module, TRUE);
@@ -151,14 +151,14 @@ DEFINE_TEST(encrypt)
 	guchar *output;
 	gsize n_output;
 
-	mech = gck_mechanism_new (CKM_CAPITALIZE);
+	mech = gck_mechanism_new (CKM_MOCK_CAPITALIZE);
 
 	/* Find the right key */
-	key = find_key (session, CKA_ENCRYPT, CKM_CAPITALIZE);
+	key = find_key (session, CKA_ENCRYPT, CKM_MOCK_CAPITALIZE);
 	g_assert (key);
 
 	/* Simple one */
-	output = gck_session_encrypt (session, key, CKM_CAPITALIZE, (const guchar*)"blah blah", 10, &n_output, &error);
+	output = gck_session_encrypt (session, key, CKM_MOCK_CAPITALIZE, (const guchar*)"blah blah", 10, &n_output, &error);
 	SUCCESS_RES (output, error);
 	g_assert (n_output == 10);
 	g_assert_cmpstr ((gchar*)output, ==, "BLAH BLAH");
@@ -198,14 +198,14 @@ DEFINE_TEST(decrypt)
 	guchar *output;
 	gsize n_output;
 
-	mech = gck_mechanism_new (CKM_CAPITALIZE);
+	mech = gck_mechanism_new (CKM_MOCK_CAPITALIZE);
 
 	/* Find the right key */
-	key = find_key (session, CKA_DECRYPT, CKM_CAPITALIZE);
+	key = find_key (session, CKA_DECRYPT, CKM_MOCK_CAPITALIZE);
 	g_assert (key);
 
 	/* Simple one */
-	output = gck_session_decrypt (session, key, CKM_CAPITALIZE, (const guchar*)"FRY???", 7, &n_output, &error);
+	output = gck_session_decrypt (session, key, CKM_MOCK_CAPITALIZE, (const guchar*)"FRY???", 7, &n_output, &error);
 	SUCCESS_RES (output, error);
 	g_assert (n_output == 7);
 	g_assert_cmpstr ((gchar*)output, ==, "fry???");
@@ -246,11 +246,11 @@ DEFINE_TEST(login_context_specific)
 	gsize n_output;
 
 	/* Find the right key */
-	key = find_key (session, CKA_SIGN, CKM_PREFIX);
+	key = find_key (session, CKA_SIGN, CKM_MOCK_PREFIX);
 	g_assert (key);
 
 	/* Simple one */
-	output = gck_session_sign (session, key, CKM_PREFIX, (const guchar*)"TV Monster", 11, &n_output, &error);
+	output = gck_session_sign (session, key, CKM_MOCK_PREFIX, (const guchar*)"TV Monster", 11, &n_output, &error);
 	g_assert (error && error->code == CKR_USER_NOT_LOGGED_IN);
 	FAIL_RES (output, error);
 	g_assert (output == NULL);
@@ -267,17 +267,17 @@ DEFINE_TEST(sign)
 	guchar *output;
 	gsize n_output;
 
-	mech = gck_mechanism_new_with_param (CKM_PREFIX, "my-prefix:", 10);
+	mech = gck_mechanism_new_with_param (CKM_MOCK_PREFIX, "my-prefix:", 10);
 
 	/* Enable auto-login on this session, see previous test */
 	g_signal_connect (module_with_auth, "authenticate-object", G_CALLBACK (authenticate_object), NULL);
 
 	/* Find the right key */
-	key = find_key (session_with_auth, CKA_SIGN, CKM_PREFIX);
+	key = find_key (session_with_auth, CKA_SIGN, CKM_MOCK_PREFIX);
 	g_assert (key);
 
 	/* Simple one */
-	output = gck_session_sign (session_with_auth, key, CKM_PREFIX, (const guchar*)"Labarbara", 10, &n_output, &error);
+	output = gck_session_sign (session_with_auth, key, CKM_MOCK_PREFIX, (const guchar*)"Labarbara", 10, &n_output, &error);
 	SUCCESS_RES (output, error);
 	g_assert_cmpuint (n_output, ==, 24);
 	g_assert_cmpstr ((gchar*)output, ==, "signed-prefix:Labarbara");
@@ -316,17 +316,17 @@ DEFINE_TEST(verify)
 	GckObject *key;
 	gboolean ret;
 
-	mech = gck_mechanism_new_with_param (CKM_PREFIX, "my-prefix:", 10);
+	mech = gck_mechanism_new_with_param (CKM_MOCK_PREFIX, "my-prefix:", 10);
 
 	/* Enable auto-login on this session, shouldn't be needed */
 	g_signal_connect (module, "authenticate-object", G_CALLBACK (authenticate_object), NULL);
 
 	/* Find the right key */
-	key = find_key (session, CKA_VERIFY, CKM_PREFIX);
+	key = find_key (session, CKA_VERIFY, CKM_MOCK_PREFIX);
 	g_assert (key);
 
 	/* Simple one */
-	ret = gck_session_verify (session, key, CKM_PREFIX, (const guchar*)"Labarbara", 10,
+	ret = gck_session_verify (session, key, CKM_MOCK_PREFIX, (const guchar*)"Labarbara", 10,
 	                           (const guchar*)"signed-prefix:Labarbara", 24, &error);
 	SUCCESS_RES (ret, error);
 
@@ -372,7 +372,7 @@ DEFINE_TEST(generate_key_pair)
 	GckObject *pub_key, *prv_key;
 	gboolean ret;
 
-	mech = gck_mechanism_new_with_param (CKM_GENERATE, "generate", 9);
+	mech = gck_mechanism_new_with_param (CKM_MOCK_GENERATE, "generate", 9);
 
 	pub_attrs = gck_attributes_new ();
 	gck_attributes_add_ulong (pub_attrs, CKA_CLASS, CKO_PUBLIC_KEY);
@@ -396,7 +396,7 @@ DEFINE_TEST(generate_key_pair)
 	g_assert (prv_key == NULL);
 
 	/* Asynchronous one */
-	mech->type = CKM_GENERATE;
+	mech->type = CKM_MOCK_GENERATE;
 	gck_session_generate_key_pair_async (session, mech, pub_attrs, prv_attrs, NULL, fetch_async_result, &result);
 	testing_wait_until (500);
 	g_assert (result != NULL);
@@ -433,12 +433,12 @@ DEFINE_TEST(wrap_key)
 	gpointer output;
 	gsize n_output;
 
-	mech = gck_mechanism_new_with_param (CKM_WRAP, "wrap", 4);
+	mech = gck_mechanism_new_with_param (CKM_MOCK_WRAP, "wrap", 4);
 	wrapper = find_key (session, CKA_WRAP, 0);
 	wrapped = find_key_with_value (session, "value");
 
 	/* Simple One */
-	output = gck_session_wrap_key (session, wrapper, CKM_WRAP, wrapped, &n_output, &error);
+	output = gck_session_wrap_key (session, wrapper, CKM_MOCK_WRAP, wrapped, &n_output, &error);
 	SUCCESS_RES (output, error);
 	g_assert (output);
 	g_assert_cmpsize (n_output, ==, 5);
@@ -460,7 +460,7 @@ DEFINE_TEST(wrap_key)
 	g_assert_cmpsize (n_output, ==, 0);
 
 	/* Asynchronous one */
-	mech->type = CKM_WRAP;
+	mech->type = CKM_MOCK_WRAP;
 	gck_session_wrap_key_async (session, wrapper, mech, wrapped, NULL, fetch_async_result, &result);
 	testing_wait_until (500);
 	g_assert (result != NULL);
@@ -496,7 +496,7 @@ DEFINE_TEST(unwrap_key)
 	GckObject *wrapper, *unwrapped;
 	GckAttributes *attrs;
 
-	mech = gck_mechanism_new_with_param (CKM_WRAP, "wrap", 4);
+	mech = gck_mechanism_new_with_param (CKM_MOCK_WRAP, "wrap", 4);
 	wrapper = find_key (session, CKA_UNWRAP, 0);
 	attrs = gck_attributes_new ();
 	gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_SECRET_KEY);
@@ -514,7 +514,7 @@ DEFINE_TEST(unwrap_key)
 	FAIL_RES (unwrapped, error);
 
 	/* Asynchronous one */
-	mech->type = CKM_WRAP;
+	mech->type = CKM_MOCK_WRAP;
 	gck_session_unwrap_key_async (session, wrapper, mech, "special", 7, attrs, NULL, fetch_async_result, &result);
 	testing_wait_until (500);
 	g_assert (result != NULL);
@@ -548,7 +548,7 @@ DEFINE_TEST(derive_key)
 	GckObject *wrapper, *derived;
 	GckAttributes *attrs;
 
-	mech = gck_mechanism_new_with_param (CKM_DERIVE, "derive", 6);
+	mech = gck_mechanism_new_with_param (CKM_MOCK_DERIVE, "derive", 6);
 	wrapper = find_key (session, CKA_DERIVE, 0);
 	attrs = gck_attributes_new ();
 	gck_attributes_add_ulong (attrs, CKA_CLASS, CKO_SECRET_KEY);
@@ -566,7 +566,7 @@ DEFINE_TEST(derive_key)
 	FAIL_RES (derived, error);
 
 	/* Asynchronous one */
-	mech->type = CKM_DERIVE;
+	mech->type = CKM_MOCK_DERIVE;
 	gck_session_derive_key_async (session, wrapper, mech, attrs, NULL, fetch_async_result, &result);
 	testing_wait_until (500);
 	g_assert (result != NULL);
diff --git a/gck/tests/test-gck-enumerator.c b/gck/tests/test-gck-enumerator.c
index bcae887..01332ad 100644
--- a/gck/tests/test-gck-enumerator.c
+++ b/gck/tests/test-gck-enumerator.c
@@ -14,7 +14,7 @@ DEFINE_SETUP(enumerator)
 	GError *err = NULL;
 
 	/* Successful load */
-	module = gck_module_initialize (".libs/libgck-test-module.so", NULL, 0, &err);
+	module = gck_module_initialize (".libs/libmock-test-module.so", NULL, 0, &err);
 	SUCCESS_RES (module, err);
 
 	modules = g_list_append (NULL, module);
diff --git a/gck/tests/test-gck-module.c b/gck/tests/test-gck-module.c
index 7ad2356..210ea64 100644
--- a/gck/tests/test-gck-module.c
+++ b/gck/tests/test-gck-module.c
@@ -12,7 +12,7 @@ DEFINE_SETUP(load_module)
 	GError *err = NULL;
 
 	/* Successful load */
-	module = gck_module_initialize (".libs/libgck-test-module.so", NULL, 0, &err);
+	module = gck_module_initialize (".libs/libmock-test-module.so", NULL, 0, &err);
 	SUCCESS_RES (module, err);
 }
 
@@ -64,7 +64,7 @@ DEFINE_TEST(module_props)
 
 	g_object_get (module, "path", &path, NULL);
 	g_assert (path != NULL && "no module-path");
-	g_assert (strcmp (".libs/libgck-test-module.so", path) == 0 && "module path wrong");
+	g_assert (strcmp (".libs/libmock-test-module.so", path) == 0 && "module path wrong");
 	g_free (path);
 }
 
diff --git a/gck/tests/test-gck-modules.c b/gck/tests/test-gck-modules.c
index 64ac992..8436301 100644
--- a/gck/tests/test-gck-modules.c
+++ b/gck/tests/test-gck-modules.c
@@ -13,7 +13,7 @@ DEFINE_SETUP(modules)
 	GError *err = NULL;
 
 	/* Successful load */
-	module = gck_module_initialize (".libs/libgck-test-module.so", NULL, 0, &err);
+	module = gck_module_initialize (".libs/libmock-test-module.so", NULL, 0, &err);
 	SUCCESS_RES (module, err);
 
 	modules = g_list_append (NULL, module);
diff --git a/gck/tests/test-gck-object.c b/gck/tests/test-gck-object.c
index d88300a..8c9079a 100644
--- a/gck/tests/test-gck-object.c
+++ b/gck/tests/test-gck-object.c
@@ -19,7 +19,7 @@ DEFINE_SETUP(prep_object)
 	GList *slots;
 
 	/* Successful load */
-	module = gck_module_initialize (".libs/libgck-test-module.so", NULL, 0, &err);
+	module = gck_module_initialize (".libs/libmock-test-module.so", NULL, 0, &err);
 	SUCCESS_RES (module, err);
 
 	slots = gck_module_get_slots (module, TRUE);
@@ -72,7 +72,7 @@ DEFINE_TEST(object_equals_hash)
 
 	g_assert (gck_object_equal (object, object));
 
-	other_slot = g_object_new (GCK_TYPE_SLOT, "module", module, "handle", GCK_TEST_SLOT_TWO, NULL);
+	other_slot = g_object_new (GCK_TYPE_SLOT, "module", module, "handle", GCK_MOCK_SLOT_TWO_ID, NULL);
 	other_session = gck_slot_open_session (other_slot, 0, &err);
 	SUCCESS_RES (other_session, err);
 	other_object = gck_object_from_handle (other_session, gck_object_get_handle (object));
diff --git a/gck/tests/test-gck-session.c b/gck/tests/test-gck-session.c
index 19495be..3413a0a 100644
--- a/gck/tests/test-gck-session.c
+++ b/gck/tests/test-gck-session.c
@@ -18,7 +18,7 @@ DEFINE_SETUP(load_session)
 	GList *slots;
 
 	/* Successful load */
-	module = gck_module_initialize (".libs/libgck-test-module.so", NULL, 0, &err);
+	module = gck_module_initialize (".libs/libmock-test-module.so", NULL, 0, &err);
 	SUCCESS_RES (module, err);
 
 	slots = gck_module_get_slots (module, TRUE);
diff --git a/gck/tests/test-gck-slot.c b/gck/tests/test-gck-slot.c
index 8ea75f0..f8fb189 100644
--- a/gck/tests/test-gck-slot.c
+++ b/gck/tests/test-gck-slot.c
@@ -15,7 +15,7 @@ DEFINE_SETUP(load_slots)
 	GList *slots;
 
 	/* Successful load */
-	module = gck_module_initialize (".libs/libgck-test-module.so", NULL, 0, &err);
+	module = gck_module_initialize (".libs/libmock-test-module.so", NULL, 0, &err);
 	SUCCESS_RES (module, err);
 
 	slots = gck_module_get_slots (module, TRUE);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]