From d0a3393107a9e348bce44870ddbff3c7d790ce5e Mon Sep 17 00:00:00 2001 From: Eduard Sabirov Date: Fri, 27 Dec 2024 12:07:12 +0300 Subject: [PATCH 1/3] Fix serialization pub key Currently, EVP_PKEY_print_public specifies an incorrect key class for the generated EVP_PKEY. Now selection is also used to get the key class. Signed-off-by: Eduard Sabirov --- src/encoder.c | 8 ++++---- src/util.c | 8 ++++++-- src/util.h | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/encoder.c b/src/encoder.c index 66d75f5c..f5cae6cb 100644 --- a/src/encoder.c +++ b/src/encoder.c @@ -140,7 +140,7 @@ static int p11prov_rsa_encoder_encode_text(void *inctx, OSSL_CORE_BIO *cbio, } } - uri = p11prov_key_to_uri(ctx->provctx, key); + uri = p11prov_key_to_uri(ctx->provctx, key, selection); if (uri) { BIO_printf(out, "URI %s\n", uri); free(uri); @@ -474,7 +474,7 @@ static P11PROV_PK11_URI *p11prov_encoder_private_key_to_asn1(P11PROV_CTX *pctx, size_t uri_len; int ret = RET_OSSL_ERR; - uri = p11prov_key_to_uri(pctx, key); + uri = p11prov_key_to_uri(pctx, key, OSSL_KEYMGMT_SELECT_PRIVATE_KEY); if (!uri) { goto done; } @@ -896,7 +896,7 @@ static int p11prov_ec_encoder_encode_text(void *inctx, OSSL_CORE_BIO *cbio, } } - uri = p11prov_key_to_uri(ctx->provctx, key); + uri = p11prov_key_to_uri(ctx->provctx, key, selection); if (uri) { BIO_printf(out, "URI %s\n", uri); } @@ -1014,7 +1014,7 @@ static int p11prov_ec_edwards_encoder_encode_text( } } - uri = p11prov_key_to_uri(ctx->provctx, key); + uri = p11prov_key_to_uri(ctx->provctx, key, selection); if (uri) { BIO_printf(out, "URI %s\n", uri); } diff --git a/src/util.c b/src/util.c index 66a3bd0f..13c5f68c 100644 --- a/src/util.c +++ b/src/util.c @@ -670,7 +670,7 @@ static char *uri_component(const char *name, const char *val, size_t vlen, return c; } -char *p11prov_key_to_uri(P11PROV_CTX *ctx, P11PROV_OBJ *key) +char *p11prov_key_to_uri(P11PROV_CTX *ctx, P11PROV_OBJ *key, int selection) { P11PROV_SLOTS_CTX *slots; P11PROV_SLOT *slot; @@ -691,7 +691,11 @@ char *p11prov_key_to_uri(P11PROV_CTX *ctx, P11PROV_OBJ *key) size_t size_hint = 0; CK_RV ret; - class = p11prov_obj_get_class(key); + if (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) { + class = CKO_PUBLIC_KEY; + } else { + class = p11prov_obj_get_class(key); + } slot_id = p11prov_obj_get_slotid(key); cka_id = p11prov_obj_get_attr(key, CKA_ID); cka_label = p11prov_obj_get_attr(key, CKA_LABEL); diff --git a/src/util.h b/src/util.h index a96eec72..7c5d9d9d 100644 --- a/src/util.h +++ b/src/util.h @@ -54,7 +54,7 @@ void p11prov_fetch_attrs_free(struct fetch_attrs *attrs, int num); #define MAX_PIN_LENGTH 32 int parse_ulong(P11PROV_CTX *ctx, const char *str, size_t len, void **output); P11PROV_URI *p11prov_parse_uri(P11PROV_CTX *ctx, const char *uri); -char *p11prov_key_to_uri(P11PROV_CTX *ctx, P11PROV_OBJ *key); +char *p11prov_key_to_uri(P11PROV_CTX *ctx, P11PROV_OBJ *key, int selection); void p11prov_uri_free(P11PROV_URI *parsed_uri); CK_OBJECT_CLASS p11prov_uri_get_class(P11PROV_URI *uri); void p11prov_uri_set_class(P11PROV_URI *uri, CK_OBJECT_CLASS class); From 90a0b8a4586f545254a19dc0e87b5b3f4d3f946f Mon Sep 17 00:00:00 2001 From: Eduard Sabirov Date: Fri, 27 Dec 2024 12:12:59 +0300 Subject: [PATCH 2/3] Fix a bug with freeing up the memory of an object for which memory is allocated using openssl Signed-off-by: Eduard Sabirov --- src/encoder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/encoder.c b/src/encoder.c index f5cae6cb..4376b59f 100644 --- a/src/encoder.c +++ b/src/encoder.c @@ -143,7 +143,7 @@ static int p11prov_rsa_encoder_encode_text(void *inctx, OSSL_CORE_BIO *cbio, uri = p11prov_key_to_uri(ctx->provctx, key, selection); if (uri) { BIO_printf(out, "URI %s\n", uri); - free(uri); + OPENSSL_free(uri); } BIO_free(out); From 70f5d83728977538dcfc7f2c4cc5c3bf45a0fff1 Mon Sep 17 00:00:00 2001 From: Eduard Sabirov Date: Fri, 27 Dec 2024 11:49:07 +0300 Subject: [PATCH 3/3] Add a test with public information about the generated key Signed-off-by: Eduard Sabirov --- tests/meson.build | 2 + tests/tbasic | 4 ++ tests/tgetinfopkey.c | 127 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 133 insertions(+) create mode 100644 tests/tgetinfopkey.c diff --git a/tests/meson.build b/tests/meson.build index abbdaa62..7f052a1d 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -106,6 +106,7 @@ test_programs = { 'tcmpkeys': ['tcmpkeys.c', 'util.c'], 'tfork': ['tfork.c'], 'pincache': ['pincache.c'], + 'tgetinfopkey': ['tgetinfopkey.c'] } test_executables = [] @@ -133,6 +134,7 @@ tests = { 'rsapss': {'suites': ['softokn', 'softhsm', 'kryoptic', 'kryoptic.nss']}, 'rsapssam': {'suites': ['softhsm']}, 'genkey': {'suites': ['softokn', 'softhsm', 'kryoptic', 'kryoptic.nss']}, + 'getinfopkey': {'suites': ['softokn', 'softhsm']}, 'session': {'suites': ['softokn', 'softhsm', 'kryoptic', 'kryoptic.nss']}, 'rand': {'suites': ['softokn', 'softhsm', 'kryoptic', 'kryoptic.nss']}, 'readkeys': {'suites': ['softokn', 'softhsm', 'kryoptic', 'kryoptic.nss']}, diff --git a/tests/tbasic b/tests/tbasic index 02c9ac88..377937b2 100755 --- a/tests/tbasic +++ b/tests/tbasic @@ -296,5 +296,9 @@ if [ $FAIL -ne 0 ]; then echo exit 1 fi +OPENSSL_CONF=${ORIG_OPENSSL_CONF} + +title PARA "Test Get generated key info" +$CHECKER "${TESTBLDDIR}/tgetinfopkey" exit 0 diff --git a/tests/tgetinfopkey.c b/tests/tgetinfopkey.c new file mode 100644 index 00000000..00a370b1 --- /dev/null +++ b/tests/tgetinfopkey.c @@ -0,0 +1,127 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include + +static void hexify(char *out, unsigned char *byte, size_t len) +{ + char c[2], s; + + for (size_t i = 0; i < len; i++) { + out[i * 3] = '%'; + c[0] = byte[i] >> 4; + c[1] = byte[i] & 0x0f; + for (int j = 0; j < 2; j++) { + if (c[j] < 0x0A) { + s = '0'; + } else { + s = 'a' - 10; + } + out[i * 3 + 1 + j] = c[j] + s; + } + } + out[len * 3] = '\0'; +} + +int main(int argc, char *argv[]) +{ + char *label; + unsigned char id[16]; + char idhex[16 * 3 + 1]; + char *uri; + size_t rsa_bits = 1024; + const char *key_usage = "digitalSignature"; + OSSL_PARAM params[4]; + int miniid; + EVP_PKEY_CTX *ctx; + EVP_PKEY *key = NULL; + BIO *mem; + int maxlen = 4000; + char buf[maxlen]; + const char pub_part[] = "type=public"; + int ret; + + ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", "provider=pkcs11"); + if (ctx == NULL) { + fprintf(stderr, "Failed to init PKEY context for generate\n"); + exit(EXIT_FAILURE); + } + + ret = EVP_PKEY_keygen_init(ctx); + if (ret != 1) { + fprintf(stderr, "Failed to init keygen\n"); + exit(EXIT_FAILURE); + } + + ret = RAND_bytes(id, 16); + if (ret != 1) { + fprintf(stderr, "Failed to generate key id\n"); + exit(EXIT_FAILURE); + } + miniid = (id[0] << 24) + (id[1] << 16) + (id[2] << 8) + id[3]; + ret = asprintf(&label, "Test-RSA-gen-%08x", miniid); + if (ret == -1) { + fprintf(stderr, "Failed to make label\n"); + exit(EXIT_FAILURE); + } + hexify(idhex, id, 16); + ret = asprintf(&uri, "pkcs11:object=%s;id=%s", label, idhex); + if (ret == -1) { + fprintf(stderr, "Failed to compose PKCS#11 URI\n"); + exit(EXIT_FAILURE); + } + params[0] = OSSL_PARAM_construct_utf8_string("pkcs11_uri", uri, 0); + params[1] = OSSL_PARAM_construct_utf8_string("pkcs11_key_usage", + (char *)key_usage, 0); + params[2] = + OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_RSA_BITS, &rsa_bits); + params[3] = OSSL_PARAM_construct_end(); + ret = EVP_PKEY_CTX_set_params(ctx, params); + if (ret != 1) { + fprintf(stderr, "Failed to set params\n"); + exit(EXIT_FAILURE); + } + + ret = EVP_PKEY_generate(ctx, &key); + if (ret != 1) { + fprintf(stderr, "Failed to generate key\n"); + exit(EXIT_FAILURE); + } + + EVP_PKEY_CTX_free(ctx); + + ctx = EVP_PKEY_CTX_new_from_pkey(NULL, key, "provider=pkcs11"); + if (ctx == NULL) { + fprintf(stderr, "Failed to init PKEY context for sign\n"); + exit(EXIT_FAILURE); + } + + mem = BIO_new(BIO_s_mem()); + if (mem == NULL) { + fprintf(stderr, "Failed to init BIO\n"); + exit(EXIT_FAILURE); + } + + ret = EVP_PKEY_print_public(mem, key, 0, NULL); + if (ret != 1) { + fprintf(stderr, "Failed to print public key\n"); + exit(EXIT_FAILURE); + } + + memset(buf, 0x00, maxlen); + BIO_read(mem, buf, maxlen); + if (strstr(buf, pub_part) == NULL) { + fprintf(stderr, "Incorrect information about the public key\n"); + exit(EXIT_FAILURE); + } + + BIO_free(mem); + EVP_PKEY_CTX_free(ctx); + EVP_PKEY_free(key); + exit(EXIT_SUCCESS); +}