summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stefw@collabora.co.uk>2011-08-14 18:46:50 +0200
committerStef Walter <stefw@collabora.co.uk>2011-08-14 18:49:55 +0200
commitd4abb441450deceff760086dcdf9d493b258074a (patch)
treef991ceb0d049433d9c1a06b090040d35aeb5fd4a
parent43169c520292397439bd70fb74e9505d371f7c72 (diff)
downloadp11-kit-d4abb441450deceff760086dcdf9d493b258074a.tar.gz
Fix endless loop if module forks during initialization.
* If a module forks during its C_Initialize, previously our fork handler would try to initialize it again, ad nauseum. Reported by Nikos on the mailing list.
-rw-r--r--.gitignore1
-rw-r--r--p11-kit/modules.c12
-rw-r--r--tests/Makefile.am30
-rw-r--r--tests/mock-module.c886
-rw-r--r--tests/mock-module.h336
-rw-r--r--tests/p11-test.c114
6 files changed, 1354 insertions, 25 deletions
diff --git a/.gitignore b/.gitignore
index f4e65d0..9359157 100644
--- a/.gitignore
+++ b/.gitignore
@@ -70,6 +70,7 @@ temp.txt
/tests/coverage
/tests/coverage.info
/tests/hash-test
+/tests/p11-test
/tests/pin-test
/tests/ptr-array-test
/tests/conf-test
diff --git a/p11-kit/modules.c b/p11-kit/modules.c
index 693d342..d5dae32 100644
--- a/p11-kit/modules.c
+++ b/p11-kit/modules.c
@@ -446,7 +446,7 @@ initialize_module_unlocked_reentrant (Module *mod)
assert (mod);
/*
- * Initialize first, so module doesn't get freed out from
+ * Increase ref first, so module doesn't get freed out from
* underneath us when the mutex is unlocked below.
*/
++mod->ref_count;
@@ -499,10 +499,12 @@ reinitialize_after_fork (void)
if (gl.modules) {
hash_iterate (gl.modules, &iter);
while (hash_next (&iter, NULL, (void **)&mod)) {
- mod->initialize_count = 0;
+ if (mod->initialize_count > 0) {
+ mod->initialize_count = 0;
- /* WARNING: Reentrancy can occur here */
- initialize_module_unlocked_reentrant (mod);
+ /* WARNING: Reentrancy can occur here */
+ initialize_module_unlocked_reentrant (mod);
+ }
}
}
@@ -953,8 +955,8 @@ p11_kit_registered_option (CK_FUNCTION_LIST_PTR module, const char *field)
CK_RV
p11_kit_initialize_module (CK_FUNCTION_LIST_PTR module)
{
- Module *mod;
Module *allocated = NULL;
+ Module *mod;
CK_RV rv = CKR_OK;
/* WARNING: This function must be reentrant for the same arguments */
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 430b89e..a7796e8 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -6,32 +6,21 @@ INCLUDES = \
-DSRCDIR=\"$(srcdir)\" \
-DP11_KIT_FUTURE_UNSTABLE_API
+LDADD = \
+ $(top_builddir)/p11-kit/libp11-kit-testable.la \
+ $(LTLIBINTL)
+
noinst_PROGRAMS = \
hash-test \
ptr-array-test \
conf-test \
uri-test \
- pin-test
-
-hash_test_LDADD = \
- $(top_builddir)/p11-kit/libp11-kit-testable.la \
- $(LTLIBINTL)
-
-ptr_array_test_LDADD = \
- $(top_builddir)/p11-kit/libp11-kit-testable.la \
- $(LTLIBINTL)
+ pin-test \
+ p11-test
-conf_test_LDADD = \
- $(top_builddir)/p11-kit/libp11-kit-testable.la \
- $(LTLIBINTL)
-
-uri_test_LDADD = \
- $(top_builddir)/p11-kit/libp11-kit-testable.la \
- $(LTLIBINTL)
-
-pin_test_LDADD = \
- $(top_builddir)/p11-kit/libp11-kit-testable.la \
- $(LTLIBINTL)
+p11_test_SOURCES = \
+ p11-test.c \
+ mock-module.c mock-module.h
check-am:
./hash-test
@@ -39,6 +28,7 @@ check-am:
./conf-test
./uri-test
./pin-test
+ ./p11-test
EXTRA_DIST = \
cutest \
diff --git a/tests/mock-module.c b/tests/mock-module.c
new file mode 100644
index 0000000..a1a6a7e
--- /dev/null
+++ b/tests/mock-module.c
@@ -0,0 +1,886 @@
+/*
+ * Copyright (c) 2011, Collabora Ltd.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ * * The names of contributors to this software may not be
+ * used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Author: Stef Walter <stefw@collabora.co.uk>
+ */
+
+#include "config.h"
+
+#include "pkcs11.h"
+#include "mock-module.h"
+
+#include <pthread.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+/* -------------------------------------------------------------------
+ * GLOBALS / DEFINES
+ */
+
+/* Various mutexes */
+static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+/* Whether we've been initialized, and on what process id it happened */
+static int pkcs11_initialized = 0;
+static pid_t pkcs11_initialized_pid = 0;
+
+/* -----------------------------------------------------------------------------
+ * LOGGING and DEBUGGING
+ */
+
+#define DEBUG_OUTPUT 0
+
+#if DEBUG_OUTPUT
+#define debug(x) mock_log x
+#else
+#define debug(x)
+#endif
+
+#define warning(x) mock_log x
+
+#define return_val_if_fail(x, v) \
+ if (!(x)) { mock_log ("'%s' not true at %s", #x, __func__); return v; }
+
+static void
+mock_log (const char *format, ...)
+{
+ va_list va;
+ va_start (va, format);
+ fprintf (stderr, "mock-module: ");
+ vfprintf (stderr, format, va);
+ fprintf (stderr, "\n");
+ va_end (va);
+}
+
+/* -------------------------------------------------------------------
+ * INITIALIZATION and 'GLOBAL' CALLS
+ */
+
+CK_RV
+mock_C_Initialize (CK_VOID_PTR init_args)
+{
+ CK_C_INITIALIZE_ARGS_PTR args = NULL;
+ CK_RV ret = CKR_OK;
+ pid_t pid;
+
+ debug (("C_Initialize: enter"));
+
+ pthread_mutex_lock (&init_mutex);
+
+ if (init_args != NULL) {
+ int supplied_ok;
+
+ /* pReserved must be NULL */
+ args = init_args;
+
+ /* ALL supplied function pointers need to have the value either NULL or non-NULL. */
+ supplied_ok = (args->CreateMutex == NULL && args->DestroyMutex == NULL &&
+ args->LockMutex == NULL && args->UnlockMutex == NULL) ||
+ (args->CreateMutex != NULL && args->DestroyMutex != NULL &&
+ args->LockMutex != NULL && args->UnlockMutex != NULL);
+ if (!supplied_ok) {
+ warning (("invalid set of mutex calls supplied"));
+ ret = CKR_ARGUMENTS_BAD;
+ goto done;
+ }
+
+ /*
+ * When the CKF_OS_LOCKING_OK flag isn't set return an error.
+ * We must be able to use our pthread functionality.
+ */
+ if (!(args->flags & CKF_OS_LOCKING_OK)) {
+ warning (("can't do without os locking"));
+ ret = CKR_CANT_LOCK;
+ goto done;
+ }
+ }
+
+ pid = getpid ();
+ if (pkcs11_initialized) {
+
+ /* This process has called C_Initialize already */
+ if (pid == pkcs11_initialized_pid) {
+ warning (("C_Initialize called twice for same process"));
+ ret = CKR_CRYPTOKI_ALREADY_INITIALIZED;
+ goto done;
+ }
+ }
+
+done:
+ /* Mark us as officially initialized */
+ if (ret == CKR_OK) {
+ pkcs11_initialized = 1;
+ pkcs11_initialized_pid = pid;
+ } else if (ret != CKR_CRYPTOKI_ALREADY_INITIALIZED) {
+ pkcs11_initialized = 0;
+ pkcs11_initialized_pid = 0;
+ }
+
+ pthread_mutex_unlock (&init_mutex);
+
+ debug (("C_Initialize: %d", ret));
+ return ret;
+}
+
+CK_RV
+mock_C_Finalize (CK_VOID_PTR reserved)
+{
+ debug (("C_Finalize: enter"));
+ return_val_if_fail (pkcs11_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
+ return_val_if_fail (!reserved, CKR_ARGUMENTS_BAD);
+
+ pthread_mutex_lock (&init_mutex);
+
+ /* This should stop all other calls in */
+ pkcs11_initialized = 0;
+ pkcs11_initialized_pid = 0;
+
+ pthread_mutex_unlock (&init_mutex);
+
+ debug (("C_Finalize: %d", CKR_OK));
+ return CKR_OK;
+}
+
+static const CK_INFO MOCK_INFO = {
+ { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR },
+ "MOCK MANUFACTURER ",
+ 0,
+ "MOCK LIBRARY ",
+ { 45, 145 }
+};
+
+
+CK_RV
+mock_C_GetInfo (CK_INFO_PTR info)
+{
+ return_val_if_fail (info, CKR_ARGUMENTS_BAD);
+
+ memcpy (info, &MOCK_INFO, sizeof (*info));
+ return CKR_OK;
+}
+
+CK_RV
+mock_C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list)
+{
+ /* This would be a strange call to receive */
+ return C_GetFunctionList (list);
+}
+
+CK_RV
+mock_C_GetSlotList__no_tokens (CK_BBOOL token_present,
+ CK_SLOT_ID_PTR slot_list,
+ CK_ULONG_PTR count)
+{
+ return_val_if_fail (count, CKR_ARGUMENTS_BAD);
+
+ /* No tokens */
+ *count = 0;
+ return CKR_OK;
+}
+
+CK_RV
+mock_C_GetSlotInfo__invalid_slotid (CK_SLOT_ID id,
+ CK_SLOT_INFO_PTR info)
+{
+ return_val_if_fail (info, CKR_ARGUMENTS_BAD);
+
+ return CKR_SLOT_ID_INVALID;
+}
+
+CK_RV
+mock_C_GetTokenInfo__invalid_slotid (CK_SLOT_ID id,
+ CK_TOKEN_INFO_PTR info)
+{
+ return_val_if_fail (info, CKR_ARGUMENTS_BAD);
+
+ return CKR_SLOT_ID_INVALID;
+}
+
+CK_RV
+mock_C_GetMechanismList__invalid_slotid (CK_SLOT_ID id,
+ CK_MECHANISM_TYPE_PTR mechanism_list,
+ CK_ULONG_PTR count)
+{
+ return_val_if_fail (count, CKR_ARGUMENTS_BAD);
+
+ return CKR_SLOT_ID_INVALID;
+}
+
+CK_RV
+mock_C_GetMechanismInfo__invalid_slotid (CK_SLOT_ID id,
+ CK_MECHANISM_TYPE type,
+ CK_MECHANISM_INFO_PTR info)
+{
+ return_val_if_fail (info, CKR_ARGUMENTS_BAD);
+
+ return CKR_SLOT_ID_INVALID;
+}
+
+CK_RV
+mock_C_InitToken__invalid_slotid (CK_SLOT_ID id,
+ CK_UTF8CHAR_PTR pin,
+ CK_ULONG pin_len,
+ CK_UTF8CHAR_PTR label)
+{
+ return CKR_SLOT_ID_INVALID;
+}
+
+CK_RV
+mock_C_WaitForSlotEvent__no_event (CK_FLAGS flags,
+ CK_SLOT_ID_PTR slot,
+ CK_VOID_PTR reserved)
+{
+ return_val_if_fail (slot, CKR_ARGUMENTS_BAD);
+
+ return CKR_NO_EVENT;
+}
+
+CK_RV
+mock_C_OpenSession__invalid_slotid (CK_SLOT_ID id,
+ CK_FLAGS flags,
+ CK_VOID_PTR user_data,
+ CK_NOTIFY callback,
+ CK_SESSION_HANDLE_PTR session)
+{
+ return_val_if_fail (session, CKR_ARGUMENTS_BAD);
+
+ return CKR_SLOT_ID_INVALID;
+}
+
+CK_RV
+mock_C_CloseSession__invalid_handle (CK_SESSION_HANDLE session)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_CloseAllSessions__invalid_slotid (CK_SLOT_ID id)
+{
+ return CKR_SLOT_ID_INVALID;
+}
+
+CK_RV
+mock_C_GetFunctionStatus__not_parallel (CK_SESSION_HANDLE session)
+{
+ return CKR_FUNCTION_NOT_PARALLEL;
+}
+
+CK_RV
+mock_C_CancelFunction__not_parallel (CK_SESSION_HANDLE session)
+{
+ return CKR_FUNCTION_NOT_PARALLEL;
+}
+
+CK_RV
+mock_C_GetSessionInfo__invalid_handle (CK_SESSION_HANDLE session,
+ CK_SESSION_INFO_PTR info)
+{
+ return_val_if_fail (info, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_InitPIN__invalid_handle (CK_SESSION_HANDLE session,
+ CK_UTF8CHAR_PTR pin,
+ CK_ULONG pin_len)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_SetPIN__invalid_handle (CK_SESSION_HANDLE session,
+ CK_UTF8CHAR_PTR old_pin,
+ CK_ULONG old_pin_len,
+ CK_UTF8CHAR_PTR new_pin,
+ CK_ULONG new_pin_len)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_GetOperationState__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR operation_state,
+ CK_ULONG_PTR operation_state_len)
+{
+ return_val_if_fail (operation_state_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_SetOperationState__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR operation_state,
+ CK_ULONG operation_state_len,
+ CK_OBJECT_HANDLE encryption_key,
+ CK_OBJECT_HANDLE authentication_key)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_Login__invalid_handle (CK_SESSION_HANDLE session,
+ CK_USER_TYPE user_type,
+ CK_UTF8CHAR_PTR pin,
+ CK_ULONG pin_len)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+
+}
+
+CK_RV
+mock_C_Logout__invalid_handle (CK_SESSION_HANDLE session)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+
+}
+
+CK_RV
+mock_C_CreateObject__invalid_handle (CK_SESSION_HANDLE session,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count,
+ CK_OBJECT_HANDLE_PTR new_object)
+{
+ return_val_if_fail (new_object, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_CopyObject__invalid_handle (CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count,
+ CK_OBJECT_HANDLE_PTR new_object)
+{
+ return_val_if_fail (new_object, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+
+CK_RV
+mock_C_DestroyObject__invalid_handle (CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_GetObjectSize__invalid_handle (CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object,
+ CK_ULONG_PTR size)
+{
+ return_val_if_fail (size, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_GetAttributeValue__invalid_handle (CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_SetAttributeValue__invalid_handle (CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_FindObjectsInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_FindObjects__invalid_handle (CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE_PTR objects,
+ CK_ULONG max_count,
+ CK_ULONG_PTR count)
+{
+ return_val_if_fail (count, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_FindObjectsFinal__invalid_handle (CK_SESSION_HANDLE session)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_EncryptInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE key)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_Encrypt__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR data, CK_ULONG data_len,
+ CK_BYTE_PTR encrypted_data,
+ CK_ULONG_PTR encrypted_data_len)
+{
+ return_val_if_fail (encrypted_data_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_EncryptUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR part,
+ CK_ULONG part_len,
+ CK_BYTE_PTR encrypted_part,
+ CK_ULONG_PTR encrypted_part_len)
+{
+ return_val_if_fail (encrypted_part_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_EncryptFinal__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR last_part,
+ CK_ULONG_PTR last_part_len)
+{
+ return_val_if_fail (last_part_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_DecryptInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE key)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_Decrypt__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR enc_data,
+ CK_ULONG enc_data_len,
+ CK_BYTE_PTR data,
+ CK_ULONG_PTR data_len)
+{
+ return_val_if_fail (data_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_DecryptUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR enc_part,
+ CK_ULONG enc_part_len,
+ CK_BYTE_PTR part,
+ CK_ULONG_PTR part_len)
+{
+ return_val_if_fail (part_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_DecryptFinal__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR last_part,
+ CK_ULONG_PTR last_part_len)
+{
+ return_val_if_fail (last_part_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_DigestInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_Digest__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR data,
+ CK_ULONG data_len,
+ CK_BYTE_PTR digest,
+ CK_ULONG_PTR digest_len)
+{
+ return_val_if_fail (digest_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_DigestUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR part,
+ CK_ULONG part_len)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_DigestKey__invalid_handle (CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE key)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_DigestFinal__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR digest,
+ CK_ULONG_PTR digest_len)
+{
+ return_val_if_fail (digest_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_SignInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE key)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_Sign__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR data,
+ CK_ULONG data_len,
+ CK_BYTE_PTR signature,
+ CK_ULONG_PTR signature_len)
+{
+ return_val_if_fail (signature_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_SignUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR part,
+ CK_ULONG part_len)
+{
+ return_val_if_fail (part_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_SignFinal__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR signature,
+ CK_ULONG_PTR signature_len)
+{
+ return_val_if_fail (signature_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_SignRecoverInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE key)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_SignRecover__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR data,
+ CK_ULONG data_len,
+ CK_BYTE_PTR signature,
+ CK_ULONG_PTR signature_len)
+{
+ return_val_if_fail (signature_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_VerifyInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE key)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_Verify__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR data,
+ CK_ULONG data_len,
+ CK_BYTE_PTR signature,
+ CK_ULONG signature_len)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_VerifyUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR part,
+ CK_ULONG part_len)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_VerifyFinal__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR signature,
+ CK_ULONG signature_len)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_VerifyRecoverInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE key)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_VerifyRecover__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR signature,
+ CK_ULONG signature_len,
+ CK_BYTE_PTR data,
+ CK_ULONG_PTR data_len)
+{
+ return_val_if_fail (data_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_DigestEncryptUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR part,
+ CK_ULONG part_len, CK_BYTE_PTR enc_part,
+ CK_ULONG_PTR enc_part_len)
+{
+ return_val_if_fail (enc_part_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_DecryptDigestUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR enc_part,
+ CK_ULONG enc_part_len,
+ CK_BYTE_PTR part,
+ CK_ULONG_PTR part_len)
+{
+ return_val_if_fail (part_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_SignEncryptUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR part,
+ CK_ULONG part_len,
+ CK_BYTE_PTR enc_part,
+ CK_ULONG_PTR enc_part_len)
+{
+ return_val_if_fail (enc_part_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_DecryptVerifyUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR enc_part,
+ CK_ULONG enc_part_len,
+ CK_BYTE_PTR part,
+ CK_ULONG_PTR part_len)
+{
+ return_val_if_fail (part_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_GenerateKey__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count,
+ CK_OBJECT_HANDLE_PTR key)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_GenerateKeyPair__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_ATTRIBUTE_PTR pub_template,
+ CK_ULONG pub_count,
+ CK_ATTRIBUTE_PTR priv_template,
+ CK_ULONG priv_count,
+ CK_OBJECT_HANDLE_PTR pub_key,
+ CK_OBJECT_HANDLE_PTR priv_key)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_WrapKey__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE wrapping_key,
+ CK_OBJECT_HANDLE key,
+ CK_BYTE_PTR wrapped_key,
+ CK_ULONG_PTR wrapped_key_len)
+{
+ return_val_if_fail (wrapped_key_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_UnwrapKey__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE unwrapping_key,
+ CK_BYTE_PTR wrapped_key,
+ CK_ULONG wrapped_key_len,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count,
+ CK_OBJECT_HANDLE_PTR key)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_DeriveKey__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE base_key,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count,
+ CK_OBJECT_HANDLE_PTR key)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_SeedRandom__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR seed,
+ CK_ULONG seed_len)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_GenerateRandom__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR random_data,
+ CK_ULONG random_len)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_FUNCTION_LIST mock_module_no_slots = {
+ { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR }, /* version */
+ mock_C_Initialize,
+ mock_C_Finalize,
+ mock_C_GetInfo,
+ mock_C_GetFunctionList,
+ mock_C_GetSlotList__no_tokens,
+ mock_C_GetSlotInfo__invalid_slotid,
+ mock_C_GetTokenInfo__invalid_slotid,
+ mock_C_GetMechanismList__invalid_slotid,
+ mock_C_GetMechanismInfo__invalid_slotid,
+ mock_C_InitToken__invalid_slotid,
+ mock_C_InitPIN__invalid_handle,
+ mock_C_SetPIN__invalid_handle,
+ mock_C_OpenSession__invalid_slotid,
+ mock_C_CloseSession__invalid_handle,
+ mock_C_CloseAllSessions__invalid_slotid,
+ mock_C_GetSessionInfo__invalid_handle,
+ mock_C_GetOperationState__invalid_handle,
+ mock_C_SetOperationState__invalid_handle,
+ mock_C_Login__invalid_handle,
+ mock_C_Logout__invalid_handle,
+ mock_C_CreateObject__invalid_handle,
+ mock_C_CopyObject__invalid_handle,
+ mock_C_DestroyObject__invalid_handle,
+ mock_C_GetObjectSize__invalid_handle,
+ mock_C_GetAttributeValue__invalid_handle,
+ mock_C_SetAttributeValue__invalid_handle,
+ mock_C_FindObjectsInit__invalid_handle,
+ mock_C_FindObjects__invalid_handle,
+ mock_C_FindObjectsFinal__invalid_handle,
+ mock_C_EncryptInit__invalid_handle,
+ mock_C_Encrypt__invalid_handle,
+ mock_C_EncryptUpdate__invalid_handle,
+ mock_C_EncryptFinal__invalid_handle,
+ mock_C_DecryptInit__invalid_handle,
+ mock_C_Decrypt__invalid_handle,
+ mock_C_DecryptUpdate__invalid_handle,
+ mock_C_DecryptFinal__invalid_handle,
+ mock_C_DigestInit__invalid_handle,
+ mock_C_Digest__invalid_handle,
+ mock_C_DigestUpdate__invalid_handle,
+ mock_C_DigestKey__invalid_handle,
+ mock_C_DigestFinal__invalid_handle,
+ mock_C_SignInit__invalid_handle,
+ mock_C_Sign__invalid_handle,
+ mock_C_SignUpdate__invalid_handle,
+ mock_C_SignFinal__invalid_handle,
+ mock_C_SignRecoverInit__invalid_handle,
+ mock_C_SignRecover__invalid_handle,
+ mock_C_VerifyInit__invalid_handle,
+ mock_C_Verify__invalid_handle,
+ mock_C_VerifyUpdate__invalid_handle,
+ mock_C_VerifyFinal__invalid_handle,
+ mock_C_VerifyRecoverInit__invalid_handle,
+ mock_C_VerifyRecover__invalid_handle,
+ mock_C_DigestEncryptUpdate__invalid_handle,
+ mock_C_DecryptDigestUpdate__invalid_handle,
+ mock_C_SignEncryptUpdate__invalid_handle,
+ mock_C_DecryptVerifyUpdate__invalid_handle,
+ mock_C_GenerateKey__invalid_handle,
+ mock_C_GenerateKeyPair__invalid_handle,
+ mock_C_WrapKey__invalid_handle,
+ mock_C_UnwrapKey__invalid_handle,
+ mock_C_DeriveKey__invalid_handle,
+ mock_C_SeedRandom__invalid_handle,
+ mock_C_GenerateRandom__invalid_handle,
+ mock_C_GetFunctionStatus__not_parallel,
+ mock_C_CancelFunction__not_parallel,
+ mock_C_WaitForSlotEvent__no_event,
+};
diff --git a/tests/mock-module.h b/tests/mock-module.h
new file mode 100644
index 0000000..f198e46
--- /dev/null
+++ b/tests/mock-module.h
@@ -0,0 +1,336 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* mock-module.c - a mock PKCS#11 module
+
+ Copyright (C) 2011 Collabora Ltd.
+
+ The Gnome Keyring Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Keyring Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Stef Walter <stefw@collabora.co.uk>
+*/
+
+#ifndef __MOCK_MODULE_H__
+#define __MOCK_MODULE_H__
+
+#include "pkcs11.h"
+
+CK_FUNCTION_LIST mock_module_no_slots;
+
+
+CK_RV mock_C_Initialize (CK_VOID_PTR init_args);
+
+CK_RV mock_C_Finalize (CK_VOID_PTR reserved);
+
+CK_RV mock_C_GetInfo (CK_INFO_PTR info);
+
+CK_RV mock_C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list);
+
+CK_RV mock_C_GetSlotList__no_tokens (CK_BBOOL token_present,
+ CK_SLOT_ID_PTR slot_list,
+ CK_ULONG_PTR count);
+
+CK_RV mock_C_GetSlotInfo__invalid_slotid (CK_SLOT_ID id,
+ CK_SLOT_INFO_PTR info);
+
+CK_RV mock_C_GetTokenInfo__invalid_slotid (CK_SLOT_ID id,
+ CK_TOKEN_INFO_PTR info);
+
+CK_RV mock_C_GetMechanismList__invalid_slotid (CK_SLOT_ID id,
+ CK_MECHANISM_TYPE_PTR mechanism_list,
+ CK_ULONG_PTR count);
+
+CK_RV mock_C_GetMechanismInfo__invalid_slotid (CK_SLOT_ID id,
+ CK_MECHANISM_TYPE type,
+ CK_MECHANISM_INFO_PTR info);
+
+CK_RV mock_C_InitToken__invalid_slotid (CK_SLOT_ID id,
+ CK_UTF8CHAR_PTR pin,
+ CK_ULONG pin_len,
+ CK_UTF8CHAR_PTR label);
+
+CK_RV mock_C_WaitForSlotEvent__no_event (CK_FLAGS flags,
+ CK_SLOT_ID_PTR slot,
+ CK_VOID_PTR reserved);
+
+CK_RV mock_C_OpenSession__invalid_slotid (CK_SLOT_ID id,
+ CK_FLAGS flags,
+ CK_VOID_PTR user_data,
+ CK_NOTIFY callback,
+ CK_SESSION_HANDLE_PTR session);
+
+CK_RV mock_C_CloseSession__invalid_handle (CK_SESSION_HANDLE session);
+
+CK_RV mock_C_CloseAllSessions__invalid_slotid (CK_SLOT_ID id);
+
+CK_RV mock_C_GetFunctionStatus__not_parallel (CK_SESSION_HANDLE session);
+
+CK_RV mock_C_CancelFunction__not_parallel (CK_SESSION_HANDLE session);
+
+CK_RV mock_C_GetSessionInfo__invalid_handle (CK_SESSION_HANDLE session,
+ CK_SESSION_INFO_PTR info);
+
+CK_RV mock_C_InitPIN__invalid_handle (CK_SESSION_HANDLE session,
+ CK_UTF8CHAR_PTR pin,
+ CK_ULONG pin_len);
+
+CK_RV mock_C_SetPIN__invalid_handle (CK_SESSION_HANDLE session,
+ CK_UTF8CHAR_PTR old_pin,
+ CK_ULONG old_pin_len,
+ CK_UTF8CHAR_PTR new_pin,
+ CK_ULONG new_pin_len);
+
+CK_RV mock_C_GetOperationState__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR operation_state,
+ CK_ULONG_PTR operation_state_len);
+
+CK_RV mock_C_SetOperationState__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR operation_state,
+ CK_ULONG operation_state_len,
+ CK_OBJECT_HANDLE encryption_key,
+ CK_OBJECT_HANDLE authentication_key);
+
+CK_RV mock_C_Login__invalid_handle (CK_SESSION_HANDLE session,
+ CK_USER_TYPE user_type,
+ CK_UTF8CHAR_PTR pin,
+ CK_ULONG pin_len);
+
+CK_RV mock_C_Logout__invalid_handle (CK_SESSION_HANDLE session);
+
+CK_RV mock_C_CreateObject__invalid_handle (CK_SESSION_HANDLE session,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count,
+ CK_OBJECT_HANDLE_PTR new_object);
+
+CK_RV mock_C_CopyObject__invalid_handle (CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count,
+ CK_OBJECT_HANDLE_PTR new_object);
+
+CK_RV mock_C_DestroyObject__invalid_handle (CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object);
+
+CK_RV mock_C_GetObjectSize__invalid_handle (CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object,
+ CK_ULONG_PTR size);
+
+CK_RV mock_C_GetAttributeValue__invalid_handle (CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count);
+
+CK_RV mock_C_SetAttributeValue__invalid_handle (CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count);
+
+CK_RV mock_C_FindObjectsInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count);
+
+CK_RV mock_C_FindObjects__invalid_handle (CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE_PTR objects,
+ CK_ULONG max_count,
+ CK_ULONG_PTR count);
+
+CK_RV mock_C_FindObjectsFinal__invalid_handle (CK_SESSION_HANDLE session);
+
+CK_RV mock_C_EncryptInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE key);
+
+CK_RV mock_C_Encrypt__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR data,
+ CK_ULONG data_len,
+ CK_BYTE_PTR encrypted_data,
+ CK_ULONG_PTR encrypted_data_len);
+
+CK_RV mock_C_EncryptUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR part,
+ CK_ULONG part_len,
+ CK_BYTE_PTR encrypted_part,
+ CK_ULONG_PTR encrypted_part_len);
+
+CK_RV mock_C_EncryptFinal__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR last_part,
+ CK_ULONG_PTR last_part_len);
+
+CK_RV mock_C_DecryptInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE key);
+
+CK_RV mock_C_Decrypt__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR enc_data,
+ CK_ULONG enc_data_len,
+ CK_BYTE_PTR data,
+ CK_ULONG_PTR data_len);
+
+CK_RV mock_C_DecryptUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR enc_part,
+ CK_ULONG enc_part_len,
+ CK_BYTE_PTR part,
+ CK_ULONG_PTR part_len);
+
+CK_RV mock_C_DecryptFinal__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR last_part,
+ CK_ULONG_PTR last_part_len);
+
+CK_RV mock_C_DigestInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism);
+
+CK_RV mock_C_Digest__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR data,
+ CK_ULONG data_len,
+ CK_BYTE_PTR digest,
+ CK_ULONG_PTR digest_len);
+
+CK_RV mock_C_DigestUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR part,
+ CK_ULONG part_len);
+
+CK_RV mock_C_DigestKey__invalid_handle (CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE key);
+
+CK_RV mock_C_DigestFinal__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR digest,
+ CK_ULONG_PTR digest_len);
+
+CK_RV mock_C_SignInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE key);
+
+CK_RV mock_C_Sign__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR data,
+ CK_ULONG data_len,
+ CK_BYTE_PTR signature,
+ CK_ULONG_PTR signature_len);
+
+CK_RV mock_C_SignUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR part,
+ CK_ULONG part_len);
+
+CK_RV mock_C_SignFinal__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR signature,
+ CK_ULONG_PTR signature_len);
+
+CK_RV mock_C_SignRecoverInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE key);
+
+CK_RV mock_C_SignRecover__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR data,
+ CK_ULONG data_len,
+ CK_BYTE_PTR signature,
+ CK_ULONG_PTR signature_len);
+
+CK_RV mock_C_VerifyInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE key);
+
+CK_RV mock_C_Verify__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR data,
+ CK_ULONG data_len,
+ CK_BYTE_PTR signature,
+ CK_ULONG signature_len);
+
+CK_RV mock_C_VerifyUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR part,
+ CK_ULONG part_len);
+
+CK_RV mock_C_VerifyFinal__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR signature,
+ CK_ULONG signature_len);
+
+CK_RV mock_C_VerifyRecoverInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE key);
+
+CK_RV mock_C_VerifyRecover__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR signature,
+ CK_ULONG signature_len,
+ CK_BYTE_PTR data,
+ CK_ULONG_PTR data_len);
+
+CK_RV mock_C_DigestEncryptUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR part,
+ CK_ULONG part_len,
+ CK_BYTE_PTR enc_part,
+ CK_ULONG_PTR enc_part_len);
+
+CK_RV mock_C_DecryptDigestUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR enc_part,
+ CK_ULONG enc_part_len,
+ CK_BYTE_PTR part,
+ CK_ULONG_PTR part_len);
+
+CK_RV mock_C_SignEncryptUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR part,
+ CK_ULONG part_len,
+ CK_BYTE_PTR enc_part,
+ CK_ULONG_PTR enc_part_len);
+
+CK_RV mock_C_DecryptVerifyUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR enc_part,
+ CK_ULONG enc_part_len,
+ CK_BYTE_PTR part,
+ CK_ULONG_PTR part_len);
+
+CK_RV mock_C_GenerateKey__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count,
+ CK_OBJECT_HANDLE_PTR key);
+
+CK_RV mock_C_GenerateKeyPair__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_ATTRIBUTE_PTR pub_template,
+ CK_ULONG pub_count,
+ CK_ATTRIBUTE_PTR priv_template,
+ CK_ULONG priv_count,
+ CK_OBJECT_HANDLE_PTR pub_key,
+ CK_OBJECT_HANDLE_PTR priv_key);
+
+CK_RV mock_C_WrapKey__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE wrapping_key,
+ CK_OBJECT_HANDLE key,
+ CK_BYTE_PTR wrapped_key,
+ CK_ULONG_PTR wrapped_key_len);
+
+CK_RV mock_C_UnwrapKey__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE unwrapping_key,
+ CK_BYTE_PTR wrapped_key,
+ CK_ULONG wrapped_key_len,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count,
+ CK_OBJECT_HANDLE_PTR key);
+
+CK_RV mock_C_DeriveKey__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE base_key,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count,
+ CK_OBJECT_HANDLE_PTR key);
+
+CK_RV mock_C_SeedRandom__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR seed,
+ CK_ULONG seed_len);
+
+CK_RV mock_C_GenerateRandom__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR random_data,
+ CK_ULONG random_len);
+
+#endif /* __MOCK_MODULE_H__ */
diff --git a/tests/p11-test.c b/tests/p11-test.c
new file mode 100644
index 0000000..fcdcbe9
--- /dev/null
+++ b/tests/p11-test.c
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2011, Collabora Ltd.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ * * The names of contributors to this software may not be
+ * used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Author: Stef Walter <stefw@collabora.co.uk>
+ */
+
+#include "config.h"
+#include "CuTest.h"
+
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "p11-kit/p11-kit.h"
+
+#include "mock-module.h"
+
+static CK_RV
+mock_C_Initialize__with_fork (CK_VOID_PTR init_args)
+{
+ CK_RV rv;
+ pid_t child;
+ pid_t ret;
+ int status;
+
+ rv = mock_C_Initialize (init_args);
+ assert (rv == CKR_OK);
+
+ /* Fork during the initialization */
+ child = fork ();
+ if (child == 0) {
+ sleep (1);
+ exit (66);
+ }
+
+ ret = waitpid (child, &status, 0);
+ assert (ret == child);
+ assert (WIFEXITED (status));
+ assert (WEXITSTATUS (status) == 66);
+
+ return CKR_OK;
+}
+
+static void
+test_fork_initialization (CuTest *tc)
+{
+ CK_FUNCTION_LIST module;
+ CK_RV rv;
+
+ /* Build up our own function list */
+ memcpy (&module, &mock_module_no_slots, sizeof (CK_FUNCTION_LIST));
+ module.C_Initialize = mock_C_Initialize__with_fork;
+
+ rv = p11_kit_initialize_module (&module);
+ CuAssertTrue (tc, rv == CKR_OK);
+
+ rv = p11_kit_finalize_module (&module);
+ CuAssertTrue (tc, rv == CKR_OK);
+}
+
+int
+main (void)
+{
+ CuString *output = CuStringNew ();
+ CuSuite* suite = CuSuiteNew ();
+ int ret;
+
+ SUITE_ADD_TEST (suite, test_fork_initialization);
+
+ CuSuiteRun (suite);
+ CuSuiteSummary (suite, output);
+ CuSuiteDetails (suite, output);
+ printf ("%s\n", output->buffer);
+ ret = suite->failCount;
+ CuSuiteDelete (suite);
+ CuStringDelete (output);
+
+ return ret;
+}
+
+#include "CuTest.c"