Home | History | Annotate | Line # | Download | only in keymgmt
      1 /*
      2  * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved.
      3  *
      4  * Licensed under the Apache License 2.0 (the "License").  You may not use
      5  * this file except in compliance with the License.  You can obtain a copy
      6  * in the file LICENSE in the source distribution or at
      7  * https://www.openssl.org/source/license.html
      8  */
      9 
     10 #include <openssl/core_dispatch.h>
     11 #include <openssl/core_names.h>
     12 #include <openssl/params.h>
     13 #include <openssl/err.h>
     14 #include <openssl/proverr.h>
     15 #include <openssl/evp.h>
     16 #include <openssl/rand.h>
     17 #include <openssl/self_test.h>
     18 #include "internal/param_build_set.h"
     19 #include <openssl/param_build.h>
     20 #include "prov/implementations.h"
     21 #include "prov/providercommon.h"
     22 #include "prov/provider_ctx.h"
     23 #include "prov/securitycheck.h"
     24 
     25 extern const OSSL_DISPATCH ossl_template_keymgmt_functions[];
     26 
     27 #define BUFSIZE 1000
     28 #if defined(NDEBUG) || defined(OPENSSL_NO_STDIO)
     29 static void debug_print(char *fmt, ...)
     30 {
     31 }
     32 #else
     33 static void debug_print(char *fmt, ...)
     34 {
     35     char out[BUFSIZE];
     36     va_list argptr;
     37 
     38     va_start(argptr, fmt);
     39     vsnprintf(out, BUFSIZE, fmt, argptr);
     40     va_end(argptr);
     41     if (getenv("TEMPLATEKM"))
     42         fprintf(stderr, "TEMPLATE_KM: %s", out);
     43 }
     44 #endif
     45 
     46 static OSSL_FUNC_keymgmt_new_fn template_new;
     47 static OSSL_FUNC_keymgmt_free_fn template_free;
     48 static OSSL_FUNC_keymgmt_gen_init_fn template_gen_init;
     49 static OSSL_FUNC_keymgmt_gen_fn template_gen;
     50 static OSSL_FUNC_keymgmt_gen_cleanup_fn template_gen_cleanup;
     51 static OSSL_FUNC_keymgmt_gen_set_params_fn template_gen_set_params;
     52 static OSSL_FUNC_keymgmt_gen_settable_params_fn template_gen_settable_params;
     53 static OSSL_FUNC_keymgmt_get_params_fn template_get_params;
     54 static OSSL_FUNC_keymgmt_gettable_params_fn template_gettable_params;
     55 static OSSL_FUNC_keymgmt_set_params_fn template_set_params;
     56 static OSSL_FUNC_keymgmt_settable_params_fn template_settable_params;
     57 static OSSL_FUNC_keymgmt_has_fn template_has;
     58 static OSSL_FUNC_keymgmt_match_fn template_match;
     59 static OSSL_FUNC_keymgmt_import_fn template_import;
     60 static OSSL_FUNC_keymgmt_export_fn template_export;
     61 static OSSL_FUNC_keymgmt_import_types_fn template_imexport_types;
     62 static OSSL_FUNC_keymgmt_export_types_fn template_imexport_types;
     63 
     64 static OSSL_FUNC_keymgmt_dup_fn template_dup;
     65 
     66 struct template_gen_ctx {
     67     void *provctx;
     68     int selection;
     69 };
     70 
     71 static void *template_new(void *provctx)
     72 {
     73     void *key = NULL;
     74 
     75     debug_print("new key req\n");
     76     if (!ossl_prov_is_running())
     77         return 0;
     78 
     79     /* add logic to create new key */
     80 
     81     debug_print("new key = %p\n", key);
     82     return key;
     83 }
     84 
     85 static void template_free(void *vkey)
     86 {
     87     debug_print("free key %p\n", vkey);
     88     if (vkey == NULL)
     89         return;
     90 
     91     /* add logic to free all key components */
     92 
     93     OPENSSL_free(vkey);
     94 }
     95 
     96 static int template_has(const void *keydata, int selection)
     97 {
     98     int ok = 0;
     99 
    100     debug_print("has %p\n", keydata);
    101     if (ossl_prov_is_running() && keydata != NULL) {
    102         /* add logic to check whether this key has the requested parameters */
    103     }
    104     debug_print("has result %d\n", ok);
    105     return ok;
    106 }
    107 
    108 static int template_match(const void *keydata1, const void *keydata2, int selection)
    109 {
    110     int ok = 1;
    111 
    112     debug_print("matching %p and %p\n", keydata1, keydata2);
    113     if (!ossl_prov_is_running())
    114         return 0;
    115 
    116     if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
    117         ok = ok && keydata1 != NULL && keydata2 != NULL;
    118 
    119     if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
    120         int key_checked = 0;
    121 
    122         if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
    123             /* validate whether the public keys match */
    124         }
    125         if (!key_checked
    126             && (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
    127             /* validate whether the private keys match */
    128         }
    129         ok = ok && key_checked;
    130     }
    131     debug_print("match result %d\n", ok);
    132     return ok;
    133 }
    134 
    135 static int key_to_params(void *key, OSSL_PARAM_BLD *tmpl,
    136     OSSL_PARAM params[], int include_private)
    137 {
    138     if (key == NULL)
    139         return 0;
    140 
    141     /* add public and/or private key parts to templ as possible */
    142 
    143     return 1;
    144 }
    145 
    146 static int template_export(void *key, int selection, OSSL_CALLBACK *param_cb,
    147     void *cbarg)
    148 {
    149     OSSL_PARAM_BLD *tmpl;
    150     OSSL_PARAM *params = NULL;
    151     int ret = 0;
    152 
    153     debug_print("export %p\n", key);
    154     if (!ossl_prov_is_running() || key == NULL)
    155         return 0;
    156 
    157     if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
    158         return 0;
    159 
    160     tmpl = OSSL_PARAM_BLD_new();
    161     if (tmpl == NULL)
    162         return 0;
    163 
    164     if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
    165         int include_private = ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0);
    166 
    167         if (!key_to_params(key, tmpl, NULL, include_private))
    168             goto err;
    169     }
    170 
    171     params = OSSL_PARAM_BLD_to_param(tmpl);
    172     if (params == NULL)
    173         goto err;
    174 
    175     ret = param_cb(params, cbarg);
    176     OSSL_PARAM_free(params);
    177 err:
    178     OSSL_PARAM_BLD_free(tmpl);
    179     debug_print("export result %d\n", ret);
    180     return ret;
    181 }
    182 
    183 static int ossl_template_key_fromdata(void *key,
    184     const OSSL_PARAM params[],
    185     int include_private)
    186 {
    187     const OSSL_PARAM *param_priv_key = NULL, *param_pub_key;
    188 
    189     if (key == NULL)
    190         return 0;
    191     if (ossl_param_is_empty(params))
    192         return 0;
    193 
    194     /* validate integrity of key (algorithm type specific) */
    195 
    196     param_pub_key = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY);
    197     if (include_private)
    198         param_priv_key = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY);
    199 
    200     if (param_pub_key == NULL && param_priv_key == NULL)
    201         return 0;
    202 
    203     if (param_priv_key != NULL) {
    204         /* retrieve private key and check integrity */
    205     }
    206 
    207     if (param_pub_key != NULL) {
    208         /* retrieve public key and check integrity */
    209     }
    210 
    211     return 1;
    212 }
    213 
    214 static int template_import(void *key, int selection, const OSSL_PARAM params[])
    215 {
    216     int ok = 1;
    217     int include_private;
    218 
    219     debug_print("import %p\n", key);
    220     if (!ossl_prov_is_running() || key == NULL)
    221         return 0;
    222 
    223     if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
    224         return 0;
    225 
    226     include_private = selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0;
    227     ok = ok && ossl_template_key_fromdata(key, params, include_private);
    228 
    229     debug_print("import result %d\n", ok);
    230     return ok;
    231 }
    232 
    233 #define TEMPLATE_KEY_TYPES()                                   \
    234     OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0), \
    235         OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0)
    236 
    237 static const OSSL_PARAM template_key_types[] = {
    238     TEMPLATE_KEY_TYPES(),
    239     OSSL_PARAM_END
    240 };
    241 
    242 static const OSSL_PARAM *template_imexport_types(int selection)
    243 {
    244     debug_print("getting imexport types\n");
    245     if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0)
    246         return template_key_types;
    247     return NULL;
    248 }
    249 
    250 static int template_get_params(void *key, OSSL_PARAM params[])
    251 {
    252     OSSL_PARAM *p;
    253 
    254     debug_print("get params %p\n", key);
    255 
    256     if (ossl_param_is_empty(params))
    257         return 0;
    258 
    259     /* return sensible values for at least these parameters */
    260 
    261     if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL
    262         && !OSSL_PARAM_set_int(p, 0))
    263         return 0;
    264     if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL
    265         && !OSSL_PARAM_set_int(p, 0))
    266         return 0;
    267     if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL
    268         && !OSSL_PARAM_set_int(p, 0))
    269         return 0;
    270     if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY)) != NULL) {
    271         if (!OSSL_PARAM_set_octet_string(p, NULL, 0))
    272             return 0;
    273     }
    274 
    275     debug_print("get params OK\n");
    276     return 1;
    277 }
    278 
    279 static const OSSL_PARAM template_gettable_params_arr[] = {
    280     OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL),
    281     OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
    282     OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
    283     OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),
    284     OSSL_PARAM_END
    285 };
    286 
    287 static const OSSL_PARAM *template_gettable_params(void *provctx)
    288 {
    289     debug_print("gettable params called\n");
    290     return template_gettable_params_arr;
    291 }
    292 
    293 static int template_set_params(void *key, const OSSL_PARAM params[])
    294 {
    295     const OSSL_PARAM *p;
    296 
    297     debug_print("set params called for %p\n", key);
    298     if (ossl_param_is_empty(params))
    299         return 1; /* OK not to set anything */
    300 
    301     p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY);
    302     if (p != NULL) {
    303         /* load public key structure */
    304     }
    305 
    306     debug_print("set params OK\n");
    307     return 1;
    308 }
    309 
    310 static const OSSL_PARAM template_settable_params_arr[] = {
    311     OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),
    312     OSSL_PARAM_END
    313 };
    314 
    315 static const OSSL_PARAM *template_settable_params(void *provctx)
    316 {
    317     debug_print("settable params called\n");
    318     return template_settable_params_arr;
    319 }
    320 
    321 static int template_gen_set_params(void *genctx, const OSSL_PARAM params[])
    322 {
    323     struct template_gen_ctx *gctx = genctx;
    324 
    325     if (gctx == NULL)
    326         return 0;
    327 
    328     debug_print("empty gen_set params called for %p\n", gctx);
    329     return 1;
    330 }
    331 
    332 static void *template_gen_init(void *provctx, int selection,
    333     const OSSL_PARAM params[])
    334 {
    335     struct template_gen_ctx *gctx = NULL;
    336 
    337     debug_print("gen init called for %p\n", provctx);
    338 
    339     /* perform algorithm type specific sanity checks */
    340 
    341     if (!ossl_prov_is_running())
    342         return NULL;
    343 
    344     if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) {
    345         gctx->provctx = provctx;
    346         gctx->selection = selection;
    347     }
    348     if (!template_gen_set_params(gctx, params)) {
    349         OPENSSL_free(gctx);
    350         gctx = NULL;
    351     }
    352     debug_print("gen init returns %p\n", gctx);
    353     return gctx;
    354 }
    355 
    356 static const OSSL_PARAM *template_gen_settable_params(ossl_unused void *genctx,
    357     ossl_unused void *provctx)
    358 {
    359     static OSSL_PARAM settable[] = {
    360         OSSL_PARAM_END
    361     };
    362     return settable;
    363 }
    364 
    365 static void *template_gen(void *vctx, OSSL_CALLBACK *osslcb, void *cbarg)
    366 {
    367     struct template_gen_ctx *gctx = (struct template_gen_ctx *)vctx;
    368     void *key = NULL;
    369 
    370     debug_print("gen called for %p\n", gctx);
    371 
    372     if (gctx == NULL)
    373         goto err;
    374 
    375     /* generate and return new key */
    376 
    377     debug_print("gen returns set %p\n", key);
    378     return key;
    379 err:
    380     template_free(key);
    381     debug_print("gen returns NULL\n");
    382     return NULL;
    383 }
    384 
    385 static void template_gen_cleanup(void *genctx)
    386 {
    387     struct template_gen_ctx *gctx = genctx;
    388 
    389     if (gctx == NULL)
    390         return;
    391 
    392     debug_print("gen cleanup for %p\n", gctx);
    393     OPENSSL_free(gctx);
    394 }
    395 
    396 static void *template_dup(const void *vsrckey, int selection)
    397 {
    398     void *dstkey = NULL;
    399 
    400     debug_print("dup called for %p\n", vsrckey);
    401     if (!ossl_prov_is_running())
    402         return NULL;
    403 
    404     dstkey = template_new(NULL);
    405     if (dstkey == NULL)
    406         goto err;
    407 
    408     /* populate dstkey from vsrckey material */
    409 
    410     debug_print("dup returns %p\n", dstkey);
    411     return dstkey;
    412 err:
    413     template_free(dstkey);
    414     debug_print("dup returns NULL\n");
    415     return NULL;
    416 }
    417 
    418 const 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 },
    438     OSSL_DISPATCH_END
    439 };
    440