Skip to content

Commit

Permalink
Implement settable param OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY for EC keys
Browse files Browse the repository at this point in the history
This is required for EVP_PKEY_set1_encoded_public_key (used by
CMS_decrypt_set1_pkey_and_peer for example).

Signed-off-by: manison <[email protected]>
  • Loading branch information
manison committed Aug 28, 2023
1 parent ac2cffa commit 11d8f68
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 0 deletions.
38 changes: 38 additions & 0 deletions src/keymgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1003,6 +1003,8 @@ DISPATCH_KEYMGMT_FN(ec, export_types);
DISPATCH_KEYMGMT_FN(ec, query_operation_name);
DISPATCH_KEYMGMT_FN(ec, get_params);
DISPATCH_KEYMGMT_FN(ec, gettable_params);
DISPATCH_KEYMGMT_FN(ec, set_params);
DISPATCH_KEYMGMT_FN(ec, settable_params);

static void *p11prov_ec_new(void *provctx)
{
Expand Down Expand Up @@ -1373,6 +1375,40 @@ static const OSSL_PARAM *p11prov_ec_gettable_params(void *provctx)
return params;
}

static int p11prov_ec_set_params(void *keydata, const OSSL_PARAM params[])
{
P11PROV_OBJ *key = (P11PROV_OBJ *)keydata;
const OSSL_PARAM *p;

P11PROV_debug("ec set params %p", keydata);

if (key == NULL) {
return RET_OSSL_ERR;
}

p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY);
if (p) {
if (p->data_type != OSSL_PARAM_OCTET_STRING) {
return RET_OSSL_ERR;
}
if (p11prov_obj_set_ec_encoded_public_key(key, p->data, p->data_size)
!= CKR_OK) {
return RET_OSSL_ERR;
}
}

return RET_OSSL_OK;
}

static const OSSL_PARAM *p11prov_ec_settable_params(void *provctx)
{
static const OSSL_PARAM params[] = {
OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),
OSSL_PARAM_END,
};
return params;
}

const OSSL_DISPATCH p11prov_ec_keymgmt_functions[] = {
DISPATCH_KEYMGMT_ELEM(ec, NEW, new),
DISPATCH_KEYMGMT_ELEM(ec, GEN_INIT, gen_init),
Expand All @@ -1391,6 +1427,8 @@ const OSSL_DISPATCH p11prov_ec_keymgmt_functions[] = {
DISPATCH_KEYMGMT_ELEM(ec, QUERY_OPERATION_NAME, query_operation_name),
DISPATCH_KEYMGMT_ELEM(ec, GET_PARAMS, get_params),
DISPATCH_KEYMGMT_ELEM(ec, GETTABLE_PARAMS, gettable_params),
DISPATCH_KEYMGMT_ELEM(ec, SET_PARAMS, set_params),
DISPATCH_KEYMGMT_ELEM(ec, SETTABLE_PARAMS, settable_params),
{ 0, NULL },
};

Expand Down
62 changes: 62 additions & 0 deletions src/objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -2557,3 +2557,65 @@ CK_RV p11prov_obj_import_key(P11PROV_OBJ *key, CK_KEY_TYPE type,
}
return rv;
}

CK_RV p11prov_obj_set_ec_encoded_public_key(P11PROV_OBJ *key,
const void *pubkey,
size_t pubkey_len)
{
CK_RV rv;
CK_ATTRIBUTE *pub;
CK_ATTRIBUTE *ecpoint;
CK_ATTRIBUTE new_pub;
ASN1_OCTET_STRING oct;
unsigned char *der = NULL;
int len;

if (key->handle != CK_INVALID_HANDLE) {
/*
* not a mock object, cannot set public key to a token object backed by
* an actual handle
*/
P11PROV_raise(key->ctx, CKR_KEY_INDIGESTIBLE,
"Cannot change public key of a token object");
return CKR_KEY_INDIGESTIBLE;
}

pub = p11prov_obj_get_attr(key, CKA_P11PROV_PUB_KEY);
if (!pub) {
P11PROV_raise(key->ctx, CKR_KEY_INDIGESTIBLE, "No public key found");
return CKR_KEY_INDIGESTIBLE;
}

ecpoint = p11prov_obj_get_attr(key, CKA_EC_POINT);
if (!ecpoint) {
P11PROV_raise(key->ctx, CKR_KEY_INDIGESTIBLE, "No public key found");
return CKR_KEY_INDIGESTIBLE;
}

OPENSSL_free(pub->pValue);
memset(pub, 0, sizeof(CK_ATTRIBUTE));
new_pub.type = CKA_P11PROV_PUB_KEY;
new_pub.pValue = (CK_VOID_PTR)pubkey;
new_pub.ulValueLen = (CK_ULONG)pubkey_len;
rv = p11prov_copy_attr(pub, &new_pub);
if (rv != CKR_OK) {
return rv;
}

oct.data = (unsigned char *)pubkey;
oct.length = (int)pubkey_len;
oct.flags = 0;

len = i2d_ASN1_OCTET_STRING(&oct, &der);
if (len < 0) {
P11PROV_raise(key->ctx, CKR_KEY_INDIGESTIBLE,
"Failure to encode EC point to DER");
return CKR_KEY_INDIGESTIBLE;
}

OPENSSL_free(ecpoint->pValue);
ecpoint->pValue = der;
ecpoint->ulValueLen = len;

return CKR_OK;
}
4 changes: 4 additions & 0 deletions src/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ int p11prov_obj_key_cmp(P11PROV_OBJ *obj1, P11PROV_OBJ *obj2, CK_KEY_TYPE type,
CK_RV p11prov_obj_import_key(P11PROV_OBJ *key, CK_KEY_TYPE type,
CK_OBJECT_CLASS class, const OSSL_PARAM params[]);

CK_RV p11prov_obj_set_ec_encoded_public_key(P11PROV_OBJ *key,
const void *pubkey,
size_t pubkey_len);

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

0 comments on commit 11d8f68

Please sign in to comment.