From 363a869b000ee1c9337bc0086108f6a5960da326 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Sun, 15 Nov 2009 20:26:16 +0000 Subject: Allow use of p11-tests as a library. --- src/Makefile.am | 21 ++++- src/certificate.c | 1 + src/check.c | 7 +- src/config.c | 33 ++++--- src/crypto.c | 1 + src/dsa.c | 2 +- src/key.c | 2 +- src/module.c | 109 ++++++---------------- src/msg.c | 78 ++++++++-------- src/object.c | 2 +- src/p11-tests-lib.c | 94 +++++++++++++++++++ src/p11-tests-lib.h | 252 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/p11-tests.c | 123 ++++++++++++++++++------- src/p11-tests.h | 255 +++++----------------------------------------------- src/rsa.c | 2 +- src/session.c | 2 +- src/slot.c | 2 +- src/test-data.c | 2 +- 18 files changed, 580 insertions(+), 408 deletions(-) create mode 100644 src/p11-tests-lib.c create mode 100644 src/p11-tests-lib.h (limited to 'src') 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 #include 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 #include @@ -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 #include @@ -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 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 #include 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 +#include +#include + #ifdef _WIN32 #define WIN32_LEAN_AND_MEAN #define _WIN32_WINNT 0x400 #include -static HMODULE module = NULL; - #else /* !_WIN32 */ -#include #include -static void *module = NULL; - #endif /* !_WIN32 */ -#include "p11-tests.h" - -#include -#include -#include - 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 #include @@ -15,7 +16,10 @@ #include -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 #include 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 +#include + +#include +#include + +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 +#include + +#include +#include + +#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 #include -#include -#include +#ifdef _WIN32 + +#define WIN32_LEAN_AND_MEAN +#define _WIN32_WINNT 0x400 +#include + +static HMODULE module = NULL; + +#else /* !_WIN32 */ + +#include +#include + +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 -#include - -#include -#include - -#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 #include 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 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 #include 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[] = -- cgit v1.2.3