From 03f42fa00c2efbc8da9777ee10ee2771975fb4c8 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 25 Jan 2024 17:38:54 +0100 Subject: [PATCH] Implement text encoder for Ed25519 keys Signed-off-by: Jakub Jelen --- src/encoder.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/encoder.h | 1 + src/provider.c | 4 +++ tests/tedwards | 2 +- 4 files changed, 78 insertions(+), 1 deletion(-) diff --git a/src/encoder.c b/src/encoder.c index 1de54cc6..40aecdb7 100644 --- a/src/encoder.c +++ b/src/encoder.c @@ -802,3 +802,75 @@ const OSSL_DISPATCH p11prov_ec_encoder_text_functions[] = { DISPATCH_TEXT_ENCODER_ELEM(ENCODE, ec, encode_text), { 0, NULL }, }; + +DISPATCH_TEXT_ENCODER_FN(ed, encode); + +static int p11prov_ed_encoder_encode_text(void *inctx, OSSL_CORE_BIO *cbio, + const void *inkey, + const OSSL_PARAM key_abstract[], + int selection, + OSSL_PASSPHRASE_CALLBACK *cb, + void *cbarg) +{ + struct p11prov_encoder_ctx *ctx = (struct p11prov_encoder_ctx *)inctx; + P11PROV_OBJ *key = (P11PROV_OBJ *)inkey; + CK_KEY_TYPE type; + CK_ULONG keysize; + const char *type_name = "ED25519"; + char *uri = NULL; + BIO *out; + int ret; + + P11PROV_debug("EdDSA Text Encoder"); + + type = p11prov_obj_get_key_type(key); + if (type != CKK_EC_EDWARDS) { + P11PROV_raise(ctx->provctx, CKR_GENERAL_ERROR, "Invalid Key Type"); + return RET_OSSL_ERR; + } + + out = BIO_new_from_core_bio(p11prov_ctx_get_libctx(ctx->provctx), cbio); + if (!out) { + P11PROV_raise(ctx->provctx, CKR_GENERAL_ERROR, "Failed to init BIO"); + return RET_OSSL_ERR; + } + + keysize = p11prov_obj_get_key_bit_size(key); + if (keysize == 448) { + type_name = "ED448"; + } + if (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) { + CK_OBJECT_CLASS class = p11prov_obj_get_class(key); + if (class != CKO_PRIVATE_KEY) { + return RET_OSSL_ERR; + } + BIO_printf(out, "PKCS11 %s Private Key (%lu bits)\n", type_name, keysize); + BIO_printf(out, "[Can't export and print private key data]\n"); + } + + if (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) { + BIO_printf(out, "PKCS11 %s Public Key (%lu bits)\n", type_name, keysize); + ret = p11prov_obj_export_public_key(key, CKK_EC_EDWARDS, true, + p11prov_ec_print_public_key, out); + /* FIXME if we want print in different format */ + if (ret != RET_OSSL_OK) { + BIO_printf(out, "[Error: Failed to decode public key data]\n"); + } + } + + uri = p11prov_key_to_uri(ctx->provctx, key); + if (uri) { + BIO_printf(out, "URI %s\n", uri); + } + + OPENSSL_free(uri); + BIO_free(out); + return RET_OSSL_OK; +} + +const OSSL_DISPATCH p11prov_ed_encoder_text_functions[] = { + DISPATCH_BASE_ENCODER_ELEM(NEWCTX, newctx), + DISPATCH_BASE_ENCODER_ELEM(FREECTX, freectx), + DISPATCH_TEXT_ENCODER_ELEM(ENCODE, ed, encode_text), + { 0, NULL }, +}; diff --git a/src/encoder.h b/src/encoder.h index 1e4b2944..9e97a756 100644 --- a/src/encoder.h +++ b/src/encoder.h @@ -36,5 +36,6 @@ extern const OSSL_DISPATCH p11prov_ec_encoder_text_functions[]; extern const OSSL_DISPATCH p11prov_ec_encoder_pkcs1_der_functions[]; extern const OSSL_DISPATCH p11prov_ec_encoder_pkcs1_pem_functions[]; extern const OSSL_DISPATCH p11prov_ec_encoder_spki_der_functions[]; +extern const OSSL_DISPATCH p11prov_ed_encoder_text_functions[]; #endif /* _ENCODER_H */ diff --git a/src/provider.c b/src/provider.c index 0d416fea..3617a4a3 100644 --- a/src/provider.c +++ b/src/provider.c @@ -1075,6 +1075,10 @@ static CK_RV operations_init(P11PROV_CTX *ctx) ADD_ALGO_EXT(EC, encoder, "provider=pkcs11,output=der,structure=SubjectPublicKeyInfo", p11prov_ec_encoder_spki_der_functions); + ADD_ALGO_EXT(ED25519, encoder, "provider=pkcs11,output=text", + p11prov_ed_encoder_text_functions); + ADD_ALGO_EXT(ED448, encoder, "provider=pkcs11,output=text", + p11prov_ed_encoder_text_functions); TERM_ALGO(encoder); /* handle random */ diff --git a/tests/tedwards b/tests/tedwards index 425e5434..c1ea7aca 100755 --- a/tests/tedwards +++ b/tests/tedwards @@ -11,7 +11,7 @@ title LINE "Print ED25519 Public key from private" ossl 'pkey -in $EDPRIURI -pubout -text' $helper_emit output="$helper_output" FAIL=0 -echo "$output" | grep "ED25519 Public-Key" > /dev/null 2>&1 || FAIL=1 +echo "$output" | grep "ED25519 Public Key" > /dev/null 2>&1 || FAIL=1 if [ $FAIL -eq 1 ]; then echo "Could not extract public key from private" echo