summaryrefslogtreecommitdiff
path: root/src/slot.c
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 /src/slot.c
parent91d28a736abc1e1cd04b453f5c16f343feb91a3d (diff)
Implement mechanism info tests.
Diffstat (limited to 'src/slot.c')
-rw-r--r--src/slot.c358
1 files changed, 358 insertions, 0 deletions
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();
+}