summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/certificate.c33
-rw-r--r--src/key.c497
-rw-r--r--src/object.c47
-rw-r--r--src/p11-tests.c1
-rw-r--r--src/p11-tests.h4
-rw-r--r--src/slot.c18
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
@@ -36,6 +36,51 @@ test_destroy_object(CK_SESSION_HANDLE session_rw, CK_SESSION_HANDLE session_ro)
}
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)
{
CK_OBJECT_HANDLE objects[1024];
@@ -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)