diff options
-rw-r--r-- | src/dsa.c | 32 | ||||
-rw-r--r-- | src/key.c | 372 | ||||
-rw-r--r-- | src/p11-tests.c | 6 | ||||
-rw-r--r-- | src/p11-tests.h | 10 | ||||
-rw-r--r-- | src/rsa.c | 33 | ||||
-rw-r--r-- | src/slot.c | 1 |
6 files changed, 452 insertions, 2 deletions
@@ -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); +} @@ -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 @@ -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); +} @@ -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); |