summaryrefslogtreecommitdiff
path: root/src/object.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/object.c')
-rw-r--r--src/object.c244
1 files changed, 239 insertions, 5 deletions
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;
+}
+