diff --git a/ocki-3.8.2-Fix-Hardware-Feature-Object-validation-and-tests.patch b/ocki-3.8.2-Fix-Hardware-Feature-Object-validation-and-tests.patch new file mode 100644 index 0000000..b57b1d8 --- /dev/null +++ b/ocki-3.8.2-Fix-Hardware-Feature-Object-validation-and-tests.patch @@ -0,0 +1,965 @@ +From f55886b7fae14a7a13c2a532224584de51d6ad84 Mon Sep 17 00:00:00 2001 +From: Eduardo Barretto +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 +--- + 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 + diff --git a/openCryptoki.changes b/openCryptoki.changes index 2f77346..9fd9b9e 100644 --- a/openCryptoki.changes +++ b/openCryptoki.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Tue Apr 17 22:56:43 UTC 2018 - mpost@suse.com + +- Added ocki-3.8.2-Fix-Hardware-Feature-Object-validation-and-tests.patch + (bsc#1086678) + ------------------------------------------------------------------- Fri Mar 9 19:25:51 UTC 2018 - mpost@suse.com diff --git a/openCryptoki.spec b/openCryptoki.spec index cd62878..bb79ce6 100644 --- a/openCryptoki.spec +++ b/openCryptoki.spec @@ -65,6 +65,7 @@ Source3: openCryptoki-tmp.conf # and because we don't want(?) various file and directory permissions to be 0700. Patch1: ocki-3.1-remove-make-install-chgrp.patch Patch2: ocki-3.5-icsf-coverity-memoryleakfix.patch +Patch3: ocki-3.8.2-Fix-Hardware-Feature-Object-validation-and-tests.patch Url: https://sourceforge.net/projects/opencryptoki/ BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -145,6 +146,7 @@ Cryptographic Accelerator (FC 4960 on pSeries). %setup -q -n %{oc_cvs_tag}-%{version} %patch1 -p1 %patch2 -p1 +%patch3 -p1 cp %{SOURCE2} .