From c99cd6c23327788196dd96eb7b6a1718546a4cf0 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Tue, 9 Dec 2008 17:13:39 +0000 Subject: Add testing of key objects. --- src/certificate.c | 33 ++-- src/key.c | 497 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/object.c | 47 ++++++ src/p11-tests.c | 1 + src/p11-tests.h | 4 + src/slot.c | 18 ++ 6 files changed, 590 insertions(+), 10 deletions(-) diff --git a/src/certificate.c b/src/certificate.c index acb7b37..36e6b5b 100644 --- a/src/certificate.c +++ b/src/certificate.c @@ -17,7 +17,7 @@ test_x509_name(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object, { CK_BYTE_PTR ptr, encoded; CK_ATTRIBUTE attr; - X509_NAME* name; + const char *msg; CK_RV rv; int len; @@ -40,13 +40,9 @@ test_x509_name(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object, if(rv != CKR_OK) return p11t_msg_rv(rv); - /* Let openssl parse it */ - ptr = attr.pValue; - name = d2i_X509_NAME(NULL, (const unsigned char**)&ptr, attr.ulValueLen); - if(name == NULL) - return p11t_msg_openssl(); - if(ptr - (CK_BYTE_PTR)attr.pValue != attr.ulValueLen) - return "Extra trailing bytes"; + msg = p11t_certificate_validate_dn(attr.pValue, attr.ulValueLen); + if(msg != NULL) + return msg; /* Serialize the compare one */ len = i2d_X509_NAME(compare, NULL); @@ -63,8 +59,6 @@ test_x509_name(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object, free(attr.pValue); free(encoded); - X509_NAME_free(name); - return NULL; } @@ -355,3 +349,22 @@ p11t_certificate_tests(void) p11t_session_close(session); } } + +const char* +p11t_certificate_validate_dn(CK_BYTE_PTR der, CK_ULONG n_der) +{ + CK_BYTE_PTR ptr; + X509_NAME* name; + + /* Let openssl parse it */ + ptr = der; + name = d2i_X509_NAME(NULL, (const unsigned char**)&ptr, n_der); + if(name == NULL) + return p11t_msg_openssl(); + if(ptr - der != n_der) + return "Extra trailing bytes"; + + X509_NAME_free(name); + + return NULL; +} diff --git a/src/key.c b/src/key.c index 495cff4..e37cdfe 100644 --- a/src/key.c +++ b/src/key.c @@ -1,6 +1,503 @@ #include "p11-tests.h" +/* ---------------------------------------------------------------------------------- + * TESTS + */ + +static int +test_key_attributes(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object, CK_KEY_TYPE* key_type) +{ + CK_BYTE buffer[4096]; + CK_ATTRIBUTE attr; + CK_MECHANISM_TYPE mech_type; + CK_MECHANISM_TYPE_PTR mechanisms; + CK_ULONG n_mechanisms, i; + CK_BBOOL bval, local; + CK_DATE date; + CK_RV rv; + + P11T_SECTION("Key Object"); + + attr.type = CKA_KEY_TYPE; + attr.ulValueLen = sizeof(*key_type); + attr.pValue = key_type; + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + P11T_CHECK_RV("CKA_KEY_TYPE", rv, CKR_OK); + + attr.type = CKA_ID; + attr.ulValueLen = sizeof(buffer); + attr.pValue = buffer; + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + P11T_CHECK_RV("CKA_ID", rv, CKR_OK); + + attr.type = CKA_DERIVE; + attr.ulValueLen = sizeof(bval); + attr.pValue = &bval; + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + P11T_CHECK_RV("CKA_DERIVE", rv, CKR_OK); + P11T_CHECK_BOOL("CKA_DERIVE", bval); + + if(p11t_test_unexpected) + { + attr.type = CKA_START_DATE; + attr.ulValueLen = sizeof(date); + attr.pValue = &date; + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + P11T_CHECK_RV("CKA_START_DATE", rv, CKR_OK); + if(attr.ulValueLen > 0) + P11T_CHECK_DATE("CKA_START_DATE", &date); + + attr.type = CKA_END_DATE; + attr.ulValueLen = sizeof(date); + attr.pValue = &date; + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + P11T_CHECK_RV("CKA_END_DATE", rv, CKR_OK); + if(attr.ulValueLen > 0) + P11T_CHECK_DATE("CKA_END_DATE", &date); + + attr.type = CKA_LOCAL; + attr.ulValueLen = sizeof(local); + attr.pValue = &local; + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + P11T_CHECK_RV("CKA_LOCAL", rv, CKR_OK); + P11T_CHECK_BOOL("CKA_LOCAL", local); + + attr.type = CKA_KEY_GEN_MECHANISM; + attr.ulValueLen = sizeof(mech_type); + attr.pValue = &mech_type; + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + P11T_CHECK_RV("CKA_KEY_GEN_MECHANISM", rv, CKR_OK); + + /* Key was generated with this */ + if(mech_type != CK_UNAVAILABLE_INFORMATION) + { + if(!local) + P11T_CHECK_FAIL_MSG("CKA_KEY_GEN_MECHANISM", "Non locally generated key has key gen mechanism"); + if(!p11t_slot_get_mech_info(slot, mech_type)) + P11T_CHECK_FAIL_MSG("CKA_KEY_GEN_MECHANISM", "Mechanism not present on slot"); + } + + attr.type = CKA_ALLOWED_MECHANISMS; + attr.ulValueLen = sizeof(buffer); + attr.pValue = buffer; + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + P11T_CHECK_RV("CKA_ALLOWED_MECHANISMS", rv, CKR_OK); + + if(attr.ulValueLen % sizeof(CK_MECHANISM_TYPE) != 0) + P11T_CHECK_FAIL_MSG("CKA_ALLOWED_MECHANISMS", "Invalid size memory returned"); + + mechanisms = (CK_MECHANISM_TYPE_PTR)buffer; + n_mechanisms = attr.ulValueLen / sizeof(CK_MECHANISM_TYPE); + for(i = 0; i < n_mechanisms; ++i) + { + if(!p11t_slot_get_mech_info(slot, mechanisms[i])) + P11T_CHECK_FAIL_MSG("CKA_ALLOWED_MECHANISMS", "Mechanism not present in slot"); + } + } + + return CONTINUE; +} + +static int +test_rsa_public(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object) +{ + CK_ATTRIBUTE attr; + CK_BYTE modulus[16384]; + CK_ULONG n_modulus; + CK_BYTE exponent[1024]; + CK_ULONG n_exponent; + CK_ULONG bits; + CK_RV rv; + RSA* rsa; + + P11T_SECTION("CKK_RSA Public"); + + attr.type = CKA_MODULUS; + attr.pValue = modulus; + attr.ulValueLen = sizeof(modulus); + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + P11T_CHECK_RV("CKA_MODULUS", rv, CKR_OK); + n_modulus = attr.ulValueLen; + + attr.type = CKA_PUBLIC_EXPONENT; + attr.pValue = exponent; + attr.ulValueLen = sizeof(exponent); + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + P11T_CHECK_RV("CKA_PUBLIC_EXPONENT", rv, CKR_OK); + n_exponent = attr.ulValueLen; + + attr.type = CKA_MODULUS_BITS; + attr.pValue = &bits; + attr.ulValueLen = sizeof(bits); + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + P11T_CHECK_RV("CKA_MODULUS_BITS", rv, CKR_OK); + + rsa = RSA_new(); + assert(rsa); + rsa->n = BN_bin2bn(modulus, n_modulus, NULL); + if(!rsa->n) + P11T_CHECK_FAIL_MSG("CKA_MODULUS", "Couldn't parse"); + rsa->e = BN_bin2bn(exponent, n_exponent, NULL); + if(!rsa->e) + P11T_CHECK_FAIL_MSG("CKA_PUBLIC_EXPONENT", "Couldn't parse"); + + if(RSA_size(rsa) != bits / 8) + P11T_CHECK_FAIL_MSG("CKA_MODULUS_BITS", "Does not match bits in actual modulus"); + + return CONTINUE; +} + +static int +test_rsa_private(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object) +{ + CK_ATTRIBUTE attr; + CK_BYTE buffer[32768]; + CK_RV rv; + RSA* rsa; + + P11T_SECTION("CKK_RSA Private"); + + rsa = RSA_new(); + assert(rsa); + + attr.type = CKA_MODULUS; + attr.pValue = buffer; + attr.ulValueLen = sizeof(buffer); + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + P11T_CHECK_RV("CKA_MODULUS", rv, CKR_OK); + rsa->n = BN_bin2bn(attr.pValue, attr.ulValueLen, NULL); + if(rsa->n == NULL) + P11T_CHECK_FAIL_MSG("CKA_MODULUS", p11t_msg_openssl()); + + attr.type = CKA_PRIVATE_EXPONENT; + attr.pValue = buffer; + attr.ulValueLen = sizeof(buffer); + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + if(rv == CKR_ATTRIBUTE_SENSITIVE) + return CONTINUE; + P11T_CHECK_RV("CKA_PRIVATE_EXPONENT", rv, CKR_OK); + rsa->d = BN_bin2bn(attr.pValue, attr.ulValueLen, NULL); + if(rsa->d == NULL) + P11T_CHECK_FAIL_MSG("CKA_PRIVATE_EXPONENT", p11t_msg_openssl()); + + if(p11t_test_unexpected) + { + attr.type = CKA_PUBLIC_EXPONENT; + attr.pValue = buffer; + attr.ulValueLen = sizeof(buffer); + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + if(rv != CKR_ATTRIBUTE_SENSITIVE || rv != CKR_ATTRIBUTE_TYPE_INVALID) + { + P11T_CHECK_RV("CKA_PUBLIC_EXPONENT", rv, CKR_OK); + rsa->e = BN_bin2bn(attr.pValue, attr.ulValueLen, NULL); + if(rsa->e == NULL) + P11T_CHECK_FAIL_MSG("CKA_PUBLIC_EXPONENT", p11t_msg_openssl()); + + } + + attr.type = CKA_PRIME_1; + attr.pValue = buffer; + attr.ulValueLen = sizeof(buffer); + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + if(rv != CKR_ATTRIBUTE_SENSITIVE || rv != CKR_ATTRIBUTE_TYPE_INVALID) + { + P11T_CHECK_RV("CKA_PRIME_1", rv, CKR_OK); + rsa->p = BN_bin2bn(attr.pValue, attr.ulValueLen, NULL); + if(rsa->p == NULL) + P11T_CHECK_FAIL_MSG("CKA_PRIME_1", p11t_msg_openssl()); + } + + attr.type = CKA_PRIME_2; + attr.pValue = buffer; + attr.ulValueLen = sizeof(buffer); + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + if(rv != CKR_ATTRIBUTE_SENSITIVE || rv != CKR_ATTRIBUTE_TYPE_INVALID) + { + P11T_CHECK_RV("CKA_PRIME_2", rv, CKR_OK); + rsa->q = BN_bin2bn(attr.pValue, attr.ulValueLen, NULL); + if(rsa->q == NULL) + P11T_CHECK_FAIL_MSG("CKA_PRIME_2", p11t_msg_openssl()); + } + + attr.type = CKA_EXPONENT_1; + attr.pValue = buffer; + attr.ulValueLen = sizeof(buffer); + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + if(rv != CKR_ATTRIBUTE_SENSITIVE || rv != CKR_ATTRIBUTE_TYPE_INVALID) + { + P11T_CHECK_RV("CKA_EXPONENT_1", rv, CKR_OK); + rsa->dmp1 = BN_bin2bn(attr.pValue, attr.ulValueLen, NULL); + if(rsa->dmp1 == NULL) + P11T_CHECK_FAIL_MSG("CKA_EXPONENT_1", p11t_msg_openssl()); + } + + attr.type = CKA_EXPONENT_2; + attr.pValue = buffer; + attr.ulValueLen = sizeof(buffer); + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + if(rv != CKR_ATTRIBUTE_SENSITIVE || rv != CKR_ATTRIBUTE_TYPE_INVALID) + { + P11T_CHECK_RV("CKA_EXPONENT_2", rv, CKR_OK); + rsa->dmq1 = BN_bin2bn(attr.pValue, attr.ulValueLen, NULL); + if(rsa->dmq1 == NULL) + P11T_CHECK_FAIL_MSG("CKA_EXPONENT_2", p11t_msg_openssl()); + } + + attr.type = CKA_COEFFICIENT; + attr.pValue = buffer; + attr.ulValueLen = sizeof(buffer); + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + if(rv != CKR_ATTRIBUTE_SENSITIVE || rv != CKR_ATTRIBUTE_TYPE_INVALID) + { + P11T_CHECK_RV("CKA_COEFFICIENT", rv, CKR_OK); + rsa->iqmp = BN_bin2bn(attr.pValue, attr.ulValueLen, NULL); + if(rsa->iqmp == NULL) + P11T_CHECK_FAIL_MSG("CKA_COEFFICIENT", p11t_msg_openssl()); + } + } + + /* Can we validate the key? */ + assert(rsa->n && rsa->d); + if(rsa->e && rsa->p && rsa->q) + { + int res = RSA_check_key(rsa); + if(res < 0) + P11T_CHECK_FAIL_MSG("Check RSA private key", p11t_msg_openssl()); + else if(res == 0) + P11T_CHECK_FAIL_MSG("Check RSA private key", "RSA key is not valid"); + } + + return CONTINUE; +} + +static int +test_public_attributes(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object) +{ + CK_BYTE buffer[4096]; + CK_ATTRIBUTE attr; + CK_BBOOL bval, wrap; + const char *msg; + CK_RV rv; + + P11T_SECTION("CKO_PUBLIC_KEY"); + + attr.type = CKA_SUBJECT; + attr.pValue = buffer; + attr.ulValueLen = sizeof(buffer); + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + P11T_CHECK_RV("CKA_SUBJECT", rv, CKR_OK); + + if(attr.ulValueLen) + { + msg = p11t_certificate_validate_dn(attr.pValue, attr.ulValueLen); + if(msg != NULL) + P11T_CHECK_FAIL_MSG("CKA_SUBJECT", msg); + } + + attr.type = CKA_ENCRYPT; + attr.pValue = &bval; + attr.ulValueLen = sizeof(bval); + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + P11T_CHECK_RV("CKA_ENCRYPT", rv, CKR_OK); + P11T_CHECK_BOOL("CKA_ENCRYPT", bval); + + attr.type = CKA_VERIFY; + attr.pValue = &bval; + attr.ulValueLen = sizeof(bval); + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + P11T_CHECK_RV("CKA_VERIFY", rv, CKR_OK); + P11T_CHECK_BOOL("CKA_VERIFY", bval); + + attr.type = CKA_VERIFY_RECOVER; + attr.pValue = &bval; + attr.ulValueLen = sizeof(bval); + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + P11T_CHECK_RV("CKA_VERIFY_RECOVER", rv, CKR_OK); + P11T_CHECK_BOOL("CKA_VERIFY_RECOVER", bval); + + attr.type = CKA_TRUSTED; + attr.pValue = &bval; + attr.ulValueLen = sizeof(bval); + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + P11T_CHECK_RV("CKA_TRUSTED", rv, CKR_OK); + P11T_CHECK_BOOL("CKA_TRUSTED", bval); + + attr.type = CKA_WRAP; + attr.pValue = &wrap; + attr.ulValueLen = sizeof(wrap); + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + P11T_CHECK_RV("CKA_WRAP", rv, CKR_OK); + P11T_CHECK_BOOL("CKA_WRAP", wrap); + + return CONTINUE; +} + +static int +test_private_attributes(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object) +{ + CK_BYTE buffer[4096]; + CK_ATTRIBUTE attr; + CK_BBOOL bval; + const char *msg; + CK_RV rv; + + P11T_SECTION("CKO_PRIVATE_KEY"); + + attr.type = CKA_SUBJECT; + attr.pValue = buffer; + attr.ulValueLen = sizeof(buffer); + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + P11T_CHECK_RV("CKA_SUBJECT", rv, CKR_OK); + + if(attr.ulValueLen) + { + msg = p11t_certificate_validate_dn(attr.pValue, attr.ulValueLen); + if(msg != NULL) + P11T_CHECK_FAIL_MSG("CKA_SUBJECT", msg); + } + + attr.type = CKA_SENSITIVE; + attr.pValue = &bval; + attr.ulValueLen = sizeof(bval); + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + P11T_CHECK_RV("CKA_SENSITIVE", rv, CKR_OK); + P11T_CHECK_BOOL("CKA_SENSITIVE", bval); + + attr.type = CKA_DECRYPT; + attr.pValue = &bval; + attr.ulValueLen = sizeof(bval); + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + P11T_CHECK_RV("CKA_DECRYPT", rv, CKR_OK); + P11T_CHECK_BOOL("CKA_DECRYPT", bval); + + attr.type = CKA_SIGN; + attr.pValue = &bval; + attr.ulValueLen = sizeof(bval); + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + P11T_CHECK_RV("CKA_SIGN", rv, CKR_OK); + P11T_CHECK_BOOL("CKA_SIGN", bval); + + attr.type = CKA_SIGN_RECOVER; + attr.pValue = &bval; + attr.ulValueLen = sizeof(bval); + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + P11T_CHECK_RV("CKA_SIGN_RECOVER", rv, CKR_OK); + P11T_CHECK_BOOL("CKA_SIGN_RECOVER", bval); + + attr.type = CKA_UNWRAP; + attr.pValue = &bval; + attr.ulValueLen = sizeof(bval); + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + P11T_CHECK_RV("CKA_UNWRAP", rv, CKR_OK); + P11T_CHECK_BOOL("CKA_UNWRAP", bval); + + attr.type = CKA_EXTRACTABLE; + attr.pValue = &bval; + attr.ulValueLen = sizeof(bval); + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + P11T_CHECK_RV("CKA_EXTRACTABLE", rv, CKR_OK); + P11T_CHECK_BOOL("CKA_EXTRACTABLE", bval); + + attr.type = CKA_ALWAYS_SENSITIVE; + attr.pValue = &bval; + attr.ulValueLen = sizeof(bval); + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + P11T_CHECK_RV("CKA_ALWAYS_SENSITIVE", rv, CKR_OK); + P11T_CHECK_BOOL("CKA_ALWAYS_SENSITIVE", bval); + + attr.type = CKA_NEVER_EXTRACTABLE; + attr.pValue = &bval; + attr.ulValueLen = sizeof(bval); + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + P11T_CHECK_RV("CKA_NEVER_EXTRACTABLE", rv, CKR_OK); + P11T_CHECK_BOOL("CKA_NEVER_EXTRACTABLE", bval); + + if(p11t_test_unexpected) + { + attr.type = CKA_WRAP_WITH_TRUSTED; + attr.pValue = &bval; + attr.ulValueLen = sizeof(bval); + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + P11T_CHECK_RV("CKA_WRAP_WITH_TRUSTED", rv, CKR_OK); + P11T_CHECK_BOOL("CKA_WRAP_WITH_TRUSTED", bval); + + attr.type = CKA_ALWAYS_AUTHENTICATE; + attr.pValue = &bval; + attr.ulValueLen = sizeof(bval); + rv = (p11t_module_funcs->C_GetAttributeValue)(session, object, &attr, 1); + P11T_CHECK_RV("CKA_ALWAYS_AUTHENTICATE", rv, CKR_OK); + P11T_CHECK_BOOL("CKA_ALWAYS_AUTHENTICATE", bval); + } + + return CONTINUE; +} + +void +p11t_key_tests(void) +{ + CK_OBJECT_CLASS klass; + CK_OBJECT_HANDLE_PTR objects; + CK_SESSION_HANDLE session; + CK_OBJECT_HANDLE object; + CK_ATTRIBUTE attrs[1]; + CK_ULONG j, i, n_objects; + CK_SLOT_ID slot; + CK_KEY_TYPE key_type; + + attrs[0].type = CKA_CLASS; + attrs[0].ulValueLen = sizeof(klass); + attrs[0].pValue = &klass; + + for(j = 0; j < p11t_slot_count; ++j) + { + slot = p11t_slot_get_id(j); + session = p11t_session_open(slot, 0); + if(!session) + continue; + + klass = CKO_PUBLIC_KEY; + + objects = p11t_object_find(session, attrs, 1, &n_objects); + for(i = 0; objects && i < n_objects; ++i) + { + object = objects[i]; + if(test_key_attributes(slot, session, object, &key_type)) + { + test_public_attributes(session, object); + if(key_type == CKK_RSA) + test_rsa_public(session, object); + } + } + free(objects); + + if(p11t_session_login(session)) + { + klass = CKO_PRIVATE_KEY; + + objects = p11t_object_find(session, attrs, 1, &n_objects); + for(i = 0; objects && i < n_objects; ++i) + { + object = objects[i]; + if(test_key_attributes(slot, session, object, &key_type)) + { + test_private_attributes(session, object); + if(key_type == CKK_RSA) + test_rsa_private(session, object); + } + } + free(objects); + } + + p11t_session_close(session); + } +} + + +/* ---------------------------------------------------------------------------------- + * METHODS + */ + CK_OBJECT_HANDLE find_related_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_OBJECT_CLASS klass) { diff --git a/src/object.c b/src/object.c index 1b9427a..db82fbc 100644 --- a/src/object.c +++ b/src/object.c @@ -35,6 +35,51 @@ test_destroy_object(CK_SESSION_HANDLE session_rw, CK_SESSION_HANDLE session_ro) return CONTINUE; } +static int +compar_object_handles(const void *one, const void *two) +{ + CK_OBJECT_HANDLE a = *((CK_SLOT_ID*)one); + CK_OBJECT_HANDLE b = *((CK_SLOT_ID*)two); + if(a == b) + return 0; + if(a > b) + return 1; + return -1; +} + +static int +test_find_consistent(CK_SESSION_HANDLE session) +{ + CK_OBJECT_HANDLE_PTR objects; + CK_OBJECT_HANDLE_PTR check; + CK_ULONG n_objects; + CK_ULONG i, n_check; + + objects = p11t_object_find(session, NULL, 0, &n_objects); + if(!objects) + return CONTINUE; + + qsort(objects, n_objects, sizeof(CK_OBJECT_HANDLE), compar_object_handles); + + for(i = 0; i < 10; ++i) + { + check = p11t_object_find(session, NULL, 0, &n_check); + if(check == NULL) + P11T_CHECK_FAIL_MSG("Consistently finds same objects", "no objects found"); + if(n_objects != n_check) + P11T_CHECK_FAIL_MSG("Consistently finds same objects", "wrong number of objects found"); + qsort(check, n_check, sizeof(CK_OBJECT_HANDLE), compar_object_handles); + if(memcmp(objects, check, n_check * sizeof(CK_OBJECT_HANDLE)) != 0) + P11T_CHECK_FAIL_MSG("Consistently finds same objects", "different objects found"); + + free(check); + } + + free(objects); + + return CONTINUE; +} + static int test_find_objects(CK_SESSION_HANDLE session) { @@ -311,6 +356,7 @@ p11t_object_tests(void) continue; test_find_objects(session_ro); + test_find_consistent(session_ro); test_objects(session_ro); if(!p11t_session_login(session_ro)) @@ -322,6 +368,7 @@ p11t_object_tests(void) if(session_rw != CK_INVALID) { test_find_objects(session_rw); + test_find_consistent(session_rw); test_objects(session_rw); test_create_object(session_rw, session_ro); test_copy_object(session_rw, session_ro); diff --git a/src/p11-tests.c b/src/p11-tests.c index 0d54172..7950fdd 100644 --- a/src/p11-tests.c +++ b/src/p11-tests.c @@ -63,6 +63,7 @@ main(int argc, char* argv[]) p11t_slot_tests(); p11t_session_tests(); p11t_object_tests(); + p11t_key_tests(); p11t_certificate_tests(); p11t_rsa_tests(); diff --git a/src/p11-tests.h b/src/p11-tests.h index efacace..ffca8f8 100644 --- a/src/p11-tests.h +++ b/src/p11-tests.h @@ -24,6 +24,8 @@ extern int p11t_test_unexpected; * certificate.c */ +const char* p11t_certificate_validate_dn(CK_BYTE_PTR der, CK_ULONG n_der); + void p11t_certificate_tests(void); /* ------------------------------------------------------------------- @@ -201,6 +203,8 @@ typedef void (*P11tSlotMechCallback)(CK_SLOT_ID slot, CK_MECHANISM_TYPE mech_typ void p11t_slot_for_each_mech(CK_MECHANISM_TYPE mech_type, P11tSlotMechCallback callback); +CK_MECHANISM_INFO_PTR p11t_slot_get_mech_info(CK_SLOT_ID slot, CK_MECHANISM_TYPE mech_type); + /* ------------------------------------------------------------------ * test-data.c */ diff --git a/src/slot.c b/src/slot.c index 44035e8..9658ea6 100644 --- a/src/slot.c +++ b/src/slot.c @@ -437,6 +437,24 @@ p11t_slot_get_token_info(CK_SLOT_ID slot) return NULL; } +CK_MECHANISM_INFO_PTR +p11t_slot_get_mech_info(CK_SLOT_ID slot, CK_MECHANISM_TYPE mech) +{ + int i; + CK_ULONG j; + + i = get_slot_index(slot); + assert(i >= 0); + + for(j = 0; j < slot_mech_count[i]; ++j) + { + if(mech == slot_mech_type[i][j]) + return &slot_mech_info[i][j]; + } + + return CK_FALSE; +} + void p11t_slot_for_each_mech(CK_MECHANISM_TYPE mech_type, P11tSlotMechCallback callback) -- cgit v1.2.3