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