summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stef@memberwebs.com>2008-12-05 00:31:51 +0000
committerStef Walter <stef@memberwebs.com>2008-12-05 00:31:51 +0000
commitfb19dad45d9961903b947d77af52d12e928df342 (patch)
treec088acab7029221789d062e6c0e5261b8998f9b3
parent91d28a736abc1e1cd04b453f5c16f343feb91a3d (diff)
Implement mechanism info tests.
-rw-r--r--doc/pkcs11-coverage.txt15
-rw-r--r--src/Makefile.am5
-rw-r--r--src/check.c38
-rw-r--r--src/info.c241
-rw-r--r--src/p11-tests.c2
-rw-r--r--src/p11-tests.h23
-rw-r--r--src/slot.c358
7 files changed, 426 insertions, 256 deletions
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 <ctype.h>
+
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 <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-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 <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+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();
+}