From e4b44e81e8a4aa92ab62eca00eb046a99956b04d Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 13 Mar 2025 10:48:25 -0400 Subject: [PATCH] Fix peer keys domain parameter copying OpenSSL assumes you can create a new EC key by copying the domain parameters from a peer key first (to establish a compatible key type for operations like ECDH), and only later generates the private key material. Better identify those keys by assigning the CKO_DOMAIN_PARAMETER class to them as parameters are set. We do not have a fully formed key at this point but we already have a bunch of parameters so this also allows to make decisions on what should or should not be changed anymore at this point. (for example this now will prevent re-importing other parameters over the "proto" key). Fixes #543 Signed-off-by: Simo Sorce --- src/objects.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/objects.c b/src/objects.c index 310e6a5..69688a0 100644 --- a/src/objects.c +++ b/src/objects.c @@ -574,6 +574,7 @@ CK_KEY_TYPE p11prov_obj_get_key_type(P11PROV_OBJ *obj) switch (obj->class) { case CKO_PRIVATE_KEY: case CKO_PUBLIC_KEY: + case CKO_DOMAIN_PARAMETERS: return obj->data.key.type; } } @@ -638,6 +639,7 @@ CK_ULONG p11prov_obj_get_key_bit_size(P11PROV_OBJ *obj) switch (obj->class) { case CKO_PRIVATE_KEY: case CKO_PUBLIC_KEY: + case CKO_DOMAIN_PARAMETERS: return obj->data.key.bit_size; } } @@ -650,6 +652,7 @@ CK_ULONG p11prov_obj_get_key_size(P11PROV_OBJ *obj) switch (obj->class) { case CKO_PRIVATE_KEY: case CKO_PUBLIC_KEY: + case CKO_DOMAIN_PARAMETERS: return obj->data.key.size; } } @@ -4277,10 +4280,13 @@ CK_RV p11prov_obj_import_key(P11PROV_OBJ *key, CK_KEY_TYPE type, switch (class) { case CKO_PUBLIC_KEY: + key->class = CKO_PUBLIC_KEY; return p11prov_obj_import_public_key(key, type, params); case CKO_PRIVATE_KEY: + key->class = CKO_PRIVATE_KEY; return p11prov_obj_import_private_key(key, type, params); case CKO_DOMAIN_PARAMETERS: + key->class = CKO_DOMAIN_PARAMETERS; return p11prov_obj_set_domain_params(key, type, params); default: P11PROV_raise(key->ctx, CKR_KEY_INDIGESTIBLE, @@ -4313,15 +4319,15 @@ CK_RV p11prov_obj_set_ec_encoded_public_key(P11PROV_OBJ *key, return CKR_KEY_INDIGESTIBLE; } - if (key->class == CK_UNAVAILABLE_INFORMATION) { - key->class = CKO_PUBLIC_KEY; - } - switch (key->data.key.type) { case CKK_EC: case CKK_EC_EDWARDS: - /* check that this is a public key */ - if (key->class != CKO_PUBLIC_KEY) { + /* if class is still "domain parameters" convert it to + * a public key */ + if (key->class == CKO_DOMAIN_PARAMETERS) { + key->class = CKO_PUBLIC_KEY; + } else if (key->class != CKO_PUBLIC_KEY) { + /* check that this is a public key */ P11PROV_raise(key->ctx, CKR_KEY_INDIGESTIBLE, "Invalid Key type, not a public key"); return CKR_KEY_INDIGESTIBLE; -- 2.48.1