pkcs11_1000: test C_CreateObject() and C_DestroyObject()
Test C_CreateObject() and C_DestroyObject() over basic objects.
Reviewed-by: Joakim Bech <joakim.bech@linaro.org>
Co-developed-by: Etienne Carriere <etienne.carriere@linaro.org>
Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
diff --git a/host/xtest/pkcs11_1000.c b/host/xtest/pkcs11_1000.c
index 6c0a5fc..ad300e6 100644
--- a/host/xtest/pkcs11_1000.c
+++ b/host/xtest/pkcs11_1000.c
@@ -9,11 +9,17 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <util.h>
#include "xtest_test.h"
#include "xtest_helpers.h"
/*
+ * Some PKCS#11 object resources used in the tests
+ */
+static const CK_BYTE cktest_aes128_key[16];
+
+/*
* Util to find a slot on which to open a session
*/
static CK_RV close_lib(void)
@@ -827,3 +833,197 @@
ADBG_CASE_DEFINE(pkcs11, 1003, xtest_pkcs11_test_1003,
"PKCS11: Login to PKCS#11 token");
+
+static CK_ATTRIBUTE cktest_token_object[] = {
+ { CKA_DECRYPT, &(CK_BBOOL){CK_TRUE}, sizeof(CK_BBOOL) },
+ { CKA_TOKEN, &(CK_BBOOL){CK_TRUE}, sizeof(CK_BBOOL) },
+ { CKA_MODIFIABLE, &(CK_BBOOL){CK_TRUE}, sizeof(CK_BBOOL) },
+ { CKA_CLASS, &(CK_OBJECT_CLASS){CKO_SECRET_KEY},
+ sizeof(CK_OBJECT_CLASS) },
+ { CKA_KEY_TYPE, &(CK_KEY_TYPE){CKK_AES}, sizeof(CK_KEY_TYPE) },
+ { CKA_VALUE, (void *)cktest_aes128_key, sizeof(cktest_aes128_key) },
+};
+
+static CK_ATTRIBUTE cktest_session_object[] = {
+ { CKA_DECRYPT, &(CK_BBOOL){CK_TRUE}, sizeof(CK_BBOOL) },
+ { CKA_TOKEN, &(CK_BBOOL){CK_FALSE}, sizeof(CK_BBOOL) },
+ { CKA_MODIFIABLE, &(CK_BBOOL){CK_TRUE}, sizeof(CK_BBOOL) },
+ { CKA_KEY_TYPE, &(CK_KEY_TYPE){CKK_AES}, sizeof(CK_KEY_TYPE) },
+ { CKA_CLASS, &(CK_OBJECT_CLASS){CKO_SECRET_KEY},
+ sizeof(CK_OBJECT_CLASS) },
+ { CKA_VALUE, (void *)cktest_aes128_key, sizeof(cktest_aes128_key) },
+};
+
+/* Create session object and token object from a session */
+static void test_create_destroy_single_object(ADBG_Case_t *c, bool persistent)
+{
+ CK_RV rv = CKR_GENERAL_ERROR;
+ CK_SLOT_ID slot = 0;
+ CK_SESSION_HANDLE session = CK_INVALID_HANDLE;
+ CK_OBJECT_HANDLE obj_hdl = CK_INVALID_HANDLE;
+ CK_FLAGS session_flags = CKF_SERIAL_SESSION | CKF_RW_SESSION;
+
+ rv = init_lib_and_find_token_slot(&slot);
+ if (!ADBG_EXPECT_CK_OK(c, rv))
+ return;
+
+ rv = C_OpenSession(slot, session_flags, NULL, 0, &session);
+ if (!ADBG_EXPECT_CK_OK(c, rv))
+ goto out;
+
+ if (persistent) {
+ rv = C_CreateObject(session, cktest_token_object,
+ ARRAY_SIZE(cktest_token_object),
+ &obj_hdl);
+ } else {
+ rv = C_CreateObject(session, cktest_session_object,
+ ARRAY_SIZE(cktest_session_object),
+ &obj_hdl);
+ }
+
+ if (!ADBG_EXPECT_CK_OK(c, rv))
+ goto out;
+
+ rv = C_DestroyObject(session, obj_hdl);
+ ADBG_EXPECT_CK_OK(c, rv);
+out:
+ rv = C_CloseSession(session);
+ ADBG_EXPECT_CK_OK(c, rv);
+
+ rv = close_lib();
+ ADBG_EXPECT_CK_OK(c, rv);
+}
+
+static void test_create_destroy_session_objects(ADBG_Case_t *c)
+{
+ CK_RV rv = CKR_GENERAL_ERROR;
+ CK_SLOT_ID slot = 0;
+ CK_SESSION_HANDLE session = CK_INVALID_HANDLE;
+ CK_OBJECT_HANDLE obj_hdl[512] = { 0 };
+ CK_FLAGS session_flags = CKF_SERIAL_SESSION | CKF_RW_SESSION;
+ size_t n = 0;
+
+ for (n = 0; n < ARRAY_SIZE(obj_hdl); n++)
+ obj_hdl[n] = CK_INVALID_HANDLE;
+
+ rv = init_lib_and_find_token_slot(&slot);
+ if (!ADBG_EXPECT_CK_OK(c, rv))
+ return;
+
+ rv = C_OpenSession(slot, session_flags, NULL, 0, &session);
+ if (!ADBG_EXPECT_CK_OK(c, rv))
+ goto out;
+
+ for (n = 0; n < ARRAY_SIZE(obj_hdl); n++) {
+ rv = C_CreateObject(session, cktest_session_object,
+ ARRAY_SIZE(cktest_session_object),
+ obj_hdl + n);
+
+ if (rv == CKR_DEVICE_MEMORY || !ADBG_EXPECT_CK_OK(c, rv))
+ break;
+ }
+
+ Do_ADBG_Log(" created object count: %zu", n);
+
+ rv = C_CloseSession(session);
+ ADBG_EXPECT_CK_OK(c, rv);
+
+ rv = C_OpenSession(slot, session_flags, NULL, 0, &session);
+ if (!ADBG_EXPECT_CK_OK(c, rv))
+ goto out;
+
+ rv = C_CreateObject(session, cktest_session_object,
+ ARRAY_SIZE(cktest_session_object),
+ obj_hdl);
+
+ ADBG_EXPECT_CK_OK(c, rv);
+
+out:
+ rv = C_CloseSession(session);
+ ADBG_EXPECT_CK_OK(c, rv);
+
+ rv = close_lib();
+ ADBG_EXPECT_CK_OK(c, rv);
+}
+
+/* Create session object and token object from a session */
+static void test_create_objects_in_session(ADBG_Case_t *c, bool readwrite)
+{
+ CK_RV rv = CKR_GENERAL_ERROR;
+ CK_SLOT_ID slot = 0;
+ CK_SESSION_HANDLE session = CK_INVALID_HANDLE;
+ CK_OBJECT_HANDLE token_obj_hld = CK_INVALID_HANDLE;
+ CK_OBJECT_HANDLE session_obj_hld = CK_INVALID_HANDLE;
+ CK_FLAGS session_flags = CKF_SERIAL_SESSION;
+
+ rv = init_lib_and_find_token_slot(&slot);
+ if (!ADBG_EXPECT_CK_OK(c, rv))
+ return;
+
+ if (readwrite)
+ session_flags |= CKF_RW_SESSION;
+
+ rv = C_OpenSession(slot, session_flags, NULL, 0, &session);
+ if (!ADBG_EXPECT_CK_OK(c, rv))
+ goto out;
+
+ rv = C_CreateObject(session, cktest_token_object,
+ ARRAY_SIZE(cktest_token_object),
+ &token_obj_hld);
+
+ if (readwrite) {
+ if (!ADBG_EXPECT_CK_OK(c, rv))
+ goto out;
+ } else {
+ if (!ADBG_EXPECT_CK_RESULT(c, CKR_SESSION_READ_ONLY, rv))
+ goto out;
+ }
+
+ rv = C_CreateObject(session, cktest_session_object,
+ ARRAY_SIZE(cktest_session_object),
+ &session_obj_hld);
+
+ if (!ADBG_EXPECT_CK_OK(c, rv))
+ goto out_tobj;
+
+ rv = C_DestroyObject(session, session_obj_hld);
+ ADBG_EXPECT_CK_OK(c, rv);
+
+out_tobj:
+ if (readwrite) {
+ rv = C_DestroyObject(session, token_obj_hld);
+ ADBG_EXPECT_CK_OK(c, rv);
+ }
+out:
+ rv = C_CloseSession(session);
+ ADBG_EXPECT_CK_OK(c, rv);
+
+ rv = close_lib();
+ ADBG_EXPECT_CK_OK(c, rv);
+}
+
+static void xtest_pkcs11_test_1004(ADBG_Case_t *c)
+{
+ Do_ADBG_BeginSubCase(c, "Create and destroy a volatile object");
+ test_create_destroy_single_object(c, false /*!persistent*/);
+ Do_ADBG_EndSubCase(c, "Create and destroy a volatile object");
+
+ Do_ADBG_BeginSubCase(c, "Create and destroy a persistent object");
+ test_create_destroy_single_object(c, true /*persistent*/);
+ Do_ADBG_EndSubCase(c, "Create and destroy a persistent object");
+
+ Do_ADBG_BeginSubCase(c, "Create and destroy many session objects");
+ test_create_destroy_session_objects(c);
+ Do_ADBG_EndSubCase(c, "Create and destroy many session objects");
+
+ Do_ADBG_BeginSubCase(c, "Create objects in a read-only session");
+ test_create_objects_in_session(c, false /*!readwrite*/);
+ Do_ADBG_EndSubCase(c, "Create objects in a read-only session");
+
+ Do_ADBG_BeginSubCase(c, "Create objects in a read/write session");
+ test_create_objects_in_session(c, true /*readwrite*/);
+ Do_ADBG_EndSubCase(c, "Create objects in a read/write session");
+}
+
+ADBG_CASE_DEFINE(pkcs11, 1004, xtest_pkcs11_test_1004,
+ "PKCS11: create/destroy PKCS#11 simple objects");