2
0

file_store.c 23 KB

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