Path: blob/main/crypto/openssl/providers/implementations/keymgmt/template_kmgmt.c
108395 views
/*1* Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved.2*3* Licensed under the Apache License 2.0 (the "License"). You may not use4* this file except in compliance with the License. You can obtain a copy5* in the file LICENSE in the source distribution or at6* https://www.openssl.org/source/license.html7*/89#include <openssl/core_dispatch.h>10#include <openssl/core_names.h>11#include <openssl/params.h>12#include <openssl/err.h>13#include <openssl/proverr.h>14#include <openssl/evp.h>15#include <openssl/rand.h>16#include <openssl/self_test.h>17#include "internal/param_build_set.h"18#include <openssl/param_build.h>19#include "prov/implementations.h"20#include "prov/providercommon.h"21#include "prov/provider_ctx.h"22#include "prov/securitycheck.h"2324extern const OSSL_DISPATCH ossl_template_keymgmt_functions[];2526#define BUFSIZE 100027#if defined(NDEBUG) || defined(OPENSSL_NO_STDIO)28static void debug_print(char *fmt, ...)29{30}31#else32static void debug_print(char *fmt, ...)33{34char out[BUFSIZE];35va_list argptr;3637va_start(argptr, fmt);38vsnprintf(out, BUFSIZE, fmt, argptr);39va_end(argptr);40if (getenv("TEMPLATEKM"))41fprintf(stderr, "TEMPLATE_KM: %s", out);42}43#endif4445static OSSL_FUNC_keymgmt_new_fn template_new;46static OSSL_FUNC_keymgmt_free_fn template_free;47static OSSL_FUNC_keymgmt_gen_init_fn template_gen_init;48static OSSL_FUNC_keymgmt_gen_fn template_gen;49static OSSL_FUNC_keymgmt_gen_cleanup_fn template_gen_cleanup;50static OSSL_FUNC_keymgmt_gen_set_params_fn template_gen_set_params;51static OSSL_FUNC_keymgmt_gen_settable_params_fn template_gen_settable_params;52static OSSL_FUNC_keymgmt_get_params_fn template_get_params;53static OSSL_FUNC_keymgmt_gettable_params_fn template_gettable_params;54static OSSL_FUNC_keymgmt_set_params_fn template_set_params;55static OSSL_FUNC_keymgmt_settable_params_fn template_settable_params;56static OSSL_FUNC_keymgmt_has_fn template_has;57static OSSL_FUNC_keymgmt_match_fn template_match;58static OSSL_FUNC_keymgmt_import_fn template_import;59static OSSL_FUNC_keymgmt_export_fn template_export;60static OSSL_FUNC_keymgmt_import_types_fn template_imexport_types;61static OSSL_FUNC_keymgmt_export_types_fn template_imexport_types;6263static OSSL_FUNC_keymgmt_dup_fn template_dup;6465struct template_gen_ctx {66void *provctx;67int selection;68};6970static void *template_new(void *provctx)71{72void *key = NULL;7374debug_print("new key req\n");75if (!ossl_prov_is_running())76return 0;7778/* add logic to create new key */7980debug_print("new key = %p\n", key);81return key;82}8384static void template_free(void *vkey)85{86debug_print("free key %p\n", vkey);87if (vkey == NULL)88return;8990/* add logic to free all key components */9192OPENSSL_free(vkey);93}9495static int template_has(const void *keydata, int selection)96{97int ok = 0;9899debug_print("has %p\n", keydata);100if (ossl_prov_is_running() && keydata != NULL) {101/* add logic to check whether this key has the requested parameters */102}103debug_print("has result %d\n", ok);104return ok;105}106107static int template_match(const void *keydata1, const void *keydata2, int selection)108{109int ok = 1;110111debug_print("matching %p and %p\n", keydata1, keydata2);112if (!ossl_prov_is_running())113return 0;114115if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)116ok = ok && keydata1 != NULL && keydata2 != NULL;117118if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {119int key_checked = 0;120121if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {122/* validate whether the public keys match */123}124if (!key_checked125&& (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {126/* validate whether the private keys match */127}128ok = ok && key_checked;129}130debug_print("match result %d\n", ok);131return ok;132}133134static int key_to_params(void *key, OSSL_PARAM_BLD *tmpl,135OSSL_PARAM params[], int include_private)136{137if (key == NULL)138return 0;139140/* add public and/or private key parts to templ as possible */141142return 1;143}144145static int template_export(void *key, int selection, OSSL_CALLBACK *param_cb,146void *cbarg)147{148OSSL_PARAM_BLD *tmpl;149OSSL_PARAM *params = NULL;150int ret = 0;151152debug_print("export %p\n", key);153if (!ossl_prov_is_running() || key == NULL)154return 0;155156if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)157return 0;158159tmpl = OSSL_PARAM_BLD_new();160if (tmpl == NULL)161return 0;162163if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {164int include_private = ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0);165166if (!key_to_params(key, tmpl, NULL, include_private))167goto err;168}169170params = OSSL_PARAM_BLD_to_param(tmpl);171if (params == NULL)172goto err;173174ret = param_cb(params, cbarg);175OSSL_PARAM_free(params);176err:177OSSL_PARAM_BLD_free(tmpl);178debug_print("export result %d\n", ret);179return ret;180}181182static int ossl_template_key_fromdata(void *key,183const OSSL_PARAM params[],184int include_private)185{186const OSSL_PARAM *param_priv_key = NULL, *param_pub_key;187188if (key == NULL)189return 0;190if (ossl_param_is_empty(params))191return 0;192193/* validate integrity of key (algorithm type specific) */194195param_pub_key = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY);196if (include_private)197param_priv_key = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY);198199if (param_pub_key == NULL && param_priv_key == NULL)200return 0;201202if (param_priv_key != NULL) {203/* retrieve private key and check integrity */204}205206if (param_pub_key != NULL) {207/* retrieve public key and check integrity */208}209210return 1;211}212213static int template_import(void *key, int selection, const OSSL_PARAM params[])214{215int ok = 1;216int include_private;217218debug_print("import %p\n", key);219if (!ossl_prov_is_running() || key == NULL)220return 0;221222if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)223return 0;224225include_private = selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;226ok = ok && ossl_template_key_fromdata(key, params, include_private);227228debug_print("import result %d\n", ok);229return ok;230}231232#define TEMPLATE_KEY_TYPES() \233OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0), \234OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0)235236static const OSSL_PARAM template_key_types[] = {237TEMPLATE_KEY_TYPES(),238OSSL_PARAM_END239};240241static const OSSL_PARAM *template_imexport_types(int selection)242{243debug_print("getting imexport types\n");244if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)245return template_key_types;246return NULL;247}248249static int template_get_params(void *key, OSSL_PARAM params[])250{251OSSL_PARAM *p;252253debug_print("get params %p\n", key);254255if (ossl_param_is_empty(params))256return 0;257258/* return sensible values for at least these parameters */259260if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL261&& !OSSL_PARAM_set_int(p, 0))262return 0;263if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL264&& !OSSL_PARAM_set_int(p, 0))265return 0;266if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL267&& !OSSL_PARAM_set_int(p, 0))268return 0;269if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY)) != NULL) {270if (!OSSL_PARAM_set_octet_string(p, NULL, 0))271return 0;272}273274debug_print("get params OK\n");275return 1;276}277278static const OSSL_PARAM template_gettable_params_arr[] = {279OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),280OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),281OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),282OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),283OSSL_PARAM_END284};285286static const OSSL_PARAM *template_gettable_params(void *provctx)287{288debug_print("gettable params called\n");289return template_gettable_params_arr;290}291292static int template_set_params(void *key, const OSSL_PARAM params[])293{294const OSSL_PARAM *p;295296debug_print("set params called for %p\n", key);297if (ossl_param_is_empty(params))298return 1; /* OK not to set anything */299300p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY);301if (p != NULL) {302/* load public key structure */303}304305debug_print("set params OK\n");306return 1;307}308309static const OSSL_PARAM template_settable_params_arr[] = {310OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),311OSSL_PARAM_END312};313314static const OSSL_PARAM *template_settable_params(void *provctx)315{316debug_print("settable params called\n");317return template_settable_params_arr;318}319320static int template_gen_set_params(void *genctx, const OSSL_PARAM params[])321{322struct template_gen_ctx *gctx = genctx;323324if (gctx == NULL)325return 0;326327debug_print("empty gen_set params called for %p\n", gctx);328return 1;329}330331static void *template_gen_init(void *provctx, int selection,332const OSSL_PARAM params[])333{334struct template_gen_ctx *gctx = NULL;335336debug_print("gen init called for %p\n", provctx);337338/* perform algorithm type specific sanity checks */339340if (!ossl_prov_is_running())341return NULL;342343if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) {344gctx->provctx = provctx;345gctx->selection = selection;346}347if (!template_gen_set_params(gctx, params)) {348OPENSSL_free(gctx);349gctx = NULL;350}351debug_print("gen init returns %p\n", gctx);352return gctx;353}354355static const OSSL_PARAM *template_gen_settable_params(ossl_unused void *genctx,356ossl_unused void *provctx)357{358static OSSL_PARAM settable[] = {359OSSL_PARAM_END360};361return settable;362}363364static void *template_gen(void *vctx, OSSL_CALLBACK *osslcb, void *cbarg)365{366struct template_gen_ctx *gctx = (struct template_gen_ctx *)vctx;367void *key = NULL;368369debug_print("gen called for %p\n", gctx);370371if (gctx == NULL)372goto err;373374/* generate and return new key */375376debug_print("gen returns set %p\n", key);377return key;378err:379template_free(key);380debug_print("gen returns NULL\n");381return NULL;382}383384static void template_gen_cleanup(void *genctx)385{386struct template_gen_ctx *gctx = genctx;387388if (gctx == NULL)389return;390391debug_print("gen cleanup for %p\n", gctx);392OPENSSL_free(gctx);393}394395static void *template_dup(const void *vsrckey, int selection)396{397void *dstkey = NULL;398399debug_print("dup called for %p\n", vsrckey);400if (!ossl_prov_is_running())401return NULL;402403dstkey = template_new(NULL);404if (dstkey == NULL)405goto err;406407/* populate dstkey from vsrckey material */408409debug_print("dup returns %p\n", dstkey);410return dstkey;411err:412template_free(dstkey);413debug_print("dup returns NULL\n");414return NULL;415}416417const OSSL_DISPATCH ossl_template_keymgmt_functions[] = {418{ OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))template_new },419{ OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))template_free },420{ OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*)(void))template_get_params },421{ OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*)(void))template_gettable_params },422{ OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*)(void))template_set_params },423{ OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*)(void))template_settable_params },424{ OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))template_has },425{ OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))template_match },426{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))template_imexport_types },427{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))template_imexport_types },428{ OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))template_import },429{ OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))template_export },430{ OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))template_gen_init },431{ OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))template_gen_set_params },432{ OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS,433(void (*)(void))template_gen_settable_params },434{ OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))template_gen },435{ OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))template_gen_cleanup },436{ OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))template_dup },437OSSL_DISPATCH_END438};439440441