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 = 199 OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY); 200 201 if (param_pub_key == NULL && param_priv_key == NULL) 202 return 0; 203 204 if (param_priv_key != NULL) { 205 /* retrieve private key and check integrity */ 206 } 207 208 if (param_pub_key != NULL) { 209 /* retrieve public key and check integrity */ 210 } 211 212 return 1; 213 } 214 215 static int template_import(void *key, int selection, const OSSL_PARAM params[]) 216 { 217 int ok = 1; 218 int include_private; 219 220 debug_print("import %p\n", key); 221 if (!ossl_prov_is_running() || key == NULL) 222 return 0; 223 224 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0) 225 return 0; 226 227 include_private = selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0; 228 ok = ok && ossl_template_key_fromdata(key, params, include_private); 229 230 debug_print("import result %d\n", ok); 231 return ok; 232 } 233 234 #define TEMPLATE_KEY_TYPES() \ 235 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0), \ 236 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0) 237 238 static const OSSL_PARAM template_key_types[] = { 239 TEMPLATE_KEY_TYPES(), 240 OSSL_PARAM_END 241 }; 242 243 static const OSSL_PARAM *template_imexport_types(int selection) 244 { 245 debug_print("getting imexport types\n"); 246 if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) 247 return template_key_types; 248 return NULL; 249 } 250 251 static int template_get_params(void *key, OSSL_PARAM params[]) 252 { 253 OSSL_PARAM *p; 254 255 debug_print("get params %p\n", key); 256 257 if (ossl_param_is_empty(params)) 258 return 0; 259 260 /* return sensible values for at least these parameters */ 261 262 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL 263 && !OSSL_PARAM_set_int(p, 0)) 264 return 0; 265 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL 266 && !OSSL_PARAM_set_int(p, 0)) 267 return 0; 268 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL 269 && !OSSL_PARAM_set_int(p, 0)) 270 return 0; 271 if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY)) != NULL) { 272 if (!OSSL_PARAM_set_octet_string(p, NULL, 0)) 273 return 0; 274 } 275 276 debug_print("get params OK\n"); 277 return 1; 278 } 279 280 static const OSSL_PARAM template_gettable_params_arr[] = { 281 OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL), 282 OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL), 283 OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL), 284 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0), 285 OSSL_PARAM_END 286 }; 287 288 static const OSSL_PARAM *template_gettable_params(void *provctx) 289 { 290 debug_print("gettable params called\n"); 291 return template_gettable_params_arr; 292 } 293 294 static int template_set_params(void *key, const OSSL_PARAM params[]) 295 { 296 const OSSL_PARAM *p; 297 298 debug_print("set params called for %p\n", key); 299 if (ossl_param_is_empty(params)) 300 return 1; /* OK not to set anything */ 301 302 p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY); 303 if (p != NULL) { 304 /* load public key structure */ 305 } 306 307 debug_print("set params OK\n"); 308 return 1; 309 } 310 311 static const OSSL_PARAM template_settable_params_arr[] = { 312 OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0), 313 OSSL_PARAM_END 314 }; 315 316 static const OSSL_PARAM *template_settable_params(void *provctx) 317 { 318 debug_print("settable params called\n"); 319 return template_settable_params_arr; 320 } 321 322 static int template_gen_set_params(void *genctx, const OSSL_PARAM params[]) 323 { 324 struct template_gen_ctx *gctx = genctx; 325 326 if (gctx == NULL) 327 return 0; 328 329 debug_print("empty gen_set params called for %p\n", gctx); 330 return 1; 331 } 332 333 static void *template_gen_init(void *provctx, int selection, 334 const OSSL_PARAM params[]) 335 { 336 struct template_gen_ctx *gctx = NULL; 337 338 debug_print("gen init called for %p\n", provctx); 339 340 /* perform algorithm type specific sanity checks */ 341 342 if (!ossl_prov_is_running()) 343 return NULL; 344 345 if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) { 346 gctx->provctx = provctx; 347 gctx->selection = selection; 348 } 349 if (!template_gen_set_params(gctx, params)) { 350 OPENSSL_free(gctx); 351 gctx = NULL; 352 } 353 debug_print("gen init returns %p\n", gctx); 354 return gctx; 355 } 356 357 static const OSSL_PARAM *template_gen_settable_params(ossl_unused void *genctx, 358 ossl_unused void *provctx) 359 { 360 static OSSL_PARAM settable[] = { 361 OSSL_PARAM_END 362 }; 363 return settable; 364 } 365 366 static void *template_gen(void *vctx, OSSL_CALLBACK *osslcb, void *cbarg) 367 { 368 struct template_gen_ctx *gctx = (struct template_gen_ctx *)vctx; 369 void *key = NULL; 370 371 debug_print("gen called for %p\n", gctx); 372 373 if (gctx == NULL) 374 goto err; 375 376 /* generate and return new key */ 377 378 debug_print("gen returns set %p\n", key); 379 return key; 380 err: 381 template_free(key); 382 debug_print("gen returns NULL\n"); 383 return NULL; 384 } 385 386 static void template_gen_cleanup(void *genctx) 387 { 388 struct template_gen_ctx *gctx = genctx; 389 390 if (gctx == NULL) 391 return; 392 393 debug_print("gen cleanup for %p\n", gctx); 394 OPENSSL_free(gctx); 395 } 396 397 static void *template_dup(const void *vsrckey, int selection) 398 { 399 void *dstkey = NULL; 400 401 debug_print("dup called for %p\n", vsrckey); 402 if (!ossl_prov_is_running()) 403 return NULL; 404 405 dstkey = template_new(NULL); 406 if (dstkey == NULL) 407 goto err; 408 409 /* populate dstkey from vsrckey material */ 410 411 debug_print("dup returns %p\n", dstkey); 412 return dstkey; 413 err: 414 template_free(dstkey); 415 debug_print("dup returns NULL\n"); 416 return NULL; 417 } 418 419 const OSSL_DISPATCH ossl_template_keymgmt_functions[] = { 420 { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))template_new }, 421 { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))template_free }, 422 { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*) (void))template_get_params }, 423 { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*) (void))template_gettable_params }, 424 { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*) (void))template_set_params }, 425 { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*) (void))template_settable_params }, 426 { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))template_has }, 427 { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))template_match }, 428 { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))template_imexport_types }, 429 { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))template_imexport_types }, 430 { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))template_import }, 431 { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))template_export }, 432 { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))template_gen_init }, 433 { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))template_gen_set_params }, 434 { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, 435 (void (*)(void))template_gen_settable_params }, 436 { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))template_gen }, 437 { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))template_gen_cleanup }, 438 { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))template_dup }, 439 OSSL_DISPATCH_END 440 }; 441