summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stef@memberwebs.com>2008-12-05 17:39:21 +0000
committerStef Walter <stef@memberwebs.com>2008-12-05 17:39:21 +0000
commit9d75f49f5818d4cf0f960f2fa113aaefff543df7 (patch)
tree4e717abeaa742384d58f2a5e187b66c4bdf21265
parent8ebef7ee31f973b64dce777297cba0b3cfe0f3fe (diff)
Implement GetAttributeValue tests.
-rw-r--r--src/check.c30
-rw-r--r--src/module.c13
-rw-r--r--src/object.c244
-rw-r--r--src/p11-tests.h7
-rw-r--r--src/session.c28
-rw-r--r--src/slot.c8
6 files changed, 308 insertions, 22 deletions
diff --git a/src/check.c b/src/check.c
index 7e45f5f..01b19fb 100644
--- a/src/check.c
+++ b/src/check.c
@@ -56,6 +56,36 @@ p11t_check_ulong(const char *message, CK_ULONG have, CK_ULONG want)
}
int
+p11t_check_bool(const char *message, CK_BBOOL value)
+{
+ if(value != CK_FALSE && value != CK_TRUE)
+ {
+ p11t_msg_print("%s: expected CK_TRUE or CK_FALSE but got 0x%02x",
+ message, (int)value);
+ return 0;
+ }
+
+ return 1;
+}
+
+int
+p11t_check_string(const char *message, CK_UTF8CHAR_PTR value, CK_ULONG length)
+{
+ CK_ULONG i;
+
+ for(i = 0; i < length; ++i)
+ {
+ if(!value[i])
+ {
+ p11t_msg_print("%s: is null terminated", message);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+int
p11t_check_mask(const char *message, CK_ULONG flags, CK_ULONG mask)
{
if((flags & ~mask) != 0)
diff --git a/src/module.c b/src/module.c
index 9e018e7..e47ba38 100644
--- a/src/module.c
+++ b/src/module.c
@@ -17,6 +17,12 @@ static CK_C_INITIALIZE_ARGS init_args;
static void (*init_func)(void) = NULL;
static int is_initialized = 0;
+void
+p11t_module_config(const char *name, const char *value)
+{
+ if(strcmp(name, "init-string") == 0)
+ init_string = value;
+}
static CK_RV
create_mutex(void **mutex)
@@ -342,10 +348,3 @@ p11t_module_unload(void)
dlclose(module);
module = NULL;
}
-
-void
-p11t_module_config(const char *name, const char *value)
-{
- if(strcmp(name, "init-string") == 0)
- init_string = value;
-}
diff --git a/src/object.c b/src/object.c
index 450c795..71e6a0d 100644
--- a/src/object.c
+++ b/src/object.c
@@ -4,6 +4,14 @@
#include "p11-tests.h"
#include <stdlib.h>
+#include <string.h>
+
+/* An very likey to be invalid attribute */
+#define CKA_INVALID (CKA_VENDOR_DEFINED | 0x00FFFFFF)
+
+/* ----------------------------------------------------------------------------------
+ * TESTS
+ */
static void
create_object(CK_SESSION_HANDLE session_rw, CK_SESSION_HANDLE session_ro)
@@ -30,7 +38,7 @@ destroy_object(CK_SESSION_HANDLE session_rw, CK_SESSION_HANDLE session_ro)
}
static void
-find_all_objects(CK_SESSION_HANDLE session)
+find_objects(CK_SESSION_HANDLE session)
{
CK_OBJECT_HANDLE_PTR objects;
CK_OBJECT_HANDLE extra;
@@ -138,7 +146,185 @@ find_all_objects(CK_SESSION_HANDLE session)
rv = (p11t_module_funcs->C_FindObjects)(session, &extra, 1, &count);
p11t_check_returns("C_FindObjectsFinal: extra call", rv, CKR_OPERATION_NOT_INITIALIZED);
}
+}
+
+static void
+test_get_attribute_value(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object)
+{
+ CK_OBJECT_CLASS klass;
+ CK_ATTRIBUTE attrs[4];
+ CK_BYTE buffer[8];
+ CK_BBOOL bools[3];
+ CK_RV rv;
+
+ assert(p11t_module_funcs);
+
+ /** C_GetAttributeValue */
+
+ attrs[0].type = CKA_CLASS;
+
+ if(p11t_test_unexpected)
+ {
+ /** - Invalid session */
+ rv = (p11t_module_funcs->C_GetAttributeValue)((CK_SESSION_HANDLE)-57, object, attrs, 1);
+ p11t_check_returns("C_GetAttributeValue: invalid session", rv, CKR_SESSION_HANDLE_INVALID);
+
+ /** - Invalid object */
+ rv = (p11t_module_funcs->C_GetAttributeValue)(session, (CK_OBJECT_HANDLE)-58, attrs, 1);
+ p11t_check_returns("C_GetAttributeValue: invalid object", rv, CKR_OBJECT_HANDLE_INVALID);
+
+ /** - No template */
+ rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, NULL, 0);
+ p11t_check_returns("C_GetAttributeValue: no template", rv, CKR_ARGUMENTS_BAD);
+
+ /** - Buffer too small */
+ attrs[0].pValue = buffer;
+ attrs[0].ulValueLen = 2;
+ rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, attrs, 1);
+ p11t_check_returns("C_GetAttributeValue: buffer too small", rv, CKR_BUFFER_TOO_SMALL);
+ p11t_check_ulong("C_GetAttributeValue: should return size", attrs[0].ulValueLen, sizeof(CK_OBJECT_CLASS));
+ }
+
+ /** - Retrieve attribute length */
+ attrs[0].pValue = NULL;
+ attrs[0].ulValueLen = 0;
+ rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, attrs, 1);
+ p11t_check_returns("C_GetAttributeValue: get size", rv, CKR_OK);
+ p11t_check_ulong("C_GetAttributeValue: size of class", attrs[0].ulValueLen, sizeof(CK_OBJECT_CLASS));
+
+ /** - Retrieve single attribute */
+ attrs[0].pValue = buffer;
+ rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, attrs, 1);
+ p11t_check_returns("C_GetAttributeValue: get object", rv, CKR_OK);
+ /* The actual class of this object */
+ klass = *((CK_OBJECT_CLASS*)attrs[0].pValue);
+
+ if(p11t_test_unexpected)
+ {
+ /*
+ * Now we do a bit of testing to retrieve a valid and invalid attribute
+ * at the same time.
+ */
+
+ attrs[0].type = CKA_INVALID;
+ attrs[1].type = CKA_CLASS;
+ attrs[0].ulValueLen = attrs[1].ulValueLen = 0;
+ attrs[0].pValue = attrs[0].pValue = NULL;
+
+ /** - With one invalid attribute, no buffer. */
+ rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, attrs, 2);
+ p11t_check_returns("C_GetAttributeValue: with one invalid attribute", rv, CKR_ATTRIBUTE_TYPE_INVALID);
+ p11t_check_ulong("C_GetAttributeValue: should set invalid attribute to -1", attrs[0].ulValueLen, CK_INVALID);
+ p11t_check_ulong("C_GetAttributeValue: should set valid attribute to size", attrs[1].ulValueLen, sizeof(CK_OBJECT_CLASS));
+
+ /** - With one invalid attribute, with buffer. */
+ attrs[1].pValue = buffer;
+ rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, attrs, 2);
+ p11t_check_returns("C_GetAttributeValue: with one invalid attribute, buffer", rv, CKR_ATTRIBUTE_TYPE_INVALID);
+ p11t_check_ulong("C_GetAttributeValue: should set invalid attribute to -1", attrs[0].ulValueLen, CK_INVALID);
+ p11t_check_ulong("C_GetAttributeValue: should set valid attribute to size", attrs[1].ulValueLen, sizeof(CK_OBJECT_CLASS));
+ p11t_check_ulong("C_GetAttributeValue: should set valid attribute", *((CK_OBJECT_CLASS*)attrs[1].pValue), klass);
+ }
+
+ /*
+ * Now we do a bit of testing of other attributes and retrieving sets.
+ * Since we can't list which attributes an object has, we only
+ * work with 'storage' type attributes and their standard 4 attributes.
+ */
+
+ switch(klass)
+ {
+ case CKO_CERTIFICATE:
+ case CKO_DATA:
+ case CKO_PRIVATE_KEY:
+ case CKO_PUBLIC_KEY:
+ case CKO_SECRET_KEY:
+ break;
+ default:
+ return;
+ }
+
+ memset(attrs, 0, sizeof(attrs));
+ attrs[0].type = CKA_CLASS;
+ attrs[1].type = CKA_TOKEN;
+ attrs[2].type = CKA_PRIVATE;
+ attrs[3].type = CKA_MODIFIABLE;
+ attrs[4].type = CKA_LABEL;
+
+ /** - Multiple attributes, no buffer. */
+ rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, attrs, 5);
+ p11t_check_returns("C_GetAttributeValue: multiple attrs, no buffer", rv, CKR_OK);
+ p11t_check_ulong("C_GetAttributeValue: CKA_CLASS size", attrs[0].ulValueLen, sizeof(CK_OBJECT_CLASS));
+ p11t_check_ulong("C_GetAttributeValue: CKA_TOKEN size", attrs[1].ulValueLen, sizeof(CK_BBOOL));
+ p11t_check_ulong("C_GetAttributeValue: CKA_PRIVATE size", attrs[2].ulValueLen, sizeof(CK_BBOOL));
+ p11t_check_ulong("C_GetAttributeValue: CKA_MODIFIABLE size", attrs[3].ulValueLen, sizeof(CK_BBOOL));
+
+ if(attrs[4].ulValueLen)
+ attrs[4].pValue = malloc(attrs[4].ulValueLen);
+ attrs[3].pValue = &bools[0];
+ attrs[2].pValue = &bools[1];
+ attrs[1].pValue = &bools[2];
+
+ if(p11t_test_unexpected)
+ {
+ /** - Multiple attributes, some buffers */
+ rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, attrs, 5);
+ p11t_check_returns("C_GetAttributeValue: multiple attrs, some buffer", rv, CKR_OK);
+ p11t_check_ulong("C_GetAttributeValue: CKA_CLASS no buffer, size", attrs[0].ulValueLen, sizeof(CK_OBJECT_CLASS));
+ p11t_check_bool("C_GetAttributeValue: CKA_TOKEN", *((CK_BBOOL*)attrs[1].pValue));
+ p11t_check_bool("C_GetAttributeValue: CKA_PRIVATE", *((CK_BBOOL*)attrs[2].pValue));
+ p11t_check_bool("C_GetAttributeValue: CKA_MODIFIABLE", *((CK_BBOOL*)attrs[3].pValue));
+
+ attrs[0].pValue = buffer;
+ attrs[0].ulValueLen = 2;
+
+ /** - Multiple attributes, one small buffer */
+ rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, attrs, 5);
+ p11t_check_returns("C_GetAttributeValue: multiple attrs, one small buffer", rv, CKR_BUFFER_TOO_SMALL);
+ p11t_check_ulong("C_GetAttributeValue: CKA_CLASS no buffer, size", attrs[0].ulValueLen, sizeof(CK_OBJECT_CLASS));
+ p11t_check_bool("C_GetAttributeValue: CKA_TOKEN", *((CK_BBOOL*)attrs[1].pValue));
+ p11t_check_bool("C_GetAttributeValue: CKA_PRIVATE", *((CK_BBOOL*)attrs[2].pValue));
+ p11t_check_bool("C_GetAttributeValue: CKA_MODIFIABLE", *((CK_BBOOL*)attrs[3].pValue));
+ }
+
+ attrs[0].pValue = buffer;
+ attrs[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
+
+ /** - Multiple attributes, with buffers */
+ rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, attrs, 5);
+ p11t_check_returns("C_GetAttributeValue: multiple attrs, with buffers", rv, CKR_OK);
+ p11t_check_ulong("C_GetAttributeValue: CKA_CLASS no buffer, size", attrs[0].ulValueLen, sizeof(CK_OBJECT_CLASS));
+ p11t_check_ulong("C_GetAttributeValue: CKA_CLASS value", *((CK_ULONG*)attrs[0].pValue), klass);
+ p11t_check_bool("C_GetAttributeValue: CKA_TOKEN", *((CK_BBOOL*)attrs[1].pValue));
+ p11t_check_bool("C_GetAttributeValue: CKA_PRIVATE", *((CK_BBOOL*)attrs[2].pValue));
+ p11t_check_bool("C_GetAttributeValue: CKA_MODIFIABLE", *((CK_BBOOL*)attrs[3].pValue));
+ p11t_check_string("C_GetAttributeValue: CKA_LABEL", attrs[4].pValue, attrs[4].ulValueLen);
+}
+
+static void
+test_objects(CK_SESSION_HANDLE session)
+{
+ CK_OBJECT_HANDLE_PTR objects;
+ CK_ULONG n_objects;
+ CK_ULONG i;
+
+ assert(p11t_module_funcs);
+
+ objects = p11t_object_find(session, NULL, 0, &n_objects);
+ if(!objects || !n_objects)
+ return;
+
+ for(i = 0; i < n_objects; ++i)
+ {
+ /** C_GetObjectSize */
+
+ /** - Not Implemented */
+
+ test_get_attribute_value(session, objects[i]);
+ }
+
+ free (objects);
}
void
@@ -157,14 +343,16 @@ p11t_object_tests(void)
if(session_ro == CK_INVALID)
continue;
- if(p11t_session_login(session_ro))
- continue;
+ find_objects(session_ro);
+ test_objects(session_ro);
- find_all_objects(session_ro);
+ if(!p11t_session_login(session_ro))
+ continue;
if(session_rw != CK_INVALID)
{
- find_all_objects(session_rw);
+ find_objects(session_rw);
+ test_objects(session_rw);
create_object(session_rw, session_ro);
copy_object(session_rw, session_ro);
destroy_object(session_rw, session_ro);
@@ -173,3 +361,49 @@ p11t_object_tests(void)
p11t_session_close_all(p11t_slot_ids[i]);
}
}
+
+/* ----------------------------------------------------------------------------------
+ * METHODS
+ */
+
+CK_OBJECT_HANDLE_PTR
+p11t_object_find(CK_SESSION_HANDLE session, CK_ATTRIBUTE_PTR attrs,
+ CK_ULONG n_attrs, CK_ULONG_PTR n_objects)
+{
+ CK_OBJECT_HANDLE_PTR objects;
+ CK_OBJECT_HANDLE dummy_obj;
+ CK_ATTRIBUTE dummy_attr;
+ CK_ULONG count;
+
+ assert(p11t_module_funcs);
+
+ if(!attrs)
+ attrs = &dummy_attr;
+
+ if((p11t_module_funcs->C_FindObjectsInit)(session, attrs, n_attrs) != CKR_OK)
+ return NULL;
+
+ if((p11t_module_funcs->C_FindObjects)(session, &dummy_obj, 0, &count) != CKR_OK)
+ return NULL;
+
+ if(!count)
+ return NULL;
+
+ objects = calloc(count, sizeof(CK_OBJECT_HANDLE));
+ assert(objects);
+
+ if((p11t_module_funcs->C_FindObjects)(session, objects, count, n_objects) != CKR_OK)
+ {
+ free(objects);
+ return NULL;
+ }
+
+ if((p11t_module_funcs->C_FindObjectsFinal)(session) != CKR_OK)
+ {
+ free(objects);
+ return NULL;
+ }
+
+ return objects;
+}
+
diff --git a/src/p11-tests.h b/src/p11-tests.h
index d30e1cc..1118e92 100644
--- a/src/p11-tests.h
+++ b/src/p11-tests.h
@@ -44,6 +44,10 @@ 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);
+int p11t_check_bool(const char *message, CK_BBOOL value);
+
+int p11t_check_string(const char *message, CK_UTF8CHAR_PTR value, CK_ULONG length);
+
/* -------------------------------------------------------------------
* config.c
*/
@@ -69,6 +73,9 @@ void 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);
+
void p11t_object_tests(void);
/* -------------------------------------------------------------------
diff --git a/src/session.c b/src/session.c
index 51bc050..45faaa3 100644
--- a/src/session.c
+++ b/src/session.c
@@ -8,6 +8,20 @@
static const char *login_user_pin = NULL;
static const char *login_so_pin = NULL;
+
+void
+p11t_session_config(const char *name, const char *value)
+{
+ if(strcmp(name, "login-user-pin") == 0)
+ login_user_pin = value;
+ if(strcmp(name, "login-so-pin") == 0)
+ login_so_pin = value;
+}
+
+/* ----------------------------------------------------------------------------------
+ * TESTS
+ */
+
void
session_info(CK_SESSION_HANDLE session, CK_SLOT_ID slot, CK_FLAGS flags, CK_STATE state)
{
@@ -343,6 +357,10 @@ p11t_session_tests()
}
}
+/* ----------------------------------------------------------------------------------
+ * METHODS
+ */
+
CK_SESSION_HANDLE
p11t_session_open(CK_SLOT_ID slot, int readwrite)
{
@@ -442,13 +460,3 @@ p11t_session_close_all(CK_SLOT_ID slot)
return 1;
return 0;
}
-
-void
-p11t_session_config(const char *name, const char *value)
-{
- if(strcmp(name, "login-user-pin") == 0)
- login_user_pin = value;
- if(strcmp(name, "login-so-pin") == 0)
- login_so_pin = value;
-}
-
diff --git a/src/slot.c b/src/slot.c
index 6919846..2c1353a 100644
--- a/src/slot.c
+++ b/src/slot.c
@@ -17,6 +17,10 @@ CK_TOKEN_INFO_PTR p11t_slot_token_info = NULL;
CK_ULONG *p11t_slot_mech_count;
CK_MECHANISM_INFO_PTR *p11t_slot_mech_info;
+/* ----------------------------------------------------------------------------------
+ * TESTS
+ */
+
void
slot_global(void)
{
@@ -394,6 +398,10 @@ p11t_slot_tests(void)
slot_mechanisms();
}
+/* ----------------------------------------------------------------------------------
+ * METHODS
+ */
+
CK_TOKEN_INFO_PTR
p11t_slot_get_token_info(CK_SLOT_ID slot)
{