1 /* 2 * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (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 "e_os.h" 11 #include <stdlib.h> 12 #include <string.h> 13 #include <assert.h> 14 15 #include "e_os.h" 16 17 #include <openssl/crypto.h> 18 #include <openssl/err.h> 19 #include <openssl/store.h> 20 #include "internal/thread_once.h" 21 #include "crypto/store.h" 22 #include "store_local.h" 23 24 struct ossl_store_ctx_st { 25 const OSSL_STORE_LOADER *loader; 26 OSSL_STORE_LOADER_CTX *loader_ctx; 27 const UI_METHOD *ui_method; 28 void *ui_data; 29 OSSL_STORE_post_process_info_fn post_process; 30 void *post_process_data; 31 int expected_type; 32 33 /* 0 before the first STORE_load(), 1 otherwise */ 34 int loading; 35 }; 36 37 OSSL_STORE_CTX *OSSL_STORE_open(const char *uri, const UI_METHOD *ui_method, 38 void *ui_data, 39 OSSL_STORE_post_process_info_fn post_process, 40 void *post_process_data) 41 { 42 const OSSL_STORE_LOADER *loader = NULL; 43 OSSL_STORE_LOADER_CTX *loader_ctx = NULL; 44 OSSL_STORE_CTX *ctx = NULL; 45 char scheme_copy[256], *p, *schemes[2]; 46 size_t schemes_n = 0; 47 size_t i; 48 49 /* 50 * Put the file scheme first. If the uri does represent an existing file, 51 * possible device name and all, then it should be loaded. Only a failed 52 * attempt at loading a local file should have us try something else. 53 */ 54 schemes[schemes_n++] = "file"; 55 56 /* 57 * Now, check if we have something that looks like a scheme, and add it 58 * as a second scheme. However, also check if there's an authority start 59 * (://), because that will invalidate the previous file scheme. Also, 60 * check that this isn't actually the file scheme, as there's no point 61 * going through that one twice! 62 */ 63 OPENSSL_strlcpy(scheme_copy, uri, sizeof(scheme_copy)); 64 if ((p = strchr(scheme_copy, ':')) != NULL) { 65 *p++ = '\0'; 66 if (strcasecmp(scheme_copy, "file") != 0) { 67 if (strncmp(p, "//", 2) == 0) 68 schemes_n--; /* Invalidate the file scheme */ 69 schemes[schemes_n++] = scheme_copy; 70 } 71 } 72 73 ERR_set_mark(); 74 75 /* Try each scheme until we find one that could open the URI */ 76 for (i = 0; loader_ctx == NULL && i < schemes_n; i++) { 77 if ((loader = ossl_store_get0_loader_int(schemes[i])) != NULL) 78 loader_ctx = loader->open(loader, uri, ui_method, ui_data); 79 } 80 if (loader_ctx == NULL) 81 goto err; 82 83 if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { 84 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_OPEN, ERR_R_MALLOC_FAILURE); 85 goto err; 86 } 87 88 ctx->loader = loader; 89 ctx->loader_ctx = loader_ctx; 90 ctx->ui_method = ui_method; 91 ctx->ui_data = ui_data; 92 ctx->post_process = post_process; 93 ctx->post_process_data = post_process_data; 94 95 /* 96 * If the attempt to open with the 'file' scheme loader failed and the 97 * other scheme loader succeeded, the failure to open with the 'file' 98 * scheme loader leaves an error on the error stack. Let's remove it. 99 */ 100 ERR_pop_to_mark(); 101 102 return ctx; 103 104 err: 105 ERR_clear_last_mark(); 106 if (loader_ctx != NULL) { 107 /* 108 * We ignore a returned error because we will return NULL anyway in 109 * this case, so if something goes wrong when closing, that'll simply 110 * just add another entry on the error stack. 111 */ 112 (void)loader->close(loader_ctx); 113 } 114 return NULL; 115 } 116 117 int OSSL_STORE_ctrl(OSSL_STORE_CTX *ctx, int cmd, ...) 118 { 119 va_list args; 120 int ret; 121 122 va_start(args, cmd); 123 ret = OSSL_STORE_vctrl(ctx, cmd, args); 124 va_end(args); 125 126 return ret; 127 } 128 129 int OSSL_STORE_vctrl(OSSL_STORE_CTX *ctx, int cmd, va_list args) 130 { 131 if (ctx->loader->ctrl != NULL) 132 return ctx->loader->ctrl(ctx->loader_ctx, cmd, args); 133 return 0; 134 } 135 136 int OSSL_STORE_expect(OSSL_STORE_CTX *ctx, int expected_type) 137 { 138 if (ctx->loading) { 139 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_EXPECT, 140 OSSL_STORE_R_LOADING_STARTED); 141 return 0; 142 } 143 144 ctx->expected_type = expected_type; 145 if (ctx->loader->expect != NULL) 146 return ctx->loader->expect(ctx->loader_ctx, expected_type); 147 return 1; 148 } 149 150 int OSSL_STORE_find(OSSL_STORE_CTX *ctx, OSSL_STORE_SEARCH *search) 151 { 152 if (ctx->loading) { 153 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_FIND, 154 OSSL_STORE_R_LOADING_STARTED); 155 return 0; 156 } 157 if (ctx->loader->find == NULL) { 158 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_FIND, 159 OSSL_STORE_R_UNSUPPORTED_OPERATION); 160 return 0; 161 } 162 163 return ctx->loader->find(ctx->loader_ctx, search); 164 } 165 166 OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx) 167 { 168 OSSL_STORE_INFO *v = NULL; 169 170 ctx->loading = 1; 171 again: 172 if (OSSL_STORE_eof(ctx)) 173 return NULL; 174 175 v = ctx->loader->load(ctx->loader_ctx, ctx->ui_method, ctx->ui_data); 176 177 if (ctx->post_process != NULL && v != NULL) { 178 v = ctx->post_process(v, ctx->post_process_data); 179 180 /* 181 * By returning NULL, the callback decides that this object should 182 * be ignored. 183 */ 184 if (v == NULL) 185 goto again; 186 } 187 188 if (v != NULL && ctx->expected_type != 0) { 189 int returned_type = OSSL_STORE_INFO_get_type(v); 190 191 if (returned_type != OSSL_STORE_INFO_NAME && returned_type != 0) { 192 /* 193 * Soft assert here so those who want to harsly weed out faulty 194 * loaders can do so using a debugging version of libcrypto. 195 */ 196 if (ctx->loader->expect != NULL) 197 assert(ctx->expected_type == returned_type); 198 199 if (ctx->expected_type != returned_type) { 200 OSSL_STORE_INFO_free(v); 201 goto again; 202 } 203 } 204 } 205 206 return v; 207 } 208 209 int OSSL_STORE_error(OSSL_STORE_CTX *ctx) 210 { 211 return ctx->loader->error(ctx->loader_ctx); 212 } 213 214 int OSSL_STORE_eof(OSSL_STORE_CTX *ctx) 215 { 216 return ctx->loader->eof(ctx->loader_ctx); 217 } 218 219 int OSSL_STORE_close(OSSL_STORE_CTX *ctx) 220 { 221 int loader_ret; 222 223 if (ctx == NULL) 224 return 1; 225 loader_ret = ctx->loader->close(ctx->loader_ctx); 226 227 OPENSSL_free(ctx); 228 return loader_ret; 229 } 230 231 /* 232 * Functions to generate OSSL_STORE_INFOs, one function for each type we 233 * support having in them as well as a generic constructor. 234 * 235 * In all cases, ownership of the object is transferred to the OSSL_STORE_INFO 236 * and will therefore be freed when the OSSL_STORE_INFO is freed. 237 */ 238 static OSSL_STORE_INFO *store_info_new(int type, void *data) 239 { 240 OSSL_STORE_INFO *info = OPENSSL_zalloc(sizeof(*info)); 241 242 if (info == NULL) 243 return NULL; 244 245 info->type = type; 246 info->_.data = data; 247 return info; 248 } 249 250 OSSL_STORE_INFO *OSSL_STORE_INFO_new_NAME(char *name) 251 { 252 OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_NAME, NULL); 253 254 if (info == NULL) { 255 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_NAME, 256 ERR_R_MALLOC_FAILURE); 257 return NULL; 258 } 259 260 info->_.name.name = name; 261 info->_.name.desc = NULL; 262 263 return info; 264 } 265 266 int OSSL_STORE_INFO_set0_NAME_description(OSSL_STORE_INFO *info, char *desc) 267 { 268 if (info->type != OSSL_STORE_INFO_NAME) { 269 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_SET0_NAME_DESCRIPTION, 270 ERR_R_PASSED_INVALID_ARGUMENT); 271 return 0; 272 } 273 274 info->_.name.desc = desc; 275 276 return 1; 277 } 278 OSSL_STORE_INFO *OSSL_STORE_INFO_new_PARAMS(EVP_PKEY *params) 279 { 280 OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_PARAMS, params); 281 282 if (info == NULL) 283 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_PARAMS, 284 ERR_R_MALLOC_FAILURE); 285 return info; 286 } 287 288 OSSL_STORE_INFO *OSSL_STORE_INFO_new_PKEY(EVP_PKEY *pkey) 289 { 290 OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_PKEY, pkey); 291 292 if (info == NULL) 293 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_PKEY, 294 ERR_R_MALLOC_FAILURE); 295 return info; 296 } 297 298 OSSL_STORE_INFO *OSSL_STORE_INFO_new_CERT(X509 *x509) 299 { 300 OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_CERT, x509); 301 302 if (info == NULL) 303 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_CERT, 304 ERR_R_MALLOC_FAILURE); 305 return info; 306 } 307 308 OSSL_STORE_INFO *OSSL_STORE_INFO_new_CRL(X509_CRL *crl) 309 { 310 OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_CRL, crl); 311 312 if (info == NULL) 313 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_CRL, 314 ERR_R_MALLOC_FAILURE); 315 return info; 316 } 317 318 /* 319 * Functions to try to extract data from a OSSL_STORE_INFO. 320 */ 321 int OSSL_STORE_INFO_get_type(const OSSL_STORE_INFO *info) 322 { 323 return info->type; 324 } 325 326 const char *OSSL_STORE_INFO_get0_NAME(const OSSL_STORE_INFO *info) 327 { 328 if (info->type == OSSL_STORE_INFO_NAME) 329 return info->_.name.name; 330 return NULL; 331 } 332 333 char *OSSL_STORE_INFO_get1_NAME(const OSSL_STORE_INFO *info) 334 { 335 if (info->type == OSSL_STORE_INFO_NAME) { 336 char *ret = OPENSSL_strdup(info->_.name.name); 337 338 if (ret == NULL) 339 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME, 340 ERR_R_MALLOC_FAILURE); 341 return ret; 342 } 343 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME, 344 OSSL_STORE_R_NOT_A_NAME); 345 return NULL; 346 } 347 348 const char *OSSL_STORE_INFO_get0_NAME_description(const OSSL_STORE_INFO *info) 349 { 350 if (info->type == OSSL_STORE_INFO_NAME) 351 return info->_.name.desc; 352 return NULL; 353 } 354 355 char *OSSL_STORE_INFO_get1_NAME_description(const OSSL_STORE_INFO *info) 356 { 357 if (info->type == OSSL_STORE_INFO_NAME) { 358 char *ret = OPENSSL_strdup(info->_.name.desc 359 ? info->_.name.desc : ""); 360 361 if (ret == NULL) 362 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME_DESCRIPTION, 363 ERR_R_MALLOC_FAILURE); 364 return ret; 365 } 366 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME_DESCRIPTION, 367 OSSL_STORE_R_NOT_A_NAME); 368 return NULL; 369 } 370 371 EVP_PKEY *OSSL_STORE_INFO_get0_PARAMS(const OSSL_STORE_INFO *info) 372 { 373 if (info->type == OSSL_STORE_INFO_PARAMS) 374 return info->_.params; 375 return NULL; 376 } 377 378 EVP_PKEY *OSSL_STORE_INFO_get1_PARAMS(const OSSL_STORE_INFO *info) 379 { 380 if (info->type == OSSL_STORE_INFO_PARAMS) { 381 EVP_PKEY_up_ref(info->_.params); 382 return info->_.params; 383 } 384 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_PARAMS, 385 OSSL_STORE_R_NOT_PARAMETERS); 386 return NULL; 387 } 388 389 EVP_PKEY *OSSL_STORE_INFO_get0_PKEY(const OSSL_STORE_INFO *info) 390 { 391 if (info->type == OSSL_STORE_INFO_PKEY) 392 return info->_.pkey; 393 return NULL; 394 } 395 396 EVP_PKEY *OSSL_STORE_INFO_get1_PKEY(const OSSL_STORE_INFO *info) 397 { 398 if (info->type == OSSL_STORE_INFO_PKEY) { 399 EVP_PKEY_up_ref(info->_.pkey); 400 return info->_.pkey; 401 } 402 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_PKEY, 403 OSSL_STORE_R_NOT_A_KEY); 404 return NULL; 405 } 406 407 X509 *OSSL_STORE_INFO_get0_CERT(const OSSL_STORE_INFO *info) 408 { 409 if (info->type == OSSL_STORE_INFO_CERT) 410 return info->_.x509; 411 return NULL; 412 } 413 414 X509 *OSSL_STORE_INFO_get1_CERT(const OSSL_STORE_INFO *info) 415 { 416 if (info->type == OSSL_STORE_INFO_CERT) { 417 X509_up_ref(info->_.x509); 418 return info->_.x509; 419 } 420 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_CERT, 421 OSSL_STORE_R_NOT_A_CERTIFICATE); 422 return NULL; 423 } 424 425 X509_CRL *OSSL_STORE_INFO_get0_CRL(const OSSL_STORE_INFO *info) 426 { 427 if (info->type == OSSL_STORE_INFO_CRL) 428 return info->_.crl; 429 return NULL; 430 } 431 432 X509_CRL *OSSL_STORE_INFO_get1_CRL(const OSSL_STORE_INFO *info) 433 { 434 if (info->type == OSSL_STORE_INFO_CRL) { 435 X509_CRL_up_ref(info->_.crl); 436 return info->_.crl; 437 } 438 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_CRL, 439 OSSL_STORE_R_NOT_A_CRL); 440 return NULL; 441 } 442 443 /* 444 * Free the OSSL_STORE_INFO 445 */ 446 void OSSL_STORE_INFO_free(OSSL_STORE_INFO *info) 447 { 448 if (info != NULL) { 449 switch (info->type) { 450 case OSSL_STORE_INFO_EMBEDDED: 451 BUF_MEM_free(info->_.embedded.blob); 452 OPENSSL_free(info->_.embedded.pem_name); 453 break; 454 case OSSL_STORE_INFO_NAME: 455 OPENSSL_free(info->_.name.name); 456 OPENSSL_free(info->_.name.desc); 457 break; 458 case OSSL_STORE_INFO_PARAMS: 459 EVP_PKEY_free(info->_.params); 460 break; 461 case OSSL_STORE_INFO_PKEY: 462 EVP_PKEY_free(info->_.pkey); 463 break; 464 case OSSL_STORE_INFO_CERT: 465 X509_free(info->_.x509); 466 break; 467 case OSSL_STORE_INFO_CRL: 468 X509_CRL_free(info->_.crl); 469 break; 470 } 471 OPENSSL_free(info); 472 } 473 } 474 475 int OSSL_STORE_supports_search(OSSL_STORE_CTX *ctx, int search_type) 476 { 477 OSSL_STORE_SEARCH tmp_search; 478 479 if (ctx->loader->find == NULL) 480 return 0; 481 tmp_search.search_type = search_type; 482 return ctx->loader->find(NULL, &tmp_search); 483 } 484 485 /* Search term constructors */ 486 OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_name(X509_NAME *name) 487 { 488 OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); 489 490 if (search == NULL) { 491 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_SEARCH_BY_NAME, 492 ERR_R_MALLOC_FAILURE); 493 return NULL; 494 } 495 496 search->search_type = OSSL_STORE_SEARCH_BY_NAME; 497 search->name = name; 498 return search; 499 } 500 501 OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_issuer_serial(X509_NAME *name, 502 const ASN1_INTEGER *serial) 503 { 504 OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); 505 506 if (search == NULL) { 507 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ISSUER_SERIAL, 508 ERR_R_MALLOC_FAILURE); 509 return NULL; 510 } 511 512 search->search_type = OSSL_STORE_SEARCH_BY_ISSUER_SERIAL; 513 search->name = name; 514 search->serial = serial; 515 return search; 516 } 517 518 OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_key_fingerprint(const EVP_MD *digest, 519 const unsigned char 520 *bytes, size_t len) 521 { 522 OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); 523 524 if (search == NULL) { 525 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT, 526 ERR_R_MALLOC_FAILURE); 527 return NULL; 528 } 529 530 if (digest != NULL && len != (size_t)EVP_MD_size(digest)) { 531 char buf1[20], buf2[20]; 532 533 BIO_snprintf(buf1, sizeof(buf1), "%d", EVP_MD_size(digest)); 534 BIO_snprintf(buf2, sizeof(buf2), "%zu", len); 535 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT, 536 OSSL_STORE_R_FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST); 537 ERR_add_error_data(5, EVP_MD_name(digest), " size is ", buf1, 538 ", fingerprint size is ", buf2); 539 } 540 541 search->search_type = OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT; 542 search->digest = digest; 543 search->string = bytes; 544 search->stringlength = len; 545 return search; 546 } 547 548 OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_alias(const char *alias) 549 { 550 OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); 551 552 if (search == NULL) { 553 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ALIAS, 554 ERR_R_MALLOC_FAILURE); 555 return NULL; 556 } 557 558 search->search_type = OSSL_STORE_SEARCH_BY_ALIAS; 559 search->string = (const unsigned char *)alias; 560 search->stringlength = strlen(alias); 561 return search; 562 } 563 564 /* Search term destructor */ 565 void OSSL_STORE_SEARCH_free(OSSL_STORE_SEARCH *search) 566 { 567 OPENSSL_free(search); 568 } 569 570 /* Search term accessors */ 571 int OSSL_STORE_SEARCH_get_type(const OSSL_STORE_SEARCH *criterion) 572 { 573 return criterion->search_type; 574 } 575 576 X509_NAME *OSSL_STORE_SEARCH_get0_name(OSSL_STORE_SEARCH *criterion) 577 { 578 return criterion->name; 579 } 580 581 const ASN1_INTEGER *OSSL_STORE_SEARCH_get0_serial(const OSSL_STORE_SEARCH 582 *criterion) 583 { 584 return criterion->serial; 585 } 586 587 const unsigned char *OSSL_STORE_SEARCH_get0_bytes(const OSSL_STORE_SEARCH 588 *criterion, size_t *length) 589 { 590 *length = criterion->stringlength; 591 return criterion->string; 592 } 593 594 const char *OSSL_STORE_SEARCH_get0_string(const OSSL_STORE_SEARCH *criterion) 595 { 596 return (const char *)criterion->string; 597 } 598 599 const EVP_MD *OSSL_STORE_SEARCH_get0_digest(const OSSL_STORE_SEARCH *criterion) 600 { 601 return criterion->digest; 602 } 603 604 /* Internal functions */ 605 OSSL_STORE_INFO *ossl_store_info_new_EMBEDDED(const char *new_pem_name, 606 BUF_MEM *embedded) 607 { 608 OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_EMBEDDED, NULL); 609 610 if (info == NULL) { 611 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED, 612 ERR_R_MALLOC_FAILURE); 613 return NULL; 614 } 615 616 info->_.embedded.blob = embedded; 617 info->_.embedded.pem_name = 618 new_pem_name == NULL ? NULL : OPENSSL_strdup(new_pem_name); 619 620 if (new_pem_name != NULL && info->_.embedded.pem_name == NULL) { 621 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED, 622 ERR_R_MALLOC_FAILURE); 623 OSSL_STORE_INFO_free(info); 624 info = NULL; 625 } 626 627 return info; 628 } 629 630 BUF_MEM *ossl_store_info_get0_EMBEDDED_buffer(OSSL_STORE_INFO *info) 631 { 632 if (info->type == OSSL_STORE_INFO_EMBEDDED) 633 return info->_.embedded.blob; 634 return NULL; 635 } 636 637 char *ossl_store_info_get0_EMBEDDED_pem_name(OSSL_STORE_INFO *info) 638 { 639 if (info->type == OSSL_STORE_INFO_EMBEDDED) 640 return info->_.embedded.pem_name; 641 return NULL; 642 } 643 644 OSSL_STORE_CTX *ossl_store_attach_pem_bio(BIO *bp, const UI_METHOD *ui_method, 645 void *ui_data) 646 { 647 OSSL_STORE_CTX *ctx = NULL; 648 const OSSL_STORE_LOADER *loader = NULL; 649 OSSL_STORE_LOADER_CTX *loader_ctx = NULL; 650 651 if ((loader = ossl_store_get0_loader_int("file")) == NULL 652 || ((loader_ctx = ossl_store_file_attach_pem_bio_int(bp)) == NULL)) 653 goto done; 654 if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { 655 OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO, 656 ERR_R_MALLOC_FAILURE); 657 goto done; 658 } 659 660 ctx->loader = loader; 661 ctx->loader_ctx = loader_ctx; 662 loader_ctx = NULL; 663 ctx->ui_method = ui_method; 664 ctx->ui_data = ui_data; 665 ctx->post_process = NULL; 666 ctx->post_process_data = NULL; 667 668 done: 669 if (loader_ctx != NULL) 670 /* 671 * We ignore a returned error because we will return NULL anyway in 672 * this case, so if something goes wrong when closing, that'll simply 673 * just add another entry on the error stack. 674 */ 675 (void)loader->close(loader_ctx); 676 return ctx; 677 } 678 679 int ossl_store_detach_pem_bio(OSSL_STORE_CTX *ctx) 680 { 681 int loader_ret = ossl_store_file_detach_pem_bio_int(ctx->loader_ctx); 682 683 OPENSSL_free(ctx); 684 return loader_ret; 685 } 686