file_store.c 26 KB

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