From 8a36a9c42b6c327056ca334d556c221c28375d15 Mon Sep 17 00:00:00 2001 From: Rob Austein Date: Sat, 3 Sep 2016 02:27:09 -0400 Subject: Hack PKCS #11 to work with revised libhal pkey API. --- Makefile | 14 ++-- pkcs11.c | 249 +++++++++++++++++++++++----------------------------------- schema.sql | 4 +- unit_tests.py | 23 +++--- 4 files changed, 123 insertions(+), 167 deletions(-) diff --git a/Makefile b/Makefile index 0eb86e3..acb20f3 100644 --- a/Makefile +++ b/Makefile @@ -197,7 +197,7 @@ TAGS: *.[ch] # Basic testing, via the Python unittest library and our py11 interface code test: all - sudo python unit_tests.py + python unit_tests.py # Further testing using hsmbully, if we can find a copy of it. @@ -217,21 +217,21 @@ ifneq "${HSMBULLY}" "" bully: all set -x; \ - sudo rm -f ${HSMBULLY_DATABASE} ${HSMBULLY_DATABASE}-journal ${HSMBULLY_KS_CLIENT} ${HSMBULLY_KS_SERVER}; \ + rm -f ${HSMBULLY_DATABASE} ${HSMBULLY_DATABASE}-journal ${HSMBULLY_KS_CLIENT} ${HSMBULLY_KS_SERVER}; \ if test -x '${HSMBULLY_SERVER_BIN}'; \ then \ - sudo CRYPTECH_KEYSTORE=${HSMBULLY_KS_SERVER} ${HSMBULLY_SERVER_BIN} & \ + CRYPTECH_KEYSTORE=${HSMBULLY_KS_SERVER} ${HSMBULLY_SERVER_BIN} & \ pid=$$!; \ sleep 5; \ (echo YouReallyNeedToChangeThisPINRightNowWeAreNotKidding; echo fnord; echo fnord) | \ CRYPTECH_KEYSTORE=${HSMBULLY_KS_CLIENT} ./p11util --set-so-pin --set-user-pin --pin-from-stdin; \ PKCS11_DATABASE=${HSMBULLY_DATABASE} CRYPTECH_KEYSTORE=${HSMBULLY_KS_CLIENT} ${HSMBULLY} ${HSMBULLY_OPTIONS}; \ - sudo kill $$pid; \ + kill $$pid; \ else \ (echo YouReallyNeedToChangeThisPINRightNowWeAreNotKidding; echo fnord; echo fnord) | \ - sudo CRYPTECH_KEYSTORE=${HSMBULLY_KS_CLIENT} ./p11util --set-so-pin --set-user-pin --pin-from-stdin; \ - sudo PKCS11_DATABASE=${HSMBULLY_DATABASE} CRYPTECH_KEYSTORE=${HSMBULLY_KS_CLIENT} ${HSMBULLY} ${HSMBULLY_OPTIONS}; \ + CRYPTECH_KEYSTORE=${HSMBULLY_KS_CLIENT} ./p11util --set-so-pin --set-user-pin --pin-from-stdin; \ + PKCS11_DATABASE=${HSMBULLY_DATABASE} CRYPTECH_KEYSTORE=${HSMBULLY_KS_CLIENT} ${HSMBULLY} ${HSMBULLY_OPTIONS}; \ fi; \ - sudo rm -f ${HSMBULLY_DATABASE} ${HSMBULLY_DATABASE}-journal ${HSMBULLY_KS_CLIENT} ${HSMBULLY_KS_SERVER} + rm -f ${HSMBULLY_DATABASE} ${HSMBULLY_DATABASE}-journal ${HSMBULLY_KS_CLIENT} ${HSMBULLY_KS_SERVER} endif diff --git a/pkcs11.c b/pkcs11.c index cf354e6..a482de0 100644 --- a/pkcs11.c +++ b/pkcs11.c @@ -1474,66 +1474,31 @@ static CK_OBJECT_HANDLE p11_object_create(const p11_session_t *session, } /* - * Bind PKCS #11 objects to keystore objects. - * - * This requires storing the pkey type (supplied) and the SKI - * (calcualted from supplied public key DER) of the key. We return - * the calculated SKI so that the caller can use it as the pkey name. - * - * We don't work with pkey handles here because that would create a - * chicken-and-egg problem, given that the values calculated and - * stored by this function are what we use to look up a pkey given - * a PKCS #11 key object. + * Bind PKCS #11 objects to keystore objects, via the key's pkey type + * and UUID. */ static int p11_object_bind_pkey(const p11_session_t * const session, - const hal_key_type_t pkey_type_1, - const hal_key_type_t pkey_type_2, - const CK_OBJECT_HANDLE object_handle_1, - const CK_OBJECT_HANDLE object_handle_2, - const uint8_t * const der, const size_t der_len, - uint8_t *ski, const size_t ski_len) + const CK_OBJECT_HANDLE object_handle, + const hal_uuid_t * const pkey_uuid, + const hal_key_type_t pkey_type) { - assert(session != NULL && der != NULL && ski != NULL); + assert(session != NULL && pkey_uuid != NULL); static const char update_format[] = - " UPDATE %s_object SET hal_pkey_type = ?1, hal_pkey_ski = ?2" + " UPDATE %s_object SET hal_pkey_type = ?1, hal_pkey_uuid = ?2" " WHERE %s_object_id = (SELECT %s_object_id FROM object WHERE object_handle = ?3)"; - const char *flavor_1 = is_token_handle(object_handle_1) ? "token" : "session"; - const char *flavor_2 = is_token_handle(object_handle_2) ? "token" : "session"; - - hal_hash_handle_t hash = {HAL_HANDLE_NONE}; - - int ok = hal_check(hal_rpc_hash_initialize(p11_session_hal_client(session), - p11_session_hal_session(session), - &hash, P11_KEY_HASH_ALGORITHM, NULL, 0)); - if (ok) - ok = hal_check(hal_rpc_hash_update(hash, der, der_len)); - - if (hash.handle != HAL_HANDLE_NONE) - ok = hal_check(hal_rpc_hash_finalize(hash, ski, ski_len)) && ok; - - if (!ok) - return 0; - - sqlite3_stmt *q1 = NULL, *q2 = NULL; - - ok = (sql_check_ok(sql_prepare(&q1, update_format, flavor_1, flavor_1, flavor_1)) && - sql_check_ok(sqlite3_bind_int64(q1, 1, pkey_type_1)) && - sql_check_ok(sqlite3_bind_blob( q1, 2, ski, ski_len, NULL)) && - sql_check_ok(sqlite3_bind_int64(q1, 3, object_handle_1)) && - sql_check_done(sqlite3_step(q1))); + const char *flavor = is_token_handle(object_handle) ? "token" : "session"; + sqlite3_stmt *q = NULL; - if (ok && object_handle_2 != CK_INVALID_HANDLE) - ok = (sql_check_ok(sql_prepare(&q2, update_format, flavor_2, flavor_2, flavor_2)) && - sql_check_ok(sqlite3_bind_int64(q2, 1, pkey_type_2)) && - sql_check_ok(sqlite3_bind_blob( q2, 2, ski, ski_len, NULL)) && - sql_check_ok(sqlite3_bind_int64(q2, 3, object_handle_2)) && - sql_check_done(sqlite3_step(q2))); + int ok = (sql_check_ok(sql_prepare(&q, update_format, flavor, flavor, flavor)) && + sql_check_ok(sqlite3_bind_int64(q, 1, pkey_type)) && + sql_check_ok(sqlite3_bind_blob( q, 2, pkey_uuid, sizeof(*pkey_uuid), NULL)) && + sql_check_ok(sqlite3_bind_int64(q, 3, object_handle)) && + sql_check_done(sqlite3_step(q))); - sqlite3_finalize(q1); - sqlite3_finalize(q2); + sqlite3_finalize(q); return ok; } @@ -1556,11 +1521,9 @@ static inline int p11_object_create_rsa_public_key(const p11_session_t * const s uint8_t keybuf[hal_rsa_key_t_size]; hal_rsa_key_t *key = NULL; sqlite3_stmt *q = NULL; - size_t ski_len = 0; int ok - = (hal_check(hal_rpc_hash_get_digest_length(P11_KEY_HASH_ALGORITHM, &ski_len)) && - sql_check_ok(sql_prepare(&q, select_format, flavor, CKA_MODULUS, CKA_PUBLIC_EXPONENT)) && + = (sql_check_ok(sql_prepare(&q, select_format, flavor, CKA_MODULUS, CKA_PUBLIC_EXPONENT)) && sql_check_ok(sqlite3_bind_int64(q, 1, object_handle)) && sql_check_row(sqlite3_step(q)) && sqlite3_column_type(q, 0) == SQLITE_BLOB && @@ -1572,18 +1535,21 @@ static inline int p11_object_create_rsa_public_key(const p11_session_t * const s sqlite3_column_bytes(q, 1)))); if (ok) { - uint8_t der[hal_rsa_public_key_to_der_len(key)], ski[ski_len]; + uint8_t der[hal_rsa_public_key_to_der_len(key)]; + hal_uuid_t uuid; ok = (hal_check(hal_rsa_public_key_to_der(key, der, NULL, sizeof(der))) && - p11_object_bind_pkey(session, HAL_KEY_TYPE_RSA_PUBLIC, HAL_KEY_TYPE_NONE, - object_handle, CK_INVALID_HANDLE, - der, sizeof(der), ski, sizeof(ski)) && hal_check(hal_rpc_pkey_load(p11_session_hal_client(session), p11_session_hal_session(session), &pkey, HAL_KEY_TYPE_RSA_PUBLIC, HAL_CURVE_NONE, - ski, sizeof(ski), der, sizeof(der), flags))); + &uuid, der, sizeof(der), flags)) && + p11_object_bind_pkey(session, object_handle, &uuid, HAL_KEY_TYPE_RSA_PUBLIC)); } - (void) hal_rpc_pkey_close(pkey); + if (!ok && pkey.handle != HAL_HANDLE_NONE) + (void) hal_rpc_pkey_delete(pkey); + else + (void) hal_rpc_pkey_close(pkey); + sqlite3_finalize(q); return ok; } @@ -1604,11 +1570,9 @@ static inline int p11_object_create_ec_public_key(const p11_session_t * const se hal_ecdsa_key_t *key = NULL; hal_curve_name_t curve; sqlite3_stmt *q = NULL; - size_t ski_len = 0; int ok - = (hal_check(hal_rpc_hash_get_digest_length(P11_KEY_HASH_ALGORITHM, &ski_len)) && - sql_check_ok(sql_prepare(&q, select_format, flavor, CKA_EC_PARAMS, CKA_EC_POINT)) && + = (sql_check_ok(sql_prepare(&q, select_format, flavor, CKA_EC_PARAMS, CKA_EC_POINT)) && sql_check_ok(sqlite3_bind_int64(q, 1, object_handle)) && sql_check_row(sqlite3_step(q)) && sqlite3_column_type(q, 0) == SQLITE_BLOB && @@ -1620,18 +1584,21 @@ static inline int p11_object_create_ec_public_key(const p11_session_t * const se curve))); if (ok) { - uint8_t der[hal_ecdsa_public_key_to_der_len(key)], ski[ski_len]; + uint8_t der[hal_ecdsa_public_key_to_der_len(key)]; + hal_uuid_t uuid; ok = (hal_check(hal_ecdsa_public_key_to_der(key, der, NULL, sizeof(der))) && - p11_object_bind_pkey(session, HAL_KEY_TYPE_EC_PUBLIC, HAL_KEY_TYPE_NONE, - object_handle, CK_INVALID_HANDLE, - der, sizeof(der), ski, sizeof(ski)) && hal_check(hal_rpc_pkey_load(p11_session_hal_client(session), p11_session_hal_session(session), &pkey, HAL_KEY_TYPE_EC_PUBLIC, curve, - ski, sizeof(ski), der, sizeof(der), flags))); + &uuid, der, sizeof(der), flags)) && + p11_object_bind_pkey(session, object_handle, &uuid, HAL_KEY_TYPE_EC_PUBLIC)); } - (void) hal_rpc_pkey_close(pkey); + if (!ok && pkey.handle != HAL_HANDLE_NONE) + (void) hal_rpc_pkey_delete(pkey); + else + (void) hal_rpc_pkey_close(pkey); + sqlite3_finalize(q); return ok; } @@ -1653,7 +1620,6 @@ static inline int p11_object_create_rsa_private_key(const p11_session_t * const uint8_t keybuf[hal_rsa_key_t_size]; hal_rsa_key_t *key = NULL; sqlite3_stmt *q = NULL; - size_t ski_len = 0; const uint8_t *cka_private_exponent = NULL; size_t cka_private_exponent_len = 0; const uint8_t *cka_prime_1 = NULL; size_t cka_prime_1_len = 0; @@ -1686,8 +1652,7 @@ static inline int p11_object_create_rsa_private_key(const p11_session_t * const } int ok - = (hal_check(hal_rpc_hash_get_digest_length(P11_KEY_HASH_ALGORITHM, &ski_len)) && - sql_check_ok(sql_prepare(&q, select_format, flavor, CKA_MODULUS, CKA_PUBLIC_EXPONENT)) && + = (sql_check_ok(sql_prepare(&q, select_format, flavor, CKA_MODULUS, CKA_PUBLIC_EXPONENT)) && sql_check_ok(sqlite3_bind_int64(q, 1, object_handle)) && sql_check_row(sqlite3_step(q)) && sqlite3_column_type(q, 0) == SQLITE_BLOB && @@ -1703,23 +1668,24 @@ static inline int p11_object_create_rsa_private_key(const p11_session_t * const cka_exponent_2, cka_exponent_2_len))); if (ok) { - const size_t private_len = hal_rsa_private_key_to_der_len(key); - const size_t public_len = hal_rsa_public_key_to_der_len(key); - uint8_t der[public_len > private_len ? public_len : private_len], ski[ski_len]; - ok = (hal_check(hal_rsa_public_key_to_der(key, der, NULL, sizeof(der))) && - p11_object_bind_pkey(session, HAL_KEY_TYPE_RSA_PRIVATE, HAL_KEY_TYPE_NONE, - object_handle, CK_INVALID_HANDLE, - der, public_len, ski, sizeof(ski)) && - hal_check(hal_rsa_private_key_to_der(key, der, NULL, sizeof(der))) && + uint8_t der[hal_rsa_private_key_to_der_len(key)]; + hal_uuid_t uuid; + ok = (hal_check(hal_rsa_private_key_to_der(key, der, NULL, sizeof(der))) && hal_check(hal_rpc_pkey_load(p11_session_hal_client(session), p11_session_hal_session(session), &pkey, HAL_KEY_TYPE_RSA_PRIVATE, HAL_CURVE_NONE, - ski, sizeof(ski), der, private_len, flags))); + &uuid, der, sizeof(der), flags)) && + p11_object_bind_pkey(session, object_handle, &uuid, HAL_KEY_TYPE_RSA_PRIVATE)); memset(der, 0, sizeof(der)); } memset(keybuf, 0, sizeof(keybuf)); - (void) hal_rpc_pkey_close(pkey); + + if (!ok && pkey.handle != HAL_HANDLE_NONE) + (void) hal_rpc_pkey_delete(pkey); + else + (void) hal_rpc_pkey_close(pkey); + sqlite3_finalize(q); return ok; } @@ -1742,7 +1708,6 @@ static inline int p11_object_create_ec_private_key(const p11_session_t * const s hal_ecdsa_key_t *key = NULL; hal_curve_name_t curve; sqlite3_stmt *q = NULL; - size_t ski_len = 0; const uint8_t *ecpoint = NULL; size_t ecpoint_len = 0; @@ -1753,8 +1718,7 @@ static inline int p11_object_create_ec_private_key(const p11_session_t * const s cka_value = template[i].pValue, cka_value_len = template[i].ulValueLen; int ok - = (hal_check(hal_rpc_hash_get_digest_length(P11_KEY_HASH_ALGORITHM, &ski_len)) && - sql_check_ok(sql_prepare(&q, select_format, flavor, CKA_EC_PARAMS, CKA_EC_POINT)) && + = (sql_check_ok(sql_prepare(&q, select_format, flavor, CKA_EC_PARAMS, CKA_EC_POINT)) && sql_check_ok(sqlite3_bind_int64(q, 1, object_handle)) && sql_check_row(sqlite3_step(q)) && sqlite3_column_type(q, 0) == SQLITE_BLOB && @@ -1768,23 +1732,24 @@ static inline int p11_object_create_ec_private_key(const p11_session_t * const s cka_value, cka_value_len))); if (ok) { - const size_t private_len = hal_ecdsa_private_key_to_der_len(key); - const size_t public_len = hal_ecdsa_public_key_to_der_len(key); - uint8_t der[public_len > private_len ? public_len : private_len], ski[ski_len]; - ok = (hal_check(hal_ecdsa_public_key_to_der(key, der, NULL, sizeof(der))) && - p11_object_bind_pkey(session, HAL_KEY_TYPE_EC_PRIVATE, HAL_KEY_TYPE_NONE, - object_handle, CK_INVALID_HANDLE, - der, public_len, ski, sizeof(ski)) && - hal_check(hal_ecdsa_private_key_to_der(key, der, NULL, sizeof(der))) && + uint8_t der[hal_ecdsa_private_key_to_der_len(key)]; + hal_uuid_t uuid; + ok = (hal_check(hal_ecdsa_private_key_to_der(key, der, NULL, sizeof(der))) && hal_check(hal_rpc_pkey_load(p11_session_hal_client(session), p11_session_hal_session(session), &pkey, HAL_KEY_TYPE_EC_PRIVATE, curve, - ski, sizeof(ski), der, private_len, flags))); + &uuid, der, sizeof(der), flags)) && + p11_object_bind_pkey(session, object_handle, &uuid, HAL_KEY_TYPE_EC_PRIVATE)); memset(der, 0, sizeof(der)); } memset(keybuf, 0, sizeof(keybuf)); - (void) hal_rpc_pkey_close(pkey); + + if (!ok && pkey.handle != HAL_HANDLE_NONE) + (void) hal_rpc_pkey_delete(pkey); + else + (void) hal_rpc_pkey_close(pkey); + sqlite3_finalize(q); return ok; } @@ -1798,9 +1763,9 @@ static int p11_object_get_pkey_handle(const p11_session_t * const session, hal_pkey_handle_t *pkey_handle) { static const char select_format[] = - " SELECT hal_pkey_type, hal_pkey_ski FROM %s_object NATURAL JOIN object WHERE object_handle = ?1"; + " SELECT hal_pkey_type, hal_pkey_uuid FROM %s_object NATURAL JOIN object WHERE object_handle = ?1"; - hal_key_flags_t flags = is_token_handle(object_handle) ? 0 : HAL_KEY_FLAG_PROXIMATE; + hal_key_flags_t flags = is_token_handle(object_handle) ? HAL_KEY_FLAG_TOKEN : 0; const char *flavor = is_token_handle(object_handle) ? "token" : "session"; sqlite3_stmt *q = NULL; int ok = 0; @@ -1811,15 +1776,15 @@ static int p11_object_get_pkey_handle(const p11_session_t * const session, !sql_check_ok(sqlite3_bind_int64(q, 1, object_handle)) || !sql_check_row(sqlite3_step(q)) || sqlite3_column_type(q, 0) != SQLITE_INTEGER || - sqlite3_column_type(q, 1) != SQLITE_BLOB) + sqlite3_column_type(q, 1) != SQLITE_BLOB || + sqlite3_column_bytes(q, 1) != sizeof(hal_uuid_t)) goto fail; const hal_key_type_t pkey_type = sqlite3_column_int64(q, 0); - const uint8_t * const ski = sqlite3_column_blob( q, 1); - const size_t ski_len = sqlite3_column_bytes(q, 1); + const hal_uuid_t * pkey_uuid = sqlite3_column_blob( q, 1); ok = hal_check(hal_rpc_pkey_find(p11_session_hal_client(session), p11_session_hal_session(session), - pkey_handle, pkey_type, ski, ski_len, flags)); + pkey_handle, pkey_type, pkey_uuid, flags)); fail: sqlite3_finalize(q); @@ -2303,15 +2268,16 @@ static CK_RV generate_keypair_rsa_pkcs(p11_session_t *session, const CK_OBJECT_HANDLE private_handle, const hal_key_flags_t private_flags) { + const int same_keystore = is_token_handle(public_handle) == is_token_handle(private_handle); const uint8_t *public_exponent = const_0x010001; size_t public_exponent_len = sizeof(const_0x010001); hal_pkey_handle_t pkey1 = {HAL_HANDLE_NONE}, pkey2 = {HAL_HANDLE_NONE}; CK_ULONG keysize = 0; - size_t ski_len = 0; + hal_uuid_t uuid; CK_RV rv; int i; - assert(session != NULL && pPublicKeyTemplate != NULL && pPrivateKeyTemplate != NULL && is_token_handle(private_handle)); + assert(session != NULL && pPublicKeyTemplate != NULL && pPrivateKeyTemplate != NULL); for (i = 0; i < ulPublicKeyAttributeCount; i++) { const CK_ATTRIBUTE_TYPE type = pPublicKeyTemplate[i].type; @@ -2336,47 +2302,43 @@ static CK_RV generate_keypair_rsa_pkcs(p11_session_t *session, if (keysize == 0) return CKR_TEMPLATE_INCOMPLETE; - if (!hal_check(hal_rpc_hash_get_digest_length(P11_KEY_HASH_ALGORITHM, &ski_len))) - lose(CKR_FUNCTION_FAILED); - if (!hal_check(hal_rpc_pkey_generate_rsa(p11_session_hal_client(session), p11_session_hal_session(session), - &pkey1, (const uint8_t *) "", 0, keysize, + &pkey1, &uuid, keysize, public_exponent, public_exponent_len, - private_flags))) + private_flags)) || + !p11_object_bind_pkey(session, private_handle, &uuid, HAL_KEY_TYPE_RSA_PRIVATE)) lose(CKR_FUNCTION_FAILED); { - uint8_t der[hal_rpc_pkey_get_public_key_len(pkey1)], keybuf[hal_rsa_key_t_size], ski[ski_len]; + uint8_t der[hal_rpc_pkey_get_public_key_len(pkey1)], keybuf[hal_rsa_key_t_size]; size_t der_len, modulus_len; hal_rsa_key_t *key = NULL; - const hal_key_type_t pkey2_type = is_token_handle(public_handle) ? HAL_KEY_TYPE_RSA_PRIVATE : HAL_KEY_TYPE_RSA_PUBLIC; - if (!hal_check(hal_rpc_pkey_get_public_key(pkey1, der, &der_len, sizeof(der))) || - !p11_object_bind_pkey(session, HAL_KEY_TYPE_RSA_PRIVATE, pkey2_type, - private_handle, public_handle, - der, sizeof(der), ski, sizeof(ski)) || - !hal_check(hal_rpc_pkey_rename(pkey1, ski, sizeof(ski))) || !hal_check(hal_rsa_public_key_from_der(&key, keybuf, sizeof(keybuf), der, der_len)) || !hal_check(hal_rsa_key_get_modulus(key, NULL, &modulus_len, 0))) lose(CKR_FUNCTION_FAILED); uint8_t modulus[modulus_len]; - if (!hal_check(hal_rsa_key_get_modulus(key, modulus, NULL, sizeof(modulus))) || - !p11_attribute_set(public_handle, CKA_MODULUS, modulus, modulus_len) || + if (!hal_check(hal_rsa_key_get_modulus(key, modulus, NULL, sizeof(modulus))) || + !p11_attribute_set(public_handle, CKA_MODULUS, modulus, modulus_len) || !p11_attribute_set(private_handle, CKA_MODULUS, modulus, modulus_len)) lose(CKR_FUNCTION_FAILED); - if (!is_token_handle(public_handle) && + if (!same_keystore && !hal_check(hal_rpc_pkey_load(p11_session_hal_client(session), p11_session_hal_session(session), &pkey2, HAL_KEY_TYPE_RSA_PUBLIC, HAL_CURVE_NONE, - ski, sizeof(ski), der, der_len, public_flags))) + &uuid, der, der_len, public_flags))) lose(CKR_FUNCTION_FAILED); } + if (!p11_object_bind_pkey(session, public_handle, &uuid, + same_keystore ? HAL_KEY_TYPE_RSA_PRIVATE : HAL_KEY_TYPE_RSA_PUBLIC)) + lose(CKR_FUNCTION_FAILED); + rv = CKR_OK; fail: @@ -2399,15 +2361,16 @@ static CK_RV generate_keypair_ec(p11_session_t *session, const CK_OBJECT_HANDLE private_handle, const hal_key_flags_t private_flags) { + const int same_keystore = is_token_handle(public_handle) == is_token_handle(private_handle); hal_pkey_handle_t pkey1 = {HAL_HANDLE_NONE}, pkey2 = {HAL_HANDLE_NONE}; const CK_BYTE *params = NULL; hal_curve_name_t curve; size_t params_len; - size_t ski_len = 0; + hal_uuid_t uuid; CK_RV rv; int i; - assert(session != NULL && pPublicKeyTemplate != NULL && pPrivateKeyTemplate != NULL && is_token_handle(private_handle)); + assert(session != NULL && pPublicKeyTemplate != NULL && pPrivateKeyTemplate != NULL); for (i = 0; i < ulPublicKeyAttributeCount; i++) { const CK_ATTRIBUTE_TYPE type = pPublicKeyTemplate[i].type; @@ -2426,46 +2389,41 @@ static CK_RV generate_keypair_ec(p11_session_t *session, if (!ec_curve_oid_to_name(params, params_len, &curve)) return CKR_TEMPLATE_INCOMPLETE; - if (!hal_check(hal_rpc_hash_get_digest_length(P11_KEY_HASH_ALGORITHM, &ski_len))) - lose(CKR_FUNCTION_FAILED); - if (!hal_check(hal_rpc_pkey_generate_ec(p11_session_hal_client(session), p11_session_hal_session(session), - &pkey1, (const uint8_t *) "", 0, - curve, private_flags)) || - !p11_attribute_set(public_handle, CKA_EC_PARAMS, params, params_len) || + &pkey1, &uuid, curve, private_flags)) || + !p11_object_bind_pkey(session, private_handle, &uuid, HAL_KEY_TYPE_EC_PRIVATE) || + !p11_attribute_set(public_handle, CKA_EC_PARAMS, params, params_len) || !p11_attribute_set(private_handle, CKA_EC_PARAMS, params, params_len)) lose(CKR_FUNCTION_FAILED); { - uint8_t der[hal_rpc_pkey_get_public_key_len(pkey1)], keybuf[hal_ecdsa_key_t_size], ski[ski_len]; + uint8_t der[hal_rpc_pkey_get_public_key_len(pkey1)], keybuf[hal_ecdsa_key_t_size]; hal_ecdsa_key_t *key = NULL; size_t der_len; - const hal_key_type_t pkey2_type = is_token_handle(public_handle) ? HAL_KEY_TYPE_EC_PRIVATE : HAL_KEY_TYPE_EC_PUBLIC; - if (!hal_check(hal_rpc_pkey_get_public_key(pkey1, der, &der_len, sizeof(der))) || - !p11_object_bind_pkey(session, HAL_KEY_TYPE_EC_PRIVATE, pkey2_type, - private_handle, public_handle, - der, sizeof(der), ski, sizeof(ski)) || - !hal_check(hal_rpc_pkey_rename(pkey1, ski, sizeof(ski))) || !hal_check(hal_ecdsa_public_key_from_der(&key, keybuf, sizeof(keybuf), der, der_len))) lose(CKR_FUNCTION_FAILED); uint8_t point[hal_ecdsa_key_to_ecpoint_len(key)]; - if (!hal_check(hal_ecdsa_key_to_ecpoint(key, point, NULL, sizeof(point))) || + if (!hal_check(hal_ecdsa_key_to_ecpoint(key, point, NULL, sizeof(point))) || !p11_attribute_set(public_handle, CKA_EC_POINT, point, sizeof(point))) lose(CKR_FUNCTION_FAILED); - if (!is_token_handle(public_handle) && + if (!same_keystore && !hal_check(hal_rpc_pkey_load(p11_session_hal_client(session), p11_session_hal_session(session), &pkey2, HAL_KEY_TYPE_EC_PUBLIC, curve, - ski, sizeof(ski), der, der_len, public_flags))) + &uuid, der, der_len, public_flags))) lose(CKR_FUNCTION_FAILED); } + if (!p11_object_bind_pkey(session, public_handle, &uuid, + same_keystore ? HAL_KEY_TYPE_EC_PRIVATE : HAL_KEY_TYPE_EC_PUBLIC)) + lose(CKR_FUNCTION_FAILED); + rv = CKR_OK; fail: @@ -2477,10 +2435,6 @@ static CK_RV generate_keypair_ec(p11_session_t *session, /* * Key pair generation. This needs a mechanism-specific function to * do the inner bits, but there's a lot of boilerplate. - * - * We have no real way to protect session objects, so we don't allow - * them to hold private keys. PKCS #11 wants us to report this kind - * of restriction as a template inconsistency. */ static CK_RV generate_keypair(p11_session_t *session, @@ -2533,11 +2487,11 @@ static CK_RV generate_keypair(p11_session_t *session, if (pPrivateKeyTemplate[i].type == CKA_TOKEN) private_handle_flavor = p11_handle_flavor_from_cka_token(pPrivateKeyTemplate[i].pValue); - if (public_handle_flavor == handle_flavor_session_object) - public_flags |= HAL_KEY_FLAG_PROXIMATE; + if (public_handle_flavor == handle_flavor_token_object) + public_flags |= HAL_KEY_FLAG_TOKEN; - if (private_handle_flavor == handle_flavor_session_object) - return CKR_TEMPLATE_INCONSISTENT; + if (private_handle_flavor == handle_flavor_token_object) + private_flags |= HAL_KEY_FLAG_TOKEN; if (!sql_exec("BEGIN")) lose(CKR_FUNCTION_FAILED); @@ -3088,7 +3042,7 @@ CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, psnprintf(pInfo->serialNumber, sizeof(pInfo->serialNumber), "007"); - pInfo->flags = CKF_RNG | CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED; + pInfo->flags = CKF_RNG | CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED | CKF_TOKEN_INITIALIZED; #warning Have not yet sorted out token flags #if 0 @@ -3447,9 +3401,6 @@ CK_RV C_CreateObject(CK_SESSION_HANDLE hSession, lose(CKR_SESSION_READ_ONLY); } - if (flavor == handle_flavor_session_object && *cka_class == CKO_PRIVATE_KEY) - lose(CKR_TEMPLATE_INCONSISTENT); - if (!sql_exec("BEGIN")) lose(CKR_FUNCTION_FAILED); @@ -3469,7 +3420,7 @@ CK_RV C_CreateObject(CK_SESSION_HANDLE hSession, lose(CKR_FUNCTION_FAILED); } - hal_key_flags_t flags = flavor == handle_flavor_session_object ? HAL_KEY_FLAG_PROXIMATE : 0; + hal_key_flags_t flags = flavor == handle_flavor_token_object ? HAL_KEY_FLAG_TOKEN : 0; for (int i = 0; i < ulCount; i++) p11_attribute_apply_keyusage(&flags, pTemplate[i].type, pTemplate[i].pValue); diff --git a/schema.sql b/schema.sql index 9de8ce2..1db361c 100644 --- a/schema.sql +++ b/schema.sql @@ -78,7 +78,7 @@ CREATE TEMPORARY TABLE IF NOT EXISTS object ( CREATE TEMPORARY TABLE IF NOT EXISTS session_object ( session_object_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, hal_pkey_type INTEGER, - hal_pkey_ski BLOB, + hal_pkey_uuid BLOB, object_id INTEGER NOT NULL UNIQUE REFERENCES object ON DELETE CASCADE ON UPDATE CASCADE @@ -96,7 +96,7 @@ CREATE TEMPORARY TABLE IF NOT EXISTS session_attribute ( CREATE TABLE IF NOT EXISTS token_object ( token_object_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, hal_pkey_type INTEGER, - hal_pkey_ski BLOB + hal_pkey_uuid BLOB ); CREATE TABLE IF NOT EXISTS token_attribute ( diff --git a/unit_tests.py b/unit_tests.py index c9d3886..02863c8 100644 --- a/unit_tests.py +++ b/unit_tests.py @@ -259,27 +259,32 @@ class TestKeys(TestCase): def test_keygen_token_vs_session(self): "Test C_GenerateKeypair() CKA_TOKEN restrictions" - with self.assertRaises(CKR_TEMPLATE_INCONSISTENT): - p11.C_GenerateKeyPair(self.session, CKM_EC_KEY_PAIR_GEN, CKA_TOKEN = False, - CKA_ID = "EC-P256", CKA_EC_PARAMS = self.oid_p256, - CKA_SIGN = True, CKA_VERIFY = True) + self.assertIsKeypair( + p11.C_GenerateKeyPair(self.session, CKM_EC_KEY_PAIR_GEN, CKA_TOKEN = False, + CKA_ID = "EC-P256", CKA_EC_PARAMS = self.oid_p256, + CKA_SIGN = True, CKA_VERIFY = True)) self.assertIsKeypair( p11.C_GenerateKeyPair(self.session, CKM_EC_KEY_PAIR_GEN, CKA_TOKEN = True, CKA_ID = "EC-P256", CKA_EC_PARAMS = self.oid_p256, CKA_SIGN = True, CKA_VERIFY = True)) + # Might need to do this until we expand the number of key slots + if False: + for handle in p11.FindObjects(self.session): + p11.C_DestroyObject(self.session, handle) + self.assertIsKeypair( p11.C_GenerateKeyPair(self.session, CKM_EC_KEY_PAIR_GEN, public_CKA_TOKEN = False, private_CKA_TOKEN = True, CKA_ID = "EC-P256", CKA_EC_PARAMS = self.oid_p256, CKA_SIGN = True, CKA_VERIFY = True)) - with self.assertRaises(CKR_TEMPLATE_INCONSISTENT): - p11.C_GenerateKeyPair(self.session, CKM_EC_KEY_PAIR_GEN, - public_CKA_TOKEN = True, private_CKA_TOKEN = False, - CKA_ID = "EC-P256", CKA_EC_PARAMS = self.oid_p256, - CKA_SIGN = True, CKA_VERIFY = True) + self.assertIsKeypair( + p11.C_GenerateKeyPair(self.session, CKM_EC_KEY_PAIR_GEN, + public_CKA_TOKEN = True, private_CKA_TOKEN = False, + CKA_ID = "EC-P256", CKA_EC_PARAMS = self.oid_p256, + CKA_SIGN = True, CKA_VERIFY = True)) def test_gen_sign_verify_ecdsa_p256_sha256(self): "Generate/sign/verify with ECDSA-P256-SHA-256" -- cgit v1.2.3