1 /* 2 * Copyright 2020-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_names.h> 11 #include <openssl/core_object.h> 12 #include <openssl/provider.h> 13 #include <openssl/evp.h> 14 #include <openssl/ui.h> 15 #include <openssl/decoder.h> 16 #include <openssl/safestack.h> 17 #include <openssl/trace.h> 18 #include "crypto/evp.h" 19 #include "crypto/decoder.h" 20 #include "crypto/evp/evp_local.h" 21 #include "crypto/lhash.h" 22 #include "encoder_local.h" 23 #include "internal/namemap.h" 24 #include "internal/sizes.h" 25 26 int OSSL_DECODER_CTX_set_passphrase(OSSL_DECODER_CTX *ctx, 27 const unsigned char *kstr, 28 size_t klen) 29 { 30 return ossl_pw_set_passphrase(&ctx->pwdata, kstr, klen); 31 } 32 33 int OSSL_DECODER_CTX_set_passphrase_ui(OSSL_DECODER_CTX *ctx, 34 const UI_METHOD *ui_method, 35 void *ui_data) 36 { 37 return ossl_pw_set_ui_method(&ctx->pwdata, ui_method, ui_data); 38 } 39 40 int OSSL_DECODER_CTX_set_pem_password_cb(OSSL_DECODER_CTX *ctx, 41 pem_password_cb *cb, void *cbarg) 42 { 43 return ossl_pw_set_pem_password_cb(&ctx->pwdata, cb, cbarg); 44 } 45 46 int OSSL_DECODER_CTX_set_passphrase_cb(OSSL_DECODER_CTX *ctx, 47 OSSL_PASSPHRASE_CALLBACK *cb, 48 void *cbarg) 49 { 50 return ossl_pw_set_ossl_passphrase_cb(&ctx->pwdata, cb, cbarg); 51 } 52 53 /* 54 * Support for OSSL_DECODER_CTX_new_for_pkey: 55 * The construct data, and collecting keymgmt information for it 56 */ 57 58 DEFINE_STACK_OF(EVP_KEYMGMT) 59 60 struct decoder_pkey_data_st { 61 OSSL_LIB_CTX *libctx; 62 char *propq; 63 int selection; 64 65 STACK_OF(EVP_KEYMGMT) *keymgmts; 66 char *object_type; /* recorded object data type, may be NULL */ 67 void **object; /* Where the result should end up */ 68 OSSL_DECODER_CTX *ctx; /* The parent decoder context */ 69 }; 70 71 static int decoder_construct_pkey(OSSL_DECODER_INSTANCE *decoder_inst, 72 const OSSL_PARAM *params, 73 void *construct_data) 74 { 75 struct decoder_pkey_data_st *data = construct_data; 76 OSSL_DECODER *decoder = OSSL_DECODER_INSTANCE_get_decoder(decoder_inst); 77 void *decoderctx = OSSL_DECODER_INSTANCE_get_decoder_ctx(decoder_inst); 78 const OSSL_PROVIDER *decoder_prov = OSSL_DECODER_get0_provider(decoder); 79 EVP_KEYMGMT *keymgmt = NULL; 80 const OSSL_PROVIDER *keymgmt_prov = NULL; 81 int i, end; 82 /* 83 * |object_ref| points to a provider reference to an object, its exact 84 * contents entirely opaque to us, but may be passed to any provider 85 * function that expects this (such as OSSL_FUNC_keymgmt_load(). 86 * 87 * This pointer is considered volatile, i.e. whatever it points at 88 * is assumed to be freed as soon as this function returns. 89 */ 90 void *object_ref = NULL; 91 size_t object_ref_sz = 0; 92 const OSSL_PARAM *p; 93 94 p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_DATA_TYPE); 95 if (p != NULL) { 96 char *object_type = NULL; 97 98 if (!OSSL_PARAM_get_utf8_string(p, &object_type, 0)) 99 return 0; 100 OPENSSL_free(data->object_type); 101 data->object_type = object_type; 102 } 103 104 /* 105 * For stuff that should end up in an EVP_PKEY, we only accept an object 106 * reference for the moment. This enforces that the key data itself 107 * remains with the provider. 108 */ 109 p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_REFERENCE); 110 if (p == NULL || p->data_type != OSSL_PARAM_OCTET_STRING) 111 return 0; 112 object_ref = p->data; 113 object_ref_sz = p->data_size; 114 115 /* 116 * First, we try to find a keymgmt that comes from the same provider as 117 * the decoder that passed the params. 118 */ 119 end = sk_EVP_KEYMGMT_num(data->keymgmts); 120 for (i = 0; i < end; i++) { 121 keymgmt = sk_EVP_KEYMGMT_value(data->keymgmts, i); 122 keymgmt_prov = EVP_KEYMGMT_get0_provider(keymgmt); 123 124 if (keymgmt_prov == decoder_prov 125 && evp_keymgmt_has_load(keymgmt) 126 && EVP_KEYMGMT_is_a(keymgmt, data->object_type)) 127 break; 128 } 129 if (i < end) { 130 /* To allow it to be freed further down */ 131 if (!EVP_KEYMGMT_up_ref(keymgmt)) 132 return 0; 133 } else if ((keymgmt = EVP_KEYMGMT_fetch(data->libctx, 134 data->object_type, 135 data->propq)) != NULL) { 136 keymgmt_prov = EVP_KEYMGMT_get0_provider(keymgmt); 137 } 138 139 if (keymgmt != NULL) { 140 EVP_PKEY *pkey = NULL; 141 void *keydata = NULL; 142 143 /* 144 * If the EVP_KEYMGMT and the OSSL_DECODER are from the 145 * same provider, we assume that the KEYMGMT has a key loading 146 * function that can handle the provider reference we hold. 147 * 148 * Otherwise, we export from the decoder and import the 149 * result in the keymgmt. 150 */ 151 if (keymgmt_prov == decoder_prov) { 152 keydata = evp_keymgmt_load(keymgmt, object_ref, object_ref_sz); 153 } else { 154 struct evp_keymgmt_util_try_import_data_st import_data; 155 156 import_data.keymgmt = keymgmt; 157 import_data.keydata = NULL; 158 if (data->selection == 0) 159 /* import/export functions do not tolerate 0 selection */ 160 import_data.selection = OSSL_KEYMGMT_SELECT_ALL; 161 else 162 import_data.selection = data->selection; 163 164 /* 165 * No need to check for errors here, the value of 166 * |import_data.keydata| is as much an indicator. 167 */ 168 (void)decoder->export_object(decoderctx, 169 object_ref, object_ref_sz, 170 &evp_keymgmt_util_try_import, 171 &import_data); 172 keydata = import_data.keydata; 173 import_data.keydata = NULL; 174 } 175 /* 176 * When load or import fails, because this is not an acceptable key 177 * (despite the provided key material being syntactically valid), the 178 * reason why the key is rejected would be lost, unless we signal a 179 * hard error, and suppress resetting for another try. 180 */ 181 if (keydata == NULL) 182 ossl_decoder_ctx_set_harderr(data->ctx); 183 184 if (keydata != NULL 185 && (pkey = evp_keymgmt_util_make_pkey(keymgmt, keydata)) == NULL) 186 evp_keymgmt_freedata(keymgmt, keydata); 187 188 *data->object = pkey; 189 190 /* 191 * evp_keymgmt_util_make_pkey() increments the reference count when 192 * assigning the EVP_PKEY, so we can free the keymgmt here. 193 */ 194 EVP_KEYMGMT_free(keymgmt); 195 } 196 /* 197 * We successfully looked through, |*ctx->object| determines if we 198 * actually found something. 199 */ 200 return (*data->object != NULL); 201 } 202 203 static void decoder_clean_pkey_construct_arg(void *construct_data) 204 { 205 struct decoder_pkey_data_st *data = construct_data; 206 207 if (data != NULL) { 208 sk_EVP_KEYMGMT_pop_free(data->keymgmts, EVP_KEYMGMT_free); 209 OPENSSL_free(data->propq); 210 OPENSSL_free(data->object_type); 211 OPENSSL_free(data); 212 } 213 } 214 215 struct collect_data_st { 216 OSSL_LIB_CTX *libctx; 217 OSSL_DECODER_CTX *ctx; 218 219 const char *keytype; /* the keytype requested, if any */ 220 int keytype_id; /* if keytype_resolved is set, keymgmt name_id; else 0 */ 221 int sm2_id; /* if keytype_resolved is set and EC, SM2 name_id; else 0 */ 222 int total; /* number of matching results */ 223 char error_occurred; 224 char keytype_resolved; 225 226 STACK_OF(EVP_KEYMGMT) *keymgmts; 227 }; 228 229 static void collect_decoder_keymgmt(EVP_KEYMGMT *keymgmt, OSSL_DECODER *decoder, 230 void *provctx, struct collect_data_st *data) 231 { 232 void *decoderctx = NULL; 233 OSSL_DECODER_INSTANCE *di = NULL; 234 235 /* 236 * We already checked the EVP_KEYMGMT is applicable in check_keymgmt so we 237 * don't check it again here. 238 */ 239 240 if (keymgmt->name_id != decoder->base.id) 241 /* Mismatch is not an error, continue. */ 242 return; 243 244 if ((decoderctx = decoder->newctx(provctx)) == NULL) { 245 data->error_occurred = 1; 246 return; 247 } 248 249 if ((di = ossl_decoder_instance_new(decoder, decoderctx)) == NULL) { 250 decoder->freectx(decoderctx); 251 data->error_occurred = 1; 252 return; 253 } 254 255 /* 256 * Input types must be compatible, but we must accept DER encoders when the 257 * start input type is "PEM". 258 */ 259 if (data->ctx->start_input_type != NULL 260 && di->input_type != NULL 261 && OPENSSL_strcasecmp(di->input_type, data->ctx->start_input_type) != 0 262 && (OPENSSL_strcasecmp(di->input_type, "DER") != 0 263 || OPENSSL_strcasecmp(data->ctx->start_input_type, "PEM") != 0)) { 264 /* Mismatch is not an error, continue. */ 265 ossl_decoder_instance_free(di); 266 return; 267 } 268 269 OSSL_TRACE_BEGIN(DECODER) { 270 BIO_printf(trc_out, 271 "(ctx %p) Checking out decoder %p:\n" 272 " %s with %s\n", 273 (void *)data->ctx, (void *)decoder, 274 OSSL_DECODER_get0_name(decoder), 275 OSSL_DECODER_get0_properties(decoder)); 276 } OSSL_TRACE_END(DECODER); 277 278 if (!ossl_decoder_ctx_add_decoder_inst(data->ctx, di)) { 279 ossl_decoder_instance_free(di); 280 data->error_occurred = 1; 281 return; 282 } 283 284 ++data->total; 285 } 286 287 static void collect_decoder(OSSL_DECODER *decoder, void *arg) 288 { 289 struct collect_data_st *data = arg; 290 STACK_OF(EVP_KEYMGMT) *keymgmts = data->keymgmts; 291 int i, end_i; 292 EVP_KEYMGMT *keymgmt; 293 const OSSL_PROVIDER *prov; 294 void *provctx; 295 296 if (data->error_occurred) 297 return; 298 299 prov = OSSL_DECODER_get0_provider(decoder); 300 provctx = OSSL_PROVIDER_get0_provider_ctx(prov); 301 302 /* 303 * Either the caller didn't give us a selection, or if they did, the decoder 304 * must tell us if it supports that selection to be accepted. If the decoder 305 * doesn't have |does_selection|, it's seen as taking anything. 306 */ 307 if (decoder->does_selection != NULL 308 && !decoder->does_selection(provctx, data->ctx->selection)) 309 return; 310 311 OSSL_TRACE_BEGIN(DECODER) { 312 BIO_printf(trc_out, 313 "(ctx %p) Checking out decoder %p:\n" 314 " %s with %s\n", 315 (void *)data->ctx, (void *)decoder, 316 OSSL_DECODER_get0_name(decoder), 317 OSSL_DECODER_get0_properties(decoder)); 318 } OSSL_TRACE_END(DECODER); 319 320 end_i = sk_EVP_KEYMGMT_num(keymgmts); 321 for (i = 0; i < end_i; ++i) { 322 keymgmt = sk_EVP_KEYMGMT_value(keymgmts, i); 323 324 collect_decoder_keymgmt(keymgmt, decoder, provctx, data); 325 if (data->error_occurred) 326 return; 327 } 328 } 329 330 /* 331 * Is this EVP_KEYMGMT applicable given the key type given in the call to 332 * ossl_decoder_ctx_setup_for_pkey (if any)? 333 */ 334 static int check_keymgmt(EVP_KEYMGMT *keymgmt, struct collect_data_st *data) 335 { 336 /* If no keytype was specified, everything matches. */ 337 if (data->keytype == NULL) 338 return 1; 339 340 if (!data->keytype_resolved) { 341 /* We haven't cached the IDs from the keytype string yet. */ 342 OSSL_NAMEMAP *namemap = ossl_namemap_stored(data->libctx); 343 data->keytype_id = ossl_namemap_name2num(namemap, data->keytype); 344 345 /* 346 * If keytype is a value ambiguously used for both EC and SM2, 347 * collect the ID for SM2 as well. 348 */ 349 if (data->keytype_id != 0 350 && (strcmp(data->keytype, "id-ecPublicKey") == 0 351 || strcmp(data->keytype, "1.2.840.10045.2.1") == 0)) 352 data->sm2_id = ossl_namemap_name2num(namemap, "SM2"); 353 354 /* 355 * If keytype_id is zero the name was not found, but we still 356 * set keytype_resolved to avoid trying all this again. 357 */ 358 data->keytype_resolved = 1; 359 } 360 361 /* Specified keytype could not be resolved, so nothing matches. */ 362 if (data->keytype_id == 0) 363 return 0; 364 365 /* Does not match the keytype specified, so skip. */ 366 if (keymgmt->name_id != data->keytype_id 367 && keymgmt->name_id != data->sm2_id) 368 return 0; 369 370 return 1; 371 } 372 373 static void collect_keymgmt(EVP_KEYMGMT *keymgmt, void *arg) 374 { 375 struct collect_data_st *data = arg; 376 377 if (!check_keymgmt(keymgmt, data)) 378 return; 379 380 /* 381 * We have to ref EVP_KEYMGMT here because in the success case, 382 * data->keymgmts is referenced by the constructor we register in the 383 * OSSL_DECODER_CTX. The registered cleanup function 384 * (decoder_clean_pkey_construct_arg) unrefs every element of the stack and 385 * frees it. 386 */ 387 if (!EVP_KEYMGMT_up_ref(keymgmt)) 388 return; 389 390 if (sk_EVP_KEYMGMT_push(data->keymgmts, keymgmt) <= 0) { 391 EVP_KEYMGMT_free(keymgmt); 392 data->error_occurred = 1; 393 } 394 } 395 396 /* 397 * This function does the actual binding of decoders to the OSSL_DECODER_CTX. It 398 * searches for decoders matching 'keytype', which is a string like "RSA", "DH", 399 * etc. If 'keytype' is NULL, decoders for all keytypes are bound. 400 */ 401 static int ossl_decoder_ctx_setup_for_pkey(OSSL_DECODER_CTX *ctx, 402 const char *keytype, 403 OSSL_LIB_CTX *libctx, 404 const char *propquery) 405 { 406 int ok = 0; 407 struct decoder_pkey_data_st *process_data = NULL; 408 struct collect_data_st collect_data = { NULL }; 409 STACK_OF(EVP_KEYMGMT) *keymgmts = NULL; 410 411 OSSL_TRACE_BEGIN(DECODER) { 412 const char *input_type = ctx->start_input_type; 413 const char *input_structure = ctx->input_structure; 414 415 BIO_printf(trc_out, 416 "(ctx %p) Looking for decoders producing %s%s%s%s%s%s\n", 417 (void *)ctx, 418 keytype != NULL ? keytype : "", 419 keytype != NULL ? " keys" : "keys of any type", 420 input_type != NULL ? " from " : "", 421 input_type != NULL ? input_type : "", 422 input_structure != NULL ? " with " : "", 423 input_structure != NULL ? input_structure : ""); 424 } OSSL_TRACE_END(DECODER); 425 426 /* Allocate data. */ 427 if ((process_data = OPENSSL_zalloc(sizeof(*process_data))) == NULL) 428 goto err; 429 if ((propquery != NULL 430 && (process_data->propq = OPENSSL_strdup(propquery)) == NULL)) 431 goto err; 432 433 /* Allocate our list of EVP_KEYMGMTs. */ 434 keymgmts = sk_EVP_KEYMGMT_new_null(); 435 if (keymgmts == NULL) { 436 ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_CRYPTO_LIB); 437 goto err; 438 } 439 440 process_data->object = NULL; 441 process_data->libctx = libctx; 442 process_data->selection = ctx->selection; 443 process_data->keymgmts = keymgmts; 444 445 /* 446 * Enumerate all keymgmts into a stack. 447 * 448 * We could nest EVP_KEYMGMT_do_all_provided inside 449 * OSSL_DECODER_do_all_provided or vice versa but these functions become 450 * bottlenecks if called repeatedly, which is why we collect the 451 * EVP_KEYMGMTs into a stack here and call both functions only once. 452 * 453 * We resolve the keytype string to a name ID so we don't have to resolve it 454 * multiple times, avoiding repeated calls to EVP_KEYMGMT_is_a, which is a 455 * performance bottleneck. However, we do this lazily on the first call to 456 * collect_keymgmt made by EVP_KEYMGMT_do_all_provided, rather than do it 457 * upfront, as this ensures that the names for all loaded providers have 458 * been registered by the time we try to resolve the keytype string. 459 */ 460 collect_data.ctx = ctx; 461 collect_data.libctx = libctx; 462 collect_data.keymgmts = keymgmts; 463 collect_data.keytype = keytype; 464 EVP_KEYMGMT_do_all_provided(libctx, collect_keymgmt, &collect_data); 465 466 if (collect_data.error_occurred) 467 goto err; 468 469 /* Enumerate all matching decoders. */ 470 OSSL_DECODER_do_all_provided(libctx, collect_decoder, &collect_data); 471 472 if (collect_data.error_occurred) 473 goto err; 474 475 OSSL_TRACE_BEGIN(DECODER) { 476 BIO_printf(trc_out, 477 "(ctx %p) Got %d decoders producing keys\n", 478 (void *)ctx, collect_data.total); 479 } OSSL_TRACE_END(DECODER); 480 481 /* 482 * Finish initializing the decoder context. If one or more decoders matched 483 * above then the number of decoders attached to the OSSL_DECODER_CTX will 484 * be nonzero. Else nothing was found and we do nothing. 485 */ 486 if (OSSL_DECODER_CTX_get_num_decoders(ctx) != 0) { 487 if (!OSSL_DECODER_CTX_set_construct(ctx, decoder_construct_pkey) 488 || !OSSL_DECODER_CTX_set_construct_data(ctx, process_data) 489 || !OSSL_DECODER_CTX_set_cleanup(ctx, 490 decoder_clean_pkey_construct_arg)) 491 goto err; 492 493 process_data = NULL; /* Avoid it being freed */ 494 } 495 496 ok = 1; 497 err: 498 decoder_clean_pkey_construct_arg(process_data); 499 return ok; 500 } 501 502 /* Only const here because deep_copy requires it */ 503 static EVP_KEYMGMT *keymgmt_dup(const EVP_KEYMGMT *keymgmt) 504 { 505 if (!EVP_KEYMGMT_up_ref((EVP_KEYMGMT *)keymgmt)) 506 return NULL; 507 508 return (EVP_KEYMGMT *)keymgmt; 509 } 510 511 /* 512 * Duplicates a template OSSL_DECODER_CTX that has been setup for an EVP_PKEY 513 * operation and sets up the duplicate for a new operation. 514 * It does not duplicate the pwdata on the assumption that this does not form 515 * part of the template. That is set up later. 516 */ 517 static OSSL_DECODER_CTX * 518 ossl_decoder_ctx_for_pkey_dup(OSSL_DECODER_CTX *src, 519 EVP_PKEY **pkey, 520 const char *input_type, 521 const char *input_structure) 522 { 523 OSSL_DECODER_CTX *dest; 524 struct decoder_pkey_data_st *process_data_src, *process_data_dest = NULL; 525 526 if (src == NULL) 527 return NULL; 528 529 if ((dest = OSSL_DECODER_CTX_new()) == NULL) { 530 ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB); 531 return NULL; 532 } 533 534 if (!OSSL_DECODER_CTX_set_input_type(dest, input_type) 535 || !OSSL_DECODER_CTX_set_input_structure(dest, input_structure)) { 536 ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB); 537 goto err; 538 } 539 dest->selection = src->selection; 540 541 if (src->decoder_insts != NULL) { 542 dest->decoder_insts 543 = sk_OSSL_DECODER_INSTANCE_deep_copy(src->decoder_insts, 544 ossl_decoder_instance_dup, 545 ossl_decoder_instance_free); 546 if (dest->decoder_insts == NULL) { 547 ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB); 548 goto err; 549 } 550 } 551 552 if (!OSSL_DECODER_CTX_set_construct(dest, 553 OSSL_DECODER_CTX_get_construct(src))) { 554 ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB); 555 goto err; 556 } 557 558 process_data_src = OSSL_DECODER_CTX_get_construct_data(src); 559 if (process_data_src != NULL) { 560 process_data_dest = OPENSSL_zalloc(sizeof(*process_data_dest)); 561 if (process_data_dest == NULL) { 562 ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_CRYPTO_LIB); 563 goto err; 564 } 565 if (process_data_src->propq != NULL) { 566 process_data_dest->propq = OPENSSL_strdup(process_data_src->propq); 567 if (process_data_dest->propq == NULL) { 568 ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_CRYPTO_LIB); 569 goto err; 570 } 571 } 572 573 if (process_data_src->keymgmts != NULL) { 574 process_data_dest->keymgmts 575 = sk_EVP_KEYMGMT_deep_copy(process_data_src->keymgmts, 576 keymgmt_dup, 577 EVP_KEYMGMT_free); 578 if (process_data_dest->keymgmts == NULL) { 579 ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_EVP_LIB); 580 goto err; 581 } 582 } 583 584 process_data_dest->object = (void **)pkey; 585 process_data_dest->libctx = process_data_src->libctx; 586 process_data_dest->selection = process_data_src->selection; 587 process_data_dest->ctx = dest; 588 if (!OSSL_DECODER_CTX_set_construct_data(dest, process_data_dest)) { 589 ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB); 590 goto err; 591 } 592 process_data_dest = NULL; 593 } 594 595 if (!OSSL_DECODER_CTX_set_cleanup(dest, 596 OSSL_DECODER_CTX_get_cleanup(src))) { 597 ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB); 598 goto err; 599 } 600 601 return dest; 602 err: 603 decoder_clean_pkey_construct_arg(process_data_dest); 604 OSSL_DECODER_CTX_free(dest); 605 return NULL; 606 } 607 608 typedef struct { 609 char *input_type; 610 char *input_structure; 611 char *keytype; 612 int selection; 613 char *propquery; 614 OSSL_DECODER_CTX *template; 615 } DECODER_CACHE_ENTRY; 616 617 DEFINE_LHASH_OF_EX(DECODER_CACHE_ENTRY); 618 619 typedef struct { 620 CRYPTO_RWLOCK *lock; 621 LHASH_OF(DECODER_CACHE_ENTRY) *hashtable; 622 } DECODER_CACHE; 623 624 static void decoder_cache_entry_free(DECODER_CACHE_ENTRY *entry) 625 { 626 if (entry == NULL) 627 return; 628 OPENSSL_free(entry->input_type); 629 OPENSSL_free(entry->input_structure); 630 OPENSSL_free(entry->keytype); 631 OPENSSL_free(entry->propquery); 632 OSSL_DECODER_CTX_free(entry->template); 633 OPENSSL_free(entry); 634 } 635 636 static unsigned long decoder_cache_entry_hash(const DECODER_CACHE_ENTRY *cache) 637 { 638 unsigned long hash = 17; 639 640 hash = (hash * 23) 641 + (cache->propquery == NULL 642 ? 0 : ossl_lh_strcasehash(cache->propquery)); 643 hash = (hash * 23) 644 + (cache->input_structure == NULL 645 ? 0 : ossl_lh_strcasehash(cache->input_structure)); 646 hash = (hash * 23) 647 + (cache->input_type == NULL 648 ? 0 : ossl_lh_strcasehash(cache->input_type)); 649 hash = (hash * 23) 650 + (cache->keytype == NULL 651 ? 0 : ossl_lh_strcasehash(cache->keytype)); 652 653 hash ^= cache->selection; 654 655 return hash; 656 } 657 658 static ossl_inline int nullstrcmp(const char *a, const char *b, int casecmp) 659 { 660 if (a == NULL || b == NULL) { 661 if (a == NULL) { 662 if (b == NULL) 663 return 0; 664 else 665 return 1; 666 } else { 667 return -1; 668 } 669 } else { 670 if (casecmp) 671 return OPENSSL_strcasecmp(a, b); 672 else 673 return strcmp(a, b); 674 } 675 } 676 677 static int decoder_cache_entry_cmp(const DECODER_CACHE_ENTRY *a, 678 const DECODER_CACHE_ENTRY *b) 679 { 680 int cmp; 681 682 if (a->selection != b->selection) 683 return (a->selection < b->selection) ? -1 : 1; 684 685 cmp = nullstrcmp(a->keytype, b->keytype, 1); 686 if (cmp != 0) 687 return cmp; 688 689 cmp = nullstrcmp(a->input_type, b->input_type, 1); 690 if (cmp != 0) 691 return cmp; 692 693 cmp = nullstrcmp(a->input_structure, b->input_structure, 1); 694 if (cmp != 0) 695 return cmp; 696 697 cmp = nullstrcmp(a->propquery, b->propquery, 0); 698 699 return cmp; 700 } 701 702 void *ossl_decoder_cache_new(OSSL_LIB_CTX *ctx) 703 { 704 DECODER_CACHE *cache = OPENSSL_malloc(sizeof(*cache)); 705 706 if (cache == NULL) 707 return NULL; 708 709 cache->lock = CRYPTO_THREAD_lock_new(); 710 if (cache->lock == NULL) { 711 OPENSSL_free(cache); 712 return NULL; 713 } 714 cache->hashtable = lh_DECODER_CACHE_ENTRY_new(decoder_cache_entry_hash, 715 decoder_cache_entry_cmp); 716 if (cache->hashtable == NULL) { 717 CRYPTO_THREAD_lock_free(cache->lock); 718 OPENSSL_free(cache); 719 return NULL; 720 } 721 722 return cache; 723 } 724 725 void ossl_decoder_cache_free(void *vcache) 726 { 727 DECODER_CACHE *cache = (DECODER_CACHE *)vcache; 728 729 lh_DECODER_CACHE_ENTRY_doall(cache->hashtable, decoder_cache_entry_free); 730 lh_DECODER_CACHE_ENTRY_free(cache->hashtable); 731 CRYPTO_THREAD_lock_free(cache->lock); 732 OPENSSL_free(cache); 733 } 734 735 /* 736 * Called whenever a provider gets activated/deactivated. In that case the 737 * decoders that are available might change so we flush our cache. 738 */ 739 int ossl_decoder_cache_flush(OSSL_LIB_CTX *libctx) 740 { 741 DECODER_CACHE *cache 742 = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_DECODER_CACHE_INDEX); 743 744 if (cache == NULL) 745 return 0; 746 747 748 if (!CRYPTO_THREAD_write_lock(cache->lock)) { 749 ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB); 750 return 0; 751 } 752 753 lh_DECODER_CACHE_ENTRY_doall(cache->hashtable, decoder_cache_entry_free); 754 lh_DECODER_CACHE_ENTRY_flush(cache->hashtable); 755 756 CRYPTO_THREAD_unlock(cache->lock); 757 return 1; 758 } 759 760 OSSL_DECODER_CTX * 761 OSSL_DECODER_CTX_new_for_pkey(EVP_PKEY **pkey, 762 const char *input_type, 763 const char *input_structure, 764 const char *keytype, int selection, 765 OSSL_LIB_CTX *libctx, const char *propquery) 766 { 767 OSSL_DECODER_CTX *ctx = NULL; 768 OSSL_PARAM decoder_params[] = { 769 OSSL_PARAM_END, 770 OSSL_PARAM_END, 771 OSSL_PARAM_END 772 }; 773 DECODER_CACHE *cache 774 = ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_DECODER_CACHE_INDEX); 775 DECODER_CACHE_ENTRY cacheent, *res, *newcache = NULL; 776 int i = 0; 777 778 if (cache == NULL) { 779 ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB); 780 return NULL; 781 } 782 if (input_structure != NULL) 783 decoder_params[i++] = 784 OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_STRUCTURE, 785 (char *)input_structure, 0); 786 if (propquery != NULL) 787 decoder_params[i++] = 788 OSSL_PARAM_construct_utf8_string(OSSL_DECODER_PARAM_PROPERTIES, 789 (char *)propquery, 0); 790 791 /* It is safe to cast away the const here */ 792 cacheent.input_type = (char *)input_type; 793 cacheent.input_structure = (char *)input_structure; 794 cacheent.keytype = (char *)keytype; 795 cacheent.selection = selection; 796 cacheent.propquery = (char *)propquery; 797 798 if (!CRYPTO_THREAD_read_lock(cache->lock)) { 799 ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_CRYPTO_LIB); 800 return NULL; 801 } 802 803 /* First see if we have a template OSSL_DECODER_CTX */ 804 res = lh_DECODER_CACHE_ENTRY_retrieve(cache->hashtable, &cacheent); 805 806 if (res == NULL) { 807 /* 808 * There is no template so we will have to construct one. This will be 809 * time consuming so release the lock and we will later upgrade it to a 810 * write lock. 811 */ 812 CRYPTO_THREAD_unlock(cache->lock); 813 814 if ((ctx = OSSL_DECODER_CTX_new()) == NULL) { 815 ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB); 816 return NULL; 817 } 818 819 OSSL_TRACE_BEGIN(DECODER) { 820 BIO_printf(trc_out, 821 "(ctx %p) Looking for %s decoders with selection %d\n", 822 (void *)ctx, keytype, selection); 823 BIO_printf(trc_out, " input type: %s, input structure: %s\n", 824 input_type, input_structure); 825 } OSSL_TRACE_END(DECODER); 826 827 if (OSSL_DECODER_CTX_set_input_type(ctx, input_type) 828 && OSSL_DECODER_CTX_set_input_structure(ctx, input_structure) 829 && OSSL_DECODER_CTX_set_selection(ctx, selection) 830 && ossl_decoder_ctx_setup_for_pkey(ctx, keytype, libctx, propquery) 831 && OSSL_DECODER_CTX_add_extra(ctx, libctx, propquery) 832 && (propquery == NULL 833 || OSSL_DECODER_CTX_set_params(ctx, decoder_params))) { 834 OSSL_TRACE_BEGIN(DECODER) { 835 BIO_printf(trc_out, "(ctx %p) Got %d decoders\n", 836 (void *)ctx, OSSL_DECODER_CTX_get_num_decoders(ctx)); 837 } OSSL_TRACE_END(DECODER); 838 } else { 839 ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_OSSL_DECODER_LIB); 840 OSSL_DECODER_CTX_free(ctx); 841 return NULL; 842 } 843 844 newcache = OPENSSL_zalloc(sizeof(*newcache)); 845 if (newcache == NULL) { 846 OSSL_DECODER_CTX_free(ctx); 847 return NULL; 848 } 849 850 if (input_type != NULL) { 851 newcache->input_type = OPENSSL_strdup(input_type); 852 if (newcache->input_type == NULL) 853 goto err; 854 } 855 if (input_structure != NULL) { 856 newcache->input_structure = OPENSSL_strdup(input_structure); 857 if (newcache->input_structure == NULL) 858 goto err; 859 } 860 if (keytype != NULL) { 861 newcache->keytype = OPENSSL_strdup(keytype); 862 if (newcache->keytype == NULL) 863 goto err; 864 } 865 if (propquery != NULL) { 866 newcache->propquery = OPENSSL_strdup(propquery); 867 if (newcache->propquery == NULL) 868 goto err; 869 } 870 newcache->selection = selection; 871 newcache->template = ctx; 872 873 if (!CRYPTO_THREAD_write_lock(cache->lock)) { 874 ctx = NULL; 875 ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_CRYPTO_LIB); 876 goto err; 877 } 878 res = lh_DECODER_CACHE_ENTRY_retrieve(cache->hashtable, &cacheent); 879 if (res == NULL) { 880 (void)lh_DECODER_CACHE_ENTRY_insert(cache->hashtable, newcache); 881 if (lh_DECODER_CACHE_ENTRY_error(cache->hashtable)) { 882 ctx = NULL; 883 ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_CRYPTO_LIB); 884 goto err; 885 } 886 } else { 887 /* 888 * We raced with another thread to construct this and lost. Free 889 * what we just created and use the entry from the hashtable instead 890 */ 891 decoder_cache_entry_free(newcache); 892 ctx = res->template; 893 } 894 } else { 895 ctx = res->template; 896 } 897 898 ctx = ossl_decoder_ctx_for_pkey_dup(ctx, pkey, input_type, input_structure); 899 CRYPTO_THREAD_unlock(cache->lock); 900 901 return ctx; 902 err: 903 decoder_cache_entry_free(newcache); 904 OSSL_DECODER_CTX_free(ctx); 905 return NULL; 906 } 907