Path: blob/main/crypto/openssl/providers/implementations/keymgmt/template_kmgmt.c
48292 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 =198OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY);199200if (param_pub_key == NULL && param_priv_key == NULL)201return 0;202203if (param_priv_key != NULL) {204/* retrieve private key and check integrity */205}206207if (param_pub_key != NULL) {208/* retrieve public key and check integrity */209}210211return 1;212}213214static int template_import(void *key, int selection, const OSSL_PARAM params[])215{216int ok = 1;217int include_private;218219debug_print("import %p\n", key);220if (!ossl_prov_is_running() || key == NULL)221return 0;222223if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)224return 0;225226include_private = selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;227ok = ok && ossl_template_key_fromdata(key, params, include_private);228229debug_print("import result %d\n", ok);230return ok;231}232233#define TEMPLATE_KEY_TYPES() \234OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0), \235OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0)236237static const OSSL_PARAM template_key_types[] = {238TEMPLATE_KEY_TYPES(),239OSSL_PARAM_END240};241242static const OSSL_PARAM *template_imexport_types(int selection)243{244debug_print("getting imexport types\n");245if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)246return template_key_types;247return NULL;248}249250static int template_get_params(void *key, OSSL_PARAM params[])251{252OSSL_PARAM *p;253254debug_print("get params %p\n", key);255256if (ossl_param_is_empty(params))257return 0;258259/* return sensible values for at least these parameters */260261if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL262&& !OSSL_PARAM_set_int(p, 0))263return 0;264if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL265&& !OSSL_PARAM_set_int(p, 0))266return 0;267if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL268&& !OSSL_PARAM_set_int(p, 0))269return 0;270if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY)) != NULL) {271if (!OSSL_PARAM_set_octet_string(p, NULL, 0))272return 0;273}274275debug_print("get params OK\n");276return 1;277}278279static const OSSL_PARAM template_gettable_params_arr[] = {280OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),281OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),282OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),283OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),284OSSL_PARAM_END285};286287static const OSSL_PARAM *template_gettable_params(void *provctx)288{289debug_print("gettable params called\n");290return template_gettable_params_arr;291}292293static int template_set_params(void *key, const OSSL_PARAM params[])294{295const OSSL_PARAM *p;296297debug_print("set params called for %p\n", key);298if (ossl_param_is_empty(params))299return 1; /* OK not to set anything */300301p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY);302if (p != NULL) {303/* load public key structure */304}305306debug_print("set params OK\n");307return 1;308}309310static const OSSL_PARAM template_settable_params_arr[] = {311OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),312OSSL_PARAM_END313};314315static const OSSL_PARAM *template_settable_params(void *provctx)316{317debug_print("settable params called\n");318return template_settable_params_arr;319}320321static int template_gen_set_params(void *genctx, const OSSL_PARAM params[])322{323struct template_gen_ctx *gctx = genctx;324325if (gctx == NULL)326return 0;327328debug_print("empty gen_set params called for %p\n", gctx);329return 1;330}331332static void *template_gen_init(void *provctx, int selection,333const OSSL_PARAM params[])334{335struct template_gen_ctx *gctx = NULL;336337debug_print("gen init called for %p\n", provctx);338339/* perform algorithm type specific sanity checks */340341if (!ossl_prov_is_running())342return NULL;343344if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) {345gctx->provctx = provctx;346gctx->selection = selection;347}348if (!template_gen_set_params(gctx, params)) {349OPENSSL_free(gctx);350gctx = NULL;351}352debug_print("gen init returns %p\n", gctx);353return gctx;354}355356static const OSSL_PARAM *template_gen_settable_params(ossl_unused void *genctx,357ossl_unused void *provctx)358{359static OSSL_PARAM settable[] = {360OSSL_PARAM_END361};362return settable;363}364365static void *template_gen(void *vctx, OSSL_CALLBACK *osslcb, void *cbarg)366{367struct template_gen_ctx *gctx = (struct template_gen_ctx *)vctx;368void *key = NULL;369370debug_print("gen called for %p\n", gctx);371372if (gctx == NULL)373goto err;374375/* generate and return new key */376377debug_print("gen returns set %p\n", key);378return key;379err:380template_free(key);381debug_print("gen returns NULL\n");382return NULL;383}384385static void template_gen_cleanup(void *genctx)386{387struct template_gen_ctx *gctx = genctx;388389if (gctx == NULL)390return;391392debug_print("gen cleanup for %p\n", gctx);393OPENSSL_free(gctx);394}395396static void *template_dup(const void *vsrckey, int selection)397{398void *dstkey = NULL;399400debug_print("dup called for %p\n", vsrckey);401if (!ossl_prov_is_running())402return NULL;403404dstkey = template_new(NULL);405if (dstkey == NULL)406goto err;407408/* populate dstkey from vsrckey material */409410debug_print("dup returns %p\n", dstkey);411return dstkey;412err:413template_free(dstkey);414debug_print("dup returns NULL\n");415return NULL;416}417418const OSSL_DISPATCH ossl_template_keymgmt_functions[] = {419{ OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))template_new },420{ OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))template_free },421{ OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))template_get_params },422{ OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))template_gettable_params },423{ OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))template_set_params },424{ OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))template_settable_params },425{ OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))template_has },426{ OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))template_match },427{ OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))template_imexport_types },428{ OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))template_imexport_types },429{ OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))template_import },430{ OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))template_export },431{ OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))template_gen_init },432{ OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))template_gen_set_params },433{ OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS,434(void (*)(void))template_gen_settable_params },435{ OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))template_gen },436{ OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))template_gen_cleanup },437{ OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))template_dup },438OSSL_DISPATCH_END439};440441442