From e8144a27a6c5f1e323bc054c367180c2f84f476a Mon Sep 17 00:00:00 2001 From: latal-1 Date: Tue, 26 Nov 2024 00:38:30 +0300 Subject: [PATCH] Allow generated EVP_PKEY to be used to verify operation Previously generated EVP_PKEY could be used for operations that only require a private key Signed-off-by: latal-1 --- src/objects.c | 24 ++++++++++++++++++++---- src/objects.h | 1 + src/signature.c | 30 ++++++++++++++++-------------- 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/src/objects.c b/src/objects.c index 722abe14..f35553f7 100644 --- a/src/objects.c +++ b/src/objects.c @@ -39,6 +39,7 @@ struct p11prov_obj { CK_OBJECT_HANDLE cached; CK_BBOOL cka_copyable; CK_BBOOL cka_token; + bool isGenerated; P11PROV_URI *refresh_uri; @@ -108,8 +109,8 @@ void p11prov_obj_pool_free(P11PROV_OBJ_POOL *pool) } OPENSSL_free(pool->objects); (void)MUTEX_UNLOCK(pool); - /* ------------- LOCKED SECTION */ } - else { + /* ------------- LOCKED SECTION */ + } else { P11PROV_debug("Failed to lock object pool, leaking it!"); return; } @@ -269,6 +270,7 @@ P11PROV_OBJ *p11prov_obj_new(P11PROV_CTX *ctx, CK_SLOT_ID slotid, obj->handle = handle; obj->class = class; obj->cached = CK_INVALID_HANDLE; + obj->isGenerated = false; obj->refcnt = 1; @@ -3111,6 +3113,7 @@ static CK_RV return_dup_key(P11PROV_OBJ *dst, P11PROV_OBJ *src) dst->class = src->class; dst->cka_copyable = src->cka_copyable; dst->cka_token = src->cka_token; + dst->isGenerated = src->isGenerated; dst->data.key = src->data.key; dst->attrs = OPENSSL_zalloc(sizeof(CK_ATTRIBUTE) * src->numattrs); @@ -3991,8 +3994,8 @@ CK_RV p11prov_merge_pub_attrs_into_priv(P11PROV_OBJ *pub_key, CK_RV ret = CKR_OK; if (!pub_key || !priv_key) { - P11PROV_debug( - "Empty keys. Cannot copy public key attributes into private key"); + P11PROV_debug("Empty keys. Cannot copy public key attributes into " + "private key"); return CKR_ARGUMENTS_BAD; } @@ -4051,6 +4054,11 @@ CK_RV p11prov_merge_pub_attrs_into_priv(P11PROV_OBJ *pub_key, return CKR_ARGUMENTS_BAD; } + /* P11PROV_OBJ has only one handle (for generation is a private key handle), + * but user can use generated EVP_PKEY for verify or encrypt so + * necessary to signal that key has been generated to find the associated public key for the sign context */ + priv_key->isGenerated = true; + return ret; err: @@ -4107,3 +4115,11 @@ P11PROV_OBJ *mock_pub_ec_key(P11PROV_CTX *ctx, CK_ATTRIBUTE_TYPE type, return key; } + +P11PROV_OBJ *p11prov_obj_pub_from_generated(P11PROV_OBJ *obj) +{ + if (obj == NULL || obj->isGenerated == false) { + return NULL; + } + return find_associated_obj(obj->ctx, obj, CKO_PUBLIC_KEY); +} diff --git a/src/objects.h b/src/objects.h index c6ee04ff..30dfafd0 100644 --- a/src/objects.h +++ b/src/objects.h @@ -62,6 +62,7 @@ int p11prov_obj_get_ed_pub_key(P11PROV_OBJ *obj, CK_ATTRIBUTE **pub); CK_ATTRIBUTE *p11prov_obj_get_ec_public_raw(P11PROV_OBJ *key); P11PROV_OBJ *mock_pub_ec_key(P11PROV_CTX *ctx, CK_ATTRIBUTE_TYPE type, CK_ATTRIBUTE *ec_params); +P11PROV_OBJ *p11prov_obj_pub_from_generated(P11PROV_OBJ *obj); #define OBJ_CMP_KEY_TYPE 0x00 #define OBJ_CMP_KEY_PUBLIC 0x01 diff --git a/src/signature.c b/src/signature.c index 10465962..b72112d9 100644 --- a/src/signature.c +++ b/src/signature.c @@ -686,20 +686,23 @@ static CK_RV p11prov_sig_op_init(void *ctx, void *provkey, CK_FLAGS operation, return ret; } - sigctx->key = p11prov_obj_ref(key); - if (sigctx->key == NULL) { - return CKR_KEY_NEEDED; - } - class = p11prov_obj_get_class(sigctx->key); + class = p11prov_obj_get_class(key); switch (operation) { case CKF_SIGN: if (class != CKO_PRIVATE_KEY) { return CKR_KEY_TYPE_INCONSISTENT; } + sigctx->key = p11prov_obj_ref(key); + if (sigctx->key == NULL) { + return CKR_KEY_NEEDED; + } break; case CKF_VERIFY: if (class != CKO_PUBLIC_KEY) { - return CKR_KEY_TYPE_INCONSISTENT; + sigctx->key = p11prov_obj_pub_from_generated(key); + if (sigctx->key == NULL) { + return CKR_KEY_TYPE_INCONSISTENT; + } } break; default: @@ -710,6 +713,7 @@ static CK_RV p11prov_sig_op_init(void *ctx, void *provkey, CK_FLAGS operation, if (digest) { ret = p11prov_digest_get_by_name(digest, &sigctx->digest); if (ret != CKR_OK) { + p11prov_obj_free(sigctx->key); ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST); return ret; } @@ -1252,10 +1256,9 @@ static int p11prov_rsasig_digest_sign_final(void *ctx, unsigned char *sig, /* the siglen might be uninitialized when called from openssl */ *siglen = 0; - P11PROV_debug( - "rsa digest sign final (ctx=%p, sig=%p, siglen=%zu, " - "sigsize=%zu)", - ctx, sig, *siglen, sigsize); + P11PROV_debug("rsa digest sign final (ctx=%p, sig=%p, siglen=%zu, " + "sigsize=%zu)", + ctx, sig, *siglen, sigsize); if (sigctx == NULL) { return RET_OSSL_ERR; @@ -1903,10 +1906,9 @@ static int p11prov_ecdsa_digest_sign_final(void *ctx, unsigned char *sig, /* the siglen might be uninitialized when called from openssl */ *siglen = 0; - P11PROV_debug( - "ecdsa digest sign final (ctx=%p, sig=%p, siglen=%zu, " - "sigsize=%zu)", - ctx, sig, *siglen, sigsize); + P11PROV_debug("ecdsa digest sign final (ctx=%p, sig=%p, siglen=%zu, " + "sigsize=%zu)", + ctx, sig, *siglen, sigsize); if (sigctx == NULL) { return RET_OSSL_ERR;