1 /* 2 * Copyright 2016-2022 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 <stdlib.h> 11 #include <string.h> 12 #include <assert.h> 13 14 /* We need to use some STORE deprecated APIs */ 15 #define OPENSSL_SUPPRESS_DEPRECATED 16 17 #include "e_os.h" 18 19 #include <openssl/crypto.h> 20 #include <openssl/err.h> 21 #include <openssl/trace.h> 22 #include <openssl/core_names.h> 23 #include <openssl/provider.h> 24 #include <openssl/param_build.h> 25 #include <openssl/store.h> 26 #include "internal/thread_once.h" 27 #include "internal/cryptlib.h" 28 #include "internal/provider.h" 29 #include "internal/bio.h" 30 #include "crypto/store.h" 31 #include "store_local.h" 32 33 static int ossl_store_close_it(OSSL_STORE_CTX *ctx); 34 35 static int loader_set_params(OSSL_STORE_LOADER *loader, 36 OSSL_STORE_LOADER_CTX *loader_ctx, 37 const OSSL_PARAM params[], const char *propq) 38 { 39 if (params != NULL) { 40 if (!loader->p_set_ctx_params(loader_ctx, params)) 41 return 0; 42 } 43 44 if (propq != NULL) { 45 OSSL_PARAM propp[2]; 46 47 if (OSSL_PARAM_locate_const(params, 48 OSSL_STORE_PARAM_PROPERTIES) != NULL) 49 /* use the propq from params */ 50 return 1; 51 52 propp[0] = OSSL_PARAM_construct_utf8_string(OSSL_STORE_PARAM_PROPERTIES, 53 (char *)propq, 0); 54 propp[1] = OSSL_PARAM_construct_end(); 55 56 if (!loader->p_set_ctx_params(loader_ctx, propp)) 57 return 0; 58 } 59 return 1; 60 } 61 62 OSSL_STORE_CTX * 63 OSSL_STORE_open_ex(const char *uri, OSSL_LIB_CTX *libctx, const char *propq, 64 const UI_METHOD *ui_method, void *ui_data, 65 const OSSL_PARAM params[], 66 OSSL_STORE_post_process_info_fn post_process, 67 void *post_process_data) 68 { 69 const OSSL_STORE_LOADER *loader = NULL; 70 OSSL_STORE_LOADER *fetched_loader = NULL; 71 OSSL_STORE_LOADER_CTX *loader_ctx = NULL; 72 OSSL_STORE_CTX *ctx = NULL; 73 char *propq_copy = NULL; 74 int no_loader_found = 1; 75 char scheme_copy[256], *p, *schemes[2], *scheme = NULL; 76 size_t schemes_n = 0; 77 size_t i; 78 79 /* 80 * Put the file scheme first. If the uri does represent an existing file, 81 * possible device name and all, then it should be loaded. Only a failed 82 * attempt at loading a local file should have us try something else. 83 */ 84 schemes[schemes_n++] = "file"; 85 86 /* 87 * Now, check if we have something that looks like a scheme, and add it 88 * as a second scheme. However, also check if there's an authority start 89 * (://), because that will invalidate the previous file scheme. Also, 90 * check that this isn't actually the file scheme, as there's no point 91 * going through that one twice! 92 */ 93 OPENSSL_strlcpy(scheme_copy, uri, sizeof(scheme_copy)); 94 if ((p = strchr(scheme_copy, ':')) != NULL) { 95 *p++ = '\0'; 96 if (OPENSSL_strcasecmp(scheme_copy, "file") != 0) { 97 if (strncmp(p, "//", 2) == 0) 98 schemes_n--; /* Invalidate the file scheme */ 99 schemes[schemes_n++] = scheme_copy; 100 } 101 } 102 103 ERR_set_mark(); 104 105 /* 106 * Try each scheme until we find one that could open the URI. 107 * 108 * For each scheme, we look for the engine implementation first, and 109 * failing that, we then try to fetch a provided implementation. 110 * This is consistent with how we handle legacy / engine implementations 111 * elsewhere. 112 */ 113 for (i = 0; loader_ctx == NULL && i < schemes_n; i++) { 114 scheme = schemes[i]; 115 OSSL_TRACE1(STORE, "Looking up scheme %s\n", scheme); 116 #ifndef OPENSSL_NO_DEPRECATED_3_0 117 if ((loader = ossl_store_get0_loader_int(scheme)) != NULL) { 118 no_loader_found = 0; 119 if (loader->open_ex != NULL) 120 loader_ctx = loader->open_ex(loader, uri, libctx, propq, 121 ui_method, ui_data); 122 else 123 loader_ctx = loader->open(loader, uri, ui_method, ui_data); 124 } 125 #endif 126 if (loader == NULL 127 && (fetched_loader = 128 OSSL_STORE_LOADER_fetch(libctx, scheme, propq)) != NULL) { 129 const OSSL_PROVIDER *provider = 130 OSSL_STORE_LOADER_get0_provider(fetched_loader); 131 void *provctx = OSSL_PROVIDER_get0_provider_ctx(provider); 132 133 no_loader_found = 0; 134 loader_ctx = fetched_loader->p_open(provctx, uri); 135 if (loader_ctx == NULL) { 136 OSSL_STORE_LOADER_free(fetched_loader); 137 fetched_loader = NULL; 138 } else if(!loader_set_params(fetched_loader, loader_ctx, 139 params, propq)) { 140 (void)fetched_loader->p_close(loader_ctx); 141 OSSL_STORE_LOADER_free(fetched_loader); 142 fetched_loader = NULL; 143 } 144 loader = fetched_loader; 145 } 146 } 147 148 if (no_loader_found) 149 /* 150 * It's assumed that ossl_store_get0_loader_int() and 151 * OSSL_STORE_LOADER_fetch() report their own errors 152 */ 153 goto err; 154 155 OSSL_TRACE1(STORE, "Found loader for scheme %s\n", scheme); 156 157 if (loader_ctx == NULL) 158 /* 159 * It's assumed that the loader's open() method reports its own 160 * errors 161 */ 162 goto err; 163 164 OSSL_TRACE2(STORE, "Opened %s => %p\n", uri, (void *)loader_ctx); 165 166 if ((propq != NULL && (propq_copy = OPENSSL_strdup(propq)) == NULL) 167 || (ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { 168 ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); 169 goto err; 170 } 171 172 if (ui_method != NULL 173 && (!ossl_pw_set_ui_method(&ctx->pwdata, ui_method, ui_data) 174 || !ossl_pw_enable_passphrase_caching(&ctx->pwdata))) { 175 ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_CRYPTO_LIB); 176 goto err; 177 } 178 ctx->properties = propq_copy; 179 ctx->fetched_loader = fetched_loader; 180 ctx->loader = loader; 181 ctx->loader_ctx = loader_ctx; 182 ctx->post_process = post_process; 183 ctx->post_process_data = post_process_data; 184 185 /* 186 * If the attempt to open with the 'file' scheme loader failed and the 187 * other scheme loader succeeded, the failure to open with the 'file' 188 * scheme loader leaves an error on the error stack. Let's remove it. 189 */ 190 ERR_pop_to_mark(); 191 192 return ctx; 193 194 err: 195 ERR_clear_last_mark(); 196 if (loader_ctx != NULL) { 197 /* 198 * Temporary structure so OSSL_STORE_close() can work even when 199 * |ctx| couldn't be allocated properly 200 */ 201 OSSL_STORE_CTX tmpctx = { NULL, }; 202 203 tmpctx.fetched_loader = fetched_loader; 204 tmpctx.loader = loader; 205 tmpctx.loader_ctx = loader_ctx; 206 207 /* 208 * We ignore a returned error because we will return NULL anyway in 209 * this case, so if something goes wrong when closing, that'll simply 210 * just add another entry on the error stack. 211 */ 212 (void)ossl_store_close_it(&tmpctx); 213 } 214 OSSL_STORE_LOADER_free(fetched_loader); 215 OPENSSL_free(propq_copy); 216 OPENSSL_free(ctx); 217 return NULL; 218 } 219 220 OSSL_STORE_CTX *OSSL_STORE_open(const char *uri, 221 const UI_METHOD *ui_method, void *ui_data, 222 OSSL_STORE_post_process_info_fn post_process, 223 void *post_process_data) 224 { 225 return OSSL_STORE_open_ex(uri, NULL, NULL, ui_method, ui_data, NULL, 226 post_process, post_process_data); 227 } 228 229 #ifndef OPENSSL_NO_DEPRECATED_3_0 230 int OSSL_STORE_ctrl(OSSL_STORE_CTX *ctx, int cmd, ...) 231 { 232 va_list args; 233 int ret; 234 235 va_start(args, cmd); 236 ret = OSSL_STORE_vctrl(ctx, cmd, args); 237 va_end(args); 238 239 return ret; 240 } 241 242 int OSSL_STORE_vctrl(OSSL_STORE_CTX *ctx, int cmd, va_list args) 243 { 244 if (ctx->fetched_loader != NULL) { 245 if (ctx->fetched_loader->p_set_ctx_params != NULL) { 246 OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; 247 248 switch (cmd) { 249 case OSSL_STORE_C_USE_SECMEM: 250 { 251 int on = *(va_arg(args, int *)); 252 253 params[0] = OSSL_PARAM_construct_int("use_secmem", &on); 254 } 255 break; 256 default: 257 break; 258 } 259 260 return ctx->fetched_loader->p_set_ctx_params(ctx->loader_ctx, 261 params); 262 } 263 } else if (ctx->loader->ctrl != NULL) { 264 return ctx->loader->ctrl(ctx->loader_ctx, cmd, args); 265 } 266 267 /* 268 * If the fetched loader doesn't have a set_ctx_params or a ctrl, it's as 269 * if there was one that ignored our params, which usually returns 1. 270 */ 271 return 1; 272 } 273 #endif 274 275 int OSSL_STORE_expect(OSSL_STORE_CTX *ctx, int expected_type) 276 { 277 int ret = 1; 278 279 if (ctx == NULL 280 || expected_type < 0 || expected_type > OSSL_STORE_INFO_CRL) { 281 ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_PASSED_INVALID_ARGUMENT); 282 return 0; 283 } 284 if (ctx->loading) { 285 ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_LOADING_STARTED); 286 return 0; 287 } 288 289 ctx->expected_type = expected_type; 290 if (ctx->fetched_loader != NULL 291 && ctx->fetched_loader->p_set_ctx_params != NULL) { 292 OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; 293 294 params[0] = 295 OSSL_PARAM_construct_int(OSSL_STORE_PARAM_EXPECT, &expected_type); 296 ret = ctx->fetched_loader->p_set_ctx_params(ctx->loader_ctx, params); 297 } 298 #ifndef OPENSSL_NO_DEPRECATED_3_0 299 if (ctx->fetched_loader == NULL 300 && ctx->loader->expect != NULL) { 301 ret = ctx->loader->expect(ctx->loader_ctx, expected_type); 302 } 303 #endif 304 return ret; 305 } 306 307 int OSSL_STORE_find(OSSL_STORE_CTX *ctx, const OSSL_STORE_SEARCH *search) 308 { 309 int ret = 1; 310 311 if (ctx->loading) { 312 ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_LOADING_STARTED); 313 return 0; 314 } 315 if (search == NULL) { 316 ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_PASSED_NULL_PARAMETER); 317 return 0; 318 } 319 320 if (ctx->fetched_loader != NULL) { 321 OSSL_PARAM_BLD *bld; 322 OSSL_PARAM *params; 323 /* OSSL_STORE_SEARCH_BY_NAME, OSSL_STORE_SEARCH_BY_ISSUER_SERIAL*/ 324 void *name_der = NULL; 325 int name_der_sz; 326 /* OSSL_STORE_SEARCH_BY_ISSUER_SERIAL */ 327 BIGNUM *number = NULL; 328 329 if (ctx->fetched_loader->p_set_ctx_params == NULL) { 330 ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_UNSUPPORTED_OPERATION); 331 return 0; 332 } 333 334 if ((bld = OSSL_PARAM_BLD_new()) == NULL) { 335 ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); 336 return 0; 337 } 338 339 ret = 0; /* Assume the worst */ 340 341 switch (search->search_type) { 342 case OSSL_STORE_SEARCH_BY_NAME: 343 if ((name_der_sz = i2d_X509_NAME(search->name, 344 (unsigned char **)&name_der)) > 0 345 && OSSL_PARAM_BLD_push_octet_string(bld, 346 OSSL_STORE_PARAM_SUBJECT, 347 name_der, name_der_sz)) 348 ret = 1; 349 break; 350 case OSSL_STORE_SEARCH_BY_ISSUER_SERIAL: 351 if ((name_der_sz = i2d_X509_NAME(search->name, 352 (unsigned char **)&name_der)) > 0 353 && (number = ASN1_INTEGER_to_BN(search->serial, NULL)) != NULL 354 && OSSL_PARAM_BLD_push_octet_string(bld, 355 OSSL_STORE_PARAM_ISSUER, 356 name_der, name_der_sz) 357 && OSSL_PARAM_BLD_push_BN(bld, OSSL_STORE_PARAM_SERIAL, 358 number)) 359 ret = 1; 360 break; 361 case OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT: 362 if (OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_STORE_PARAM_DIGEST, 363 EVP_MD_get0_name(search->digest), 364 0) 365 && OSSL_PARAM_BLD_push_octet_string(bld, 366 OSSL_STORE_PARAM_FINGERPRINT, 367 search->string, 368 search->stringlength)) 369 ret = 1; 370 break; 371 case OSSL_STORE_SEARCH_BY_ALIAS: 372 if (OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_STORE_PARAM_ALIAS, 373 (char *)search->string, 374 search->stringlength)) 375 ret = 1; 376 break; 377 } 378 if (ret) { 379 params = OSSL_PARAM_BLD_to_param(bld); 380 ret = ctx->fetched_loader->p_set_ctx_params(ctx->loader_ctx, 381 params); 382 OSSL_PARAM_free(params); 383 } 384 OSSL_PARAM_BLD_free(bld); 385 OPENSSL_free(name_der); 386 BN_free(number); 387 } else { 388 #ifndef OPENSSL_NO_DEPRECATED_3_0 389 /* legacy loader section */ 390 if (ctx->loader->find == NULL) { 391 ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_UNSUPPORTED_OPERATION); 392 return 0; 393 } 394 ret = ctx->loader->find(ctx->loader_ctx, search); 395 #endif 396 } 397 398 return ret; 399 } 400 401 OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx) 402 { 403 OSSL_STORE_INFO *v = NULL; 404 405 ctx->loading = 1; 406 again: 407 if (OSSL_STORE_eof(ctx)) 408 return NULL; 409 410 if (ctx->loader != NULL) 411 OSSL_TRACE(STORE, "Loading next object\n"); 412 413 if (ctx->cached_info != NULL 414 && sk_OSSL_STORE_INFO_num(ctx->cached_info) == 0) { 415 sk_OSSL_STORE_INFO_free(ctx->cached_info); 416 ctx->cached_info = NULL; 417 } 418 419 if (ctx->cached_info != NULL) { 420 v = sk_OSSL_STORE_INFO_shift(ctx->cached_info); 421 } else { 422 if (ctx->fetched_loader != NULL) { 423 struct ossl_load_result_data_st load_data; 424 425 load_data.v = NULL; 426 load_data.ctx = ctx; 427 428 if (!ctx->fetched_loader->p_load(ctx->loader_ctx, 429 ossl_store_handle_load_result, 430 &load_data, 431 ossl_pw_passphrase_callback_dec, 432 &ctx->pwdata)) { 433 if (!OSSL_STORE_eof(ctx)) 434 ctx->error_flag = 1; 435 return NULL; 436 } 437 v = load_data.v; 438 } 439 #ifndef OPENSSL_NO_DEPRECATED_3_0 440 if (ctx->fetched_loader == NULL) 441 v = ctx->loader->load(ctx->loader_ctx, 442 ctx->pwdata._.ui_method.ui_method, 443 ctx->pwdata._.ui_method.ui_method_data); 444 #endif 445 } 446 447 if (ctx->post_process != NULL && v != NULL) { 448 v = ctx->post_process(v, ctx->post_process_data); 449 450 /* 451 * By returning NULL, the callback decides that this object should 452 * be ignored. 453 */ 454 if (v == NULL) 455 goto again; 456 } 457 458 /* Clear any internally cached passphrase */ 459 (void)ossl_pw_clear_passphrase_cache(&ctx->pwdata); 460 461 if (v != NULL && ctx->expected_type != 0) { 462 int returned_type = OSSL_STORE_INFO_get_type(v); 463 464 if (returned_type != OSSL_STORE_INFO_NAME && returned_type != 0) { 465 if (ctx->expected_type != returned_type) { 466 OSSL_STORE_INFO_free(v); 467 goto again; 468 } 469 } 470 } 471 472 if (v != NULL) 473 OSSL_TRACE1(STORE, "Got a %s\n", 474 OSSL_STORE_INFO_type_string(OSSL_STORE_INFO_get_type(v))); 475 476 return v; 477 } 478 479 int OSSL_STORE_error(OSSL_STORE_CTX *ctx) 480 { 481 int ret = 1; 482 483 if (ctx->fetched_loader != NULL) 484 ret = ctx->error_flag; 485 #ifndef OPENSSL_NO_DEPRECATED_3_0 486 if (ctx->fetched_loader == NULL) 487 ret = ctx->loader->error(ctx->loader_ctx); 488 #endif 489 return ret; 490 } 491 492 int OSSL_STORE_eof(OSSL_STORE_CTX *ctx) 493 { 494 int ret = 1; 495 496 if (ctx->fetched_loader != NULL) 497 ret = ctx->loader->p_eof(ctx->loader_ctx); 498 #ifndef OPENSSL_NO_DEPRECATED_3_0 499 if (ctx->fetched_loader == NULL) 500 ret = ctx->loader->eof(ctx->loader_ctx); 501 #endif 502 return ret != 0; 503 } 504 505 static int ossl_store_close_it(OSSL_STORE_CTX *ctx) 506 { 507 int ret = 0; 508 509 if (ctx == NULL) 510 return 1; 511 OSSL_TRACE1(STORE, "Closing %p\n", (void *)ctx->loader_ctx); 512 513 if (ctx->fetched_loader != NULL) 514 ret = ctx->loader->p_close(ctx->loader_ctx); 515 #ifndef OPENSSL_NO_DEPRECATED_3_0 516 if (ctx->fetched_loader == NULL) 517 ret = ctx->loader->closefn(ctx->loader_ctx); 518 #endif 519 520 sk_OSSL_STORE_INFO_pop_free(ctx->cached_info, OSSL_STORE_INFO_free); 521 OSSL_STORE_LOADER_free(ctx->fetched_loader); 522 OPENSSL_free(ctx->properties); 523 ossl_pw_clear_passphrase_data(&ctx->pwdata); 524 return ret; 525 } 526 527 int OSSL_STORE_close(OSSL_STORE_CTX *ctx) 528 { 529 int ret = ossl_store_close_it(ctx); 530 531 OPENSSL_free(ctx); 532 return ret; 533 } 534 535 /* 536 * Functions to generate OSSL_STORE_INFOs, one function for each type we 537 * support having in them as well as a generic constructor. 538 * 539 * In all cases, ownership of the object is transferred to the OSSL_STORE_INFO 540 * and will therefore be freed when the OSSL_STORE_INFO is freed. 541 */ 542 OSSL_STORE_INFO *OSSL_STORE_INFO_new(int type, void *data) 543 { 544 OSSL_STORE_INFO *info = OPENSSL_zalloc(sizeof(*info)); 545 546 if (info == NULL) 547 return NULL; 548 549 info->type = type; 550 info->_.data = data; 551 return info; 552 } 553 554 OSSL_STORE_INFO *OSSL_STORE_INFO_new_NAME(char *name) 555 { 556 OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_NAME, NULL); 557 558 if (info == NULL) { 559 ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); 560 return NULL; 561 } 562 563 info->_.name.name = name; 564 info->_.name.desc = NULL; 565 566 return info; 567 } 568 569 int OSSL_STORE_INFO_set0_NAME_description(OSSL_STORE_INFO *info, char *desc) 570 { 571 if (info->type != OSSL_STORE_INFO_NAME) { 572 ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_PASSED_INVALID_ARGUMENT); 573 return 0; 574 } 575 576 info->_.name.desc = desc; 577 578 return 1; 579 } 580 OSSL_STORE_INFO *OSSL_STORE_INFO_new_PARAMS(EVP_PKEY *params) 581 { 582 OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_PARAMS, params); 583 584 if (info == NULL) 585 ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); 586 return info; 587 } 588 589 OSSL_STORE_INFO *OSSL_STORE_INFO_new_PUBKEY(EVP_PKEY *pkey) 590 { 591 OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_PUBKEY, pkey); 592 593 if (info == NULL) 594 ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); 595 return info; 596 } 597 598 OSSL_STORE_INFO *OSSL_STORE_INFO_new_PKEY(EVP_PKEY *pkey) 599 { 600 OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_PKEY, pkey); 601 602 if (info == NULL) 603 ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); 604 return info; 605 } 606 607 OSSL_STORE_INFO *OSSL_STORE_INFO_new_CERT(X509 *x509) 608 { 609 OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_CERT, x509); 610 611 if (info == NULL) 612 ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); 613 return info; 614 } 615 616 OSSL_STORE_INFO *OSSL_STORE_INFO_new_CRL(X509_CRL *crl) 617 { 618 OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_CRL, crl); 619 620 if (info == NULL) 621 ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); 622 return info; 623 } 624 625 /* 626 * Functions to try to extract data from a OSSL_STORE_INFO. 627 */ 628 int OSSL_STORE_INFO_get_type(const OSSL_STORE_INFO *info) 629 { 630 return info->type; 631 } 632 633 void *OSSL_STORE_INFO_get0_data(int type, const OSSL_STORE_INFO *info) 634 { 635 if (info->type == type) 636 return info->_.data; 637 return NULL; 638 } 639 640 const char *OSSL_STORE_INFO_get0_NAME(const OSSL_STORE_INFO *info) 641 { 642 if (info->type == OSSL_STORE_INFO_NAME) 643 return info->_.name.name; 644 return NULL; 645 } 646 647 char *OSSL_STORE_INFO_get1_NAME(const OSSL_STORE_INFO *info) 648 { 649 if (info->type == OSSL_STORE_INFO_NAME) { 650 char *ret = OPENSSL_strdup(info->_.name.name); 651 652 if (ret == NULL) 653 ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); 654 return ret; 655 } 656 ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_NAME); 657 return NULL; 658 } 659 660 const char *OSSL_STORE_INFO_get0_NAME_description(const OSSL_STORE_INFO *info) 661 { 662 if (info->type == OSSL_STORE_INFO_NAME) 663 return info->_.name.desc; 664 return NULL; 665 } 666 667 char *OSSL_STORE_INFO_get1_NAME_description(const OSSL_STORE_INFO *info) 668 { 669 if (info->type == OSSL_STORE_INFO_NAME) { 670 char *ret = OPENSSL_strdup(info->_.name.desc 671 ? info->_.name.desc : ""); 672 673 if (ret == NULL) 674 ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); 675 return ret; 676 } 677 ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_NAME); 678 return NULL; 679 } 680 681 EVP_PKEY *OSSL_STORE_INFO_get0_PARAMS(const OSSL_STORE_INFO *info) 682 { 683 if (info->type == OSSL_STORE_INFO_PARAMS) 684 return info->_.params; 685 return NULL; 686 } 687 688 EVP_PKEY *OSSL_STORE_INFO_get1_PARAMS(const OSSL_STORE_INFO *info) 689 { 690 if (info->type == OSSL_STORE_INFO_PARAMS) { 691 EVP_PKEY_up_ref(info->_.params); 692 return info->_.params; 693 } 694 ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_PARAMETERS); 695 return NULL; 696 } 697 698 EVP_PKEY *OSSL_STORE_INFO_get0_PUBKEY(const OSSL_STORE_INFO *info) 699 { 700 if (info->type == OSSL_STORE_INFO_PUBKEY) 701 return info->_.pubkey; 702 return NULL; 703 } 704 705 EVP_PKEY *OSSL_STORE_INFO_get1_PUBKEY(const OSSL_STORE_INFO *info) 706 { 707 if (info->type == OSSL_STORE_INFO_PUBKEY) { 708 EVP_PKEY_up_ref(info->_.pubkey); 709 return info->_.pubkey; 710 } 711 ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_PUBLIC_KEY); 712 return NULL; 713 } 714 715 EVP_PKEY *OSSL_STORE_INFO_get0_PKEY(const OSSL_STORE_INFO *info) 716 { 717 if (info->type == OSSL_STORE_INFO_PKEY) 718 return info->_.pkey; 719 return NULL; 720 } 721 722 EVP_PKEY *OSSL_STORE_INFO_get1_PKEY(const OSSL_STORE_INFO *info) 723 { 724 if (info->type == OSSL_STORE_INFO_PKEY) { 725 EVP_PKEY_up_ref(info->_.pkey); 726 return info->_.pkey; 727 } 728 ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_PRIVATE_KEY); 729 return NULL; 730 } 731 732 X509 *OSSL_STORE_INFO_get0_CERT(const OSSL_STORE_INFO *info) 733 { 734 if (info->type == OSSL_STORE_INFO_CERT) 735 return info->_.x509; 736 return NULL; 737 } 738 739 X509 *OSSL_STORE_INFO_get1_CERT(const OSSL_STORE_INFO *info) 740 { 741 if (info->type == OSSL_STORE_INFO_CERT) { 742 X509_up_ref(info->_.x509); 743 return info->_.x509; 744 } 745 ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_CERTIFICATE); 746 return NULL; 747 } 748 749 X509_CRL *OSSL_STORE_INFO_get0_CRL(const OSSL_STORE_INFO *info) 750 { 751 if (info->type == OSSL_STORE_INFO_CRL) 752 return info->_.crl; 753 return NULL; 754 } 755 756 X509_CRL *OSSL_STORE_INFO_get1_CRL(const OSSL_STORE_INFO *info) 757 { 758 if (info->type == OSSL_STORE_INFO_CRL) { 759 X509_CRL_up_ref(info->_.crl); 760 return info->_.crl; 761 } 762 ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_CRL); 763 return NULL; 764 } 765 766 /* 767 * Free the OSSL_STORE_INFO 768 */ 769 void OSSL_STORE_INFO_free(OSSL_STORE_INFO *info) 770 { 771 if (info != NULL) { 772 switch (info->type) { 773 case OSSL_STORE_INFO_NAME: 774 OPENSSL_free(info->_.name.name); 775 OPENSSL_free(info->_.name.desc); 776 break; 777 case OSSL_STORE_INFO_PARAMS: 778 EVP_PKEY_free(info->_.params); 779 break; 780 case OSSL_STORE_INFO_PUBKEY: 781 EVP_PKEY_free(info->_.pubkey); 782 break; 783 case OSSL_STORE_INFO_PKEY: 784 EVP_PKEY_free(info->_.pkey); 785 break; 786 case OSSL_STORE_INFO_CERT: 787 X509_free(info->_.x509); 788 break; 789 case OSSL_STORE_INFO_CRL: 790 X509_CRL_free(info->_.crl); 791 break; 792 } 793 OPENSSL_free(info); 794 } 795 } 796 797 int OSSL_STORE_supports_search(OSSL_STORE_CTX *ctx, int search_type) 798 { 799 int ret = 0; 800 801 if (ctx->fetched_loader != NULL) { 802 void *provctx = 803 ossl_provider_ctx(OSSL_STORE_LOADER_get0_provider(ctx->fetched_loader)); 804 const OSSL_PARAM *params; 805 const OSSL_PARAM *p_subject = NULL; 806 const OSSL_PARAM *p_issuer = NULL; 807 const OSSL_PARAM *p_serial = NULL; 808 const OSSL_PARAM *p_fingerprint = NULL; 809 const OSSL_PARAM *p_alias = NULL; 810 811 if (ctx->fetched_loader->p_settable_ctx_params == NULL) 812 return 0; 813 814 params = ctx->fetched_loader->p_settable_ctx_params(provctx); 815 p_subject = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_SUBJECT); 816 p_issuer = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_ISSUER); 817 p_serial = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_SERIAL); 818 p_fingerprint = 819 OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_FINGERPRINT); 820 p_alias = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_ALIAS); 821 822 switch (search_type) { 823 case OSSL_STORE_SEARCH_BY_NAME: 824 ret = (p_subject != NULL); 825 break; 826 case OSSL_STORE_SEARCH_BY_ISSUER_SERIAL: 827 ret = (p_issuer != NULL && p_serial != NULL); 828 break; 829 case OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT: 830 ret = (p_fingerprint != NULL); 831 break; 832 case OSSL_STORE_SEARCH_BY_ALIAS: 833 ret = (p_alias != NULL); 834 break; 835 } 836 } 837 #ifndef OPENSSL_NO_DEPRECATED_3_0 838 if (ctx->fetched_loader == NULL) { 839 OSSL_STORE_SEARCH tmp_search; 840 841 if (ctx->loader->find == NULL) 842 return 0; 843 tmp_search.search_type = search_type; 844 ret = ctx->loader->find(NULL, &tmp_search); 845 } 846 #endif 847 return ret; 848 } 849 850 /* Search term constructors */ 851 OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_name(X509_NAME *name) 852 { 853 OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); 854 855 if (search == NULL) { 856 ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); 857 return NULL; 858 } 859 860 search->search_type = OSSL_STORE_SEARCH_BY_NAME; 861 search->name = name; 862 return search; 863 } 864 865 OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_issuer_serial(X509_NAME *name, 866 const ASN1_INTEGER *serial) 867 { 868 OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); 869 870 if (search == NULL) { 871 ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); 872 return NULL; 873 } 874 875 search->search_type = OSSL_STORE_SEARCH_BY_ISSUER_SERIAL; 876 search->name = name; 877 search->serial = serial; 878 return search; 879 } 880 881 OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_key_fingerprint(const EVP_MD *digest, 882 const unsigned char 883 *bytes, size_t len) 884 { 885 OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); 886 887 if (search == NULL) { 888 ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); 889 return NULL; 890 } 891 892 if (digest != NULL && len != (size_t)EVP_MD_get_size(digest)) { 893 ERR_raise_data(ERR_LIB_OSSL_STORE, 894 OSSL_STORE_R_FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST, 895 "%s size is %d, fingerprint size is %zu", 896 EVP_MD_get0_name(digest), EVP_MD_get_size(digest), len); 897 OPENSSL_free(search); 898 return NULL; 899 } 900 901 search->search_type = OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT; 902 search->digest = digest; 903 search->string = bytes; 904 search->stringlength = len; 905 return search; 906 } 907 908 OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_alias(const char *alias) 909 { 910 OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); 911 912 if (search == NULL) { 913 ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); 914 return NULL; 915 } 916 917 search->search_type = OSSL_STORE_SEARCH_BY_ALIAS; 918 search->string = (const unsigned char *)alias; 919 search->stringlength = strlen(alias); 920 return search; 921 } 922 923 /* Search term destructor */ 924 void OSSL_STORE_SEARCH_free(OSSL_STORE_SEARCH *search) 925 { 926 OPENSSL_free(search); 927 } 928 929 /* Search term accessors */ 930 int OSSL_STORE_SEARCH_get_type(const OSSL_STORE_SEARCH *criterion) 931 { 932 return criterion->search_type; 933 } 934 935 X509_NAME *OSSL_STORE_SEARCH_get0_name(const OSSL_STORE_SEARCH *criterion) 936 { 937 return criterion->name; 938 } 939 940 const ASN1_INTEGER *OSSL_STORE_SEARCH_get0_serial(const OSSL_STORE_SEARCH 941 *criterion) 942 { 943 return criterion->serial; 944 } 945 946 const unsigned char *OSSL_STORE_SEARCH_get0_bytes(const OSSL_STORE_SEARCH 947 *criterion, size_t *length) 948 { 949 *length = criterion->stringlength; 950 return criterion->string; 951 } 952 953 const char *OSSL_STORE_SEARCH_get0_string(const OSSL_STORE_SEARCH *criterion) 954 { 955 return (const char *)criterion->string; 956 } 957 958 const EVP_MD *OSSL_STORE_SEARCH_get0_digest(const OSSL_STORE_SEARCH *criterion) 959 { 960 return criterion->digest; 961 } 962 963 OSSL_STORE_CTX *OSSL_STORE_attach(BIO *bp, const char *scheme, 964 OSSL_LIB_CTX *libctx, const char *propq, 965 const UI_METHOD *ui_method, void *ui_data, 966 const OSSL_PARAM params[], 967 OSSL_STORE_post_process_info_fn post_process, 968 void *post_process_data) 969 { 970 const OSSL_STORE_LOADER *loader = NULL; 971 OSSL_STORE_LOADER *fetched_loader = NULL; 972 OSSL_STORE_LOADER_CTX *loader_ctx = NULL; 973 OSSL_STORE_CTX *ctx = NULL; 974 975 if (scheme == NULL) 976 scheme = "file"; 977 978 OSSL_TRACE1(STORE, "Looking up scheme %s\n", scheme); 979 ERR_set_mark(); 980 #ifndef OPENSSL_NO_DEPRECATED_3_0 981 if ((loader = ossl_store_get0_loader_int(scheme)) != NULL) 982 loader_ctx = loader->attach(loader, bp, libctx, propq, 983 ui_method, ui_data); 984 #endif 985 if (loader == NULL 986 && (fetched_loader = 987 OSSL_STORE_LOADER_fetch(libctx, scheme, propq)) != NULL) { 988 const OSSL_PROVIDER *provider = 989 OSSL_STORE_LOADER_get0_provider(fetched_loader); 990 void *provctx = OSSL_PROVIDER_get0_provider_ctx(provider); 991 OSSL_CORE_BIO *cbio = ossl_core_bio_new_from_bio(bp); 992 993 if (cbio == NULL 994 || (loader_ctx = fetched_loader->p_attach(provctx, cbio)) == NULL) { 995 OSSL_STORE_LOADER_free(fetched_loader); 996 fetched_loader = NULL; 997 } else if (!loader_set_params(fetched_loader, loader_ctx, 998 params, propq)) { 999 (void)fetched_loader->p_close(loader_ctx); 1000 OSSL_STORE_LOADER_free(fetched_loader); 1001 fetched_loader = NULL; 1002 } 1003 loader = fetched_loader; 1004 ossl_core_bio_free(cbio); 1005 } 1006 1007 if (loader_ctx == NULL) { 1008 ERR_clear_last_mark(); 1009 return NULL; 1010 } 1011 1012 if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { 1013 ERR_clear_last_mark(); 1014 ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); 1015 return NULL; 1016 } 1017 1018 if (ui_method != NULL 1019 && !ossl_pw_set_ui_method(&ctx->pwdata, ui_method, ui_data)) { 1020 ERR_clear_last_mark(); 1021 OPENSSL_free(ctx); 1022 return NULL; 1023 } 1024 1025 ctx->fetched_loader = fetched_loader; 1026 ctx->loader = loader; 1027 ctx->loader_ctx = loader_ctx; 1028 ctx->post_process = post_process; 1029 ctx->post_process_data = post_process_data; 1030 1031 /* 1032 * ossl_store_get0_loader_int will raise an error if the loader for the 1033 * the scheme cannot be retrieved. But if a loader was successfully 1034 * fetched then we remove this error from the error stack. 1035 */ 1036 ERR_pop_to_mark(); 1037 1038 return ctx; 1039 } 1040