4866a500c9
- Added ocki-3.8.2-Fix-Hardware-Feature-Object-validation-and-tests.patch (bsc#1086678) OBS-URL: https://build.opensuse.org/request/show/597601 OBS-URL: https://build.opensuse.org/package/show/security/openCryptoki?expand=0&rev=76
966 lines
33 KiB
Diff
966 lines
33 KiB
Diff
From f55886b7fae14a7a13c2a532224584de51d6ad84 Mon Sep 17 00:00:00 2001
|
|
From: Eduardo Barretto <ebarretto@linux.vnet.ibm.com>
|
|
Date: Thu, 8 Mar 2018 15:12:20 -0300
|
|
Subject: [PATCH 1/3] Fix Hardware Feature Object validation and tests
|
|
|
|
Monotonic Counters have read-only attributes. If during CreateObject the
|
|
supplied template specifies a value for any of the read-only attributes,
|
|
then the attempt should fail with the error code CKR_ATTRIBUTE_READ_ONLY.
|
|
Fixed tests that created Monotonic counters objects.
|
|
|
|
Signed-off-by: Eduardo Barretto <ebarretto@linux.vnet.ibm.com>
|
|
---
|
|
testcases/misc_tests/obj_mgmt.c | 451 ++++++++++++++++++++--------------------
|
|
testcases/pkcs11/hw_fn.c | 413 ++++++++++++++++++------------------
|
|
usr/lib/pkcs11/common/hwf_obj.c | 4 +-
|
|
3 files changed, 444 insertions(+), 424 deletions(-)
|
|
|
|
diff --git a/testcases/misc_tests/obj_mgmt.c b/testcases/misc_tests/obj_mgmt.c
|
|
index 3ab0d03a..bc875c7c 100644
|
|
--- a/testcases/misc_tests/obj_mgmt.c
|
|
+++ b/testcases/misc_tests/obj_mgmt.c
|
|
@@ -1162,251 +1162,260 @@ CK_RV do_CreateTokenObjects(void)
|
|
}
|
|
|
|
/*
|
|
- * do_HW_Feature_Search Test:
|
|
+ * do_HWFeatureSearch Test:
|
|
*
|
|
- * 1. Create 5 objects, 3 of which are HW_FEATURE objects.
|
|
+ * 1. Create 4 objects, 2 of which are HW_FEATURE objects (1 of them is a
|
|
+ * monotonic counter).
|
|
* 2. Search for objects using a template that does not have its
|
|
* HW_FEATURE attribute set.
|
|
* 3. Result should be that the other 2 objects are returned, and
|
|
* not the HW_FEATURE objects.
|
|
* 4. Search for objects using a template that does have its
|
|
* HW_FEATURE attribute set.
|
|
- * 5. Result should be that the 3 hardware feature objects are returned.
|
|
+ * 5. Result should be that the only hardware feature objects that is not a
|
|
+ * monotonic counter should be returned.
|
|
*
|
|
*/
|
|
-
|
|
CK_RV do_HWFeatureSearch(void)
|
|
{
|
|
- unsigned int i;
|
|
- CK_RV rc, loc_rc;
|
|
- CK_ULONG find_count;
|
|
- CK_SLOT_ID slot_id;
|
|
- CK_BBOOL false = FALSE;
|
|
- CK_BBOOL true = TRUE;
|
|
-
|
|
- CK_SESSION_HANDLE h_session;
|
|
- CK_BYTE user_pin[PKCS11_MAX_PIN_LEN];
|
|
- CK_ULONG user_pin_len;
|
|
-
|
|
- /* A counter object */
|
|
- CK_OBJECT_CLASS counter1_class = CKO_HW_FEATURE;
|
|
- CK_HW_FEATURE_TYPE feature1_type = CKH_MONOTONIC_COUNTER;
|
|
- CK_UTF8CHAR counter1_label[] = "Monotonic counter";
|
|
- CK_CHAR counter1_value[16];
|
|
- CK_ATTRIBUTE counter1_template[] = {
|
|
- {CKA_CLASS, &counter1_class, sizeof(counter1_class)},
|
|
- {CKA_HW_FEATURE_TYPE, &feature1_type, sizeof(feature1_type)},
|
|
- {CKA_LABEL, counter1_label, sizeof(counter1_label)-1},
|
|
- {CKA_VALUE, counter1_value, sizeof(counter1_value)},
|
|
- {CKA_RESET_ON_INIT, &true, sizeof(true)},
|
|
- {CKA_HAS_RESET, &false, sizeof(false)}
|
|
- };
|
|
- /* A clock object */
|
|
- CK_OBJECT_CLASS clock_class = CKO_HW_FEATURE;
|
|
- CK_HW_FEATURE_TYPE clock_type = CKH_CLOCK;
|
|
- CK_UTF8CHAR clock_label[] = "Clock";
|
|
- CK_CHAR clock_value[16];
|
|
- CK_ATTRIBUTE clock_template[] = {
|
|
- {CKA_CLASS, &clock_class, sizeof(clock_class)},
|
|
- {CKA_HW_FEATURE_TYPE, &clock_type, sizeof(clock_type)},
|
|
- {CKA_LABEL, clock_label, sizeof(clock_label)-1},
|
|
- {CKA_VALUE, clock_value, sizeof(clock_value)}
|
|
- };
|
|
- /* A data object */
|
|
- CK_OBJECT_CLASS obj1_class = CKO_DATA;
|
|
- CK_UTF8CHAR obj1_label[] = "Object 1";
|
|
- CK_BYTE obj1_data[] = "Object 1's data";
|
|
- CK_ATTRIBUTE obj1_template[] = {
|
|
- {CKA_CLASS, &obj1_class, sizeof(obj1_class)},
|
|
- {CKA_TOKEN, &true, sizeof(true)},
|
|
- {CKA_LABEL, obj1_label, sizeof(obj1_label)-1},
|
|
- {CKA_VALUE, obj1_data, sizeof(obj1_data)}
|
|
- };
|
|
- /* A secret key object */
|
|
- CK_OBJECT_CLASS obj2_class = CKO_SECRET_KEY;
|
|
- CK_KEY_TYPE obj2_type = CKK_AES;
|
|
- CK_UTF8CHAR obj2_label[] = "Object 2";
|
|
- CK_BYTE obj2_data[AES_KEY_SIZE_128];
|
|
- CK_ATTRIBUTE obj2_template[] = {
|
|
- {CKA_CLASS, &obj2_class, sizeof(obj2_class)},
|
|
- {CKA_TOKEN, &true, sizeof(true)},
|
|
- {CKA_KEY_TYPE, &obj2_type, sizeof(obj2_type)},
|
|
- {CKA_LABEL, obj2_label, sizeof(obj2_label)-1},
|
|
- {CKA_VALUE, obj2_data, sizeof(obj2_data)}
|
|
- };
|
|
-
|
|
- CK_OBJECT_HANDLE h_counter1,
|
|
- h_clock,
|
|
- h_obj1,
|
|
- h_obj2,
|
|
- obj_list[10];
|
|
- CK_ATTRIBUTE find_tmpl[] = {
|
|
- {CKA_CLASS, &counter1_class, sizeof(counter1_class)}
|
|
+ unsigned int i;
|
|
+ CK_RV rc, loc_rc;
|
|
+ CK_ULONG find_count;
|
|
+ CK_SLOT_ID slot_id;
|
|
+ CK_BBOOL false = FALSE;
|
|
+ CK_BBOOL true = TRUE;
|
|
+
|
|
+ CK_SESSION_HANDLE h_session;
|
|
+ CK_BYTE user_pin[PKCS11_MAX_PIN_LEN];
|
|
+ CK_ULONG user_pin_len;
|
|
+
|
|
+ /* A counter object */
|
|
+ CK_OBJECT_CLASS counter1_class = CKO_HW_FEATURE;
|
|
+ CK_HW_FEATURE_TYPE feature1_type = CKH_MONOTONIC_COUNTER;
|
|
+ CK_UTF8CHAR counter1_label[] = "Monotonic counter";
|
|
+ CK_CHAR counter1_value[16];
|
|
+ CK_ATTRIBUTE counter1_template[] = {
|
|
+ {CKA_CLASS, &counter1_class, sizeof(counter1_class)},
|
|
+ {CKA_HW_FEATURE_TYPE, &feature1_type, sizeof(feature1_type)},
|
|
+ {CKA_LABEL, counter1_label, sizeof(counter1_label)-1},
|
|
+ {CKA_VALUE, counter1_value, sizeof(counter1_value)},
|
|
+ {CKA_RESET_ON_INIT, &true, sizeof(true)},
|
|
+ {CKA_HAS_RESET, &false, sizeof(false)}
|
|
+ };
|
|
+
|
|
+ /* A clock object */
|
|
+ CK_OBJECT_CLASS clock_class = CKO_HW_FEATURE;
|
|
+ CK_HW_FEATURE_TYPE clock_type = CKH_CLOCK;
|
|
+ CK_UTF8CHAR clock_label[] = "Clock";
|
|
+ CK_CHAR clock_value[16];
|
|
+ CK_ATTRIBUTE clock_template[] = {
|
|
+ {CKA_CLASS, &clock_class, sizeof(clock_class)},
|
|
+ {CKA_HW_FEATURE_TYPE, &clock_type, sizeof(clock_type)},
|
|
+ {CKA_LABEL, clock_label, sizeof(clock_label)-1},
|
|
+ {CKA_VALUE, clock_value, sizeof(clock_value)}
|
|
+ };
|
|
+
|
|
+ /* A data object */
|
|
+ CK_OBJECT_CLASS obj1_class = CKO_DATA;
|
|
+ CK_UTF8CHAR obj1_label[] = "Object 1";
|
|
+ CK_BYTE obj1_data[] = "Object 1's data";
|
|
+ CK_ATTRIBUTE obj1_template[] = {
|
|
+ {CKA_CLASS, &obj1_class, sizeof(obj1_class)},
|
|
+ {CKA_TOKEN, &true, sizeof(true)},
|
|
+ {CKA_LABEL, obj1_label, sizeof(obj1_label)-1},
|
|
+ {CKA_VALUE, obj1_data, sizeof(obj1_data)}
|
|
+ };
|
|
+
|
|
+ /* A secret key object */
|
|
+ CK_OBJECT_CLASS obj2_class = CKO_SECRET_KEY;
|
|
+ CK_KEY_TYPE obj2_type = CKK_AES;
|
|
+ CK_UTF8CHAR obj2_label[] = "Object 2";
|
|
+ CK_BYTE obj2_data[AES_KEY_SIZE_128];
|
|
+ CK_ATTRIBUTE obj2_template[] = {
|
|
+ {CKA_CLASS, &obj2_class, sizeof(obj2_class)},
|
|
+ {CKA_TOKEN, &true, sizeof(true)},
|
|
+ {CKA_KEY_TYPE, &obj2_type, sizeof(obj2_type)},
|
|
+ {CKA_LABEL, obj2_label, sizeof(obj2_label)-1},
|
|
+ {CKA_VALUE, obj2_data, sizeof(obj2_data)}
|
|
};
|
|
|
|
- if (skip_token_obj == TRUE) {
|
|
- testcase_notice("Skipping tests that creates token objects");
|
|
- return CKR_OK;
|
|
+ CK_OBJECT_HANDLE h_counter1,
|
|
+ h_clock,
|
|
+ h_obj1,
|
|
+ h_obj2,
|
|
+ obj_list[10];
|
|
+
|
|
+ CK_ATTRIBUTE find_tmpl[] = {
|
|
+ {CKA_CLASS, &counter1_class, sizeof(counter1_class)}
|
|
+ };
|
|
+
|
|
+ if (skip_token_obj == TRUE) {
|
|
+ testcase_notice("Skipping tests that creates token objects");
|
|
+ return CKR_OK;
|
|
+ }
|
|
+
|
|
+ slot_id = SLOT_ID;
|
|
+
|
|
+ testcase_begin("starting...");
|
|
+
|
|
+ if (get_user_pin(user_pin))
|
|
+ return CKR_FUNCTION_FAILED;
|
|
+
|
|
+ user_pin_len = (CK_ULONG)strlen((char *)user_pin);
|
|
+
|
|
+ /* Open a session with the token */
|
|
+ rc = funcs->C_OpenSession(slot_id,
|
|
+ (CKF_SERIAL_SESSION|CKF_RW_SESSION),
|
|
+ NULL_PTR,
|
|
+ NULL_PTR,
|
|
+ &h_session);
|
|
+ if (rc != CKR_OK) {
|
|
+ testcase_fail("C_OpenSession() rc = %s", p11_get_ckr(rc));
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ // Login correctly
|
|
+ rc = funcs->C_Login(h_session, CKU_USER, user_pin, user_pin_len);
|
|
+ if (rc != CKR_OK) {
|
|
+ testcase_fail("C_Login() rc = %s", p11_get_ckr(rc));
|
|
+ goto session_close;
|
|
+ }
|
|
+
|
|
+ /* Create the 4 test objects */
|
|
+ rc = funcs->C_CreateObject(h_session, obj1_template, 4, &h_obj1);
|
|
+ if (rc != CKR_OK) {
|
|
+ testcase_fail("C_CreateObject() rc = %s", p11_get_ckr(rc));
|
|
+ return rc;
|
|
+ }
|
|
+
|
|
+ rc = funcs->C_CreateObject(h_session, obj2_template, 5, &h_obj2);
|
|
+ if (rc != CKR_OK) {
|
|
+ testcase_fail("C_CreateObject() rc = %s", p11_get_ckr(rc));
|
|
+ goto destroy_1;
|
|
+ }
|
|
+
|
|
+ /* try and create a monotonic object. This should fail
|
|
+ * since it is a read only feature.
|
|
+ */
|
|
+ rc = funcs->C_CreateObject(h_session, counter1_template, 6, &h_counter1);
|
|
+ if (rc != CKR_ATTRIBUTE_READ_ONLY) {
|
|
+ testcase_fail("C_CreateObject() rc = %s", p11_get_ckr(rc));
|
|
+ goto destroy_2;
|
|
+ }
|
|
+
|
|
+ rc = funcs->C_CreateObject(h_session, clock_template, 4, &h_clock);
|
|
+ if (rc != CKR_OK) {
|
|
+ testcase_fail("C_CreateObject() rc = %s", p11_get_ckr(rc));
|
|
+ goto destroy_2;
|
|
+ }
|
|
+
|
|
+
|
|
+ /* Search for the 2 objects w/o HW_FEATURE set */
|
|
+ /* A NULL template here should return all objects in v2.01, but
|
|
+ * in v2.11, it should return all objects *except* HW_FEATURE
|
|
+ * objects.
|
|
+ */
|
|
+ rc = funcs->C_FindObjectsInit(h_session, NULL, 0);
|
|
+ if (rc != CKR_OK) {
|
|
+ testcase_fail("C_FindObjectsInit() rc = %s", p11_get_ckr(rc));
|
|
+ goto destroy;
|
|
+ }
|
|
+
|
|
+ rc = funcs->C_FindObjects(h_session, obj_list, 10, &find_count);
|
|
+ if (rc != CKR_OK) {
|
|
+ testcase_fail("C_FindObjects() rc = %s", p11_get_ckr(rc));
|
|
+ goto destroy;
|
|
+ }
|
|
+
|
|
+ /* So, we created 4 objects before here, and then searched with a NULL
|
|
+ * template, so that should return all objects except our hardware
|
|
+ * feature object
|
|
+ */
|
|
+ if (find_count != 2) {
|
|
+ testcase_fail("found %ld objects when expected 2", find_count);
|
|
+ rc = -1;
|
|
+ goto destroy;
|
|
+ }
|
|
+
|
|
+ if (obj_list[0] != h_obj1 && obj_list[0] != h_obj2) {
|
|
+ testcase_fail("found the wrong object handle");
|
|
+ rc = -1;
|
|
+ goto destroy;
|
|
+ }
|
|
+
|
|
+ if (obj_list[1] != h_obj1 && obj_list[1] != h_obj2) {
|
|
+ testcase_fail("found the wrong object handle");
|
|
+ rc = -1;
|
|
+ goto destroy;
|
|
+ }
|
|
+
|
|
+ rc = funcs->C_FindObjectsFinal(h_session);
|
|
+ if (rc != CKR_OK) {
|
|
+ testcase_fail("C_FindObjectsFinal() rc = %s", p11_get_ckr(rc));
|
|
+ goto destroy;
|
|
+ }
|
|
+
|
|
+ // Now find the hardware feature objects
|
|
+ rc = funcs->C_FindObjectsInit(h_session, find_tmpl, 1);
|
|
+ if (rc != CKR_OK) {
|
|
+ testcase_fail("C_FindObjectsInit() rc = %s", p11_get_ckr(rc));
|
|
+ goto destroy;
|
|
+ }
|
|
+
|
|
+ rc = funcs->C_FindObjects(h_session, obj_list, 10, &find_count);
|
|
+ if (rc != CKR_OK) {
|
|
+ testcase_fail("C_FindObjects() rc = %s", p11_get_ckr(rc));
|
|
+ goto destroy;
|
|
+ }
|
|
+
|
|
+ if (find_count != 1) {
|
|
+ testcase_fail("found %ld objects when expected 1", find_count);
|
|
+ funcs->C_FindObjectsFinal(h_session);
|
|
+ rc = -1;
|
|
+ goto destroy;
|
|
+ }
|
|
+
|
|
+ /* Make sure we got the right ones */
|
|
+ for (i=0; i < find_count; i++) {
|
|
+ if (obj_list[i] != h_counter1 && obj_list[i] != h_clock) {
|
|
+ testcase_fail("found the wrong object handles");
|
|
+ rc = -1;
|
|
}
|
|
+ }
|
|
|
|
- slot_id = SLOT_ID;
|
|
-
|
|
- testcase_begin("starting...");
|
|
-
|
|
- if (get_user_pin(user_pin))
|
|
- return CKR_FUNCTION_FAILED;
|
|
- user_pin_len = (CK_ULONG)strlen((char *)user_pin);
|
|
-
|
|
- /* Open a session with the token */
|
|
- if( (rc = funcs->C_OpenSession(slot_id,
|
|
- (CKF_SERIAL_SESSION|CKF_RW_SESSION),
|
|
- NULL_PTR,
|
|
- NULL_PTR,
|
|
- &h_session)) != CKR_OK ) {
|
|
- testcase_fail("C_OpenSession() rc = %s", p11_get_ckr(rc));
|
|
- goto done;
|
|
- }
|
|
-
|
|
- // Login correctly
|
|
- rc = funcs->C_Login(h_session, CKU_USER, user_pin, user_pin_len);
|
|
- if( rc != CKR_OK ) {
|
|
- testcase_fail("C_Login() rc = %s", p11_get_ckr(rc));
|
|
- goto session_close;
|
|
- }
|
|
-
|
|
- /* Create the 3 test objects */
|
|
- if( (rc = funcs->C_CreateObject(h_session, obj1_template, 4, &h_obj1)) != CKR_OK) {
|
|
- testcase_fail("C_CreateObject() rc = %s", p11_get_ckr(rc));
|
|
- return rc;
|
|
- }
|
|
-
|
|
- if( (rc = funcs->C_CreateObject(h_session, obj2_template, 5, &h_obj2)) != CKR_OK) {
|
|
- testcase_fail("C_CreateObject() rc = %s", p11_get_ckr(rc));
|
|
- goto destroy_1;
|
|
- }
|
|
-
|
|
- /* try and create a monotonic object. This should fail
|
|
- * since it is a read only feature.
|
|
- */
|
|
- if( (rc = funcs->C_CreateObject(h_session, counter1_template, 6, &h_counter1)) != CKR_ATTRIBUTE_READ_ONLY) {
|
|
- testcase_fail("C_CreateObject() rc = %s", p11_get_ckr(rc));
|
|
- goto destroy_2;
|
|
- }
|
|
-
|
|
- if( (rc = funcs->C_CreateObject(h_session, clock_template, 4, &h_clock)) != CKR_OK) {
|
|
- testcase_fail("C_CreateObject() rc = %s", p11_get_ckr(rc));
|
|
- goto destroy_2;
|
|
- }
|
|
-
|
|
-
|
|
- /* Search for the 2 objects w/o HW_FEATURE set */
|
|
-
|
|
- /* A NULL template here should return all objects in v2.01, but
|
|
- * in v2.11, it should return all objects *except* HW_FEATURE
|
|
- * objects. - KEY
|
|
- */
|
|
- rc = funcs->C_FindObjectsInit(h_session, NULL, 0 );
|
|
- if (rc != CKR_OK) {
|
|
- testcase_fail("C_FindObjectsInit() rc = %s", p11_get_ckr(rc));
|
|
- goto destroy;
|
|
- }
|
|
-
|
|
- rc = funcs->C_FindObjects(h_session, obj_list, 10, &find_count );
|
|
- if (rc != CKR_OK) {
|
|
- testcase_fail("C_FindObjects() rc = %s", p11_get_ckr(rc));
|
|
- goto destroy;
|
|
- }
|
|
-
|
|
- /* So, we created 3 objects before here, and then searched with a NULL
|
|
- * template, so that should return all objects except our hardware
|
|
- * feature object. -KEY */
|
|
- if (find_count != 2) {
|
|
- testcase_fail("found %ld objects when expected 2", find_count);
|
|
- rc = -1;
|
|
- goto destroy;
|
|
- }
|
|
-
|
|
- if (obj_list[0] != h_obj1 && obj_list[0] != h_obj2) {
|
|
- testcase_fail("found the wrong object handle");
|
|
- rc = -1;
|
|
- goto destroy;
|
|
- }
|
|
-
|
|
- if (obj_list[1] != h_obj1 && obj_list[1] != h_obj2) {
|
|
- testcase_fail("found the wrong object handle");
|
|
- rc = -1;
|
|
- goto destroy;
|
|
- }
|
|
-
|
|
- rc = funcs->C_FindObjectsFinal(h_session);
|
|
- if (rc != CKR_OK) {
|
|
- testcase_fail("C_FindObjectsFinal() rc = %s", p11_get_ckr(rc));
|
|
- goto destroy;
|
|
- }
|
|
-
|
|
-
|
|
- // Now find the hardware feature objects
|
|
- rc = funcs->C_FindObjectsInit(h_session, find_tmpl, 1 );
|
|
- if (rc != CKR_OK) {
|
|
- testcase_fail("C_FindObjectsInit() rc = %s", p11_get_ckr(rc));
|
|
- goto destroy;
|
|
- }
|
|
+ rc = funcs->C_FindObjectsFinal(h_session);
|
|
+ if (rc != CKR_OK) {
|
|
+ testcase_fail("C_FindObjectsFinal() rc = %s", p11_get_ckr(rc));
|
|
+ }
|
|
|
|
- rc = funcs->C_FindObjects(h_session, obj_list, 10, &find_count );
|
|
- if (rc != CKR_OK) {
|
|
- testcase_fail("C_FindObjects() rc = %s", p11_get_ckr(rc));
|
|
- goto destroy;
|
|
- }
|
|
-
|
|
- if (find_count != 1) {
|
|
- testcase_fail("found %ld objects when expected 1", find_count);
|
|
- funcs->C_FindObjectsFinal(h_session); // TODO: check if we really need this here
|
|
- rc = -1;
|
|
- goto destroy;
|
|
- }
|
|
-
|
|
- /* Make sure we got the right ones */
|
|
- for( i=0; i < find_count; i++) {
|
|
- if(obj_list[i] != h_counter1 &&
|
|
- obj_list[i] != h_clock)
|
|
- {
|
|
-
|
|
- testcase_fail("found the wrong object handles");
|
|
- rc = -1;
|
|
- }
|
|
- }
|
|
-
|
|
- rc = funcs->C_FindObjectsFinal(h_session );
|
|
- if (rc != CKR_OK) {
|
|
- testcase_fail("C_FindObjectsFinal() rc = %s", p11_get_ckr(rc));
|
|
- }
|
|
-
|
|
- testcase_pass("Looks okay...");
|
|
+ testcase_pass("Looks okay...");
|
|
|
|
destroy:
|
|
- /* Destroy the created objects, don't clobber the rc */
|
|
- loc_rc = funcs->C_DestroyObject(h_session, h_clock);
|
|
- if( loc_rc != CKR_OK )
|
|
- testcase_fail("C_DestroyObject() rc = %s", p11_get_ckr(loc_rc));
|
|
+ /* Destroy the created objects, don't clobber the rc */
|
|
+ loc_rc = funcs->C_DestroyObject(h_session, h_clock);
|
|
+ if (loc_rc != CKR_OK)
|
|
+ testcase_fail("C_DestroyObject() rc = %s", p11_get_ckr(loc_rc));
|
|
destroy_2:
|
|
- loc_rc = funcs->C_DestroyObject(h_session, h_obj2);
|
|
- if( loc_rc != CKR_OK )
|
|
- testcase_fail("C_DestroyObject() rc = %s", p11_get_ckr(loc_rc));
|
|
+ loc_rc = funcs->C_DestroyObject(h_session, h_obj2);
|
|
+ if (loc_rc != CKR_OK)
|
|
+ testcase_fail("C_DestroyObject() rc = %s", p11_get_ckr(loc_rc));
|
|
destroy_1:
|
|
- loc_rc = funcs->C_DestroyObject(h_session, h_obj1);
|
|
- if( loc_rc != CKR_OK )
|
|
- testcase_fail("C_DestroyObject() rc = %s", p11_get_ckr(loc_rc));
|
|
+ loc_rc = funcs->C_DestroyObject(h_session, h_obj1);
|
|
+ if (loc_rc != CKR_OK)
|
|
+ testcase_fail("C_DestroyObject() rc = %s", p11_get_ckr(loc_rc));
|
|
|
|
- loc_rc = funcs->C_Logout(h_session);
|
|
- if( loc_rc != CKR_OK )
|
|
- testcase_fail("C_Logout() rc = %s", p11_get_ckr(loc_rc));
|
|
+ loc_rc = funcs->C_Logout(h_session);
|
|
+ if (loc_rc != CKR_OK)
|
|
+ testcase_fail("C_Logout() rc = %s", p11_get_ckr(loc_rc));
|
|
|
|
session_close:
|
|
- /* Close the session */
|
|
- if( (loc_rc = funcs->C_CloseSession(h_session)) != CKR_OK )
|
|
- testcase_fail("C_CloseSession() rc = %s", p11_get_ckr(loc_rc));
|
|
+ /* Close the session */
|
|
+ loc_rc = funcs->C_CloseSession(h_session);
|
|
+ if (loc_rc != CKR_OK)
|
|
+ testcase_fail("C_CloseSession() rc = %s", p11_get_ckr(loc_rc));
|
|
+
|
|
done:
|
|
- return rc;
|
|
+ return rc;
|
|
}
|
|
|
|
CK_RV obj_mgmt_functions()
|
|
diff --git a/testcases/pkcs11/hw_fn.c b/testcases/pkcs11/hw_fn.c
|
|
index 701a6770..62632291 100644
|
|
--- a/testcases/pkcs11/hw_fn.c
|
|
+++ b/testcases/pkcs11/hw_fn.c
|
|
@@ -40,227 +40,238 @@ CK_SESSION_HANDLE sess;
|
|
/*
|
|
* do_HW_Feature_Seatch Test:
|
|
*
|
|
- * 1. Create 5 objects, 3 of which are HW_FEATURE objects.
|
|
+ * 1. Create 5 objects, 3 of which are HW_FEATURE objects (2 of them are
|
|
+ * monotonic counters).
|
|
* 2. Search for objects using a template that does not have its
|
|
* HW_FEATURE attribute set.
|
|
* 3. Result should be that the other 2 objects are returned, and
|
|
* not the HW_FEATURE objects.
|
|
* 4. Search for objects using a template that does have its
|
|
* HW_FEATURE attribute set.
|
|
- * 5. Result should be that the 3 hardware feature objects are returned.
|
|
+ * 5. Result should be that the only hardware feature objects that are not
|
|
+ * monotonic counters should be returned.
|
|
*
|
|
*/
|
|
-
|
|
int do_HW_Feature_Search(void)
|
|
{
|
|
- unsigned int i;
|
|
- CK_RV rc;
|
|
- CK_ULONG find_count;
|
|
-
|
|
- CK_BBOOL false = FALSE;
|
|
- CK_BBOOL true = TRUE;
|
|
-
|
|
- // A counter object
|
|
- CK_OBJECT_CLASS counter1_class = CKO_HW_FEATURE;
|
|
- CK_HW_FEATURE_TYPE feature1_type = CKH_MONOTONIC_COUNTER;
|
|
- CK_UTF8CHAR counter1_label[] = "Monotonic counter";
|
|
- CK_CHAR counter1_value[16];
|
|
- CK_ATTRIBUTE counter1_template[] = {
|
|
- {CKA_CLASS, &counter1_class, sizeof(counter1_class)},
|
|
- {CKA_HW_FEATURE_TYPE, &feature1_type, sizeof(feature1_type)},
|
|
- {CKA_LABEL, counter1_label, sizeof(counter1_label)-1},
|
|
- {CKA_VALUE, counter1_value, sizeof(counter1_value)},
|
|
- {CKA_RESET_ON_INIT, &true, sizeof(true)},
|
|
- {CKA_HAS_RESET, &false, sizeof(false)}
|
|
- };
|
|
- // Another counter object
|
|
- CK_OBJECT_CLASS counter2_class = CKO_HW_FEATURE;
|
|
- CK_HW_FEATURE_TYPE feature2_type = CKH_MONOTONIC_COUNTER;
|
|
- CK_UTF8CHAR counter2_label[] = "Monotonic counter";
|
|
- CK_CHAR counter2_value[16];
|
|
- CK_ATTRIBUTE counter2_template[] = {
|
|
- {CKA_CLASS, &counter2_class, sizeof(counter2_class)},
|
|
- {CKA_HW_FEATURE_TYPE, &feature2_type, sizeof(feature2_type)},
|
|
- {CKA_LABEL, counter2_label, sizeof(counter2_label)-1},
|
|
- {CKA_VALUE, counter2_value, sizeof(counter2_value)},
|
|
- {CKA_RESET_ON_INIT, &true, sizeof(true)},
|
|
- {CKA_HAS_RESET, &false, sizeof(false)}
|
|
- };
|
|
- // A clock object
|
|
- CK_OBJECT_CLASS clock_class = CKO_HW_FEATURE;
|
|
- CK_HW_FEATURE_TYPE clock_type = CKH_CLOCK;
|
|
- CK_UTF8CHAR clock_label[] = "Clock";
|
|
- CK_CHAR clock_value[16];
|
|
- CK_ATTRIBUTE clock_template[] = {
|
|
- {CKA_CLASS, &clock_class, sizeof(clock_class)},
|
|
- {CKA_HW_FEATURE_TYPE, &clock_type, sizeof(clock_type)},
|
|
- {CKA_LABEL, clock_label, sizeof(clock_label)-1},
|
|
- {CKA_VALUE, clock_value, sizeof(clock_value)}
|
|
- };
|
|
- // A data object
|
|
- CK_OBJECT_CLASS obj1_class = CKO_DATA;
|
|
- CK_UTF8CHAR obj1_label[] = "Object 1";
|
|
- CK_BYTE obj1_data[] = "Object 1's data";
|
|
- CK_ATTRIBUTE obj1_template[] = {
|
|
- {CKA_CLASS, &obj1_class, sizeof(obj1_class)},
|
|
- {CKA_TOKEN, &true, sizeof(true)},
|
|
- {CKA_LABEL, obj1_label, sizeof(obj1_label)-1},
|
|
- {CKA_VALUE, obj1_data, sizeof(obj1_data)}
|
|
- };
|
|
- // A secret key object
|
|
- CK_OBJECT_CLASS obj2_class = CKO_SECRET_KEY;
|
|
- CK_KEY_TYPE obj2_type = CKK_AES;
|
|
- CK_UTF8CHAR obj2_label[] = "Object 2";
|
|
- CK_BYTE obj2_data[AES_KEY_SIZE_128];
|
|
- CK_ATTRIBUTE obj2_template[] = {
|
|
- {CKA_CLASS, &obj2_class, sizeof(obj2_class)},
|
|
- {CKA_TOKEN, &true, sizeof(true)},
|
|
- {CKA_KEY_TYPE, &obj2_type, sizeof(obj2_type)},
|
|
- {CKA_LABEL, obj2_label, sizeof(obj2_label)-1},
|
|
- {CKA_VALUE, obj2_data, sizeof(obj2_data)}
|
|
- };
|
|
-
|
|
- CK_OBJECT_HANDLE h_counter1,
|
|
- h_counter2,
|
|
- h_clock,
|
|
- h_obj1,
|
|
- h_obj2,
|
|
- obj_list[10];
|
|
- CK_ATTRIBUTE find_tmpl[] = {
|
|
- {CKA_CLASS, &counter1_class, sizeof(counter1_class)}
|
|
- };
|
|
-
|
|
-
|
|
- /* Create the 3 test objects */
|
|
- if( (rc = funcs->C_CreateObject(sess, obj1_template, 4, &h_obj1)) != CKR_OK) {
|
|
- show_error("C_CreateObject #1", rc);
|
|
- return rc;
|
|
- }
|
|
-
|
|
- if( (rc = funcs->C_CreateObject(sess, obj2_template, 5, &h_obj2)) != CKR_OK) {
|
|
- show_error("C_CreateObject #2", rc);
|
|
- goto destroy_1;
|
|
- }
|
|
-
|
|
- if( (rc = funcs->C_CreateObject(sess, counter1_template, 6, &h_counter1)) != CKR_OK) {
|
|
- show_error("C_CreateObject #3", rc);
|
|
- goto destroy_2;
|
|
- }
|
|
-
|
|
- if( (rc = funcs->C_CreateObject(sess, counter2_template, 6, &h_counter2)) != CKR_OK) {
|
|
- show_error("C_CreateObject #4", rc);
|
|
- goto destroy_3;
|
|
- }
|
|
-
|
|
- if( (rc = funcs->C_CreateObject(sess, clock_template, 4, &h_clock)) != CKR_OK) {
|
|
- show_error("C_CreateObject #5", rc);
|
|
- goto destroy_4;
|
|
- }
|
|
-
|
|
-
|
|
- // Search for the 2 objects w/o HW_FEATURE set
|
|
- //
|
|
-
|
|
- // A NULL template here should return all objects in v2.01, but
|
|
- // in v2.11, it should return all objects *except* HW_FEATURE
|
|
- // objects. - KEY
|
|
- rc = funcs->C_FindObjectsInit( sess, NULL, 0 );
|
|
- if (rc != CKR_OK) {
|
|
- show_error(" C_FindObjectsInit #1", rc );
|
|
- goto done;
|
|
- }
|
|
-
|
|
- rc = funcs->C_FindObjects( sess, obj_list, 10, &find_count );
|
|
- if (rc != CKR_OK) {
|
|
- show_error(" C_FindObjects #1", rc );
|
|
- goto done;
|
|
- }
|
|
-
|
|
- /* So, we created 3 objects before here, and then searched with a NULL
|
|
- * template, so that should return all objects except our hardware
|
|
- * feature object. -KEY */
|
|
- if (find_count != 2) {
|
|
- printf("%s:%d ERROR: C_FindObjects #1 should have found 2 objects!\n"
|
|
- " It found %ld objects\n", __FILE__, __LINE__,
|
|
- find_count);
|
|
- rc = -1;
|
|
- goto done;
|
|
- }
|
|
-
|
|
- if (obj_list[0] != h_obj1 && obj_list[0] != h_obj2) {
|
|
- printf("%s:%d ERROR: C_FindObjects #1 found the wrong objects!\n",
|
|
- __FILE__, __LINE__);
|
|
- rc = -1;
|
|
- goto done;
|
|
- }
|
|
-
|
|
- if (obj_list[1] != h_obj1 && obj_list[1] != h_obj2) {
|
|
- printf("%s:%d ERROR: C_FindObjects #1 found the wrong objects!\n",
|
|
- __FILE__, __LINE__);
|
|
- rc = -1;
|
|
- goto done;
|
|
- }
|
|
-
|
|
- rc = funcs->C_FindObjectsFinal( sess );
|
|
- if (rc != CKR_OK) {
|
|
- show_error(" C_FindObjectsFinal #1", rc );
|
|
- goto done;
|
|
- }
|
|
-
|
|
+ unsigned int i;
|
|
+ CK_RV rc;
|
|
+ CK_ULONG find_count;
|
|
+
|
|
+ CK_BBOOL false = FALSE;
|
|
+ CK_BBOOL true = TRUE;
|
|
+
|
|
+ // A counter object
|
|
+ CK_OBJECT_CLASS counter1_class = CKO_HW_FEATURE;
|
|
+ CK_HW_FEATURE_TYPE feature1_type = CKH_MONOTONIC_COUNTER;
|
|
+ CK_UTF8CHAR counter1_label[] = "Monotonic counter";
|
|
+ CK_CHAR counter1_value[16];
|
|
+ CK_ATTRIBUTE counter1_template[] = {
|
|
+ {CKA_CLASS, &counter1_class, sizeof(counter1_class)},
|
|
+ {CKA_HW_FEATURE_TYPE, &feature1_type, sizeof(feature1_type)},
|
|
+ {CKA_LABEL, counter1_label, sizeof(counter1_label)-1},
|
|
+ {CKA_VALUE, counter1_value, sizeof(counter1_value)},
|
|
+ {CKA_RESET_ON_INIT, &true, sizeof(true)},
|
|
+ {CKA_HAS_RESET, &false, sizeof(false)}
|
|
+ };
|
|
+
|
|
+ // Another counter object
|
|
+ CK_OBJECT_CLASS counter2_class = CKO_HW_FEATURE;
|
|
+ CK_HW_FEATURE_TYPE feature2_type = CKH_MONOTONIC_COUNTER;
|
|
+ CK_UTF8CHAR counter2_label[] = "Monotonic counter";
|
|
+ CK_CHAR counter2_value[16];
|
|
+ CK_ATTRIBUTE counter2_template[] = {
|
|
+ {CKA_CLASS, &counter2_class, sizeof(counter2_class)},
|
|
+ {CKA_HW_FEATURE_TYPE, &feature2_type, sizeof(feature2_type)},
|
|
+ {CKA_LABEL, counter2_label, sizeof(counter2_label)-1},
|
|
+ {CKA_VALUE, counter2_value, sizeof(counter2_value)},
|
|
+ {CKA_RESET_ON_INIT, &true, sizeof(true)},
|
|
+ {CKA_HAS_RESET, &false, sizeof(false)}
|
|
+ };
|
|
+
|
|
+ // A clock object
|
|
+ CK_OBJECT_CLASS clock_class = CKO_HW_FEATURE;
|
|
+ CK_HW_FEATURE_TYPE clock_type = CKH_CLOCK;
|
|
+ CK_UTF8CHAR clock_label[] = "Clock";
|
|
+ CK_CHAR clock_value[16];
|
|
+ CK_ATTRIBUTE clock_template[] = {
|
|
+ {CKA_CLASS, &clock_class, sizeof(clock_class)},
|
|
+ {CKA_HW_FEATURE_TYPE, &clock_type, sizeof(clock_type)},
|
|
+ {CKA_LABEL, clock_label, sizeof(clock_label)-1},
|
|
+ {CKA_VALUE, clock_value, sizeof(clock_value)}
|
|
+ };
|
|
+
|
|
+ // A data object
|
|
+ CK_OBJECT_CLASS obj1_class = CKO_DATA;
|
|
+ CK_UTF8CHAR obj1_label[] = "Object 1";
|
|
+ CK_BYTE obj1_data[] = "Object 1's data";
|
|
+ CK_ATTRIBUTE obj1_template[] = {
|
|
+ {CKA_CLASS, &obj1_class, sizeof(obj1_class)},
|
|
+ {CKA_TOKEN, &true, sizeof(true)},
|
|
+ {CKA_LABEL, obj1_label, sizeof(obj1_label)-1},
|
|
+ {CKA_VALUE, obj1_data, sizeof(obj1_data)}
|
|
+ };
|
|
|
|
- // Now find the hardware feature objects
|
|
- rc = funcs->C_FindObjectsInit( sess, find_tmpl, 1 );
|
|
- if (rc != CKR_OK) {
|
|
- show_error(" C_FindObjectsInit #2", rc );
|
|
- goto done;
|
|
- }
|
|
-
|
|
- rc = funcs->C_FindObjects( sess, obj_list, 10, &find_count );
|
|
- if (rc != CKR_OK) {
|
|
- show_error(" C_FindObjects #2", rc );
|
|
- goto done;
|
|
- }
|
|
-
|
|
- if (find_count != 3) {
|
|
- printf("%s:%d ERROR: C_FindObjects #2 should have found 3 objects!\n"
|
|
- " It found %ld objects\n", __FILE__, __LINE__,
|
|
- find_count);
|
|
- funcs->C_FindObjectsFinal( sess );
|
|
- rc = -1;
|
|
- goto done;
|
|
- }
|
|
-
|
|
- /* Make sure we got the right ones */
|
|
- for( i=0; i < find_count; i++) {
|
|
- if( obj_list[i] != h_counter1 &&
|
|
- obj_list[i] != h_counter2 &&
|
|
- obj_list[i] != h_clock)
|
|
- {
|
|
-
|
|
- printf("%s:%d ERROR: C_FindObjects #2 found the wrong\n"
|
|
- " objects!", __FILE__, __LINE__);
|
|
- rc = -1;
|
|
- }
|
|
+ // A secret key object
|
|
+ CK_OBJECT_CLASS obj2_class = CKO_SECRET_KEY;
|
|
+ CK_KEY_TYPE obj2_type = CKK_AES;
|
|
+ CK_UTF8CHAR obj2_label[] = "Object 2";
|
|
+ CK_BYTE obj2_data[AES_KEY_SIZE_128];
|
|
+ CK_ATTRIBUTE obj2_template[] = {
|
|
+ {CKA_CLASS, &obj2_class, sizeof(obj2_class)},
|
|
+ {CKA_TOKEN, &true, sizeof(true)},
|
|
+ {CKA_KEY_TYPE, &obj2_type, sizeof(obj2_type)},
|
|
+ {CKA_LABEL, obj2_label, sizeof(obj2_label)-1},
|
|
+ {CKA_VALUE, obj2_data, sizeof(obj2_data)}
|
|
+ };
|
|
+
|
|
+ CK_OBJECT_HANDLE h_counter1,
|
|
+ h_counter2,
|
|
+ h_clock,
|
|
+ h_obj1,
|
|
+ h_obj2,
|
|
+ obj_list[10];
|
|
+
|
|
+ CK_ATTRIBUTE find_tmpl[] = {
|
|
+ {CKA_CLASS, &counter1_class, sizeof(counter1_class)}
|
|
+ };
|
|
+
|
|
+ /* Create the 5 test objects */
|
|
+ rc = funcs->C_CreateObject(sess, obj1_template, 4, &h_obj1);
|
|
+ if (rc != CKR_OK) {
|
|
+ show_error("C_CreateObject #1", rc);
|
|
+ return rc;
|
|
+ }
|
|
+
|
|
+ rc = funcs->C_CreateObject(sess, obj2_template, 5, &h_obj2);
|
|
+ if (rc != CKR_OK) {
|
|
+ show_error("C_CreateObject #2", rc);
|
|
+ goto destroy_1;
|
|
+ }
|
|
+
|
|
+ rc = funcs->C_CreateObject(sess, counter1_template, 6, &h_counter1);
|
|
+ if (rc != CKR_ATTRIBUTE_READ_ONLY) {
|
|
+ show_error("C_CreateObject #3", rc);
|
|
+ goto destroy_2;
|
|
+ }
|
|
+
|
|
+ rc = funcs->C_CreateObject(sess, counter2_template, 6, &h_counter2);
|
|
+ if (rc != CKR_ATTRIBUTE_READ_ONLY) {
|
|
+ show_error("C_CreateObject #4", rc);
|
|
+ goto destroy_3;
|
|
+ }
|
|
+
|
|
+ rc = funcs->C_CreateObject(sess, clock_template, 4, &h_clock);
|
|
+ if (rc != CKR_OK) {
|
|
+ show_error("C_CreateObject #5", rc);
|
|
+ goto destroy_4;
|
|
+ }
|
|
+
|
|
+
|
|
+ /* Search for the 2 objects w/o HW_FEATURE set
|
|
+ * A NULL template here should return all objects in v2.01, but
|
|
+ * in v2.11, it should return all objects *except* HW_FEATURE
|
|
+ * objects.
|
|
+ */
|
|
+ rc = funcs->C_FindObjectsInit(sess, NULL, 0);
|
|
+ if (rc != CKR_OK) {
|
|
+ show_error(" C_FindObjectsInit #1", rc);
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ rc = funcs->C_FindObjects(sess, obj_list, 10, &find_count);
|
|
+ if (rc != CKR_OK) {
|
|
+ show_error(" C_FindObjects #1", rc);
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ /* So, we created 5 objects before here, and then searched with a NULL
|
|
+ * template, so that should return all objects except our hardware
|
|
+ * feature object.
|
|
+ */
|
|
+ if (find_count != 2) {
|
|
+ printf("%s:%d ERROR: C_FindObjects #1 should have found 2 objects!\n"
|
|
+ " It found %ld objects\n", __FILE__, __LINE__,
|
|
+ find_count);
|
|
+ rc = -1;
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ if (obj_list[0] != h_obj1 && obj_list[0] != h_obj2) {
|
|
+ printf("%s:%d ERROR: C_FindObjects #1 found the wrong objects!\n",
|
|
+ __FILE__, __LINE__);
|
|
+ rc = -1;
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ if (obj_list[1] != h_obj1 && obj_list[1] != h_obj2) {
|
|
+ printf("%s:%d ERROR: C_FindObjects #1 found the wrong objects!\n",
|
|
+ __FILE__, __LINE__);
|
|
+ rc = -1;
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ rc = funcs->C_FindObjectsFinal(sess);
|
|
+ if (rc != CKR_OK) {
|
|
+ show_error(" C_FindObjectsFinal #1", rc);
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+
|
|
+ /* Now find the hardware feature objects (should find only 1 since monotonic
|
|
+ * counters are read-only
|
|
+ */
|
|
+ rc = funcs->C_FindObjectsInit(sess, find_tmpl, 1);
|
|
+ if (rc != CKR_OK) {
|
|
+ show_error(" C_FindObjectsInit #2", rc);
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ rc = funcs->C_FindObjects(sess, obj_list, 10, &find_count);
|
|
+ if (rc != CKR_OK) {
|
|
+ show_error(" C_FindObjects #2", rc);
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ if (find_count != 1) {
|
|
+ printf("%s:%d ERROR: C_FindObjects #2 should have found 1 object!\n"
|
|
+ " It found %ld objects\n", __FILE__, __LINE__,
|
|
+ find_count);
|
|
+ funcs->C_FindObjectsFinal(sess);
|
|
+ rc = -1;
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ /* Make sure we got the right ones */
|
|
+ for( i=0; i < find_count; i++) {
|
|
+ if (obj_list[i] != h_counter1 &&
|
|
+ obj_list[i] != h_counter2 &&
|
|
+ obj_list[i] != h_clock) {
|
|
+
|
|
+ printf("%s:%d ERROR: C_FindObjects #2 found the wrong\n"
|
|
+ " objects!", __FILE__, __LINE__);
|
|
+ rc = -1;
|
|
}
|
|
+ }
|
|
|
|
- rc = funcs->C_FindObjectsFinal( sess );
|
|
- if (rc != CKR_OK) {
|
|
- show_error(" C_FindObjectsFinal #2", rc );
|
|
- }
|
|
+ rc = funcs->C_FindObjectsFinal(sess);
|
|
+ if (rc != CKR_OK) {
|
|
+ show_error(" C_FindObjectsFinal #2", rc);
|
|
+ }
|
|
|
|
done:
|
|
- /* Destroy the created objects, don't clobber the rc */
|
|
- funcs->C_DestroyObject(sess, h_clock);
|
|
+ /* Destroy the created objects, don't clobber the rc */
|
|
+ funcs->C_DestroyObject(sess, h_clock);
|
|
destroy_4:
|
|
- funcs->C_DestroyObject(sess, h_counter2);
|
|
+ funcs->C_DestroyObject(sess, h_counter2);
|
|
destroy_3:
|
|
- funcs->C_DestroyObject(sess, h_counter1);
|
|
+ funcs->C_DestroyObject(sess, h_counter1);
|
|
destroy_2:
|
|
- funcs->C_DestroyObject(sess, h_obj2);
|
|
+ funcs->C_DestroyObject(sess, h_obj2);
|
|
destroy_1:
|
|
- funcs->C_DestroyObject(sess, h_obj1);
|
|
+ funcs->C_DestroyObject(sess, h_obj1);
|
|
|
|
- return rc;
|
|
+ return rc;
|
|
}
|
|
|
|
|
|
diff --git a/usr/lib/pkcs11/common/hwf_obj.c b/usr/lib/pkcs11/common/hwf_obj.c
|
|
index 0decc22b..2a6ac45a 100644
|
|
--- a/usr/lib/pkcs11/common/hwf_obj.c
|
|
+++ b/usr/lib/pkcs11/common/hwf_obj.c
|
|
@@ -169,8 +169,8 @@ counter_validate_attribute( TEMPLATE *tmpl, CK_ATTRIBUTE *attr, CK_ULONG mode)
|
|
case CKA_HAS_RESET:
|
|
/* Fall Through */
|
|
case CKA_RESET_ON_INIT:
|
|
- return CKR_OK;
|
|
-
|
|
+ TRACE_ERROR("%s\n", ock_err(ERR_ATTRIBUTE_READ_ONLY));
|
|
+ return CKR_ATTRIBUTE_READ_ONLY;
|
|
default:
|
|
return hwf_validate_attribute( tmpl, attr, mode );
|
|
}
|
|
--
|
|
2.13.6
|
|
|