aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2016-09-03 02:27:09 -0400
committerRob Austein <sra@hactrn.net>2016-09-03 02:27:09 -0400
commit8a36a9c42b6c327056ca334d556c221c28375d15 (patch)
treecea62955ffe0cbb05b4c584ff441abc7a1e50d8b
parent1d60161a9eae18e339232bed879f0525925e10cb (diff)
Hack PKCS #11 to work with revised libhal pkey API.
-rw-r--r--Makefile14
-rw-r--r--pkcs11.c249
-rw-r--r--schema.sql4
-rw-r--r--unit_tests.py23
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"