summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dsa.c32
-rw-r--r--src/key.c372
-rw-r--r--src/p11-tests.c6
-rw-r--r--src/p11-tests.h10
-rw-r--r--src/rsa.c33
-rw-r--r--src/slot.c1
6 files changed, 452 insertions, 2 deletions
diff --git a/src/dsa.c b/src/dsa.c
index 88d755c..f7f4ee3 100644
--- a/src/dsa.c
+++ b/src/dsa.c
@@ -199,3 +199,35 @@ p11t_dsa_tests(void)
{
p11t_slot_for_each_mech(CKM_DSA, test_dsa);
}
+
+void
+p11t_dsa_test_public_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE handle)
+{
+ CK_MECHANISM_TYPE_PTR mechanisms;
+ CK_ULONG n_mechanisms, i;
+
+ mechanisms = p11t_key_get_mechanisms (session, handle, &n_mechanisms);
+ if (!mechanisms)
+ return;
+
+ for (i = 0; i < n_mechanisms; ++i)
+ test_dsa_public_key (session, handle, mechanisms[i]);
+
+ free (mechanisms);
+}
+
+void
+p11t_dsa_test_private_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE handle)
+{
+ CK_MECHANISM_TYPE_PTR mechanisms;
+ CK_ULONG n_mechanisms, i;
+
+ mechanisms = p11t_key_get_mechanisms (session, handle, &n_mechanisms);
+ if (!mechanisms)
+ return;
+
+ for (i = 0; i < n_mechanisms; ++i)
+ test_dsa_private_key (session, handle, mechanisms[i]);
+
+ free (mechanisms);
+}
diff --git a/src/key.c b/src/key.c
index 2405b36..95b0fb7 100644
--- a/src/key.c
+++ b/src/key.c
@@ -419,6 +419,345 @@ test_dsa_private(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object)
}
static int
+test_rsa_public_create(CK_SESSION_HANDLE session, CK_BBOOL token, RSA *rsa, CK_OBJECT_HANDLE_PTR result)
+{
+ CK_OBJECT_HANDLE object;
+ CK_ATTRIBUTE attrs[10];
+ CK_KEY_TYPE key_type = CKK_RSA;
+ CK_ULONG rsa_bits = 1024;
+ CK_OBJECT_CLASS klass = CKO_PUBLIC_KEY;
+ CK_RV rv;
+
+ P11T_SECTION("C_CreateObject");
+
+ /* Fill in all the attributes */
+ attrs[0].type = CKA_TOKEN;
+ attrs[0].pValue = &token;
+ attrs[0].ulValueLen = sizeof (token);
+
+ attrs[1].type = CKA_CLASS;
+ attrs[1].ulValueLen = sizeof (klass);
+ attrs[1].pValue = &klass;
+
+ attrs[2].type = CKA_LABEL;
+ attrs[2].pValue = "Test Public Key";
+ attrs[2].ulValueLen = 15;
+
+ attrs[3].type = CKA_KEY_TYPE;
+ attrs[3].pValue = &key_type;
+ attrs[3].ulValueLen = sizeof (key_type);
+
+ attrs[4].type = CKA_MODULUS_BITS;
+ attrs[4].pValue = &rsa_bits;
+ attrs[4].ulValueLen = sizeof (rsa_bits);
+
+ if(p11t_test_unexpected)
+ {
+ rv = (p11t_module_funcs->C_CreateObject)(session, attrs, 5, &object);
+ P11T_CHECK_RV("RSA Public incomplete template", rv, CKR_TEMPLATE_INCOMPLETE);
+ }
+
+ attrs[5].type = CKA_MODULUS;
+ attrs[5].ulValueLen = BN_num_bytes (rsa->n);
+ attrs[5].pValue = alloca (attrs[5].ulValueLen);
+ BN_bn2bin (rsa->n, (unsigned char*)attrs[5].pValue);
+
+ attrs[6].type = CKA_PUBLIC_EXPONENT;
+ attrs[6].ulValueLen = BN_num_bytes (rsa->e);
+ attrs[6].pValue = alloca (attrs[6].ulValueLen);
+ BN_bn2bin (rsa->e, (unsigned char*)attrs[6].pValue);
+
+ rv = (p11t_module_funcs->C_CreateObject)(session, attrs, 7, &object);
+ if (rv == CKR_TEMPLATE_INCOMPLETE)
+ return CONTINUE;
+ P11T_CHECK_RV("RSA Public Key", rv, CKR_OK);
+
+ test_rsa_public (session, object);
+
+ *result = object;
+ return CONTINUE;
+}
+
+static int
+test_rsa_private_create(CK_SESSION_HANDLE session, CK_BBOOL token, RSA *rsa, CK_OBJECT_HANDLE_PTR result)
+{
+ CK_OBJECT_HANDLE object;
+ CK_ATTRIBUTE attrs[10];
+ CK_KEY_TYPE key_type = CKK_RSA;
+ CK_OBJECT_CLASS klass = CKO_PRIVATE_KEY;
+ CK_RV rv;
+
+ P11T_SECTION("C_CreateObject");
+
+ /* Fill in all the attributes */
+ attrs[0].type = CKA_TOKEN;
+ attrs[0].pValue = &token;
+ attrs[0].ulValueLen = sizeof (token);
+
+ attrs[1].type = CKA_CLASS;
+ attrs[1].ulValueLen = sizeof (klass);
+ attrs[1].pValue = &klass;
+
+ attrs[2].type = CKA_LABEL;
+ attrs[2].pValue = "Test Private Key";
+ attrs[2].ulValueLen = 15;
+
+ attrs[3].type = CKA_KEY_TYPE;
+ attrs[3].pValue = &key_type;
+ attrs[3].ulValueLen = sizeof (key_type);
+
+ attrs[4].type = CKA_MODULUS;
+ attrs[4].ulValueLen = BN_num_bytes (rsa->n);
+ attrs[4].pValue = alloca (attrs[4].ulValueLen);
+ BN_bn2bin (rsa->n, (unsigned char*)attrs[4].pValue);
+
+ attrs[5].type = CKA_PRIVATE_EXPONENT;
+ attrs[5].ulValueLen = BN_num_bytes (rsa->d);
+ attrs[5].pValue = alloca (attrs[5].ulValueLen);
+ BN_bn2bin (rsa->d, (unsigned char*)attrs[5].pValue);
+
+ attrs[6].type = CKA_PUBLIC_EXPONENT;
+ attrs[6].ulValueLen = BN_num_bytes (rsa->e);
+ attrs[6].pValue = alloca (attrs[6].ulValueLen);
+ BN_bn2bin (rsa->e, (unsigned char*)attrs[6].pValue);
+
+ attrs[7].type = CKA_PRIME_1;
+ attrs[7].ulValueLen = BN_num_bytes (rsa->p);
+ attrs[7].pValue = alloca (attrs[7].ulValueLen);
+ BN_bn2bin (rsa->p, (unsigned char*)attrs[7].pValue);
+
+ attrs[8].type = CKA_PRIME_2;
+ attrs[8].ulValueLen = BN_num_bytes (rsa->q);
+ attrs[8].pValue = alloca (attrs[8].ulValueLen);
+ BN_bn2bin (rsa->q, (unsigned char*)attrs[8].pValue);
+
+ rv = (p11t_module_funcs->C_CreateObject)(session, attrs, 9, &object);
+ if (rv == CKR_TEMPLATE_INCOMPLETE)
+ return STOP;
+ P11T_CHECK_RV("RSA Private Key", rv, CKR_OK);
+
+ test_rsa_private (session, object);
+
+ *result = object;
+ return CONTINUE;
+}
+
+static int
+test_rsa_create(CK_SESSION_HANDLE session, CK_BBOOL token)
+{
+ CK_OBJECT_HANDLE pub, prv;
+ CK_RV rv;
+ RSA *rsa;
+
+ rsa = RSA_generate_key (1024, 17, NULL, NULL);
+ assert (rsa);
+
+ pub = prv = 0;
+ test_rsa_public_create (session, token, rsa, &pub);
+ test_rsa_private_create (session, token, rsa, &prv);
+
+ if (pub != 0)
+ p11t_rsa_test_public_key (session, pub);
+ if (prv != 0)
+ p11t_rsa_test_private_key (session, prv);
+
+ P11T_SECTION("C_DestroyObject");
+
+ rv = (p11t_module_funcs->C_DestroyObject)(session, pub);
+ P11T_CHECK_RV("RSA Public Key", rv, CKR_OK);
+
+ rv = (p11t_module_funcs->C_DestroyObject)(session, pub);
+ P11T_CHECK_RV("Deleted object", rv, CKR_OBJECT_HANDLE_INVALID);
+
+ RSA_free (rsa);
+ return CONTINUE;
+}
+
+
+static int
+test_dsa_public_create(CK_SESSION_HANDLE session, CK_BBOOL token, DSA *dsa, CK_OBJECT_HANDLE_PTR result)
+{
+ CK_OBJECT_HANDLE object;
+ CK_ATTRIBUTE attrs[10];
+ CK_KEY_TYPE key_type = CKK_DSA;
+ CK_OBJECT_CLASS klass = CKO_PUBLIC_KEY;
+ CK_RV rv;
+
+ P11T_SECTION("C_CreateObject");
+
+ /* Fill in all the attributes */
+ attrs[0].type = CKA_TOKEN;
+ attrs[0].pValue = &token;
+ attrs[0].ulValueLen = sizeof (token);
+
+ attrs[1].type = CKA_CLASS;
+ attrs[1].ulValueLen = sizeof (klass);
+ attrs[1].pValue = &klass;
+
+ attrs[2].type = CKA_LABEL;
+ attrs[2].pValue = "Test DSA Public Key";
+ attrs[2].ulValueLen = 19;
+
+ attrs[3].type = CKA_KEY_TYPE;
+ attrs[3].pValue = &key_type;
+ attrs[3].ulValueLen = sizeof (key_type);
+
+ attrs[4].type = CKA_PRIME;
+ attrs[4].ulValueLen = BN_num_bytes (dsa->p);
+ attrs[4].pValue = alloca (attrs[4].ulValueLen);
+ BN_bn2bin (dsa->p, (unsigned char*)attrs[4].pValue);
+
+ attrs[5].type = CKA_SUBPRIME;
+ attrs[5].ulValueLen = BN_num_bytes (dsa->q);
+ attrs[5].pValue = alloca (attrs[5].ulValueLen);
+ BN_bn2bin (dsa->q, (unsigned char*)attrs[5].pValue);
+
+ attrs[6].type = CKA_BASE;
+ attrs[6].ulValueLen = BN_num_bytes (dsa->g);
+ attrs[6].pValue = alloca (attrs[6].ulValueLen);
+ BN_bn2bin (dsa->g, (unsigned char*)attrs[6].pValue);
+
+ attrs[7].type = CKA_VALUE;
+ attrs[7].ulValueLen = BN_num_bytes (dsa->pub_key);
+ attrs[7].pValue = alloca (attrs[7].ulValueLen);
+ BN_bn2bin (dsa->pub_key, (unsigned char*)attrs[7].pValue);
+
+ rv = (p11t_module_funcs->C_CreateObject)(session, attrs, 8, &object);
+ if (rv == CKR_TEMPLATE_INCOMPLETE)
+ return CONTINUE;
+ P11T_CHECK_RV("DSA Public Key", rv, CKR_OK);
+
+ test_dsa_public (session, object);
+
+ *result = object;
+ return CONTINUE;
+}
+
+static int
+test_dsa_private_create(CK_SESSION_HANDLE session, CK_BBOOL token, DSA *dsa, CK_OBJECT_HANDLE_PTR result)
+{
+ CK_OBJECT_HANDLE object;
+ CK_ATTRIBUTE attrs[10];
+ CK_KEY_TYPE key_type = CKK_DSA;
+ CK_OBJECT_CLASS klass = CKO_PRIVATE_KEY;
+ CK_RV rv;
+
+ P11T_SECTION("C_CreateObject");
+
+ /* Fill in all the attributes */
+ attrs[0].type = CKA_TOKEN;
+ attrs[0].pValue = &token;
+ attrs[0].ulValueLen = sizeof (token);
+
+ attrs[1].type = CKA_CLASS;
+ attrs[1].ulValueLen = sizeof (klass);
+ attrs[1].pValue = &klass;
+
+ attrs[2].type = CKA_LABEL;
+ attrs[2].pValue = "Test DSA Private Key";
+ attrs[2].ulValueLen = 20;
+
+ attrs[3].type = CKA_KEY_TYPE;
+ attrs[3].pValue = &key_type;
+ attrs[3].ulValueLen = sizeof (key_type);
+
+ attrs[4].type = CKA_PRIME;
+ attrs[4].ulValueLen = BN_num_bytes (dsa->p);
+ attrs[4].pValue = alloca (attrs[4].ulValueLen);
+ BN_bn2bin (dsa->p, (unsigned char*)attrs[4].pValue);
+
+ attrs[5].type = CKA_SUBPRIME;
+ attrs[5].ulValueLen = BN_num_bytes (dsa->q);
+ attrs[5].pValue = alloca (attrs[5].ulValueLen);
+ BN_bn2bin (dsa->q, (unsigned char*)attrs[5].pValue);
+
+ attrs[6].type = CKA_BASE;
+ attrs[6].ulValueLen = BN_num_bytes (dsa->g);
+ attrs[6].pValue = alloca (attrs[6].ulValueLen);
+ BN_bn2bin (dsa->g, (unsigned char*)attrs[6].pValue);
+
+ attrs[7].type = CKA_VALUE;
+ attrs[7].ulValueLen = BN_num_bytes (dsa->priv_key);
+ attrs[7].pValue = alloca (attrs[7].ulValueLen);
+ BN_bn2bin (dsa->priv_key, (unsigned char*)attrs[7].pValue);
+
+ rv = (p11t_module_funcs->C_CreateObject)(session, attrs, 8, &object);
+ if (rv == CKR_TEMPLATE_INCOMPLETE)
+ return CONTINUE;
+ P11T_CHECK_RV("DSA Private Key", rv, CKR_OK);
+
+ test_dsa_private (session, object);
+
+ *result = object;
+ return CONTINUE;
+}
+
+static int
+test_dsa_create(CK_SESSION_HANDLE session, CK_BBOOL token)
+{
+ CK_OBJECT_HANDLE pub, prv;
+ CK_RV rv;
+ DSA *dsa;
+ int ret;
+
+ dsa = DSA_generate_parameters(1024, NULL, 0, NULL, NULL, NULL, NULL);
+ assert (dsa);
+ ret = DSA_generate_key (dsa);
+ assert (ret == 1);
+
+ pub = prv = 0;
+ test_dsa_public_create (session, token, dsa, &pub);
+ test_dsa_private_create (session, token, dsa, &prv);
+
+ if (pub != 0)
+ p11t_dsa_test_public_key (session, pub);
+ if (prv != 0)
+ p11t_dsa_test_private_key (session, prv);
+
+ P11T_SECTION("C_DestroyObject");
+
+ rv = (p11t_module_funcs->C_DestroyObject)(session, pub);
+ P11T_CHECK_RV("DSA Public Key", rv, CKR_OK);
+
+ DSA_free (dsa);
+ return CONTINUE;
+}
+
+static int
+test_create_unexpected(CK_SESSION_HANDLE session)
+{
+ CK_OBJECT_HANDLE object;
+ CK_ATTRIBUTE attrs[1];
+ CK_BBOOL token = CK_FALSE;
+ CK_RV rv;
+
+ if(!p11t_test_unexpected)
+ return CONTINUE;
+
+ P11T_SECTION("C_CreateObject");
+
+ /* Fill in all the attributes */
+ attrs[0].type = CKA_TOKEN;
+ attrs[0].pValue = &token;
+ attrs[0].ulValueLen = sizeof (token);
+
+ rv = (p11t_module_funcs->C_CreateObject)((CK_SESSION_HANDLE)-83, attrs, 1, &object);
+ P11T_CHECK_RV("Invalid session", rv, CKR_SESSION_HANDLE_INVALID);
+
+ rv = (p11t_module_funcs->C_CreateObject)(session, NULL, 1, &object);
+ P11T_CHECK_RV("Invalid session", rv, CKR_ARGUMENTS_BAD);
+
+ rv = (p11t_module_funcs->C_CreateObject)(session, attrs, 1, NULL);
+ P11T_CHECK_RV("Invalid session", rv, CKR_ARGUMENTS_BAD);
+
+ /* No class in the template */
+ rv = (p11t_module_funcs->C_CreateObject)(session, attrs, 1, &object);
+ P11T_CHECK_RV("Invalid session", rv, CKR_TEMPLATE_INCOMPLETE);
+
+ return CONTINUE;
+}
+
+static int
test_public_attributes(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object)
{
CK_BYTE buffer[4096];
@@ -618,6 +957,10 @@ p11t_key_tests(void)
test_dsa_public(session, object);
}
}
+
+ if(p11t_test_write_session)
+ test_create_unexpected(session);
+
free(objects);
if(p11t_session_login(session))
@@ -638,6 +981,11 @@ p11t_key_tests(void)
}
}
free(objects);
+
+ if (p11t_test_write_session) {
+ test_rsa_create (session, CK_FALSE);
+ test_dsa_create (session, CK_FALSE);
+ }
}
p11t_session_close(session);
@@ -797,3 +1145,27 @@ p11t_key_login_context_specific (CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key
pin = p11t_session_get_pin (info.slotID, CKU_CONTEXT_SPECIFIC, &n_pin);
return (p11t_module_funcs->C_Login)(session, CKU_CONTEXT_SPECIFIC, pin, n_pin);
}
+
+CK_MECHANISM_TYPE_PTR
+p11t_key_get_mechanisms(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_ULONG_PTR n_mechanisms)
+{
+ CK_ATTRIBUTE attr;
+
+ attr.type = CKA_ALLOWED_MECHANISMS;
+ attr.pValue = NULL;
+ attr.ulValueLen = 0;
+
+ if (!p11t_object_get(session, key, &attr, 1))
+ return NULL;
+
+ attr.pValue = malloc(attr.ulValueLen);
+ assert (attr.pValue);
+
+ if (!p11t_object_get (session, key, &attr, 1)) {
+ free (attr.pValue);
+ return NULL;
+ }
+
+ *n_mechanisms = attr.ulValueLen / sizeof (CK_MECHANISM_TYPE);
+ return attr.pValue;
+}
diff --git a/src/p11-tests.c b/src/p11-tests.c
index b3e72d1..900338e 100644
--- a/src/p11-tests.c
+++ b/src/p11-tests.c
@@ -10,6 +10,7 @@
#include <openssl/evp.h>
int p11t_test_unexpected = 1;
+int p11t_test_write_session = 0;
static void
usage()
@@ -24,13 +25,16 @@ main(int argc, char* argv[])
const char *config = NULL;
int ch;
- while((ch = getopt(argc, argv, "f:vz")) != -1)
+ while((ch = getopt(argc, argv, "f:svz")) != -1)
{
switch(ch)
{
case 'f':
config = optarg;
break;
+ case 's':
+ p11t_test_write_session = 1;
+ break;
case 'v':
p11t_check_verbose = 1;
break;
diff --git a/src/p11-tests.h b/src/p11-tests.h
index 53f6756..15c95b3 100644
--- a/src/p11-tests.h
+++ b/src/p11-tests.h
@@ -20,6 +20,7 @@
#define CK_INVALID ((CK_ULONG)-1)
extern int p11t_test_unexpected;
+extern int p11t_test_write_session;
/* -------------------------------------------------------------------
* certificate.c
@@ -126,6 +127,9 @@ int p11t_crypto_test_verify (CK_SESSION_HANDLE session, CK_MECHANISM_TYPE mech);
void p11t_dsa_tests(void);
+void p11t_dsa_test_public_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE handle);
+void p11t_dsa_test_private_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE handle);
+
/* -------------------------------------------------------------------
* key.c
*/
@@ -134,6 +138,8 @@ CK_OBJECT_HANDLE p11t_key_get_public(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE
CK_OBJECT_HANDLE p11t_key_get_private(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key);
+CK_MECHANISM_TYPE_PTR p11t_key_get_mechanisms(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key, CK_ULONG_PTR n_mechanisms);
+
RSA* p11t_key_export_public_rsa(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key);
DSA* p11t_key_export_public_dsa(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key);
@@ -191,7 +197,9 @@ void p11t_object_tests(void);
* rsa.c
*/
-void p11t_rsa_tests(void);
+void p11t_rsa_tests (void);
+void p11t_rsa_test_public_key (CK_SESSION_HANDLE session, CK_OBJECT_HANDLE handle);
+void p11t_rsa_test_private_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE handle);
/* -------------------------------------------------------------------
* session.c
diff --git a/src/rsa.c b/src/rsa.c
index 0ae43cb..e9ab05a 100644
--- a/src/rsa.c
+++ b/src/rsa.c
@@ -630,3 +630,36 @@ p11t_rsa_tests(void)
p11t_slot_for_each_mech(CKM_RSA_PKCS, test_rsa);
p11t_slot_for_each_mech(CKM_RSA_X_509, test_rsa);
}
+
+
+void
+p11t_rsa_test_public_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE handle)
+{
+ CK_MECHANISM_TYPE_PTR mechanisms;
+ CK_ULONG n_mechanisms, i;
+
+ mechanisms = p11t_key_get_mechanisms (session, handle, &n_mechanisms);
+ if (!mechanisms)
+ return;
+
+ for (i = 0; i < n_mechanisms; ++i)
+ test_rsa_public_key (session, handle, mechanisms[i]);
+
+ free (mechanisms);
+}
+
+void
+p11t_rsa_test_private_key(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE handle)
+{
+ CK_MECHANISM_TYPE_PTR mechanisms;
+ CK_ULONG n_mechanisms, i;
+
+ mechanisms = p11t_key_get_mechanisms (session, handle, &n_mechanisms);
+ if (!mechanisms)
+ return;
+
+ for (i = 0; i < n_mechanisms; ++i)
+ test_rsa_private_key (session, handle, mechanisms[i]);
+
+ free (mechanisms);
+}
diff --git a/src/slot.c b/src/slot.c
index 48addca..c5b01d0 100644
--- a/src/slot.c
+++ b/src/slot.c
@@ -231,6 +231,7 @@ test_slot_info(void)
P11T_SECTION("C_GetSlotList");
+ n_only = p11t_slot_count;
rv = (p11t_module_funcs->C_GetSlotList)(TRUE, only, &n_only);
P11T_CHECK_RV("Listing only tokens", rv, CKR_OK);