summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--autogen.sh1
-rw-r--r--configure.in1
-rw-r--r--src/Makefile.am21
-rw-r--r--src/certificate.c1
-rw-r--r--src/check.c7
-rw-r--r--src/config.c33
-rw-r--r--src/crypto.c1
-rw-r--r--src/dsa.c2
-rw-r--r--src/key.c2
-rw-r--r--src/module.c109
-rw-r--r--src/msg.c78
-rw-r--r--src/object.c2
-rw-r--r--src/p11-tests-lib.c94
-rw-r--r--src/p11-tests-lib.h252
-rw-r--r--src/p11-tests.c123
-rw-r--r--src/p11-tests.h255
-rw-r--r--src/rsa.c2
-rw-r--r--src/session.c2
-rw-r--r--src/slot.c2
-rw-r--r--src/test-data.c2
21 files changed, 587 insertions, 408 deletions
diff --git a/.gitignore b/.gitignore
index 08d92af..a2476d4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,16 +8,21 @@
*.la
*.o
*.orig
+.settings
autom4te.cache
aclocal.m4
config.h
config.h.in
+config.guess
config.log
config.status
+config.sub
configure
depcomp
install-sh
INSTALL
+libtool
+ltmain.sh
Makefile
Makefile.in
missing
diff --git a/autogen.sh b/autogen.sh
index 82adbf2..ec0a21a 100644
--- a/autogen.sh
+++ b/autogen.sh
@@ -14,6 +14,7 @@ set -x
aclocal
autoheader
+libtoolize
automake -a
autoconf
./configure "$@"
diff --git a/configure.in b/configure.in
index 9a3d42a..807b872 100644
--- a/configure.in
+++ b/configure.in
@@ -8,6 +8,7 @@ AM_CONFIG_HEADER([config.h])
# Checks for programs.
AC_PROG_CC
AC_PROG_INSTALL
+AM_PROG_LIBTOOL
# Depend on openssl
AC_CHECK_LIB(crypto, BN_new, ,
diff --git a/src/Makefile.am b/src/Makefile.am
index d1c5d8a..e86bd04 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,9 +1,11 @@
AM_CFLAGS = -I$(top_srcdir)
-bin_PROGRAMS = p11-tests
+include_HEADERS = \
+ p11-tests.h
-p11_tests_LDADD = -ldl -lpthread
-p11_tests_SOURCES = \
+lib_LTLIBRARIES = libp11-tests.la
+
+libp11_tests_la_SOURCES = \
certificate.c \
check.c \
config.c \
@@ -13,9 +15,20 @@ p11_tests_SOURCES = \
module.c \
msg.c \
object.c \
- p11-tests.c \
+ p11-tests-lib.c \
+ p11-tests-lib.h \
rsa.c \
session.c \
slot.c \
test-data.c
+libp11_tests_la_LDFLAGS = \
+ -no-undefined -export-symbols-regex 'p11_tests_'
+
+bin_PROGRAMS = p11-tests
+p11_tests_LDADD = \
+ -ldl -lpthread \
+ libp11-tests.la
+
+p11_tests_SOURCES = \
+ p11-tests.c
diff --git a/src/certificate.c b/src/certificate.c
index 36e6b5b..83fcfd6 100644
--- a/src/certificate.c
+++ b/src/certificate.c
@@ -1,5 +1,6 @@
#include "p11-tests.h"
+#include "p11-tests-lib.h"
#include <stdlib.h>
#include <string.h>
diff --git a/src/check.c b/src/check.c
index cf12dd4..4284e70 100644
--- a/src/check.c
+++ b/src/check.c
@@ -1,5 +1,6 @@
#include "p11-tests.h"
+#include "p11-tests-lib.h"
#include <ctype.h>
#include <stdarg.h>
@@ -11,7 +12,7 @@ p11t_check_fail(const char *message, ...)
{
va_list va;
va_start(va, message);
- p11t_msg_code("FAIL", message, va);
+ p11t_msg_va (P11_TESTS_FAIL, message, va);
va_end(va);
return STOP;
}
@@ -23,7 +24,7 @@ p11t_check_info(const char *message, ...)
if(!p11t_check_verbose)
return CONTINUE;
va_start(va, message);
- p11t_msg_code("INFO", message, va);
+ p11t_msg_va (P11_TESTS_INFO, message, va);
va_end(va);
return CONTINUE;
}
@@ -33,7 +34,7 @@ p11t_check_warn(const char *message, ...)
{
va_list va;
va_start(va, message);
- p11t_msg_code("WARN", message, va);
+ p11t_msg_va (P11_TESTS_WARN, message, va);
va_end(va);
return CONTINUE;
}
diff --git a/src/config.c b/src/config.c
index 652556e..09da702 100644
--- a/src/config.c
+++ b/src/config.c
@@ -1,5 +1,6 @@
#include "p11-tests.h"
+#include "p11-tests-lib.h"
#include <ctype.h>
#include <stdio.h>
@@ -25,8 +26,8 @@ trim(char* data)
return data;
}
-void
-p11t_config_parse(const char* filename)
+int
+p11t_config_parse (const char* filename)
{
char* name = NULL;
char* value = NULL;
@@ -37,21 +38,29 @@ p11t_config_parse(const char* filename)
char* t;
f = fopen(filename, "r");
- if(f == NULL)
- p11t_msg_fatal("couldn't open config file: %s", filename);
+ if (f == NULL) {
+ p11t_msg_print ("couldn't open config file: %s", filename);
+ return -1;
+ }
/* Figure out size */
- if(fseek(f, 0, SEEK_END) == -1 || (len = ftell(f)) == -1 || fseek(f, 0, SEEK_SET) == -1)
- p11t_msg_fatal("couldn't seek config file: %s", filename);
+ if (fseek (f, 0, SEEK_END) == -1 || (len = ftell (f)) == -1 || fseek (f, 0, SEEK_SET) == -1) {
+ p11t_msg_print ("couldn't seek config file: %s", filename);
+ return -1;
+ }
assert(!config_data);
config_data = malloc(len + 2);
- if(!config_data)
- p11t_msg_fatal("out of memory");
+ if (!config_data) {
+ p11t_msg_print ("out of memory");
+ return -1;
+ }
/* And read in one block */
- if(fread(config_data, 1, len, f) != len)
- p11t_msg_fatal("couldn't read config file: %s", filename);
+ if (fread(config_data, 1, len, f) != len) {
+ p11t_msg_print ("couldn't read config file: %s", filename);
+ return -1;
+ }
fclose(f);
@@ -81,7 +90,7 @@ p11t_config_parse(const char* filename)
t = p + strcspn(p, ":=");
if(!*t)
{
- fprintf(stderr, "p11-test: invalid config line: %s", p);
+ fprintf (stderr, "p11-test: invalid config line: %s", p);
exit(1);
}
@@ -98,6 +107,8 @@ p11t_config_parse(const char* filename)
p11t_session_config(name, value);
}
}
+
+ return 0;
}
void
diff --git a/src/crypto.c b/src/crypto.c
index bef8a1e..41e95d1 100644
--- a/src/crypto.c
+++ b/src/crypto.c
@@ -1,5 +1,6 @@
#include "p11-tests.h"
+#include "p11-tests-lib.h"
#include <string.h>
diff --git a/src/dsa.c b/src/dsa.c
index f7f4ee3..ee0b9aa 100644
--- a/src/dsa.c
+++ b/src/dsa.c
@@ -1,5 +1,5 @@
-#include "p11-tests.h"
+#include "p11-tests-lib.h"
#include <stdio.h>
#include <stdlib.h>
diff --git a/src/key.c b/src/key.c
index a47cc48..0f6aa38 100644
--- a/src/key.c
+++ b/src/key.c
@@ -1,5 +1,5 @@
-#include "p11-tests.h"
+#include "p11-tests-lib.h"
/* ----------------------------------------------------------------------------------
* TESTS
diff --git a/src/module.c b/src/module.c
index b7a715b..e3008f3 100644
--- a/src/module.c
+++ b/src/module.c
@@ -1,27 +1,22 @@
+#include "p11-tests-lib.h"
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#define _WIN32_WINNT 0x400
#include <windows.h>
-static HMODULE module = NULL;
-
#else /* !_WIN32 */
-#include <dlfcn.h>
#include <pthread.h>
-static void *module = NULL;
-
#endif /* !_WIN32 */
-#include "p11-tests.h"
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-
CK_FUNCTION_LIST_PTR p11t_module_funcs = NULL;
static const char *init_string = NULL;
@@ -272,58 +267,6 @@ unlock_mutex (void *mutex)
return ret;
}
-int
-p11t_module_load(const char *filename)
-{
- CK_FUNCTION_LIST_PTR list;
- CK_C_GetFunctionList get_function_list;
- CK_RV rv;
-
-#ifdef _WIN32
-
- module = LoadLibrary(filename);
- if(!module)
- p11t_msg_fatal("couldn't load library: %s: %s", filename, p11t_msg_os());
-
- /* Lookup the appropriate function in the library */
- get_function_list = (CK_C_GetFunctionList)GetProcAddress(module, "C_GetFunctionList");
- if(!get_function_list)
- p11t_msg_fatal("C_GetFunctionList: couldn't find function in library: %s: %s",
- filename, p11t_msg_os());
-
-#else /* !_WIN32 */
-
- module = dlopen(filename, RTLD_NOW);
- if(!module)
- p11t_msg_fatal("couldn't open library: %s: %s", filename, dlerror());
-
- /* Lookup the appropriate function in library */
- get_function_list = (CK_C_GetFunctionList)dlsym (module, "C_GetFunctionList");
- if(!get_function_list)
- p11t_msg_fatal("C_GetFunctionList: couldn't find function in library: %s: %s",
- filename, dlerror());
-
-#endif /* !_WIN32 */
-
- /* Get the function list */
- rv = (get_function_list)(&p11t_module_funcs);
- if(rv != CKR_OK)
- p11t_msg_fatal("C_GetFunctiontList: couldn't get function list: %s", p11t_msg_rv(rv));
-
- if(p11t_test_unexpected)
- {
- P11T_SECTION("C_GetFunctionList");
-
- rv = (p11t_module_funcs->C_GetFunctionList)(&list);
- P11T_CHECK_RV("Call through function list", rv, CKR_OK);
-
- if(memcmp(list, p11t_module_funcs, sizeof(*list)) != 0)
- p11t_check_info("Call doesn't return same data as library C_GetFunctionList entry point");
- }
-
- return CONTINUE;
-}
-
static int
initialize_common(const char *mode)
{
@@ -408,11 +351,23 @@ initialize_locking_4(void)
int
p11t_module_initialize(void)
{
+ CK_FUNCTION_LIST_PTR list;
CK_INFO info;
CK_RV rv;
assert(p11t_module_funcs);
+ if(p11t_test_unexpected)
+ {
+ P11T_SECTION("C_GetFunctionList");
+
+ rv = (p11t_module_funcs->C_GetFunctionList)(&list);
+ P11T_CHECK_RV("Call through function list", rv, CKR_OK);
+
+ if(memcmp(list, p11t_module_funcs, sizeof(*list)) != 0)
+ p11t_check_info("Call doesn't return same data as library C_GetFunctionList entry point");
+ }
+
P11T_SECTION("C_Initialize");
if(p11t_test_unexpected)
@@ -439,11 +394,16 @@ p11t_module_initialize(void)
p11t_module_finalize();
/* Actually initialize with whatever succeeded last */
- if(!init_func)
- p11t_msg_fatal("Couldn't initialize module via any method");
+ if(!init_func) {
+ p11t_check_fail ("Couldn't initialize module via any method");
+ return STOP;
+ }
+
(init_func)();
- if(!is_initialized)
- p11t_msg_fatal("Failed to initialize module");
+ if(!is_initialized) {
+ p11t_check_fail ("Failed to initialize module");
+ return STOP;
+ }
if(p11t_test_unexpected)
{
@@ -484,18 +444,3 @@ p11t_module_finalize(void)
return CONTINUE;
}
-
-int
-p11t_module_unload(void)
-{
- if(module)
- {
-#ifdef _WIN32
- FreeLibrary(module);
-#else
- dlclose(module);
-#endif
- }
- module = NULL;
- return CONTINUE;
-}
diff --git a/src/msg.c b/src/msg.c
index be2fdcd..a0a4d6f 100644
--- a/src/msg.c
+++ b/src/msg.c
@@ -1,5 +1,6 @@
#include "p11-tests.h"
+#include "p11-tests-lib.h"
#include <stdio.h>
#include <stdlib.h>
@@ -15,7 +16,10 @@
#include <openssl/err.h>
-static const char *the_prefix = NULL;
+/* Where we log to */
+P11TestsLogFunc p11t_log_func = NULL;
+
+static const char *the_prefix = "";
const char*
p11t_msg_rv(CK_RV rv)
@@ -157,59 +161,63 @@ p11t_msg_openssl(void)
return ERR_error_string(ERR_get_error(), NULL);
}
-void
-p11t_msg_va(const char *message, va_list va)
+static void
+default_log_func (int level, const char *section, const char *message)
{
- size_t len;
-
- if(the_prefix)
- fprintf(stdout, "%s: ", the_prefix);
- vfprintf(stdout, message, va);
- len = strlen(message);
- if(len && message[len - 1] != '\n')
- fputc('\n', stdout);
- fflush(stdout);
-}
+ const char *code;
+
+ switch (level) {
+ case P11_TESTS_NONE:
+ code = NULL;
+ break;
+ case P11_TESTS_INFO:
+ code = "INFO";
+ break;
+ case P11_TESTS_WARN:
+ code = "WARN";
+ break;
+ case P11_TESTS_FAIL:
+ code = "FAIL";
+ break;
+ default:
+ assert (0 && "should not be reached");
+ }
-void
-p11t_msg_code(const char *code, const char *message, va_list va)
-{
- size_t len;
-
- fprintf(stdout, "%s: ", code);
- if(the_prefix)
- fprintf(stdout, "%s: ", the_prefix);
- vfprintf(stdout, message, va);
- len = strlen(message);
- if(len && message[len - 1] != '\n')
- fputc('\n', stdout);
+ if (code)
+ fprintf (stdout, "%s: ", code);
+ if (section && section[0])
+ fprintf (stdout, "%s: ", section);
+ fprintf (stdout, "%s\n", message);
fflush(stdout);
}
-
void
-p11t_msg_print(const char *message, ...)
+p11t_msg_va (int level, const char *message, va_list va)
{
- va_list va;
- va_start(va, message);
- p11t_msg_va(message, va);
- va_end(va);
+ char buffer[4096];
+
+ vsnprintf (buffer, sizeof (buffer), message, va);
+ if (p11t_log_func)
+ p11t_log_func (level, the_prefix, buffer);
+ else
+ default_log_func (level, the_prefix, buffer);
}
void
-p11t_msg_fatal(const char *message, ...)
+p11t_msg_print (const char *message, ...)
{
va_list va;
va_start(va, message);
- p11t_msg_va(message, va);
+ p11t_msg_va (P11_TESTS_NONE, message, va);
va_end(va);
- exit(1);
}
const char*
-p11t_msg_prefix(const char *prefix)
+p11t_msg_prefix (const char *prefix)
{
const char *old = the_prefix;
+ if (prefix == NULL)
+ prefix = "";
the_prefix = prefix;
return old;
}
diff --git a/src/object.c b/src/object.c
index cb4b59c..aee8363 100644
--- a/src/object.c
+++ b/src/object.c
@@ -1,5 +1,5 @@
-#include "p11-tests.h"
+#include "p11-tests-lib.h"
#include <stdlib.h>
#include <string.h>
diff --git a/src/p11-tests-lib.c b/src/p11-tests-lib.c
new file mode 100644
index 0000000..4e51a12
--- /dev/null
+++ b/src/p11-tests-lib.c
@@ -0,0 +1,94 @@
+
+
+#include "p11-tests.h"
+#include "p11-tests-lib.h"
+#include "compat.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <openssl/err.h>
+#include <openssl/evp.h>
+
+int p11t_test_unexpected = 1;
+int p11t_test_write_session = 0;
+
+int
+p11_tests_get_unexpected (void)
+{
+ return p11t_test_unexpected = 1;
+}
+
+void
+p11_tests_set_unexpected (int value)
+{
+ p11t_test_unexpected = value ? 1 : 0;
+}
+
+int
+p11_tests_get_write_session (void)
+{
+ return p11t_test_write_session;
+}
+
+void
+p11_tests_set_write_session (int value)
+{
+ p11t_test_write_session = value ? 1 : 0;
+}
+
+int
+p11_tests_get_verbose (void)
+{
+ return p11t_check_verbose;
+}
+
+void
+p11_tests_set_verbose (int value)
+{
+ p11t_check_verbose = value ? 1 : 0;
+}
+
+int
+p11_tests_load_config (const char *config)
+{
+ return p11t_config_parse (config);
+}
+
+P11TestsLogFunc
+p11_tests_get_log_func (void)
+{
+ return p11t_log_func;
+}
+
+void
+p11_tests_set_log_func (P11TestsLogFunc func)
+{
+ p11t_log_func = func;
+}
+
+void
+p11_tests_perform (CK_FUNCTION_LIST_PTR module)
+{
+ ERR_load_crypto_strings();
+ OpenSSL_add_all_digests();
+
+ /* Basic module tests */
+ p11t_module_funcs = module;
+ if (p11t_module_initialize () != CONTINUE)
+ return;
+
+ p11t_slot_tests();
+ p11t_session_tests();
+ p11t_object_tests();
+ p11t_key_tests();
+ p11t_certificate_tests();
+ p11t_rsa_tests();
+ p11t_dsa_tests();
+
+ /* Remaining module tests */
+ p11t_module_finalize();
+
+ p11t_slot_cleanup();
+ p11t_config_cleanup();
+}
diff --git a/src/p11-tests-lib.h b/src/p11-tests-lib.h
new file mode 100644
index 0000000..ac35204
--- /dev/null
+++ b/src/p11-tests-lib.h
@@ -0,0 +1,252 @@
+#ifndef P11_TESTS_PRIVATE_H_
+#define P11_TESTS_PRIVATE_H_
+
+#ifndef _WIN32
+#include "config.h"
+#endif
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4996)
+#endif
+
+#include "p11-tests.h"
+
+#include "pkcs11/pkcs11.h"
+
+#include <assert.h>
+#include <stdarg.h>
+
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+
+#define CK_INVALID ((CK_ULONG)-1)
+
+extern int p11t_test_unexpected;
+extern int p11t_test_write_session;
+
+/* -------------------------------------------------------------------
+ * certificate.c
+ */
+
+const char* p11t_certificate_validate_dn(CK_BYTE_PTR der, CK_ULONG n_der);
+
+void p11t_certificate_tests(void);
+
+/* -------------------------------------------------------------------
+ * check.c
+ */
+
+enum
+{
+ STOP = 0,
+ CONTINUE = 1
+};
+
+extern int p11t_check_verbose;
+
+#define P11T_SECTION(check) \
+ p11t_msg_prefix(check)
+
+#define _P11T_BEGIN do {
+#define _P11T_END } while(0)
+
+#define P11T_CHECK_FAIL(what) \
+ _P11T_BEGIN p11t_check_fail("%s", (what)); return STOP; _P11T_END
+
+#define P11T_CHECK_FAIL_MSG(what, msg) \
+ _P11T_BEGIN p11t_check_fail("%s: %s", (what), (msg)); return STOP; _P11T_END
+
+int p11t_check_fail(const char *message, ...);
+int p11t_check_warn(const char *message, ...);
+int p11t_check_info(const char *message, ...);
+
+#define P11T_CHECK_RV(what, have, want) \
+ _P11T_BEGIN if(!_p11t_check_rv((what), (have), (want))) return STOP; _P11T_END
+
+int _p11t_check_rv(const char *what, CK_RV have, CK_RV want);
+
+#define P11T_CHECK_PADDED(what, padded) \
+ _P11T_BEGIN if(!_p11t_check_padded((what), (padded), sizeof(padded))) return STOP; _P11T_END
+
+int _p11t_check_padded(const char *what, const CK_UTF8CHAR_PTR padded, CK_ULONG length);
+
+#define P11T_CHECK_ULONG(what, have, want) \
+ _P11T_BEGIN if(!_p11t_check_ulong((what), (have), (want))) return STOP; _P11T_END
+
+int _p11t_check_ulong(const char *what, CK_ULONG have, CK_ULONG want);
+
+#define P11T_CHECK_MASK(what, have, want) \
+ _P11T_BEGIN if(!_p11t_check_mask((what), (have), (want))) return STOP; _P11T_END
+
+int _p11t_check_mask(const char *what, CK_ULONG flags, CK_ULONG mask);
+
+#define P11T_CHECK_FLAG(what, have, want) \
+ _P11T_BEGIN if(!_p11t_check_flag((what), (have), (want))) return STOP; _P11T_END
+
+int _p11t_check_flag(const char *what, CK_ULONG flags, CK_ULONG flag);
+
+#define P11T_CHECK_NFLAG(what, have, want) \
+ _P11T_BEGIN if(!_p11t_check_nflag((what), (have), (want))) return STOP; _P11T_END
+
+int _p11t_check_nflag(const char *what, CK_ULONG flags, CK_ULONG nflag);
+
+#define P11T_CHECK_BOOL(what, value) \
+ _P11T_BEGIN if(!_p11t_check_bool((what), (value))) return STOP; _P11T_END
+
+int _p11t_check_bool(const char *what, CK_BBOOL value);
+
+#define P11T_CHECK_STRING(what, value, length) \
+ _P11T_BEGIN if(!_p11t_check_string((what), (value), (length))) return STOP; _P11T_END
+
+int _p11t_check_string(const char *what, CK_UTF8CHAR_PTR value, CK_ULONG length);
+
+#define P11T_CHECK_DATE(what, value) \
+ _P11T_BEGIN if(!_p11t_check_date((what), (value))) return STOP; _P11T_END
+
+int _p11t_check_date(const char *what, CK_DATE* value);
+
+#define P11T_CHECK_NOTE(what)
+
+/* -------------------------------------------------------------------
+ * config.c
+ */
+
+int p11t_config_parse(const char* filename);
+void p11t_config_cleanup(void);
+
+/* -------------------------------------------------------------------
+ * crypto.c
+ */
+
+int p11t_crypto_test_encrypt (CK_SESSION_HANDLE session, CK_MECHANISM_TYPE mech);
+int p11t_crypto_test_decrypt (CK_SESSION_HANDLE session, CK_MECHANISM_TYPE mech);
+int p11t_crypto_test_sign (CK_SESSION_HANDLE session, CK_MECHANISM_TYPE mech);
+int p11t_crypto_test_verify (CK_SESSION_HANDLE session, CK_MECHANISM_TYPE mech);
+
+/* -------------------------------------------------------------------
+ * dsa.c
+ */
+
+void p11t_dsa_tests(void);
+
+void p11t_dsa_test_public_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE handle);
+void p11t_dsa_test_private_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE handle);
+
+/* -------------------------------------------------------------------
+ * key.c
+ */
+
+CK_OBJECT_HANDLE p11t_key_get_public(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key);
+
+CK_OBJECT_HANDLE p11t_key_get_private(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key);
+
+CK_MECHANISM_TYPE_PTR p11t_key_get_mechanisms(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_ULONG_PTR n_mechanisms);
+
+RSA* p11t_key_export_public_rsa(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key);
+DSA* p11t_key_export_public_dsa(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key);
+
+CK_RV p11t_key_login_context_specific (CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key);
+
+void p11t_key_tests(void);
+
+/* -------------------------------------------------------------------
+ * msg.c
+ */
+
+const char* p11t_msg_rv(CK_RV rv);
+const char* p11t_msg_os(void);
+const char* p11t_msg_openssl(void);
+
+void p11t_msg_va(int level, const char *message, va_list va);
+void p11t_msg_print(const char *message, ...);
+const char* p11t_msg_prefix(const char *prefix);
+
+#define p11t_msg_here() \
+ (__func__ "() at " __FILE__ ":" __LINE__)
+
+extern P11TestsLogFunc p11t_log_func;
+
+/* -------------------------------------------------------------------
+ * module.c
+ */
+
+extern CK_FUNCTION_LIST_PTR p11t_module_funcs;
+
+void p11t_module_config(const char *name, const char *value);
+
+int p11t_module_load(const char *filename);
+int p11t_module_unload(void);
+
+int p11t_module_initialize(void);
+int p11t_module_finalize(void);
+
+/* -------------------------------------------------------------------
+ * object.c
+ */
+
+CK_OBJECT_HANDLE_PTR p11t_object_find(CK_SESSION_HANDLE session, CK_ATTRIBUTE_PTR attrs,
+ CK_ULONG n_attrs, CK_ULONG_PTR n_objects);
+
+int p11t_object_get(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object,
+ CK_ATTRIBUTE_PTR attrs, CK_ULONG count);
+
+CK_OBJECT_HANDLE p11t_object_find_one(CK_SESSION_HANDLE session, CK_ATTRIBUTE_PTR attrs,
+ CK_ULONG n_attrs);
+
+void p11t_object_tests(void);
+
+/* -------------------------------------------------------------------
+ * rsa.c
+ */
+
+void p11t_rsa_tests (void);
+void p11t_rsa_test_public_key (CK_SESSION_HANDLE session, CK_OBJECT_HANDLE handle);
+void p11t_rsa_test_private_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE handle);
+
+/* -------------------------------------------------------------------
+ * session.c
+ */
+
+CK_SESSION_HANDLE p11t_session_open(CK_SLOT_ID slot, int readwrite);
+int p11t_session_login(CK_SESSION_HANDLE handle);
+int p11t_session_logout(CK_SESSION_HANDLE handle);
+int p11t_session_close(CK_SESSION_HANDLE handle);
+int p11t_session_close_all(CK_SLOT_ID slot);
+CK_UTF8CHAR_PTR p11t_session_get_pin(CK_SLOT_ID slot, CK_USER_TYPE user, CK_ULONG_PTR n_pin);
+
+void p11t_session_config(const char *name, const char *value);
+
+void p11t_session_tests(void);
+
+/* -------------------------------------------------------------------
+ * slot.c
+ */
+
+extern CK_ULONG p11t_slot_count;
+extern int p11t_slot_virtual;
+
+void p11t_slot_tests(void);
+
+void p11t_slot_cleanup(void);
+
+CK_SLOT_ID p11t_slot_get_id(int index);
+CK_SLOT_INFO_PTR p11t_slot_get_info(CK_SLOT_ID slot);
+CK_TOKEN_INFO_PTR p11t_slot_get_token_info(CK_SLOT_ID slot);
+
+typedef void (*P11tSlotMechCallback)(CK_SLOT_ID slot, CK_MECHANISM_TYPE mech_type,
+ CK_MECHANISM_INFO_PTR mech_info);
+
+void p11t_slot_for_each_mech(CK_MECHANISM_TYPE mech_type, P11tSlotMechCallback callback);
+
+CK_MECHANISM_INFO_PTR p11t_slot_get_mech_info(CK_SLOT_ID slot, CK_MECHANISM_TYPE mech_type);
+
+/* ------------------------------------------------------------------
+ * test-data.c
+ */
+
+#define P11T_BLOCK 10240
+extern const CK_BYTE p11t_test_data[];
+extern const CK_ULONG p11t_test_data_size;
+extern const CK_ULONG p11t_test_data_bits;
+
+#endif /* P11_TESTS_PRIVATE_H_ */
diff --git a/src/p11-tests.c b/src/p11-tests.c
index 900338e..4d8b9ff 100644
--- a/src/p11-tests.c
+++ b/src/p11-tests.c
@@ -1,13 +1,27 @@
-
#include "p11-tests.h"
+#include "p11-tests-lib.h"
#include "compat.h"
#include <stdio.h>
#include <stdlib.h>
-#include <openssl/err.h>
-#include <openssl/evp.h>
+#ifdef _WIN32
+
+#define WIN32_LEAN_AND_MEAN
+#define _WIN32_WINNT 0x400
+#include <windows.h>
+
+static HMODULE module = NULL;
+
+#else /* !_WIN32 */
+
+#include <dlfcn.h>
+#include <pthread.h>
+
+static void *module = NULL;
+
+#endif /* !_WIN32 */
int p11t_test_unexpected = 1;
int p11t_test_write_session = 0;
@@ -19,10 +33,74 @@ usage()
exit(2);
}
+void
+fatal (const char *message, ...)
+{
+ va_list va;
+ va_start (va, message);
+ fprintf (stderr, message, va);
+ va_end (va);
+ exit (1);
+}
+
+CK_FUNCTION_LIST_PTR
+module_load(const char *filename)
+{
+ CK_FUNCTION_LIST_PTR list = NULL;
+ CK_C_GetFunctionList get_function_list;
+ CK_RV rv;
+
+#ifdef _WIN32
+
+ module = LoadLibrary (filename);
+ if (!module)
+ fatal ("couldn't load library: %s: %s", filename, p11t_msg_os ());
+
+ /* Lookup the appropriate function in the library */
+ get_function_list = (CK_C_GetFunctionList)GetProcAddress (module, "C_GetFunctionList");
+ if (!get_function_list)
+ fatal ("couldn't find function 'C_GetFunctionList' in library: %s: %s",
+ filename, p11t_msg_os ());
+
+#else /* !_WIN32 */
+
+ module = dlopen (filename, RTLD_NOW);
+ if (!module)
+ fatal ("couldn't open library: %s: %s", filename, dlerror ());
+
+ /* Lookup the appropriate function in library */
+ get_function_list = (CK_C_GetFunctionList)dlsym (module, "C_GetFunctionList");
+ if (!get_function_list)
+ fatal ("couldn't find function 'C_GetFunctionList' in library: %s: %s",
+ filename, dlerror ());
+
+#endif /* !_WIN32 */
+
+ /* Get the function list */
+ rv = (get_function_list) (&list);
+ if(rv != CKR_OK || !list)
+ fatal ("couldn't get function list: %d", (int)rv);
+
+ return list;
+}
+
+void
+module_unload (void)
+{
+ if (module) {
+#ifdef _WIN32
+ FreeLibrary (module);
+#else
+ dlclose (module);
+#endif
+ }
+ module = NULL;
+}
+
int
main(int argc, char* argv[])
{
- const char *config = NULL;
+ CK_FUNCTION_LIST_PTR module;
int ch;
while((ch = getopt(argc, argv, "f:svz")) != -1)
@@ -30,16 +108,17 @@ main(int argc, char* argv[])
switch(ch)
{
case 'f':
- config = optarg;
+ if (p11_tests_load_config (optarg) < 0)
+ exit (2);
break;
case 's':
- p11t_test_write_session = 1;
+ p11_tests_set_write_session (1);
break;
case 'v':
- p11t_check_verbose = 1;
+ p11_tests_set_verbose (1);
break;
case 'z':
- p11t_test_unexpected = 0;
+ p11_tests_set_unexpected (0);
break;
case '?':
default:
@@ -54,30 +133,10 @@ main(int argc, char* argv[])
if(argc != 1)
usage();
- if(config)
- p11t_config_parse(config);
-
- ERR_load_crypto_strings();
- OpenSSL_add_all_digests();
-
- /* Basic module tests */
- p11t_module_load(argv[0]);
- p11t_module_initialize();
-
- p11t_slot_tests();
- p11t_session_tests();
- p11t_object_tests();
- p11t_key_tests();
- p11t_certificate_tests();
- p11t_rsa_tests();
- p11t_dsa_tests();
-
- /* Remaining module tests */
- p11t_module_finalize();
- p11t_module_unload();
-
- p11t_slot_cleanup();
- p11t_config_cleanup();
+ module = module_load (argv[0]);
+ p11_tests_perform (module);
+ module_unload ();
+ /* TODO: Change return value based on tests passed, failed */
return 0;
}
diff --git a/src/p11-tests.h b/src/p11-tests.h
index 15c95b3..dcf327d 100644
--- a/src/p11-tests.h
+++ b/src/p11-tests.h
@@ -1,250 +1,37 @@
-#ifndef P11TESTST_H_
-#define P11TESTST_H_
-
-#ifndef _WIN32
-#include "config.h"
-#endif
-
-#ifdef _MSC_VER
-#pragma warning(disable : 4996)
-#endif
+#ifndef P11TESTS_H_
+#define P11TESTS_H_
#include "pkcs11/pkcs11.h"
-#include <assert.h>
-#include <stdarg.h>
-
-#include <openssl/rsa.h>
-#include <openssl/dsa.h>
-
-#define CK_INVALID ((CK_ULONG)-1)
-
-extern int p11t_test_unexpected;
-extern int p11t_test_write_session;
-
-/* -------------------------------------------------------------------
- * certificate.c
- */
-
-const char* p11t_certificate_validate_dn(CK_BYTE_PTR der, CK_ULONG n_der);
-
-void p11t_certificate_tests(void);
-
-/* -------------------------------------------------------------------
- * check.c
- */
-
-enum
-{
- STOP = 0,
- CONTINUE = 1
+enum {
+ P11_TESTS_NONE,
+ P11_TESTS_INFO,
+ P11_TESTS_WARN,
+ P11_TESTS_FAIL
};
-extern int p11t_check_verbose;
-
-#define P11T_SECTION(check) \
- p11t_msg_prefix(check)
-
-#define _P11T_BEGIN do {
-#define _P11T_END } while(0)
-
-#define P11T_CHECK_FAIL(what) \
- _P11T_BEGIN p11t_check_fail("%s", (what)); return STOP; _P11T_END
-
-#define P11T_CHECK_FAIL_MSG(what, msg) \
- _P11T_BEGIN p11t_check_fail("%s: %s", (what), (msg)); return STOP; _P11T_END
-
-int p11t_check_fail(const char *message, ...);
-int p11t_check_warn(const char *message, ...);
-int p11t_check_info(const char *message, ...);
-
-#define P11T_CHECK_RV(what, have, want) \
- _P11T_BEGIN if(!_p11t_check_rv((what), (have), (want))) return STOP; _P11T_END
-
-int _p11t_check_rv(const char *what, CK_RV have, CK_RV want);
-
-#define P11T_CHECK_PADDED(what, padded) \
- _P11T_BEGIN if(!_p11t_check_padded((what), (padded), sizeof(padded))) return STOP; _P11T_END
-
-int _p11t_check_padded(const char *what, const CK_UTF8CHAR_PTR padded, CK_ULONG length);
-
-#define P11T_CHECK_ULONG(what, have, want) \
- _P11T_BEGIN if(!_p11t_check_ulong((what), (have), (want))) return STOP; _P11T_END
-
-int _p11t_check_ulong(const char *what, CK_ULONG have, CK_ULONG want);
-
-#define P11T_CHECK_MASK(what, have, want) \
- _P11T_BEGIN if(!_p11t_check_mask((what), (have), (want))) return STOP; _P11T_END
-
-int _p11t_check_mask(const char *what, CK_ULONG flags, CK_ULONG mask);
-
-#define P11T_CHECK_FLAG(what, have, want) \
- _P11T_BEGIN if(!_p11t_check_flag((what), (have), (want))) return STOP; _P11T_END
-
-int _p11t_check_flag(const char *what, CK_ULONG flags, CK_ULONG flag);
-
-#define P11T_CHECK_NFLAG(what, have, want) \
- _P11T_BEGIN if(!_p11t_check_nflag((what), (have), (want))) return STOP; _P11T_END
-
-int _p11t_check_nflag(const char *what, CK_ULONG flags, CK_ULONG nflag);
-
-#define P11T_CHECK_BOOL(what, value) \
- _P11T_BEGIN if(!_p11t_check_bool((what), (value))) return STOP; _P11T_END
-
-int _p11t_check_bool(const char *what, CK_BBOOL value);
-
-#define P11T_CHECK_STRING(what, value, length) \
- _P11T_BEGIN if(!_p11t_check_string((what), (value), (length))) return STOP; _P11T_END
-
-int _p11t_check_string(const char *what, CK_UTF8CHAR_PTR value, CK_ULONG length);
-
-#define P11T_CHECK_DATE(what, value) \
- _P11T_BEGIN if(!_p11t_check_date((what), (value))) return STOP; _P11T_END
-
-int _p11t_check_date(const char *what, CK_DATE* value);
-
-#define P11T_CHECK_NOTE(what)
-
-/* -------------------------------------------------------------------
- * config.c
- */
-
-void p11t_config_parse(const char* filename);
-void p11t_config_cleanup(void);
-
-/* -------------------------------------------------------------------
- * crypto.c
- */
-
-int p11t_crypto_test_encrypt (CK_SESSION_HANDLE session, CK_MECHANISM_TYPE mech);
-int p11t_crypto_test_decrypt (CK_SESSION_HANDLE session, CK_MECHANISM_TYPE mech);
-int p11t_crypto_test_sign (CK_SESSION_HANDLE session, CK_MECHANISM_TYPE mech);
-int p11t_crypto_test_verify (CK_SESSION_HANDLE session, CK_MECHANISM_TYPE mech);
-
-/* -------------------------------------------------------------------
- * dsa.c
- */
-
-void p11t_dsa_tests(void);
-
-void p11t_dsa_test_public_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE handle);
-void p11t_dsa_test_private_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE handle);
-
-/* -------------------------------------------------------------------
- * key.c
- */
-
-CK_OBJECT_HANDLE p11t_key_get_public(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key);
-
-CK_OBJECT_HANDLE p11t_key_get_private(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key);
-
-CK_MECHANISM_TYPE_PTR p11t_key_get_mechanisms(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_ULONG_PTR n_mechanisms);
-
-RSA* p11t_key_export_public_rsa(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key);
-DSA* p11t_key_export_public_dsa(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key);
-
-CK_RV p11t_key_login_context_specific (CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key);
-
-void p11t_key_tests(void);
-
-/* -------------------------------------------------------------------
- * msg.c
- */
-
-const char* p11t_msg_rv(CK_RV rv);
-const char* p11t_msg_os(void);
-const char* p11t_msg_openssl(void);
-
-void p11t_msg_va(const char *message, va_list va);
-void p11t_msg_code(const char* code, const char *message, va_list va);
-void p11t_msg_print(const char *message, ...);
-void p11t_msg_fatal(const char *message, ...);
-const char* p11t_msg_prefix(const char *prefix);
-
-#define p11t_msg_here() \
- (__func__ "() at " __FILE__ ":" __LINE__)
-
-/* -------------------------------------------------------------------
- * module.c
- */
-
-extern CK_FUNCTION_LIST_PTR p11t_module_funcs;
-
-void p11t_module_config(const char *name, const char *value);
-
-int p11t_module_load(const char *filename);
-int p11t_module_unload(void);
-
-int p11t_module_initialize(void);
-int p11t_module_finalize(void);
-
-/* -------------------------------------------------------------------
- * object.c
- */
-
-CK_OBJECT_HANDLE_PTR p11t_object_find(CK_SESSION_HANDLE session, CK_ATTRIBUTE_PTR attrs,
- CK_ULONG n_attrs, CK_ULONG_PTR n_objects);
-
-int p11t_object_get(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object,
- CK_ATTRIBUTE_PTR attrs, CK_ULONG count);
-
-CK_OBJECT_HANDLE p11t_object_find_one(CK_SESSION_HANDLE session, CK_ATTRIBUTE_PTR attrs,
- CK_ULONG n_attrs);
-
-void p11t_object_tests(void);
-
-/* -------------------------------------------------------------------
- * rsa.c
- */
-
-void p11t_rsa_tests (void);
-void p11t_rsa_test_public_key (CK_SESSION_HANDLE session, CK_OBJECT_HANDLE handle);
-void p11t_rsa_test_private_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE handle);
-
-/* -------------------------------------------------------------------
- * session.c
- */
-
-CK_SESSION_HANDLE p11t_session_open(CK_SLOT_ID slot, int readwrite);
-int p11t_session_login(CK_SESSION_HANDLE handle);
-int p11t_session_logout(CK_SESSION_HANDLE handle);
-int p11t_session_close(CK_SESSION_HANDLE handle);
-int p11t_session_close_all(CK_SLOT_ID slot);
-CK_UTF8CHAR_PTR p11t_session_get_pin(CK_SLOT_ID slot, CK_USER_TYPE user, CK_ULONG_PTR n_pin);
-
-void p11t_session_config(const char *name, const char *value);
-
-void p11t_session_tests(void);
+typedef void (*P11TestsLogFunc) (int level,
+ const char *section,
+ const char *message);
-/* -------------------------------------------------------------------
- * slot.c
- */
+int p11_tests_get_unexpected (void);
-extern CK_ULONG p11t_slot_count;
-extern int p11t_slot_virtual;
+void p11_tests_set_unexpected (int value);
-void p11t_slot_tests(void);
+int p11_tests_get_write_session (void);
-void p11t_slot_cleanup(void);
+void p11_tests_set_write_session (int value);
-CK_SLOT_ID p11t_slot_get_id(int index);
-CK_SLOT_INFO_PTR p11t_slot_get_info(CK_SLOT_ID slot);
-CK_TOKEN_INFO_PTR p11t_slot_get_token_info(CK_SLOT_ID slot);
+int p11_tests_get_verbose (void);
-typedef void (*P11tSlotMechCallback)(CK_SLOT_ID slot, CK_MECHANISM_TYPE mech_type,
- CK_MECHANISM_INFO_PTR mech_info);
+void p11_tests_set_verbose (int value);
-void p11t_slot_for_each_mech(CK_MECHANISM_TYPE mech_type, P11tSlotMechCallback callback);
+int p11_tests_load_config (const char *config);
-CK_MECHANISM_INFO_PTR p11t_slot_get_mech_info(CK_SLOT_ID slot, CK_MECHANISM_TYPE mech_type);
+P11TestsLogFunc p11_tests_get_log_func (void);
-/* ------------------------------------------------------------------
- * test-data.c
- */
+void p11_tests_set_log_func (P11TestsLogFunc func);
-#define P11T_BLOCK 10240
-extern const CK_BYTE p11t_test_data[];
-extern const CK_ULONG p11t_test_data_size;
-extern const CK_ULONG p11t_test_data_bits;
+void p11_tests_perform (CK_FUNCTION_LIST_PTR module);
-#endif /* P11TESTST_H_ */
+#endif /* P11TESTS_H_ */
diff --git a/src/rsa.c b/src/rsa.c
index 1b9286f..76d5eca 100644
--- a/src/rsa.c
+++ b/src/rsa.c
@@ -1,5 +1,5 @@
-#include "p11-tests.h"
+#include "p11-tests-lib.h"
#include <stdio.h>
#include <stdlib.h>
diff --git a/src/session.c b/src/session.c
index db3ad47..680a6c4 100644
--- a/src/session.c
+++ b/src/session.c
@@ -1,5 +1,5 @@
-#include "p11-tests.h"
+#include "p11-tests-lib.h"
#include <string.h>
diff --git a/src/slot.c b/src/slot.c
index c5b01d0..6c765b6 100644
--- a/src/slot.c
+++ b/src/slot.c
@@ -1,5 +1,5 @@
-#include "p11-tests.h"
+#include "p11-tests-lib.h"
#include <stdlib.h>
#include <stdio.h>
diff --git a/src/test-data.c b/src/test-data.c
index a81b0ed..13865a2 100644
--- a/src/test-data.c
+++ b/src/test-data.c
@@ -1,5 +1,5 @@
-#include "p11-tests.h"
+#include "p11-tests-lib.h"
const CK_BYTE p11t_test_data[] =