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 /* This file has quite some overlap with engines/e_loader_attic.c */ 11 12 #include <string.h> 13 #include <sys/stat.h> 14 #include <ctype.h> /* isdigit */ 15 #include <assert.h> 16 17 #include <openssl/core_dispatch.h> 18 #include <openssl/core_names.h> 19 #include <openssl/core_object.h> 20 #include <openssl/bio.h> 21 #include <openssl/err.h> 22 #include <openssl/params.h> 23 #include <openssl/decoder.h> 24 #include <openssl/proverr.h> 25 #include <openssl/store.h> /* The OSSL_STORE_INFO type numbers */ 26 #include "internal/cryptlib.h" 27 #include "internal/o_dir.h" 28 #include "crypto/decoder.h" 29 #include "crypto/ctype.h" /* ossl_isdigit() */ 30 #include "prov/implementations.h" 31 #include "prov/bio.h" 32 #include "prov/providercommon.h" 33 #include "file_store_local.h" 34 35 DEFINE_STACK_OF(OSSL_STORE_INFO) 36 37 #ifdef _WIN32 38 # define stat _stat 39 #endif 40 41 #ifndef S_ISDIR 42 # define S_ISDIR(a) (((a) & S_IFMT) == S_IFDIR) 43 #endif 44 45 static OSSL_FUNC_store_open_fn file_open; 46 static OSSL_FUNC_store_attach_fn file_attach; 47 static OSSL_FUNC_store_settable_ctx_params_fn file_settable_ctx_params; 48 static OSSL_FUNC_store_set_ctx_params_fn file_set_ctx_params; 49 static OSSL_FUNC_store_load_fn file_load; 50 static OSSL_FUNC_store_eof_fn file_eof; 51 static OSSL_FUNC_store_close_fn file_close; 52 53 /* 54 * This implementation makes full use of OSSL_DECODER, and then some. 55 * It uses its own internal decoder implementation that reads DER and 56 * passes that on to the data callback; this decoder is created with 57 * internal OpenSSL functions, thereby bypassing the need for a surrounding 58 * provider. This is ok, since this is a local decoder, not meant for 59 * public consumption. 60 * Finally, it sets up its own construct and cleanup functions. 61 * 62 * Essentially, that makes this implementation a kind of glorified decoder. 63 */ 64 65 struct file_ctx_st { 66 void *provctx; 67 char *uri; /* The URI we currently try to load */ 68 enum { 69 IS_FILE = 0, /* Read file and pass results */ 70 IS_DIR /* Pass directory entry names */ 71 } type; 72 73 union { 74 /* Used with |IS_FILE| */ 75 struct { 76 BIO *file; 77 78 OSSL_DECODER_CTX *decoderctx; 79 char *input_type; 80 char *propq; /* The properties we got as a parameter */ 81 } file; 82 83 /* Used with |IS_DIR| */ 84 struct { 85 OPENSSL_DIR_CTX *ctx; 86 int end_reached; 87 88 /* 89 * When a search expression is given, these are filled in. 90 * |search_name| contains the file basename to look for. 91 * The string is exactly 8 characters long. 92 */ 93 char search_name[9]; 94 95 /* 96 * The directory reading utility we have combines opening with 97 * reading the first name. To make sure we can detect the end 98 * at the right time, we read early and cache the name. 99 */ 100 const char *last_entry; 101 int last_errno; 102 } dir; 103 } _; 104 105 /* Expected object type. May be unspecified */ 106 int expected_type; 107 }; 108 109 static void free_file_ctx(struct file_ctx_st *ctx) 110 { 111 if (ctx == NULL) 112 return; 113 114 OPENSSL_free(ctx->uri); 115 if (ctx->type != IS_DIR) { 116 OSSL_DECODER_CTX_free(ctx->_.file.decoderctx); 117 OPENSSL_free(ctx->_.file.propq); 118 OPENSSL_free(ctx->_.file.input_type); 119 } 120 OPENSSL_free(ctx); 121 } 122 123 static struct file_ctx_st *new_file_ctx(int type, const char *uri, 124 void *provctx) 125 { 126 struct file_ctx_st *ctx = NULL; 127 128 if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) != NULL 129 && (uri == NULL || (ctx->uri = OPENSSL_strdup(uri)) != NULL)) { 130 ctx->type = type; 131 ctx->provctx = provctx; 132 return ctx; 133 } 134 free_file_ctx(ctx); 135 return NULL; 136 } 137 138 static OSSL_DECODER_CONSTRUCT file_load_construct; 139 static OSSL_DECODER_CLEANUP file_load_cleanup; 140 141 /*- 142 * Opening / attaching streams and directories 143 * ------------------------------------------- 144 */ 145 146 /* 147 * Function to service both file_open() and file_attach() 148 * 149 * 150 */ 151 static struct file_ctx_st *file_open_stream(BIO *source, const char *uri, 152 void *provctx) 153 { 154 struct file_ctx_st *ctx; 155 156 if ((ctx = new_file_ctx(IS_FILE, uri, provctx)) == NULL) { 157 ERR_raise(ERR_LIB_PROV, ERR_R_PROV_LIB); 158 goto err; 159 } 160 161 ctx->_.file.file = source; 162 163 return ctx; 164 err: 165 free_file_ctx(ctx); 166 return NULL; 167 } 168 169 static void *file_open_dir(const char *path, const char *uri, void *provctx) 170 { 171 struct file_ctx_st *ctx; 172 173 if ((ctx = new_file_ctx(IS_DIR, uri, provctx)) == NULL) { 174 ERR_raise(ERR_LIB_PROV, ERR_R_PROV_LIB); 175 return NULL; 176 } 177 178 ctx->_.dir.last_entry = OPENSSL_DIR_read(&ctx->_.dir.ctx, path); 179 ctx->_.dir.last_errno = errno; 180 if (ctx->_.dir.last_entry == NULL) { 181 if (ctx->_.dir.last_errno != 0) { 182 ERR_raise_data(ERR_LIB_SYS, ctx->_.dir.last_errno, 183 "Calling OPENSSL_DIR_read(\"%s\")", path); 184 goto err; 185 } 186 ctx->_.dir.end_reached = 1; 187 } 188 return ctx; 189 err: 190 file_close(ctx); 191 return NULL; 192 } 193 194 static void *file_open(void *provctx, const char *uri) 195 { 196 struct file_ctx_st *ctx = NULL; 197 struct stat st; 198 struct { 199 const char *path; 200 unsigned int check_absolute:1; 201 } path_data[2]; 202 size_t path_data_n = 0, i; 203 const char *path, *p = uri, *q; 204 BIO *bio; 205 206 ERR_set_mark(); 207 208 /* 209 * First step, just take the URI as is. 210 */ 211 path_data[path_data_n].check_absolute = 0; 212 path_data[path_data_n++].path = uri; 213 214 /* 215 * Second step, if the URI appears to start with the "file" scheme, 216 * extract the path and make that the second path to check. 217 * There's a special case if the URI also contains an authority, then 218 * the full URI shouldn't be used as a path anywhere. 219 */ 220 if (CHECK_AND_SKIP_CASE_PREFIX(p, "file:")) { 221 q = p; 222 if (CHECK_AND_SKIP_CASE_PREFIX(q, "//")) { 223 path_data_n--; /* Invalidate using the full URI */ 224 if (CHECK_AND_SKIP_CASE_PREFIX(q, "localhost/") 225 || CHECK_AND_SKIP_CASE_PREFIX(q, "/")) { 226 p = q - 1; 227 } else { 228 ERR_clear_last_mark(); 229 ERR_raise(ERR_LIB_PROV, PROV_R_URI_AUTHORITY_UNSUPPORTED); 230 return NULL; 231 } 232 } 233 234 path_data[path_data_n].check_absolute = 1; 235 #ifdef _WIN32 236 /* Windows "file:" URIs with a drive letter start with a '/' */ 237 if (p[0] == '/' && p[2] == ':' && p[3] == '/') { 238 char c = tolower((unsigned char)p[1]); 239 240 if (c >= 'a' && c <= 'z') { 241 p++; 242 /* We know it's absolute, so no need to check */ 243 path_data[path_data_n].check_absolute = 0; 244 } 245 } 246 #endif 247 path_data[path_data_n++].path = p; 248 } 249 250 251 for (i = 0, path = NULL; path == NULL && i < path_data_n; i++) { 252 /* 253 * If the scheme "file" was an explicit part of the URI, the path must 254 * be absolute. So says RFC 8089 255 */ 256 if (path_data[i].check_absolute && path_data[i].path[0] != '/') { 257 ERR_clear_last_mark(); 258 ERR_raise_data(ERR_LIB_PROV, PROV_R_PATH_MUST_BE_ABSOLUTE, 259 "Given path=%s", path_data[i].path); 260 return NULL; 261 } 262 263 if (stat(path_data[i].path, &st) < 0) { 264 ERR_raise_data(ERR_LIB_SYS, errno, 265 "calling stat(%s)", 266 path_data[i].path); 267 } else { 268 path = path_data[i].path; 269 } 270 } 271 if (path == NULL) { 272 ERR_clear_last_mark(); 273 return NULL; 274 } 275 276 /* Successfully found a working path, clear possible collected errors */ 277 ERR_pop_to_mark(); 278 279 if (S_ISDIR(st.st_mode)) 280 ctx = file_open_dir(path, uri, provctx); 281 else if ((bio = BIO_new_file(path, "rb")) == NULL 282 || (ctx = file_open_stream(bio, uri, provctx)) == NULL) 283 BIO_free_all(bio); 284 285 return ctx; 286 } 287 288 void *file_attach(void *provctx, OSSL_CORE_BIO *cin) 289 { 290 struct file_ctx_st *ctx; 291 BIO *new_bio = ossl_bio_new_from_core_bio(provctx, cin); 292 293 if (new_bio == NULL) 294 return NULL; 295 296 ctx = file_open_stream(new_bio, NULL, provctx); 297 if (ctx == NULL) 298 BIO_free(new_bio); 299 return ctx; 300 } 301 302 /*- 303 * Setting parameters 304 * ------------------ 305 */ 306 307 static const OSSL_PARAM *file_settable_ctx_params(void *provctx) 308 { 309 static const OSSL_PARAM known_settable_ctx_params[] = { 310 OSSL_PARAM_utf8_string(OSSL_STORE_PARAM_PROPERTIES, NULL, 0), 311 OSSL_PARAM_int(OSSL_STORE_PARAM_EXPECT, NULL), 312 OSSL_PARAM_octet_string(OSSL_STORE_PARAM_SUBJECT, NULL, 0), 313 OSSL_PARAM_utf8_string(OSSL_STORE_PARAM_INPUT_TYPE, NULL, 0), 314 OSSL_PARAM_END 315 }; 316 return known_settable_ctx_params; 317 } 318 319 static int file_set_ctx_params(void *loaderctx, const OSSL_PARAM params[]) 320 { 321 struct file_ctx_st *ctx = loaderctx; 322 const OSSL_PARAM *p; 323 324 if (ossl_param_is_empty(params)) 325 return 1; 326 327 if (ctx->type != IS_DIR) { 328 /* these parameters are ignored for directories */ 329 p = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_PROPERTIES); 330 if (p != NULL) { 331 OPENSSL_free(ctx->_.file.propq); 332 ctx->_.file.propq = NULL; 333 if (!OSSL_PARAM_get_utf8_string(p, &ctx->_.file.propq, 0)) 334 return 0; 335 } 336 p = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_INPUT_TYPE); 337 if (p != NULL) { 338 OPENSSL_free(ctx->_.file.input_type); 339 ctx->_.file.input_type = NULL; 340 if (!OSSL_PARAM_get_utf8_string(p, &ctx->_.file.input_type, 0)) 341 return 0; 342 } 343 } 344 p = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_EXPECT); 345 if (p != NULL && !OSSL_PARAM_get_int(p, &ctx->expected_type)) 346 return 0; 347 p = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_SUBJECT); 348 if (p != NULL) { 349 const unsigned char *der = NULL; 350 size_t der_len = 0; 351 X509_NAME *x509_name; 352 unsigned long hash; 353 int ok; 354 355 if (ctx->type != IS_DIR) { 356 ERR_raise(ERR_LIB_PROV, 357 PROV_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES); 358 return 0; 359 } 360 361 if (!OSSL_PARAM_get_octet_string_ptr(p, (const void **)&der, &der_len) 362 || (x509_name = d2i_X509_NAME(NULL, &der, der_len)) == NULL) 363 return 0; 364 hash = X509_NAME_hash_ex(x509_name, 365 ossl_prov_ctx_get0_libctx(ctx->provctx), NULL, 366 &ok); 367 BIO_snprintf(ctx->_.dir.search_name, sizeof(ctx->_.dir.search_name), 368 "%08lx", hash); 369 X509_NAME_free(x509_name); 370 if (ok == 0) 371 return 0; 372 } 373 return 1; 374 } 375 376 /*- 377 * Loading an object from a stream 378 * ------------------------------- 379 */ 380 381 struct file_load_data_st { 382 OSSL_CALLBACK *object_cb; 383 void *object_cbarg; 384 }; 385 386 static int file_load_construct(OSSL_DECODER_INSTANCE *decoder_inst, 387 const OSSL_PARAM *params, void *construct_data) 388 { 389 struct file_load_data_st *data = construct_data; 390 391 /* 392 * At some point, we may find it justifiable to recognise PKCS#12 and 393 * handle it specially here, making |file_load()| return pass its 394 * contents one piece at ta time, like |e_loader_attic.c| does. 395 * 396 * However, that currently means parsing them out, which converts the 397 * DER encoded PKCS#12 into a bunch of EVP_PKEYs and X509s, just to 398 * have to re-encode them into DER to create an object abstraction for 399 * each of them. 400 * It's much simpler (less churn) to pass on the object abstraction we 401 * get to the load_result callback and leave it to that one to do the 402 * work. If that's libcrypto code, we know that it has much better 403 * possibilities to handle the EVP_PKEYs and X509s without the extra 404 * churn. 405 */ 406 407 return data->object_cb(params, data->object_cbarg); 408 } 409 410 void file_load_cleanup(void *construct_data) 411 { 412 /* Nothing to do */ 413 } 414 415 static int file_setup_decoders(struct file_ctx_st *ctx) 416 { 417 OSSL_LIB_CTX *libctx = ossl_prov_ctx_get0_libctx(ctx->provctx); 418 const OSSL_ALGORITHM *to_algo = NULL; 419 const char *input_structure = NULL; 420 int ok = 0; 421 422 /* Setup for this session, so only if not already done */ 423 if (ctx->_.file.decoderctx == NULL) { 424 if ((ctx->_.file.decoderctx = OSSL_DECODER_CTX_new()) == NULL) { 425 ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB); 426 goto err; 427 } 428 429 /* Make sure the input type is set */ 430 if (!OSSL_DECODER_CTX_set_input_type(ctx->_.file.decoderctx, 431 ctx->_.file.input_type)) { 432 ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB); 433 goto err; 434 } 435 436 /* 437 * Where applicable, set the outermost structure name. 438 * The goal is to avoid the STORE object types that are 439 * potentially password protected but aren't interesting 440 * for this load. 441 */ 442 switch (ctx->expected_type) { 443 case OSSL_STORE_INFO_PUBKEY: 444 input_structure = "SubjectPublicKeyInfo"; 445 if (!OSSL_DECODER_CTX_set_input_structure(ctx->_.file.decoderctx, 446 input_structure)) { 447 ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB); 448 goto err; 449 } 450 break; 451 case OSSL_STORE_INFO_PKEY: 452 /* 453 * The user's OSSL_STORE_INFO_PKEY covers PKCS#8, whether encrypted 454 * or not. The decoder will figure out whether decryption is 455 * applicable and fall back as necessary. We just need to indicate 456 * that it is OK to try and encrypt, which may involve a password 457 * prompt, so not done unless the data type is explicit, as we 458 * might then get a password prompt for a key when reading only 459 * certs from a file. 460 */ 461 input_structure = "EncryptedPrivateKeyInfo"; 462 if (!OSSL_DECODER_CTX_set_input_structure(ctx->_.file.decoderctx, 463 input_structure)) { 464 ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB); 465 goto err; 466 } 467 break; 468 case OSSL_STORE_INFO_CERT: 469 input_structure = "Certificate"; 470 if (!OSSL_DECODER_CTX_set_input_structure(ctx->_.file.decoderctx, 471 input_structure)) { 472 ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB); 473 goto err; 474 } 475 break; 476 case OSSL_STORE_INFO_CRL: 477 input_structure = "CertificateList"; 478 if (!OSSL_DECODER_CTX_set_input_structure(ctx->_.file.decoderctx, 479 input_structure)) { 480 ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB); 481 goto err; 482 } 483 break; 484 default: 485 break; 486 } 487 488 for (to_algo = ossl_any_to_obj_algorithm; 489 to_algo->algorithm_names != NULL; 490 to_algo++) { 491 OSSL_DECODER *to_obj = NULL; 492 OSSL_DECODER_INSTANCE *to_obj_inst = NULL; 493 const char *input_type; 494 495 /* 496 * Create the internal last resort decoder implementation 497 * together with a "decoder instance". 498 * The decoder doesn't need any identification or to be 499 * attached to any provider, since it's only used locally. 500 */ 501 to_obj = ossl_decoder_from_algorithm(0, to_algo, NULL); 502 if (to_obj != NULL) 503 to_obj_inst = 504 ossl_decoder_instance_new_forprov(to_obj, ctx->provctx, 505 input_structure); 506 OSSL_DECODER_free(to_obj); 507 if (to_obj_inst == NULL) 508 goto err; 509 /* 510 * The input type has to match unless, the input type is PEM 511 * and the decoder input type is DER, in which case we'll pick 512 * up additional decoders. 513 */ 514 input_type = OSSL_DECODER_INSTANCE_get_input_type(to_obj_inst); 515 if (ctx->_.file.input_type != NULL 516 && OPENSSL_strcasecmp(input_type, ctx->_.file.input_type) != 0 517 && (OPENSSL_strcasecmp(ctx->_.file.input_type, "PEM") != 0 518 || OPENSSL_strcasecmp(input_type, "der") != 0)) { 519 ossl_decoder_instance_free(to_obj_inst); 520 continue; 521 } 522 523 if (!ossl_decoder_ctx_add_decoder_inst(ctx->_.file.decoderctx, 524 to_obj_inst)) { 525 ossl_decoder_instance_free(to_obj_inst); 526 ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB); 527 goto err; 528 } 529 } 530 /* Add on the usual extra decoders */ 531 if (!OSSL_DECODER_CTX_add_extra(ctx->_.file.decoderctx, 532 libctx, ctx->_.file.propq)) { 533 ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB); 534 goto err; 535 } 536 537 /* 538 * Then install our constructor hooks, which just passes decoded 539 * data to the load callback 540 */ 541 if (!OSSL_DECODER_CTX_set_construct(ctx->_.file.decoderctx, 542 file_load_construct) 543 || !OSSL_DECODER_CTX_set_cleanup(ctx->_.file.decoderctx, 544 file_load_cleanup)) { 545 ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB); 546 goto err; 547 } 548 } 549 550 ok = 1; 551 err: 552 return ok; 553 } 554 555 static int file_load_file(struct file_ctx_st *ctx, 556 OSSL_CALLBACK *object_cb, void *object_cbarg, 557 OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) 558 { 559 struct file_load_data_st data; 560 int ret, err; 561 562 /* Setup the decoders (one time shot per session */ 563 564 if (!file_setup_decoders(ctx)) 565 return 0; 566 567 /* Setup for this object */ 568 569 data.object_cb = object_cb; 570 data.object_cbarg = object_cbarg; 571 OSSL_DECODER_CTX_set_construct_data(ctx->_.file.decoderctx, &data); 572 OSSL_DECODER_CTX_set_passphrase_cb(ctx->_.file.decoderctx, pw_cb, pw_cbarg); 573 574 /* Launch */ 575 576 ERR_set_mark(); 577 ret = OSSL_DECODER_from_bio(ctx->_.file.decoderctx, ctx->_.file.file); 578 if (BIO_eof(ctx->_.file.file) 579 && ((err = ERR_peek_last_error()) != 0) 580 && ERR_GET_LIB(err) == ERR_LIB_OSSL_DECODER 581 && ERR_GET_REASON(err) == ERR_R_UNSUPPORTED) 582 ERR_pop_to_mark(); 583 else 584 ERR_clear_last_mark(); 585 return ret; 586 } 587 588 /*- 589 * Loading a name object from a directory 590 * -------------------------------------- 591 */ 592 593 static char *file_name_to_uri(struct file_ctx_st *ctx, const char *name) 594 { 595 char *data = NULL; 596 597 assert(name != NULL); 598 { 599 const char *pathsep = ossl_ends_with_dirsep(ctx->uri) ? "" : "/"; 600 long calculated_length = strlen(ctx->uri) + strlen(pathsep) 601 + strlen(name) + 1 /* \0 */; 602 603 data = OPENSSL_zalloc(calculated_length); 604 if (data == NULL) 605 return NULL; 606 607 OPENSSL_strlcat(data, ctx->uri, calculated_length); 608 OPENSSL_strlcat(data, pathsep, calculated_length); 609 OPENSSL_strlcat(data, name, calculated_length); 610 } 611 return data; 612 } 613 614 static int file_name_check(struct file_ctx_st *ctx, const char *name) 615 { 616 const char *p = NULL; 617 size_t len = strlen(ctx->_.dir.search_name); 618 619 /* If there are no search criteria, all names are accepted */ 620 if (ctx->_.dir.search_name[0] == '\0') 621 return 1; 622 623 /* If the expected type isn't supported, no name is accepted */ 624 if (ctx->expected_type != 0 625 && ctx->expected_type != OSSL_STORE_INFO_CERT 626 && ctx->expected_type != OSSL_STORE_INFO_CRL) 627 return 0; 628 629 /* 630 * First, check the basename 631 */ 632 if (OPENSSL_strncasecmp(name, ctx->_.dir.search_name, len) != 0 633 || name[len] != '.') 634 return 0; 635 p = &name[len + 1]; 636 637 /* 638 * Then, if the expected type is a CRL, check that the extension starts 639 * with 'r' 640 */ 641 if (*p == 'r') { 642 p++; 643 if (ctx->expected_type != 0 644 && ctx->expected_type != OSSL_STORE_INFO_CRL) 645 return 0; 646 } else if (ctx->expected_type == OSSL_STORE_INFO_CRL) { 647 return 0; 648 } 649 650 /* 651 * Last, check that the rest of the extension is a decimal number, at 652 * least one digit long. 653 */ 654 if (!isdigit((unsigned char)*p)) 655 return 0; 656 while (isdigit((unsigned char)*p)) 657 p++; 658 659 #ifdef __VMS 660 /* 661 * One extra step here, check for a possible generation number. 662 */ 663 if (*p == ';') 664 for (p++; *p != '\0'; p++) 665 if (!ossl_isdigit((unsigned char)*p)) 666 break; 667 #endif 668 669 /* 670 * If we've reached the end of the string at this point, we've successfully 671 * found a fitting file name. 672 */ 673 return *p == '\0'; 674 } 675 676 static int file_load_dir_entry(struct file_ctx_st *ctx, 677 OSSL_CALLBACK *object_cb, void *object_cbarg, 678 OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) 679 { 680 /* Prepare as much as possible in advance */ 681 static const int object_type = OSSL_OBJECT_NAME; 682 OSSL_PARAM object[] = { 683 OSSL_PARAM_int(OSSL_OBJECT_PARAM_TYPE, (int *)&object_type), 684 OSSL_PARAM_utf8_string(OSSL_OBJECT_PARAM_DATA, NULL, 0), 685 OSSL_PARAM_END 686 }; 687 char *newname = NULL; 688 int ok; 689 690 /* Loop until we get an error or until we have a suitable name */ 691 do { 692 if (ctx->_.dir.last_entry == NULL) { 693 if (!ctx->_.dir.end_reached) { 694 assert(ctx->_.dir.last_errno != 0); 695 ERR_raise(ERR_LIB_SYS, ctx->_.dir.last_errno); 696 } 697 /* file_eof() will tell if EOF was reached */ 698 return 0; 699 } 700 701 /* flag acceptable names */ 702 if (ctx->_.dir.last_entry[0] != '.' 703 && file_name_check(ctx, ctx->_.dir.last_entry)) { 704 705 /* If we can't allocate the new name, we fail */ 706 if ((newname = 707 file_name_to_uri(ctx, ctx->_.dir.last_entry)) == NULL) 708 return 0; 709 } 710 711 /* 712 * On the first call (with a NULL context), OPENSSL_DIR_read() 713 * cares about the second argument. On the following calls, it 714 * only cares that it isn't NULL. Therefore, we can safely give 715 * it our URI here. 716 */ 717 ctx->_.dir.last_entry = OPENSSL_DIR_read(&ctx->_.dir.ctx, ctx->uri); 718 ctx->_.dir.last_errno = errno; 719 if (ctx->_.dir.last_entry == NULL && ctx->_.dir.last_errno == 0) 720 ctx->_.dir.end_reached = 1; 721 } while (newname == NULL); 722 723 object[1].data = newname; 724 object[1].data_size = strlen(newname); 725 ok = object_cb(object, object_cbarg); 726 OPENSSL_free(newname); 727 return ok; 728 } 729 730 /*- 731 * Loading, local dispatcher 732 * ------------------------- 733 */ 734 735 static int file_load(void *loaderctx, 736 OSSL_CALLBACK *object_cb, void *object_cbarg, 737 OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) 738 { 739 struct file_ctx_st *ctx = loaderctx; 740 741 switch (ctx->type) { 742 case IS_FILE: 743 return file_load_file(ctx, object_cb, object_cbarg, pw_cb, pw_cbarg); 744 case IS_DIR: 745 return 746 file_load_dir_entry(ctx, object_cb, object_cbarg, pw_cb, pw_cbarg); 747 default: 748 break; 749 } 750 751 /* ctx->type has an unexpected value */ 752 assert(0); 753 return 0; 754 } 755 756 /*- 757 * Eof detection and closing 758 * ------------------------- 759 */ 760 761 static int file_eof(void *loaderctx) 762 { 763 struct file_ctx_st *ctx = loaderctx; 764 765 switch (ctx->type) { 766 case IS_DIR: 767 return ctx->_.dir.end_reached; 768 case IS_FILE: 769 /* 770 * BIO_pending() checks any filter BIO. 771 * BIO_eof() checks the source BIO. 772 */ 773 return !BIO_pending(ctx->_.file.file) 774 && BIO_eof(ctx->_.file.file); 775 } 776 777 /* ctx->type has an unexpected value */ 778 assert(0); 779 return 1; 780 } 781 782 static int file_close_dir(struct file_ctx_st *ctx) 783 { 784 if (ctx->_.dir.ctx != NULL) 785 OPENSSL_DIR_end(&ctx->_.dir.ctx); 786 free_file_ctx(ctx); 787 return 1; 788 } 789 790 static int file_close_stream(struct file_ctx_st *ctx) 791 { 792 /* 793 * This frees either the provider BIO filter (for file_attach()) OR 794 * the allocated file BIO (for file_open()). 795 */ 796 BIO_free(ctx->_.file.file); 797 ctx->_.file.file = NULL; 798 799 free_file_ctx(ctx); 800 return 1; 801 } 802 803 static int file_close(void *loaderctx) 804 { 805 struct file_ctx_st *ctx = loaderctx; 806 807 switch (ctx->type) { 808 case IS_DIR: 809 return file_close_dir(ctx); 810 case IS_FILE: 811 return file_close_stream(ctx); 812 } 813 814 /* ctx->type has an unexpected value */ 815 assert(0); 816 return 1; 817 } 818 819 const OSSL_DISPATCH ossl_file_store_functions[] = { 820 { OSSL_FUNC_STORE_OPEN, (void (*)(void))file_open }, 821 { OSSL_FUNC_STORE_ATTACH, (void (*)(void))file_attach }, 822 { OSSL_FUNC_STORE_SETTABLE_CTX_PARAMS, 823 (void (*)(void))file_settable_ctx_params }, 824 { OSSL_FUNC_STORE_SET_CTX_PARAMS, (void (*)(void))file_set_ctx_params }, 825 { OSSL_FUNC_STORE_LOAD, (void (*)(void))file_load }, 826 { OSSL_FUNC_STORE_EOF, (void (*)(void))file_eof }, 827 { OSSL_FUNC_STORE_CLOSE, (void (*)(void))file_close }, 828 OSSL_DISPATCH_END, 829 }; 830