From fb19dad45d9961903b947d77af52d12e928df342 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Fri, 5 Dec 2008 00:31:51 +0000 Subject: Implement mechanism info tests. --- doc/pkcs11-coverage.txt | 15 ++ src/Makefile.am | 5 +- src/check.c | 38 ++++- src/info.c | 241 -------------------------------- src/p11-tests.c | 2 +- src/p11-tests.h | 23 ++-- src/slot.c | 358 ++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 426 insertions(+), 256 deletions(-) delete mode 100644 src/info.c create mode 100644 src/slot.c diff --git a/doc/pkcs11-coverage.txt b/doc/pkcs11-coverage.txt index 692af76..538d487 100644 --- a/doc/pkcs11-coverage.txt +++ b/doc/pkcs11-coverage.txt @@ -20,6 +20,18 @@ C_GetInfo - Space padded strings in CK_INFO - No flags set +C_GetMechanismInfo +- Invalid mechanism +- Null arguments +- Invalid slot id +- Normal call + +C_GetMechanismList +- Null arguments +- Without buffer +- Zero count but buffer present +- Low count but buffer present + C_GetSlotInfo - NULL argument - Normal call @@ -53,3 +65,6 @@ C_Initialize - Multiple initialize with C_Finalize between - Double initialize in a row +C_WaitForSlotEvent +- Not Implemented + diff --git a/src/Makefile.am b/src/Makefile.am index 6b24785..ee3290a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -5,7 +5,8 @@ bin_PROGRAMS = p11-tests p11_tests_LDADD = -ldl p11_tests_SOURCES = \ check.c \ - info.c \ module.c \ msg.c \ - p11-tests.c + p11-tests.c \ + slot.c + diff --git a/src/check.c b/src/check.c index 61cee45..a72cf87 100644 --- a/src/check.c +++ b/src/check.c @@ -3,6 +3,8 @@ #include "p11-tests.h" +#include + int p11t_check_returns(const char *message, CK_RV have, CK_RV want) { @@ -24,6 +26,12 @@ p11t_check_padded_len(const char *message, const CK_UTF8CHAR_PTR padded, for(i = 0; i < length; ++i) { + if(!isprint(padded[i])) + { + p11t_msg_print("%s: non printable character: %d", message, padded[i]); + return 0; + } + if(!padded[i]) { p11t_msg_print("%s: not blank padded", message); @@ -52,8 +60,34 @@ p11t_check_mask(const char *message, CK_ULONG flags, CK_ULONG mask) { if((flags & ~mask) != 0) { - p11t_msg_print("%s: extra flags outside of mask: 0x08x", - (flags & ~mask)); + p11t_msg_print("%s: extra flags outside of mask: 0x%08x", + message, (flags & ~mask)); + return 0; + } + + return 1; +} + +int +p11t_check_flag(const char *message, CK_ULONG flags, CK_ULONG flag) +{ + if((flags & flag) == 0) + { + p11t_msg_print("%s: flag 0x%08x should be set in: 0x%08x", + message, flag, flags); + return 0; + } + + return 1; +} + +int +p11t_check_nflag(const char *message, CK_ULONG flags, CK_ULONG nflag) +{ + if((flags & nflag) != 0) + { + p11t_msg_print("%s: flag 0x%08x should not be set in: 0x%08x", + message, nflag, flags); return 0; } diff --git a/src/info.c b/src/info.c deleted file mode 100644 index eedf08e..0000000 --- a/src/info.c +++ /dev/null @@ -1,241 +0,0 @@ - -#include "config.h" - -#include "p11-tests.h" - -#include -#include -#include - -CK_INFO p11t_info_global; - -CK_ULONG p11t_info_slot_count = 0; -CK_SLOT_ID_PTR p11t_info_slot_ids = NULL; -CK_SLOT_INFO_PTR p11t_info_slot_info = NULL; -CK_TOKEN_INFO_PTR p11t_info_token_info = NULL; - -CK_ULONG p11t_info_mech_count = 0; -CK_MECHANISM_TYPE_PTR p11t_info_mech_types = NULL; -CK_MECHANISM_INFO_PTR p11t_info_mech_info = NULL; - -void -info_global(void) -{ - CK_RV rv; - - /** C_GetInfo */ - - assert(p11t_module_funcs); - - /** - NULL argument */ - rv = (p11t_module_funcs->C_GetInfo)(NULL); - p11t_check_returns("C_GetInfo", rv, CKR_ARGUMENTS_BAD); - - /* Obvious crap fill */ - memset(&p11t_info_global, 0xFF, sizeof(CK_INFO)); - - /** - Normal call */ - rv = (p11t_module_funcs->C_GetInfo)(&p11t_info_global); - if(p11t_check_returns("C_GetInfo", rv, CKR_OK)) - { - memset(&p11t_info_global, 0, sizeof(CK_INFO)); - return; - } - - /** - Cryptoki version matches that in library entry point data */ - if(memcmp(&p11t_info_global.cryptokiVersion, &p11t_module_funcs->version, sizeof(CK_VERSION)) != 0) - p11t_msg_print("version from CK_INFO.cryptokiVersion does not match from CK_FUNCTION_LIST.version"); - - /** - Space padded strings in CK_INFO */ - p11t_check_padded("CK_INFO.manufacturerID", p11t_info_global.manufacturerID); - p11t_check_padded("CK_INFO.libraryDescription", p11t_info_global.libraryDescription); - - /** - No flags set */ - p11t_check_ulong("CK_INFO.flags", p11t_info_global.flags, 0); -} - -int -compar_slot_id(const void *one, const void *two) -{ - CK_SLOT_ID a = *((CK_SLOT_ID*)one); - CK_SLOT_ID b = *((CK_SLOT_ID*)two); - if(a == b) - return 0; - if(a > b) - return 1; - return -1; -} - -void -info_slots(void) -{ - CK_SLOT_ID_PTR present, only; - CK_ULONG n_present, n_only, count; - CK_ULONG i; - CK_RV rv; - - /** C_GetSlotList */ - - assert(p11t_module_funcs); - - /** - NULL arguments */ - rv = (p11t_module_funcs->C_GetSlotList)(FALSE, NULL, NULL); - p11t_check_returns("C_GetSlotList", rv, CKR_ARGUMENTS_BAD); - - /** - Retrieving the count */ - rv = (p11t_module_funcs->C_GetSlotList)(FALSE, NULL, &p11t_info_slot_count); - p11t_check_returns("C_GetSlotList", rv, CKR_OK); - - if(p11t_info_slot_count == 0) - { - p11t_msg_print("no slots to test"); - return; - } - - /* Allocate a bit extra. We're going to try and trip up module */ - p11t_info_slot_ids = calloc(p11t_info_slot_count + 5, sizeof(CK_SLOT_ID)); - assert(p11t_info_slot_ids); - - p11t_info_slot_info = calloc(p11t_info_slot_count, sizeof(CK_SLOT_INFO)); - assert(p11t_info_slot_info); - - p11t_info_token_info = calloc(p11t_info_slot_count, sizeof(CK_TOKEN_INFO)); - assert(p11t_info_token_info); - - /** - Passing buffer space along with zero count. */ - count = 0; - rv = (p11t_module_funcs->C_GetSlotList)(FALSE, p11t_info_slot_ids, &count); - p11t_check_returns("C_GetSlotList", rv, CKR_BUFFER_TOO_SMALL); - p11t_check_ulong("Count invalid zero space passed to C_GetSlotList", count, p11t_info_slot_count); - - if(p11t_info_slot_count > 1) - { - /** - Passing buffer space along with low count. */ - count = 1; - rv = (p11t_module_funcs->C_GetSlotList)(FALSE, p11t_info_slot_ids, &count); - p11t_check_returns("C_GetSlotList", rv, CKR_BUFFER_TOO_SMALL); - p11t_check_ulong("Count invalid when too little space passed to C_GetSlotList", count, p11t_info_slot_count); - } - - /** - Passing too much buffer space. */ - count = p11t_info_slot_count + 5; - rv = (p11t_module_funcs->C_GetSlotList)(FALSE, p11t_info_slot_ids, &count); - if(!p11t_check_returns("C_GetSlotList", rv, CKR_OK)) - { - p11t_info_slot_count = 0; - return; - } - - p11t_check_ulong("Count invalid when too much space passed to C_GetSlotList", count, p11t_info_slot_count); - - /* When we ask for just token valid ones, they should only be the ones we noted with flags */ - present = calloc(p11t_info_slot_count, sizeof(CK_SLOT_ID)); - only = calloc(p11t_info_slot_count, sizeof(CK_SLOT_ID)); - assert(present && only); - n_present = 0; - - /* Now go through and load info about each slot */ - for(i = 0; i < p11t_info_slot_count; ++i) - { - /** C_GetSlotInfo */ - - /** - NULL argument */ - rv = (p11t_module_funcs->C_GetSlotInfo)(p11t_info_slot_ids[i], NULL); - p11t_check_returns("C_GetSlotInfo", rv, CKR_ARGUMENTS_BAD); - - /** - Normal call */ - rv = (p11t_module_funcs->C_GetSlotInfo)(p11t_info_slot_ids[i], &p11t_info_slot_info[i]); - p11t_check_returns("C_GetSlotInfo", rv, CKR_OK); - - /** - Space padded CK_SLOT_INFO fields */ - p11t_check_padded("CK_SLOT_INFO.slotDescription", p11t_info_slot_info[i].slotDescription); - p11t_check_padded("CK_SLOT_INFO.manufacturerID", p11t_info_slot_info[i].manufacturerID); - - /** - CK_SLOT_INFO flags are from valid set */ - p11t_check_mask("CK_SLOT_INFO.flags", p11t_info_slot_info[i].flags, - CKF_TOKEN_PRESENT | CKF_REMOVABLE_DEVICE | CKF_HW_SLOT); - - /** - Track CKF_TOKEN_PRESENT flag and compare to C_GetSlotList(TRUE) */ - if((p11t_info_slot_info[i].flags & CKF_TOKEN_PRESENT) == CKF_TOKEN_PRESENT) - { - /* Note if token is present for later */ - present[n_present++] = p11t_info_slot_ids[i]; - - /** C_GetTokenInfo */ - - /** - Null arguments */ - rv = (p11t_module_funcs->C_GetTokenInfo)(p11t_info_slot_ids[i], NULL); - p11t_check_returns("C_GetSlotInfo", rv, CKR_ARGUMENTS_BAD); - - /** - Normal call */ - rv = (p11t_module_funcs->C_GetTokenInfo)(p11t_info_slot_ids[i], &p11t_info_token_info[i]); - p11t_check_returns("C_GetSlotInfo", rv, CKR_OK); - - /** - Space padded CK_TOKEN_INFO fields */ - p11t_check_padded("CK_TOKEN_INFO.label", p11t_info_token_info[i].label); - p11t_check_padded("CK_TOKEN_INFO.manufacturerID", p11t_info_token_info[i].manufacturerID); - p11t_check_padded("CK_TOKEN_INFO.model", p11t_info_token_info[i].model); - p11t_check_padded("CK_TOKEN_INFO.serialNumber", p11t_info_token_info[i].serialNumber); - - /** - CK_TOKEN_INFO flags are from valid set */ - p11t_check_mask("CK_TOKEN_INFO.flags", p11t_info_token_info[i].flags, - CKF_RNG | CKF_WRITE_PROTECTED | CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED | - CKF_RESTORE_KEY_NOT_NEEDED | CKF_CLOCK_ON_TOKEN | CKF_PROTECTED_AUTHENTICATION_PATH | - CKF_DUAL_CRYPTO_OPERATIONS | CKF_TOKEN_INITIALIZED | CKF_SECONDARY_AUTHENTICATION | - CKF_USER_PIN_COUNT_LOW | CKF_USER_PIN_FINAL_TRY | CKF_USER_PIN_LOCKED | - CKF_USER_PIN_TO_BE_CHANGED | CKF_SO_PIN_COUNT_LOW | CKF_SO_PIN_FINAL_TRY | - CKF_SO_PIN_LOCKED | CKF_SO_PIN_TO_BE_CHANGED); - - /* Can't validate all the statistics, any number is valid */ - - /** - Validate token time when CKF_CLOCK_ON_TOKEN */ - if((p11t_info_token_info[i].flags & CKF_CLOCK_ON_TOKEN) == CKF_CLOCK_ON_TOKEN) - { - int year, month, day, hour, minute, second, extra, n; - char buffer[sizeof(p11t_info_token_info[i].utcTime) + 1]; - - memcpy(buffer, (char*)p11t_info_token_info[i].utcTime, - sizeof(p11t_info_token_info[i].utcTime)); - buffer[sizeof(p11t_info_token_info[i].utcTime)] = 0; - - n = sscanf(buffer, "%04d%02d%02d%02d%02d%02d%02d", - &year, &month, &day, &hour, &minute, &second, &extra); - - if(n != 7 || - year < 0 || year > 9999 || - month < 1 || month > 12 || - day < 1 || day > 31 || - hour < 0 || hour > 23 || - minute < 0 || minute > 59 || - second < 0 || second > 50 || - extra != 0) - { - p11t_msg_print("invalid time on token: %s", buffer); - } - } - } - else - { - /** - Calling on slot without token */ - rv = (p11t_module_funcs->C_GetTokenInfo)(p11t_info_slot_ids[i], &p11t_info_token_info[i]); - p11t_check_returns("C_GetSlotInfo", rv, CKR_TOKEN_NOT_PRESENT); - } - } - - rv = (p11t_module_funcs->C_GetSlotList)(TRUE, only, &n_only); - p11t_check_returns("C_GetSlotList (only tokens)", rv, CKR_OK); - - p11t_check_ulong("number of present tokens doesn't match token info flags. ie: CKF_TOKEN_PRESENT", n_only, n_present); - - qsort(only, n_only, sizeof(CK_SLOT_ID), compar_slot_id); - qsort(present, n_present, sizeof(CK_SLOT_ID), compar_slot_id); - if(memcmp(only, present, sizeof(CK_SLOT_ID) * n_only) != 0) - p11t_msg_print("present tokens don't match those in token info flags. ie: CKF_TOKEN_PRESENT"); -} - -void -p11t_info_tests(void) -{ - info_global(); - info_slots(); -} diff --git a/src/p11-tests.c b/src/p11-tests.c index bb67dd7..2adf6e9 100644 --- a/src/p11-tests.c +++ b/src/p11-tests.c @@ -39,7 +39,7 @@ main(int argc, char* argv[]) p11t_module_load(argv[0]); p11t_module_initialize(argc == 2 ? argv[1] : NULL); - p11t_info_tests(); + p11t_slot_tests(); /* Remaining module tests */ p11t_module_finalize(); diff --git a/src/p11-tests.h b/src/p11-tests.h index 89b856c..4a79ffd 100644 --- a/src/p11-tests.h +++ b/src/p11-tests.h @@ -35,22 +35,25 @@ int p11t_check_ulong(const char *message, CK_ULONG have, CK_ULONG want); int p11t_check_mask(const char *message, CK_ULONG flags, CK_ULONG mask); +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); + /* ------------------------------------------------------------------- - * info.c + * slot.c */ -extern CK_INFO p11t_info_global; +extern CK_INFO p11t_slot_global; -extern CK_ULONG p11t_info_slot_count; -extern CK_SLOT_ID_PTR p11t_info_slot_ids; -extern CK_SLOT_INFO_PTR p11t_info_slot_info; -extern CK_TOKEN_INFO_PTR p11t_info_token_info; +extern CK_ULONG p11t_slot_count; +extern CK_SLOT_ID_PTR p11t_slot_ids; +extern CK_SLOT_INFO_PTR p11t_slot_info; +extern CK_TOKEN_INFO_PTR p11t_slot_token_info; -extern CK_ULONG p11t_info_mech_count; -extern CK_MECHANISM_TYPE_PTR p11t_info_mech_types; -extern CK_MECHANISM_INFO_PTR p11t_info_mech_info; +extern CK_ULONG* p11t_slot_mech_count; +extern CK_MECHANISM_INFO_PTR* p11t_slot_mech_info; -void p11t_info_tests(void); +void p11t_slot_tests(void); /* ------------------------------------------------------------------- * module.c diff --git a/src/slot.c b/src/slot.c new file mode 100644 index 0000000..a8733cf --- /dev/null +++ b/src/slot.c @@ -0,0 +1,358 @@ + +#include "config.h" + +#include "p11-tests.h" + +#include +#include +#include + +CK_INFO p11t_slot_global; + +CK_ULONG p11t_slot_count = 0; +CK_SLOT_ID_PTR p11t_slot_ids = NULL; +CK_SLOT_INFO_PTR p11t_slot_info = NULL; +CK_TOKEN_INFO_PTR p11t_slot_token_info = NULL; + +CK_ULONG *p11t_slot_mech_count; +CK_MECHANISM_INFO_PTR *p11t_slot_mech_info; + +void +slot_global(void) +{ + CK_RV rv; + + /** C_GetInfo */ + + assert(p11t_module_funcs); + + /** - NULL argument */ + rv = (p11t_module_funcs->C_GetInfo)(NULL); + p11t_check_returns("C_GetInfo", rv, CKR_ARGUMENTS_BAD); + + /* Obvious crap fill */ + memset(&p11t_slot_global, 0xFF, sizeof(CK_INFO)); + + /** - Normal call */ + rv = (p11t_module_funcs->C_GetInfo)(&p11t_slot_global); + if(p11t_check_returns("C_GetInfo", rv, CKR_OK)) + { + memset(&p11t_slot_global, 0, sizeof(CK_INFO)); + return; + } + + /** - Cryptoki version matches that in library entry point data */ + if(memcmp(&p11t_slot_global.cryptokiVersion, &p11t_module_funcs->version, sizeof(CK_VERSION)) != 0) + p11t_msg_print("version from CK_INFO.cryptokiVersion does not match from CK_FUNCTION_LIST.version"); + + /** - Space padded strings in CK_INFO */ + p11t_check_padded("CK_INFO.manufacturerID", p11t_slot_global.manufacturerID); + p11t_check_padded("CK_INFO.libraryDescription", p11t_slot_global.libraryDescription); + + /** - No flags set */ + p11t_check_ulong("CK_INFO.flags", p11t_slot_global.flags, 0); +} + +int +compar_slot_id(const void *one, const void *two) +{ + CK_SLOT_ID a = *((CK_SLOT_ID*)one); + CK_SLOT_ID b = *((CK_SLOT_ID*)two); + if(a == b) + return 0; + if(a > b) + return 1; + return -1; +} + +void +slot_info(void) +{ + CK_SLOT_ID_PTR present, only; + CK_ULONG n_present, n_only, count; + CK_ULONG i; + CK_RV rv; + + /** C_GetSlotList */ + + assert(p11t_module_funcs); + + /** - NULL arguments */ + rv = (p11t_module_funcs->C_GetSlotList)(FALSE, NULL, NULL); + p11t_check_returns("C_GetSlotList", rv, CKR_ARGUMENTS_BAD); + + /** - Retrieving the count */ + rv = (p11t_module_funcs->C_GetSlotList)(FALSE, NULL, &p11t_slot_count); + p11t_check_returns("C_GetSlotList", rv, CKR_OK); + + if(p11t_slot_count == 0) + { + p11t_msg_print("no slots to test"); + return; + } + + /* Allocate a bit extra. We're going to try and trip up module */ + p11t_slot_ids = calloc(p11t_slot_count + 5, sizeof(CK_SLOT_ID)); + assert(p11t_slot_ids); + + p11t_slot_info = calloc(p11t_slot_count, sizeof(CK_SLOT_INFO)); + assert(p11t_slot_info); + + p11t_slot_token_info = calloc(p11t_slot_count, sizeof(CK_TOKEN_INFO)); + assert(p11t_slot_token_info); + + /** - Passing buffer space along with zero count. */ + count = 0; + rv = (p11t_module_funcs->C_GetSlotList)(FALSE, p11t_slot_ids, &count); + p11t_check_returns("C_GetSlotList", rv, CKR_BUFFER_TOO_SMALL); + p11t_check_ulong("Count invalid zero space passed to C_GetSlotList", count, p11t_slot_count); + + if(p11t_slot_count > 1) + { + /** - Passing buffer space along with low count. */ + count = 1; + rv = (p11t_module_funcs->C_GetSlotList)(FALSE, p11t_slot_ids, &count); + p11t_check_returns("C_GetSlotList", rv, CKR_BUFFER_TOO_SMALL); + p11t_check_ulong("Count invalid when too little space passed to C_GetSlotList", count, p11t_slot_count); + } + + /** - Passing too much buffer space. */ + count = p11t_slot_count + 5; + rv = (p11t_module_funcs->C_GetSlotList)(FALSE, p11t_slot_ids, &count); + if(!p11t_check_returns("C_GetSlotList", rv, CKR_OK)) + { + p11t_slot_count = 0; + return; + } + + p11t_check_ulong("Count invalid when too much space passed to C_GetSlotList", count, p11t_slot_count); + + /* When we ask for just token valid ones, they should only be the ones we noted with flags */ + present = calloc(p11t_slot_count, sizeof(CK_SLOT_ID)); + only = calloc(p11t_slot_count, sizeof(CK_SLOT_ID)); + assert(present && only); + n_present = 0; + + /* Now go through and load info about each slot */ + for(i = 0; i < p11t_slot_count; ++i) + { + /** C_GetSlotInfo */ + + /** - NULL argument */ + rv = (p11t_module_funcs->C_GetSlotInfo)(p11t_slot_ids[i], NULL); + p11t_check_returns("C_GetSlotInfo", rv, CKR_ARGUMENTS_BAD); + + /** - Normal call */ + rv = (p11t_module_funcs->C_GetSlotInfo)(p11t_slot_ids[i], &p11t_slot_info[i]); + p11t_check_returns("C_GetSlotInfo", rv, CKR_OK); + + /** - Space padded CK_SLOT_INFO fields */ + p11t_check_padded("CK_SLOT_INFO.slotDescription", p11t_slot_info[i].slotDescription); + p11t_check_padded("CK_SLOT_INFO.manufacturerID", p11t_slot_info[i].manufacturerID); + + /** - CK_SLOT_INFO flags are from valid set */ + p11t_check_mask("CK_SLOT_INFO.flags", p11t_slot_info[i].flags, + CKF_TOKEN_PRESENT | CKF_REMOVABLE_DEVICE | CKF_HW_SLOT); + + /** - Track CKF_TOKEN_PRESENT flag and compare to C_GetSlotList(TRUE) */ + if((p11t_slot_info[i].flags & CKF_TOKEN_PRESENT) == CKF_TOKEN_PRESENT) + { + /* Note if token is present for later */ + present[n_present++] = p11t_slot_ids[i]; + + /** C_GetTokenInfo */ + + /** - Null arguments */ + rv = (p11t_module_funcs->C_GetTokenInfo)(p11t_slot_ids[i], NULL); + p11t_check_returns("C_GetSlotInfo", rv, CKR_ARGUMENTS_BAD); + + /** - Normal call */ + rv = (p11t_module_funcs->C_GetTokenInfo)(p11t_slot_ids[i], &p11t_slot_token_info[i]); + p11t_check_returns("C_GetSlotInfo", rv, CKR_OK); + + /** - Space padded CK_TOKEN_INFO fields */ + p11t_check_padded("CK_TOKEN_INFO.label", p11t_slot_token_info[i].label); + p11t_check_padded("CK_TOKEN_INFO.manufacturerID", p11t_slot_token_info[i].manufacturerID); + p11t_check_padded("CK_TOKEN_INFO.model", p11t_slot_token_info[i].model); + p11t_check_padded("CK_TOKEN_INFO.serialNumber", p11t_slot_token_info[i].serialNumber); + + /** - CK_TOKEN_INFO flags are from valid set */ + p11t_check_mask("CK_TOKEN_INFO.flags", p11t_slot_token_info[i].flags, + CKF_RNG | CKF_WRITE_PROTECTED | CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED | + CKF_RESTORE_KEY_NOT_NEEDED | CKF_CLOCK_ON_TOKEN | CKF_PROTECTED_AUTHENTICATION_PATH | + CKF_DUAL_CRYPTO_OPERATIONS | CKF_TOKEN_INITIALIZED | CKF_SECONDARY_AUTHENTICATION | + CKF_USER_PIN_COUNT_LOW | CKF_USER_PIN_FINAL_TRY | CKF_USER_PIN_LOCKED | + CKF_USER_PIN_TO_BE_CHANGED | CKF_SO_PIN_COUNT_LOW | CKF_SO_PIN_FINAL_TRY | + CKF_SO_PIN_LOCKED | CKF_SO_PIN_TO_BE_CHANGED); + + /* Can't validate all the statistics, any number is valid */ + + /** - Validate token time when CKF_CLOCK_ON_TOKEN */ + if((p11t_slot_token_info[i].flags & CKF_CLOCK_ON_TOKEN) == CKF_CLOCK_ON_TOKEN) + { + int year, month, day, hour, minute, second, extra, n; + char buffer[sizeof(p11t_slot_token_info[i].utcTime) + 1]; + + memcpy(buffer, (char*)p11t_slot_token_info[i].utcTime, + sizeof(p11t_slot_token_info[i].utcTime)); + buffer[sizeof(p11t_slot_token_info[i].utcTime)] = 0; + + n = sscanf(buffer, "%04d%02d%02d%02d%02d%02d%02d", + &year, &month, &day, &hour, &minute, &second, &extra); + + if(n != 7 || + year < 0 || year > 9999 || + month < 1 || month > 12 || + day < 1 || day > 31 || + hour < 0 || hour > 23 || + minute < 0 || minute > 59 || + second < 0 || second > 50 || + extra != 0) + { + p11t_msg_print("invalid time on token: %s", buffer); + } + } + } + else + { + /** - Calling on slot without token */ + rv = (p11t_module_funcs->C_GetTokenInfo)(p11t_slot_ids[i], &p11t_slot_token_info[i]); + p11t_check_returns("C_GetSlotInfo", rv, CKR_TOKEN_NOT_PRESENT); + } + } + + rv = (p11t_module_funcs->C_GetSlotList)(TRUE, only, &n_only); + p11t_check_returns("C_GetSlotList (only tokens)", rv, CKR_OK); + + p11t_check_ulong("number of present tokens doesn't match token info flags. ie: CKF_TOKEN_PRESENT", n_only, n_present); + + qsort(only, n_only, sizeof(CK_SLOT_ID), compar_slot_id); + qsort(present, n_present, sizeof(CK_SLOT_ID), compar_slot_id); + if(memcmp(only, present, sizeof(CK_SLOT_ID) * n_only) != 0) + p11t_msg_print("present tokens don't match those in token info flags. ie: CKF_TOKEN_PRESENT"); +} + +void +slot_events(void) +{ + /** C_WaitForSlotEvent */ + /** - Not Implemented */ +} + +void +slot_mechanisms(void) +{ + CK_MECHANISM_TYPE_PTR mech_list; + CK_MECHANISM_INFO_PTR mech_info; + CK_SLOT_ID slot_id; + CK_ULONG mech_count, value; + CK_ULONG i, j; + CK_RV rv; + + assert(p11t_module_funcs); + + /** C_GetMechanismList */ + + if(!p11t_slot_count) + return; + + /* - Invalid Slot */ + mech_count = 0; + rv = (p11t_module_funcs->C_GetMechanismList)((CK_ULONG)-10, NULL, &mech_count); + p11t_check_returns("C_GetMechanismList invalid slot id", rv, CKR_SLOT_ID_INVALID); + + p11t_slot_mech_count = calloc(p11t_slot_count, sizeof(CK_ULONG)); + assert(p11t_slot_mech_count); + + p11t_slot_mech_info = calloc(p11t_slot_count, sizeof(CK_MECHANISM_INFO_PTR)); + assert(p11t_slot_mech_info); + + + for(i = 0; i < p11t_slot_count; ++i) + { + slot_id = p11t_slot_ids[i]; + + /** - Null arguments */ + rv = (p11t_module_funcs->C_GetMechanismList)(slot_id, NULL, NULL); + p11t_check_returns("C_GetMechanismList null arguments", rv, CKR_ARGUMENTS_BAD); + + /** - Without buffer */ + rv = (p11t_module_funcs->C_GetMechanismList)(slot_id, NULL, &mech_count); + p11t_check_returns("C_GetMechanismList without buffer", rv, CKR_OK); + + if(mech_count > 0) + { + mech_list = calloc(mech_count + 5, sizeof(CK_MECHANISM_TYPE)); + assert(mech_list); + + /** - Zero count but buffer present */ + value = 0; + rv = (p11t_module_funcs->C_GetMechanismList)(slot_id, mech_list, &value); + p11t_check_returns("C_GetMechanismList zero buffer", rv, CKR_BUFFER_TOO_SMALL); + p11t_check_ulong("should have number of mechs", value, mech_count); + + if(mech_count > 1) + { + /** - Low count but buffer present */ + value = 1; + rv = (p11t_module_funcs->C_GetMechanismList)(slot_id, mech_list, &value); + p11t_check_returns("C_GetMechanismList low buffer", rv, CKR_BUFFER_TOO_SMALL); + p11t_check_ulong("should have number of mechs", value, mech_count); + } + + /* - Call with too much buffer */ + value = mech_count + 5; + rv = (p11t_module_funcs->C_GetMechanismList)(slot_id, mech_list, &value); + p11t_check_returns("C_GetMechanismList high buffer", rv, CKR_OK); + p11t_check_ulong("should have number of mechs", value, mech_count); + + + mech_info = calloc(mech_count, sizeof(CK_MECHANISM_INFO)); + assert(mech_info); + + /** C_GetMechanismInfo */ + + /** - Invalid mechanism */ + rv = (p11t_module_funcs->C_GetMechanismInfo)(slot_id, (CK_ULONG)-10, mech_info); + p11t_check_returns("C_GetMechanismInfo with invalid mech", rv, CKR_MECHANISM_INVALID); + + /** - Null arguments */ + rv = (p11t_module_funcs->C_GetMechanismInfo)(slot_id, mech_list[0], NULL); + p11t_check_returns("C_GetMechanismInfo with null arg", rv, CKR_ARGUMENTS_BAD); + + /** - Invalid slot id */ + rv = (p11t_module_funcs->C_GetMechanismInfo)((CK_ULONG)-11, mech_list[0], mech_info); + p11t_check_returns("C_GetMechanismInfo with invalid slot", rv, CKR_SLOT_ID_INVALID); + + for(j = 0; j < mech_count; ++j) + { + /** - Normal call */ + rv = (p11t_module_funcs->C_GetMechanismInfo)(slot_id, mech_list[i], &mech_info[i]); + p11t_check_returns("C_GetMechanismInfo", rv, CKR_OK); + + if(mech_info[i].ulMinKeySize > mech_info[i].ulMaxKeySize) + p11t_msg_print("Mechanism min key size is greater than max"); + + p11t_check_mask("CK_MECHANISM_INFO.flags", mech_info[i].flags, + CKF_HW | CKF_ENCRYPT | CKF_DECRYPT | CKF_DIGEST | CKF_SIGN | + CKF_SIGN_RECOVER | CKF_VERIFY | CKF_VERIFY_RECOVER | CKF_GENERATE | + CKF_GENERATE_KEY_PAIR | CKF_WRAP | CKF_UNWRAP | CKF_DERIVE); + + p11t_check_nflag("CK_MECHANISM_INFO.flags", mech_info[i].flags, CKF_EXTENSION); + } + + p11t_slot_mech_info[i] = mech_info; + } + + p11t_slot_mech_count[i] = mech_count; + } +} + +void +p11t_slot_tests(void) +{ + slot_global(); + slot_info(); + slot_events(); + slot_mechanisms(); +} -- cgit v1.2.3