Skip to content

Commit

Permalink
Embed the private key with public key attributes.
Browse files Browse the repository at this point in the history
For RSA: CKA_MODULUS, CKA_PUBLIC_EXPONENT
For EC: CKA_EC_POINT, CKA_EC_PARAMS, CKA_P11PROV_PUB_KEY

Fixes: latchset#282
Signed-off-by: Sahana Prasad <sahana@redhat.com>
  • Loading branch information
sahanaprasad07 authored and simo5 committed Sep 29, 2023
1 parent 30a1e8e commit fb3aa3b
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 3 deletions.
20 changes: 17 additions & 3 deletions src/keymgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,8 @@ static void *p11prov_common_gen(struct key_generator *ctx,
CK_OBJECT_HANDLE pubkey;
P11PROV_SESSION *session = NULL;
CK_SESSION_HANDLE sh;
P11PROV_OBJ *key = NULL;
P11PROV_OBJ *pub_key = NULL;
P11PROV_OBJ *priv_key = NULL;
CK_ATTRIBUTE cka_id = { 0 };
CK_ATTRIBUTE label = { 0 };
CK_RV ret;
Expand Down Expand Up @@ -526,14 +527,27 @@ static void *p11prov_common_gen(struct key_generator *ctx,
return NULL;
}

ret = p11prov_obj_from_handle(ctx->provctx, session, privkey, &key);
ret = p11prov_obj_from_handle(ctx->provctx, session, pubkey, &pub_key);
if (ret != CKR_OK) {
p11prov_return_session(session);
return NULL;
}

ret = p11prov_obj_from_handle(ctx->provctx, session, privkey, &priv_key);
if (ret != CKR_OK) {
p11prov_return_session(session);
return NULL;
}

ret = p11prov_merge_pub_attrs_into_priv(pub_key, priv_key);
if (ret != CKR_OK) {
p11prov_return_session(session);
return NULL;
}

p11prov_return_session(session);
return key;
p11prov_obj_free(pub_key);
return priv_key;
}

static void p11prov_common_gen_cleanup(void *genctx)
Expand Down
108 changes: 108 additions & 0 deletions src/objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -2695,3 +2695,111 @@ CK_RV p11prov_obj_set_ec_encoded_public_key(P11PROV_OBJ *key,

return CKR_OK;
}

CK_RV p11prov_obj_copy_specific_attr(P11PROV_OBJ *pub_key,
P11PROV_OBJ *priv_key,
CK_ATTRIBUTE_TYPE type)
{
CK_ATTRIBUTE *attr = NULL;
CK_RV ret = CKR_OK;

if (!pub_key || !priv_key) {
return CKR_ARGUMENTS_BAD;
}

attr = p11prov_obj_get_attr(pub_key, type);
if (!attr) {
P11PROV_debug("Failed to fetch the specific attribute");
return CKR_GENERAL_ERROR;
}

ret = p11prov_copy_attr(&priv_key->attrs[priv_key->numattrs], attr);
if (ret != CKR_OK) {
P11PROV_raise(priv_key->ctx, ret, "Failed attr copy");
return CKR_GENERAL_ERROR;
}
priv_key->numattrs++;

return ret;
}

/*
*Copy attributes from public key to private key
*so that the public key can be reconstructed from
*a private key directly.
*/
#define RSA_PRIV_ATTRS_NUM 2

#define EC_PRIV_ATTRS_NUM 3
CK_RV p11prov_merge_pub_attrs_into_priv(P11PROV_OBJ *pub_key,
P11PROV_OBJ *priv_key)
{
CK_RV ret = CKR_OK;

if (!pub_key || !priv_key) {
P11PROV_debug(
"Empty keys. Cannot copy public key attributes into private key");
return CKR_ARGUMENTS_BAD;
}

switch (pub_key->data.key.type) {
case CKK_RSA:
priv_key->attrs = OPENSSL_realloc(
priv_key->attrs,
(priv_key->numattrs + RSA_PRIV_ATTRS_NUM) * sizeof(CK_ATTRIBUTE));
if (!priv_key->attrs) {
ret = CKR_HOST_MEMORY;
P11PROV_raise(priv_key->ctx, ret, "Failed allocation");
return ret;
}

ret = p11prov_obj_copy_specific_attr(pub_key, priv_key, CKA_MODULUS);
if (ret != CKR_OK) {
goto err;
}

ret = p11prov_obj_copy_specific_attr(pub_key, priv_key,
CKA_PUBLIC_EXPONENT);
if (ret != CKR_OK) {
goto err;
}
break;
case CKK_EC:
case CKK_EC_EDWARDS:
priv_key->attrs = OPENSSL_realloc(
priv_key->attrs,
(priv_key->numattrs + EC_PRIV_ATTRS_NUM) * sizeof(CK_ATTRIBUTE));
if (!priv_key->attrs) {
ret = CKR_HOST_MEMORY;
P11PROV_raise(priv_key->ctx, ret, "Failed allocation");
return ret;
}

ret = p11prov_obj_copy_specific_attr(pub_key, priv_key, CKA_EC_POINT);
if (ret != CKR_OK) {
goto err;
}

ret = p11prov_obj_copy_specific_attr(pub_key, priv_key, CKA_EC_PARAMS);
if (ret != CKR_OK) {
goto err;
}

ret = p11prov_obj_copy_specific_attr(pub_key, priv_key,
CKA_P11PROV_PUB_KEY);
if (ret != CKR_OK) {
goto err;
}
break;
default:
/* unknown key type, we can't copy public key attributes */
P11PROV_debug("Unsupported key type (%lu)", pub_key->data.key.type);
return CKR_ARGUMENTS_BAD;
}

return ret;

err:
P11PROV_raise(priv_key->ctx, ret, "Failed attr copy");
return CKR_GENERAL_ERROR;
}
7 changes: 7 additions & 0 deletions src/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@ CK_RV p11prov_obj_set_ec_encoded_public_key(P11PROV_OBJ *key,
const void *pubkey,
size_t pubkey_len);

CK_RV p11prov_obj_copy_specific_attr(P11PROV_OBJ *pub_key,
P11PROV_OBJ *priv_key,
CK_ATTRIBUTE_TYPE type);

CK_RV p11prov_merge_pub_attrs_into_priv(P11PROV_OBJ *pub_key,
P11PROV_OBJ *priv_key);

#define ED25519 "ED25519"
#define ED25519_BIT_SIZE 256
#define ED25519_BYTE_SIZE ED25519_BIT_SIZE / 8
Expand Down

0 comments on commit fb3aa3b

Please sign in to comment.