Skip to content

Commit

Permalink
Implement EdDSA public key export
Browse files Browse the repository at this point in the history
Signed-off-by: Jakub Jelen <[email protected]>
  • Loading branch information
Jakuje committed Sep 20, 2023
1 parent aa89129 commit e159592
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 4 deletions.
23 changes: 22 additions & 1 deletion src/keymgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1757,14 +1757,35 @@ static int p11prov_ed_get_params(void *keydata, OSSL_PARAM params[])
return ret;
}
}
p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_PUB_KEY);
if (p) {
CK_ATTRIBUTE *pub;

if (p->data_type != OSSL_PARAM_OCTET_STRING) {
return RET_OSSL_ERR;
}
ret = p11prov_obj_get_ed_pub_key(key, &pub);
if (ret != RET_OSSL_OK) {
return ret;
}

p->return_size = pub->ulValueLen;
if (p->data) {
if (p->data_size < pub->ulValueLen) {
return RET_OSSL_ERR;
}
memcpy(p->data, pub->pValue, pub->ulValueLen);
p->data_size = pub->ulValueLen;
}
}

return RET_OSSL_OK;
}

static const OSSL_PARAM *p11prov_ed_gettable_params(void *provctx)
{
static const OSSL_PARAM params[] = {
/* TODO: OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0), */
OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0),
OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
Expand Down
32 changes: 32 additions & 0 deletions src/objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -1851,6 +1851,38 @@ int p11prov_obj_export_public_key(P11PROV_OBJ *obj, CK_KEY_TYPE key_type,
}
}

int p11prov_obj_get_ed_pub_key(P11PROV_OBJ *obj, CK_ATTRIBUTE **pub)
{
CK_ATTRIBUTE *a;

P11PROV_debug("get ed pubkey %p", *obj);

if (!obj) {
return RET_OSSL_ERR;
}

if (obj->class != CKO_PRIVATE_KEY && obj->class != CKO_PUBLIC_KEY) {
P11PROV_raise(obj->ctx, CKR_GENERAL_ERROR, "Invalid Object Class");
return RET_OSSL_ERR;
}

if (obj->data.key.type != CKK_EC_EDWARDS) {
P11PROV_raise(obj->ctx, CKR_GENERAL_ERROR, "Unsupported key type");
return RET_OSSL_ERR;
}

/* See if we have cached attributes first */
a = p11prov_obj_get_attr(obj, CKA_P11PROV_PUB_KEY);
if (!a) {
return RET_OSSL_ERR;
}

if (pub) {
*pub = a;
}
return RET_OSSL_OK;
}

int p11prov_obj_get_ec_public_x_y(P11PROV_OBJ *obj, CK_ATTRIBUTE **pub_x,
CK_ATTRIBUTE **pub_y)
{
Expand Down
1 change: 1 addition & 0 deletions src/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ int p11prov_obj_export_public_key(P11PROV_OBJ *obj, CK_KEY_TYPE key_type,
void *cb_arg);
int p11prov_obj_get_ec_public_x_y(P11PROV_OBJ *obj, CK_ATTRIBUTE **pub_x,
CK_ATTRIBUTE **pub_y);
int p11prov_obj_get_ed_pub_key(P11PROV_OBJ *obj, CK_ATTRIBUTE **pub);

#define OBJ_CMP_KEY_TYPE 0x00
#define OBJ_CMP_KEY_PUBLIC 0x01
Expand Down
6 changes: 4 additions & 2 deletions tests/tbasic
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,10 @@ fi
OPENSSL_CONF=${ORIG_OPENSSL_CONF}

title PARA "Test EVP_PKEY_eq on public RSA key both on token"
# shellcheck disable=SC2153 # PUBURIs is assigned
$CHECKER ./tcmpkeys "$PUBURI" "$PUBURI"
title PARA "Test EVP_PKEY_eq on public EC key both on token"
# shellcheck disable=SC2153 # ECURIs and ECXURIs are not spelling errors
# shellcheck disable=SC2153 # ECURIs and ECXURIs are assigned
$CHECKER ./tcmpkeys "$ECPUBURI" "$ECPUBURI"
if [[ -n $ECXPUBURI ]]; then
title PARA "Test EVP_PKEY_eq on public explicit EC key both on token"
Expand Down Expand Up @@ -192,7 +193,7 @@ if [[ -n $ECXPUBURI ]]; then
title PARA "Test EVP_PKEY_eq on public explicit EC key via import"
$CHECKER ./tcmpkeys "$ECXPUBURI" "${TMPPDIR}"/ecx.pub.uripin.pem
title PARA "Match private explicit EC key against public key"
# shellcheck disable=SC2153 # ECURIs and ECXURIs are not spelling errors
# shellcheck disable=SC2153 # ECURIs and ECXURIs are assigned
$CHECKER ./tcmpkeys "$ECXPRIURI" "${TMPPDIR}"/ecx.pub.uripin.pem
title PARA "Match private explicit EC key against public key (commutativity)"
$CHECKER ./tcmpkeys "${TMPPDIR}"/ecx.pub.uripin.pem "$ECXPRIURI"
Expand All @@ -203,6 +204,7 @@ if [[ -n $EDPUBURI ]]; then
title PARA "Test EVP_PKEY_eq on public Edwards key via import"
$CHECKER ./tcmpkeys "$EDPUBURI" "${TMPPDIR}"/ed.pub.uripin.pem
title PARA "Match private Edwards key against public key"
# shellcheck disable=SC2153 # EDPRIURI is assigned
$CHECKER ./tcmpkeys "$EDPRIURI" "${TMPPDIR}"/ed.pub.uripin.pem
title PARA "Match private Edwards key against public key (commutativity)"
$CHECKER ./tcmpkeys "${TMPPDIR}"/ed.pub.uripin.pem "$EDPRIURI"
Expand Down
54 changes: 53 additions & 1 deletion tests/tgenkey.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,31 @@ static void check_keys(OSSL_STORE_CTX *store, const char *key_type)
BN_free(tmp);
tmp = NULL;
}
} else if (strcmp(key_type, "ED25519") == 0) {
unsigned char *tmp = NULL;
size_t len = 0;
int ret;

ret = EVP_PKEY_get_octet_string_param(pubkey, OSSL_PKEY_PARAM_PUB_KEY,
NULL, 0, &len);
if (ret != 1) {
fprintf(stderr, "Failed to get public key size");
exit(EXIT_FAILURE);
}
tmp = malloc(len);
if (tmp == NULL) {
fprintf(stderr, "Failed to allocate memory for public key");
exit(EXIT_FAILURE);
}
ret = EVP_PKEY_get_octet_string_param(pubkey, OSSL_PKEY_PARAM_PUB_KEY,
tmp, len, NULL);
if (ret != 1) {
fprintf(stderr, "Failed to get public key");
exit(EXIT_FAILURE);
} else {
free(tmp);
tmp = NULL;
}
}

EVP_PKEY_free(privkey);
Expand Down Expand Up @@ -417,10 +442,37 @@ int main(int argc, char *argv[])
(char *)bad_usage, 0);

gen_keys("RSA", label, idhex, params, true);

free(label);
free(uri);

char *p11lib = getenv("P11LIB");
if (strstr(p11lib, "softhsm") != NULL) {
/* Check Ed25519 keys if supported */
ret = RAND_bytes(id, 16);
if (ret != 1) {
fprintf(stderr, "Failed to set generate key id\n");
exit(EXIT_FAILURE);
}
miniid = (id[0] << 24) + (id[1] << 16) + (id[2] << 8) + id[3];
ret = asprintf(&label, "Test-Ed-gen-%08x", miniid);
if (ret == -1) {
fprintf(stderr, "Failed to make label");
exit(EXIT_FAILURE);
}
hexify(idhex, id, 16);
ret = asprintf(&uri, "pkcs11:object=%s;id=%s", label, idhex);
if (ret == -1) {
fprintf(stderr, "Failed to make label");
exit(EXIT_FAILURE);
}
params[0] = OSSL_PARAM_construct_utf8_string("pkcs11_uri", uri, 0);
params[1] = OSSL_PARAM_construct_end();

gen_keys("ED25519", label, idhex, params, false);
free(label);
free(uri);
}

fprintf(stderr, "ALL A-OK!");
exit(EXIT_SUCCESS);
}

0 comments on commit e159592

Please sign in to comment.