summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.am1
-rw-r--r--src/config.c110
-rw-r--r--src/module.c75
-rw-r--r--src/msg.c18
-rw-r--r--src/p11-tests.c17
-rw-r--r--src/p11-tests.h16
-rw-r--r--src/session.c15
7 files changed, 213 insertions, 39 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 49a9801..e9cfd0e 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -5,6 +5,7 @@ bin_PROGRAMS = p11-tests
p11_tests_LDADD = -ldl
p11_tests_SOURCES = \
check.c \
+ config.c \
module.c \
msg.c \
p11-tests.c \
diff --git a/src/config.c b/src/config.c
new file mode 100644
index 0000000..65cc70c
--- /dev/null
+++ b/src/config.c
@@ -0,0 +1,110 @@
+
+#include "config.h"
+
+#include "p11-tests.h"
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static char* config_data = NULL;
+
+static char*
+trim(char* data)
+{
+ char *t;
+ while(*data && isspace(*data))
+ ++data;
+
+ t = data + strlen(data);
+ while(t > data && isspace(*(t - 1)))
+ {
+ t--;
+ *t = 0;
+ }
+
+ return data;
+}
+
+void
+p11t_config_parse(const char* filename)
+{
+ char* name = NULL;
+ char* value = NULL;
+ char* next;
+ FILE* f = NULL;
+ long len;
+ char* p;
+ char* t;
+
+ f = fopen(filename, "r");
+ if(f == NULL)
+ p11t_msg_exit(1, "couldn't open config file: %s", filename);
+
+ /* Figure out size */
+ if(fseek(f, 0, SEEK_END) == -1 || (len = ftell(f)) == -1 || fseek(f, 0, SEEK_SET) == -1)
+ p11t_msg_exit(1, "couldn't seek config file: %s", filename);
+
+ assert(!config_data);
+ config_data = malloc(len + 2);
+ if(!config_data)
+ p11t_msg_exit(1, "out of memory");
+
+ /* And read in one block */
+ if(fread(config_data, 1, len, f) != len)
+ p11t_msg_exit(1, "couldn't read config file: %s", filename);
+
+ fclose(f);
+
+ /* Null terminate the data */
+ config_data[len] = '\n';
+ config_data[len + 1] = 0;
+
+ next = config_data;
+
+ /* Go through lines and process them */
+ while((t = strchr(next, '\n')) != NULL)
+ {
+ *t = 0;
+ p = next; /* Do this before cleaning below */
+ next = t + 1;
+
+ t = trim(p);
+
+ name = NULL;
+ value = NULL;
+
+ /* Empty lines / comments at start / comments without continuation */
+ if(!*t || *p == '#')
+ continue;
+
+ /* Look for the break between name = value on the same line */
+ t = p + strcspn(p, ":=");
+ if(!*t)
+ {
+ fprintf(stderr, "p11-test: invalid config line: %s", p);
+ exit(1);
+ }
+
+ /* Null terminate and split value part */
+ *t = 0;
+ t++;
+
+ name = trim(p);
+ value = t;
+
+ if(name && value)
+ {
+ p11t_module_config(name, value);
+ p11t_session_config(name, value);
+ }
+ }
+}
+
+void
+p11t_config_cleanup(void)
+{
+ free(config_data);
+ config_data = NULL;
+}
diff --git a/src/module.c b/src/module.c
index c20bd3c..e2b2185 100644
--- a/src/module.c
+++ b/src/module.c
@@ -11,9 +11,13 @@
static void *module = NULL;
CK_FUNCTION_LIST_PTR p11t_module_funcs = NULL;
+
+static const char *init_string = NULL;
static CK_C_INITIALIZE_ARGS init_args;
+static void (*init_func)(void) = NULL;
static int is_initialized = 0;
+
static CK_RV
create_mutex(void **mutex)
{
@@ -162,12 +166,6 @@ p11t_module_load(const char *filename)
if(rv != CKR_OK)
p11t_msg_fatal("couldn't get function list: %s", p11t_msg_rv(rv));
- /* Make sure we have a compatible version */
- if(p11t_module_funcs->version.major != CRYPTOKI_VERSION_MAJOR)
- p11t_msg_fatal("incompatible version of pkcs11 module: %d.%d",
- (int)p11t_module_funcs->version.major,
- (int)p11t_module_funcs->version.minor);
-
/** C_GetFunctionList */
rv = (p11t_module_funcs->C_GetFunctionList)(&list);
if(rv != CKR_OK)
@@ -178,7 +176,7 @@ p11t_module_load(const char *filename)
p11t_msg_print("function lists returned directly and recursively differ");
}
-static void
+static int
initialize_common(const char *mode)
{
CK_RV rv;
@@ -193,34 +191,38 @@ initialize_common(const char *mode)
{
if(rv != CKR_CANT_LOCK)
p11t_msg_print("C_Initialize failed (%s): %s", mode, p11t_msg_rv(rv));
+ return 0;
}
else
{
is_initialized = 1;
+ return 1;
}
}
static void
-initialize_locking_1(const char *initstr)
+initialize_locking_1(void)
{
/** - Locking: no threads */
memset(&init_args, 0, sizeof (init_args));
- init_args.pReserved = (void*)initstr;
- initialize_common("locking mode 1: no threads");
+ init_args.pReserved = (void*)init_string;
+ if(initialize_common("locking mode 1: no threads"))
+ init_func = initialize_locking_1;
}
static void
-initialize_locking_2(const char *initstr)
+initialize_locking_2(void)
{
/** - Locking: os locking */
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");
+ init_args.pReserved = (void*)init_string;
+ if(initialize_common("locking mode 2: os locking"))
+ init_func = initialize_locking_2;
}
static void
-initialize_locking_3(const char *initstr)
+initialize_locking_3(void)
{
/** - Locking: app locking */
memset(&init_args, 0, sizeof (init_args));
@@ -229,12 +231,13 @@ initialize_locking_3(const char *initstr)
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");
+ init_args.pReserved = (void*)init_string;
+ if(initialize_common("locking mode 3: app locking"))
+ init_func = initialize_locking_3;
}
static void
-initialize_locking_4(const char *initstr)
+initialize_locking_4(void)
{
/** - Locking: either locking */
memset(&init_args, 0, sizeof (init_args));
@@ -243,12 +246,13 @@ initialize_locking_4(const char *initstr)
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");
+ init_args.pReserved = (void*)init_string;
+ if(initialize_common("locking mode 4: either locking"))
+ init_func = initialize_locking_4;
}
void
-p11t_module_initialize(const char *initstr)
+p11t_module_initialize(void)
{
CK_INFO info;
CK_RV rv;
@@ -257,24 +261,30 @@ p11t_module_initialize(const char *initstr)
/** - Calls without initializing */
rv = (p11t_module_funcs->C_GetInfo)(&info);
- p11t_check_returns("shouldn't run without initialize: %s", rv, CKR_CRYPTOKI_NOT_INITIALIZED);
+ p11t_check_returns("C_GetInfo: shouldn't run without initialize", rv, CKR_CRYPTOKI_NOT_INITIALIZED);
/** - NULL argument */
rv = (p11t_module_funcs->C_Initialize) (NULL);
p11t_check_returns("should succeed with null argument", rv, CKR_OK);
+ is_initialized = 1;
p11t_module_finalize();
/** - Multiple initialize with C_Finalize between */
- initialize_locking_1(initstr);
+ initialize_locking_1();
+ p11t_module_finalize();
+ initialize_locking_2();
p11t_module_finalize();
- initialize_locking_2(initstr);
+ initialize_locking_3();
p11t_module_finalize();
- initialize_locking_3(initstr);
+ initialize_locking_4();
p11t_module_finalize();
- initialize_locking_4(initstr);
+ /* Actually initialize with whatever succeeded last */
+ if(!init_func)
+ p11t_msg_fatal("no initialize succeded cannot continue");
+ (init_func)();
if(!is_initialized)
- p11t_msg_fatal("liberal locking strategy failed, can't continue");
+ p11t_msg_fatal("couldn't initialize pkcs11 module");
/** - Double initialize in a row */
rv = (p11t_module_funcs->C_Initialize) (&init_args);
@@ -296,6 +306,10 @@ p11t_module_finalize(void)
/** C_Finalize */
if(is_initialized)
{
+ /** - With invalid argument */
+ rv = p11t_module_funcs->C_Finalize(&rv);
+ p11t_check_returns("C_Finalize bad argument", rv, CKR_ARGUMENTS_BAD);
+
/** - Normal call */
assert(p11t_module_funcs);
rv = p11t_module_funcs->C_Finalize(NULL);
@@ -305,7 +319,7 @@ p11t_module_finalize(void)
/** - Double finalize in a row */
rv = p11t_module_funcs->C_Finalize(NULL);
- p11t_check_returns("C_Finalize", rv, CKR_CRYPTOKI_NOT_INITIALIZED);
+ p11t_check_returns("C_Finalize not initialized", rv, CKR_CRYPTOKI_NOT_INITIALIZED);
}
void
@@ -315,3 +329,10 @@ p11t_module_unload(void)
dlclose(module);
module = NULL;
}
+
+void
+p11t_module_config(const char *name, const char *value)
+{
+ if(strcmp(name, "init-string") == 0)
+ init_string = value;
+}
diff --git a/src/msg.c b/src/msg.c
index 600f217..ef218bf 100644
--- a/src/msg.c
+++ b/src/msg.c
@@ -113,12 +113,12 @@ p11t_msg_va(const char *message, va_list va)
int len;
if(the_prefix)
- fprintf(stderr, "%s: ", the_prefix);
- vfprintf(stderr, message, va);
+ fprintf(stdout, "%s: ", the_prefix);
+ vfprintf(stdout, message, va);
len = strlen(message);
if(len && message[len - 1] != '\n')
- fputc('\n', stderr);
- fflush(stderr);
+ fputc('\n', stdout);
+ fflush(stdout);
}
void
@@ -141,6 +141,16 @@ p11t_msg_fatal(const char *message, ...)
}
void
+p11t_msg_exit(int code, const char *message, ...)
+{
+ va_list va;
+ va_start(va, message);
+ p11t_msg_va(message, va);
+ va_end(va);
+ exit(code);
+}
+
+void
p11t_msg_prefix(const char *prefix)
{
the_prefix = prefix;
diff --git a/src/p11-tests.c b/src/p11-tests.c
index a77ccea..65414dd 100644
--- a/src/p11-tests.c
+++ b/src/p11-tests.c
@@ -9,19 +9,23 @@
static void
usage()
{
- fprintf(stderr, "usage: p11-tests module [init_string]\n");
+ fprintf(stderr, "usage: p11-tests [-f config] module\n");
exit(2);
}
int
main(int argc, char* argv[])
{
+ const char *config = NULL;
int ch;
- while((ch = getopt(argc, argv, "")) != -1)
+ while((ch = getopt(argc, argv, "f")) != -1)
{
switch(ch)
{
+ case 'f':
+ config = optarg;
+ break;
case '?':
default:
usage();
@@ -32,12 +36,15 @@ main(int argc, char* argv[])
argc -= optind;
argv += optind;
- if(argc < 1 || argc > 2)
+ if(argc != 1)
usage();
+ if(config)
+ p11t_config_parse(config);
+
/* Basic module tests */
p11t_module_load(argv[0]);
- p11t_module_initialize(argc == 2 ? argv[1] : NULL);
+ p11t_module_initialize();
p11t_slot_tests();
p11t_session_tests();
@@ -46,5 +53,7 @@ main(int argc, char* argv[])
p11t_module_finalize();
p11t_module_unload();
+ p11t_config_cleanup();
+
return 0;
}
diff --git a/src/p11-tests.h b/src/p11-tests.h
index 21b6064..6256bd5 100644
--- a/src/p11-tests.h
+++ b/src/p11-tests.h
@@ -7,7 +7,7 @@
#include <stdarg.h>
#define CK_INVALID ((CK_ULONG)-1)
-\
+
/* -------------------------------------------------------------------
* msg.c
*/
@@ -17,6 +17,7 @@ const char* p11t_msg_rv(CK_RV rv);
void p11t_msg_va(const char *message, va_list va);
void p11t_msg_print(const char *message, ...);
void p11t_msg_fatal(const char *message, ...);
+void p11t_msg_exit(int code, const char *message, ...);
void p11t_msg_prefix(const char *prefix);
#define p11t_msg_here() \
@@ -42,21 +43,32 @@ int p11t_check_flag(const char *message, CK_ULONG flags, CK_ULONG flag);
int p11t_check_nflag(const char *message, CK_ULONG flags, CK_ULONG nflag);
/* -------------------------------------------------------------------
+ * config.c
+ */
+
+void p11t_config_parse(const char* filename);
+void p11t_config_cleanup(void);
+
+/* -------------------------------------------------------------------
* module.c
*/
extern CK_FUNCTION_LIST_PTR p11t_module_funcs;
+void p11t_module_config(const char *name, const char *value);
+
void p11t_module_load(const char *filename);
void p11t_module_unload(void);
-void p11t_module_initialize(const char *initstr);
+void p11t_module_initialize(void);
void p11t_module_finalize(void);
/* -------------------------------------------------------------------
* session.c
*/
+void p11t_session_config(const char *name, const char *value);
+
void p11t_session_tests(void);
/* -------------------------------------------------------------------
diff --git a/src/session.c b/src/session.c
index 414a50e..a11fb50 100644
--- a/src/session.c
+++ b/src/session.c
@@ -3,6 +3,10 @@
#include "p11-tests.h"
+#include <string.h>
+
+static const char *login_pin = NULL;
+
void
session_info(CK_SESSION_HANDLE session, CK_SLOT_ID slot, CK_FLAGS flags, CK_STATE state)
{
@@ -51,11 +55,11 @@ session_main(CK_SLOT_ID slot)
/** C_OpenSession */
/** - Invalid slot */
- rv = (p11t_module_funcs->C_OpenSession)((CK_SLOT_ID)-5, 0, NULL, NULL, &session_ro);
+ rv = (p11t_module_funcs->C_OpenSession)((CK_SLOT_ID)-5, CKF_SERIAL_SESSION, NULL, NULL, &session_ro);
p11t_check_returns("C_OpenSession with invalid slot", rv, CKR_SLOT_ID_INVALID);
/** - Null arguments */
- rv = (p11t_module_funcs->C_OpenSession)(slot, 0, NULL, NULL, NULL);
+ rv = (p11t_module_funcs->C_OpenSession)(slot, CKF_SERIAL_SESSION, NULL, NULL, NULL);
p11t_check_returns("C_OpenSession with invalid slot", rv, CKR_ARGUMENTS_BAD);
/** - No flags */
@@ -163,3 +167,10 @@ p11t_session_tests()
session_main(slot);
}
}
+
+void
+p11t_session_config(const char *name, const char *value)
+{
+ if(strcmp(name, "login-pin") == 0)
+ login_pin = value;
+}