Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Embed the private key with public key attributes. #293

Merged
merged 2 commits into from
Sep 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
sahanaprasad07 marked this conversation as resolved.
Show resolved Hide resolved
}

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
94 changes: 55 additions & 39 deletions tests/tgenkey.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,52 @@ static void hexify(char *out, unsigned char *byte, size_t len)
out[len * 3] = '\0';
}

static void check_rsa_key(EVP_PKEY *pubkey)
{
BIGNUM *tmp = NULL;
int ret;

ret = EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_RSA_E, &tmp);
if (ret != 1) {
fprintf(stderr, "Failed to get E param from public key");
exit(EXIT_FAILURE);
} else {
BN_free(tmp);
tmp = NULL;
}
ret = EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_RSA_N, &tmp);
if (ret != 1) {
fprintf(stderr, "Failed to get N param from public key");
exit(EXIT_FAILURE);
} else {
BN_free(tmp);
tmp = NULL;
}
}

static void check_ec_key(EVP_PKEY *pubkey)
{
BIGNUM *tmp = NULL;
int ret;

ret = EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_EC_PUB_X, &tmp);
if (ret != 1) {
fprintf(stderr, "Failed to get X param from public key");
exit(EXIT_FAILURE);
} else {
BN_free(tmp);
tmp = NULL;
}
ret = EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_EC_PUB_Y, &tmp);
if (ret != 1) {
fprintf(stderr, "Failed to get Y param from public key");
exit(EXIT_FAILURE);
} else {
BN_free(tmp);
tmp = NULL;
}
}

static void check_keys(OSSL_STORE_CTX *store, const char *key_type)
{
OSSL_STORE_INFO *info;
Expand Down Expand Up @@ -70,46 +116,10 @@ static void check_keys(OSSL_STORE_CTX *store, const char *key_type)
}

/* check we can get pub params from key */
if (strcmp(key_type, "RSA") == 0) {
BIGNUM *tmp = NULL;
int ret;

ret = EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_RSA_E, &tmp);
if (ret != 1) {
fprintf(stderr, "Failed to get E param from public key");
exit(EXIT_FAILURE);
} else {
BN_free(tmp);
tmp = NULL;
}
ret = EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_RSA_N, &tmp);
if (ret != 1) {
fprintf(stderr, "Failed to get N param from public key");
exit(EXIT_FAILURE);
} else {
BN_free(tmp);
tmp = NULL;
}
if (strcmp(key_type, "RSA") == 0 || strcmp(key_type, "RSA-PSS") == 0) {
check_rsa_key(pubkey);
} else if (strcmp(key_type, "EC") == 0) {
BIGNUM *tmp = NULL;
int ret;

ret = EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_EC_PUB_X, &tmp);
if (ret != 1) {
fprintf(stderr, "Failed to get X param from public key");
exit(EXIT_FAILURE);
} else {
BN_free(tmp);
tmp = NULL;
}
ret = EVP_PKEY_get_bn_param(pubkey, OSSL_PKEY_PARAM_EC_PUB_Y, &tmp);
if (ret != 1) {
fprintf(stderr, "Failed to get Y param from public key");
exit(EXIT_FAILURE);
} else {
BN_free(tmp);
tmp = NULL;
}
check_ec_key(pubkey);
}

EVP_PKEY_free(privkey);
Expand Down Expand Up @@ -161,6 +171,12 @@ static void gen_keys(const char *key_type, const char *label, const char *idhex,
exit(EXIT_FAILURE);
}

if (strcmp(key_type, "RSA") == 0 || strcmp(key_type, "RSA-PSS") == 0) {
check_rsa_key(key);
} else if (strcmp(key_type, "EC") == 0) {
check_ec_key(key);
}

EVP_PKEY_free(key);
key = NULL;
EVP_PKEY_CTX_free(ctx);
Expand Down