summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/module.c247
-rw-r--r--src/p11-tests.c1
-rw-r--r--src/p11-tests.h3
3 files changed, 251 insertions, 0 deletions
diff --git a/src/module.c b/src/module.c
index 9815c21..8677c22 100644
--- a/src/module.c
+++ b/src/module.c
@@ -4,9 +4,142 @@
#include "p11-tests.h"
#include <dlfcn.h>
+#include <errno.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
static void *module = NULL;
CK_FUNCTION_LIST_PTR p11_funcs = NULL;
+static CK_C_INITIALIZE_ARGS init_args;
+static int is_initialized = 0;
+
+static CK_RV
+create_mutex(void **mutex)
+{
+ pthread_mutex_t *mut;
+
+ if(!mutex)
+ {
+ p11t_msg_print("null mutex passed to create_mutex");
+ return CKR_ARGUMENTS_BAD;
+ }
+
+ mut = malloc(sizeof(pthread_mutex_t));
+ assert(mut);
+
+ if(pthread_mutex_init(mut, NULL) != 0)
+ assert(0);
+ *mutex = mut;
+ return CKR_OK;
+}
+
+static CK_RV
+destroy_mutex (void *mutex)
+{
+ int res;
+
+ if(!mutex)
+ {
+ p11t_msg_print("destroying null mutex");
+ return CKR_MUTEX_BAD;
+ }
+
+ res = pthread_mutex_destroy(mutex);
+ if(res != 0)
+ {
+ if(res == EBUSY)
+ {
+ p11t_msg_print("trying to destroy locked mutex");
+ return CKR_GENERAL_ERROR;
+ }
+ else if(res == EINVAL)
+ {
+ p11t_msg_print("destroying invalid mutex used");
+ return CKR_MUTEX_BAD;
+ }
+ else
+ {
+ p11t_msg_print("couldn't destroy mutex: %d", res);
+ return CKR_GENERAL_ERROR;
+
+ }
+ }
+
+ return CKR_OK;
+}
+
+static CK_RV
+lock_mutex (void *mutex)
+{
+ int res;
+ if (!mutex)
+ {
+ p11t_msg_print("locking null mutex");
+ return CKR_MUTEX_BAD;
+ }
+
+ res = pthread_mutex_lock(mutex);
+ if(res != 0)
+ {
+ if(res == EDEADLK)
+ {
+ p11t_msg_print("locking mutex would deadlock");
+ return CKR_CANT_LOCK;
+ }
+ else if(res == EINVAL)
+ {
+ p11t_msg_print("locking invalid mutex used");
+ return CKR_MUTEX_BAD;
+ }
+ else
+ {
+ p11t_msg_print("couldn't lock mutex: %d", res);
+ return CKR_GENERAL_ERROR;
+
+ }
+ }
+
+ return CKR_OK;
+}
+
+static CK_RV
+unlock_mutex (void *mutex)
+{
+ int res;
+ if (!mutex)
+ {
+ p11t_msg_print("unlocking null mutex");
+ return CKR_MUTEX_BAD;
+ }
+
+ res = pthread_mutex_lock(mutex);
+ if(res != 0)
+ {
+ if(res == EPERM)
+ {
+ p11t_msg_print("unlocking mutex without locked");
+ return CKR_MUTEX_NOT_LOCKED;
+ }
+ else if(res == EINVAL)
+ {
+ p11t_msg_print("unlocking invalid mutex used");
+ return CKR_MUTEX_BAD;
+ }
+ else
+ {
+ p11t_msg_print("couldn't unlock mutex: %d", res);
+ return CKR_GENERAL_ERROR;
+
+ }
+ }
+ else
+ {
+ free(mutex);
+ }
+
+ return CKR_OK;
+}
void
p11t_module_load(const char *filename)
@@ -35,6 +168,120 @@ p11t_module_load(const char *filename)
(int)p11_funcs->version.minor);
}
+static void
+initialize_common(const char *mode)
+{
+ CK_RV rv;
+
+ assert(p11_funcs);
+
+ rv = (p11_funcs->C_Initialize) (&init_args);
+ if (rv != CKR_OK)
+ {
+ if(rv != CKR_CANT_LOCK)
+ p11t_msg_print("C_Initialize failed (%s): %s", mode, p11t_msg_rv(rv));
+ }
+ else
+ {
+ is_initialized = 1;
+ }
+}
+
+static void
+initialize_locking_1(const char *initstr)
+{
+ memset(&init_args, 0, sizeof (init_args));
+ init_args.pReserved = (void*)initstr;
+ initialize_common("locking mode 1: no threads");
+}
+
+static void
+initialize_locking_2(const char *initstr)
+{
+ memset(&init_args, 0, sizeof (init_args));
+ init_args.flags = CKF_OS_LOCKING_OK;
+ init_args.pReserved = (void*)initstr;
+ initialize_common("locking mode 2: os locking");
+}
+
+static void
+initialize_locking_3(const char *initstr)
+{
+ memset(&init_args, 0, sizeof (init_args));
+ init_args.flags = 0;
+ init_args.CreateMutex = create_mutex;
+ init_args.DestroyMutex = destroy_mutex;
+ init_args.LockMutex = lock_mutex;
+ init_args.UnlockMutex = unlock_mutex;
+ init_args.pReserved = (void*)initstr;
+ initialize_common("locking mode 3: app locking");
+}
+
+static void
+initialize_locking_4(const char *initstr)
+{
+ memset(&init_args, 0, sizeof (init_args));
+ init_args.flags = CKF_OS_LOCKING_OK;
+ init_args.CreateMutex = create_mutex;
+ init_args.DestroyMutex = destroy_mutex;
+ init_args.LockMutex = lock_mutex;
+ init_args.UnlockMutex = unlock_mutex;
+ init_args.pReserved = (void*)initstr;
+ initialize_common("locking mode 4: either locking");
+}
+
+void
+p11t_module_initialize(const char *initstr)
+{
+ CK_INFO info;
+ CK_RV rv;
+
+ assert(p11_funcs);
+
+ /* Some invalid use without initializing */
+ rv = (p11_funcs->C_GetInfo)(&info);
+ if(rv != CKR_CRYPTOKI_NOT_INITIALIZED)
+ p11t_msg_print("shouldn't run without initialize: %s", p11t_msg_rv(rv));
+
+ /* The various different locking modes */
+ initialize_locking_1(initstr);
+ p11t_module_finalize();
+ initialize_locking_2(initstr);
+ p11t_module_finalize();
+ initialize_locking_3(initstr);
+ p11t_module_finalize();
+ initialize_locking_4(initstr);
+
+ if(!is_initialized)
+ p11t_msg_fatal("liberal locking strategy failed, can't continue");
+
+ /* Double initialize */
+ rv = (p11_funcs->C_Initialize) (&init_args);
+ if (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)
+ {
+ p11t_msg_print("double initialize should return CKR_CRYPTOKI_ALREADY_INITIALIZED: %s", p11t_msg_rv(rv));
+ }
+ else
+ {
+ is_initialized = 1;
+ }
+}
+
+void
+p11t_module_finalize(void)
+{
+ CK_RV rv;
+
+ if(is_initialized)
+ {
+ assert(p11_funcs);
+ rv = p11_funcs->C_Finalize(NULL);
+ if(rv != CKR_OK)
+ p11t_msg_print("C_Finalize failed: %s", p11t_msg_rv(rv));
+ is_initialized = 0;
+ }
+}
+
void
p11t_module_unload(void)
{
diff --git a/src/p11-tests.c b/src/p11-tests.c
index 80185cf..b871533 100644
--- a/src/p11-tests.c
+++ b/src/p11-tests.c
@@ -36,6 +36,7 @@ main(int argc, char* argv[])
usage();
p11t_module_load(argv[0]);
+ p11t_module_initialize(argc == 2 ? argv[1] : NULL);
p11t_module_unload();
diff --git a/src/p11-tests.h b/src/p11-tests.h
index 83c69af..cf37346 100644
--- a/src/p11-tests.h
+++ b/src/p11-tests.h
@@ -3,6 +3,7 @@
#include "pkcs11/pkcs11.h"
+#include <assert.h>
#include <stdarg.h>
/* -------------------------------------------------------------------
@@ -21,6 +22,8 @@ void p11t_msg_prefix(const char *prefix);
*/
void p11t_module_load(const char *filename);
+void p11t_module_initialize(const char *initstr);
+void p11t_module_finalize(void);
void p11t_module_unload(void);
#endif /* P11TESTST_H_ */