context.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. /*
  2. * Copyright 2019-2021 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. #include "crypto/cryptlib.h"
  10. #include <openssl/conf.h>
  11. #include "internal/thread_once.h"
  12. #include "internal/property.h"
  13. #include "internal/core.h"
  14. #include "internal/bio.h"
  15. #include "internal/provider.h"
  16. struct ossl_lib_ctx_onfree_list_st {
  17. ossl_lib_ctx_onfree_fn *fn;
  18. struct ossl_lib_ctx_onfree_list_st *next;
  19. };
  20. struct ossl_lib_ctx_st {
  21. CRYPTO_RWLOCK *lock;
  22. CRYPTO_EX_DATA data;
  23. /*
  24. * For most data in the OSSL_LIB_CTX we just use ex_data to store it. But
  25. * that doesn't work for ex_data itself - so we store that directly.
  26. */
  27. OSSL_EX_DATA_GLOBAL global;
  28. /* Map internal static indexes to dynamically created indexes */
  29. int dyn_indexes[OSSL_LIB_CTX_MAX_INDEXES];
  30. /* Keep a separate lock for each index */
  31. CRYPTO_RWLOCK *index_locks[OSSL_LIB_CTX_MAX_INDEXES];
  32. CRYPTO_RWLOCK *oncelock;
  33. int run_once_done[OSSL_LIB_CTX_MAX_RUN_ONCE];
  34. int run_once_ret[OSSL_LIB_CTX_MAX_RUN_ONCE];
  35. struct ossl_lib_ctx_onfree_list_st *onfreelist;
  36. unsigned int ischild:1;
  37. };
  38. int ossl_lib_ctx_write_lock(OSSL_LIB_CTX *ctx)
  39. {
  40. return CRYPTO_THREAD_write_lock(ossl_lib_ctx_get_concrete(ctx)->lock);
  41. }
  42. int ossl_lib_ctx_read_lock(OSSL_LIB_CTX *ctx)
  43. {
  44. return CRYPTO_THREAD_read_lock(ossl_lib_ctx_get_concrete(ctx)->lock);
  45. }
  46. int ossl_lib_ctx_unlock(OSSL_LIB_CTX *ctx)
  47. {
  48. return CRYPTO_THREAD_unlock(ossl_lib_ctx_get_concrete(ctx)->lock);
  49. }
  50. int ossl_lib_ctx_is_child(OSSL_LIB_CTX *ctx)
  51. {
  52. ctx = ossl_lib_ctx_get_concrete(ctx);
  53. if (ctx == NULL)
  54. return 0;
  55. return ctx->ischild;
  56. }
  57. static int context_init(OSSL_LIB_CTX *ctx)
  58. {
  59. size_t i;
  60. int exdata_done = 0;
  61. ctx->lock = CRYPTO_THREAD_lock_new();
  62. if (ctx->lock == NULL)
  63. return 0;
  64. ctx->oncelock = CRYPTO_THREAD_lock_new();
  65. if (ctx->oncelock == NULL)
  66. goto err;
  67. for (i = 0; i < OSSL_LIB_CTX_MAX_INDEXES; i++) {
  68. ctx->index_locks[i] = CRYPTO_THREAD_lock_new();
  69. ctx->dyn_indexes[i] = -1;
  70. if (ctx->index_locks[i] == NULL)
  71. goto err;
  72. }
  73. /* OSSL_LIB_CTX is built on top of ex_data so we initialise that directly */
  74. if (!ossl_do_ex_data_init(ctx))
  75. goto err;
  76. exdata_done = 1;
  77. if (!ossl_crypto_new_ex_data_ex(ctx, CRYPTO_EX_INDEX_OSSL_LIB_CTX, NULL,
  78. &ctx->data)) {
  79. ossl_crypto_cleanup_all_ex_data_int(ctx);
  80. goto err;
  81. }
  82. /* Everything depends on properties, so we also pre-initialise that */
  83. if (!ossl_property_parse_init(ctx))
  84. goto err;
  85. return 1;
  86. err:
  87. if (exdata_done)
  88. ossl_crypto_cleanup_all_ex_data_int(ctx);
  89. CRYPTO_THREAD_lock_free(ctx->oncelock);
  90. CRYPTO_THREAD_lock_free(ctx->lock);
  91. ctx->lock = NULL;
  92. return 0;
  93. }
  94. static int context_deinit(OSSL_LIB_CTX *ctx)
  95. {
  96. struct ossl_lib_ctx_onfree_list_st *tmp, *onfree;
  97. int i;
  98. if (ctx == NULL)
  99. return 1;
  100. ossl_ctx_thread_stop(ctx);
  101. onfree = ctx->onfreelist;
  102. while (onfree != NULL) {
  103. onfree->fn(ctx);
  104. tmp = onfree;
  105. onfree = onfree->next;
  106. OPENSSL_free(tmp);
  107. }
  108. CRYPTO_free_ex_data(CRYPTO_EX_INDEX_OSSL_LIB_CTX, NULL, &ctx->data);
  109. ossl_crypto_cleanup_all_ex_data_int(ctx);
  110. for (i = 0; i < OSSL_LIB_CTX_MAX_INDEXES; i++)
  111. CRYPTO_THREAD_lock_free(ctx->index_locks[i]);
  112. CRYPTO_THREAD_lock_free(ctx->oncelock);
  113. CRYPTO_THREAD_lock_free(ctx->lock);
  114. ctx->lock = NULL;
  115. return 1;
  116. }
  117. #ifndef FIPS_MODULE
  118. /* The default default context */
  119. static OSSL_LIB_CTX default_context_int;
  120. static CRYPTO_ONCE default_context_init = CRYPTO_ONCE_STATIC_INIT;
  121. static CRYPTO_THREAD_LOCAL default_context_thread_local;
  122. DEFINE_RUN_ONCE_STATIC(default_context_do_init)
  123. {
  124. return CRYPTO_THREAD_init_local(&default_context_thread_local, NULL)
  125. && context_init(&default_context_int);
  126. }
  127. void ossl_lib_ctx_default_deinit(void)
  128. {
  129. context_deinit(&default_context_int);
  130. }
  131. static OSSL_LIB_CTX *get_thread_default_context(void)
  132. {
  133. if (!RUN_ONCE(&default_context_init, default_context_do_init))
  134. return NULL;
  135. return CRYPTO_THREAD_get_local(&default_context_thread_local);
  136. }
  137. static OSSL_LIB_CTX *get_default_context(void)
  138. {
  139. OSSL_LIB_CTX *current_defctx = get_thread_default_context();
  140. if (current_defctx == NULL)
  141. current_defctx = &default_context_int;
  142. return current_defctx;
  143. }
  144. static int set_default_context(OSSL_LIB_CTX *defctx)
  145. {
  146. if (defctx == &default_context_int)
  147. defctx = NULL;
  148. return CRYPTO_THREAD_set_local(&default_context_thread_local, defctx);
  149. }
  150. #endif
  151. OSSL_LIB_CTX *OSSL_LIB_CTX_new(void)
  152. {
  153. OSSL_LIB_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
  154. if (ctx != NULL && !context_init(ctx)) {
  155. OSSL_LIB_CTX_free(ctx);
  156. ctx = NULL;
  157. }
  158. return ctx;
  159. }
  160. #ifndef FIPS_MODULE
  161. OSSL_LIB_CTX *OSSL_LIB_CTX_new_from_dispatch(const OSSL_CORE_HANDLE *handle,
  162. const OSSL_DISPATCH *in)
  163. {
  164. OSSL_LIB_CTX *ctx = OSSL_LIB_CTX_new();
  165. if (ctx == NULL)
  166. return NULL;
  167. if (!ossl_bio_init_core(ctx, in)) {
  168. OSSL_LIB_CTX_free(ctx);
  169. return NULL;
  170. }
  171. return ctx;
  172. }
  173. OSSL_LIB_CTX *OSSL_LIB_CTX_new_child(const OSSL_CORE_HANDLE *handle,
  174. const OSSL_DISPATCH *in)
  175. {
  176. OSSL_LIB_CTX *ctx = OSSL_LIB_CTX_new_from_dispatch(handle, in);
  177. if (ctx == NULL)
  178. return NULL;
  179. if (!ossl_provider_init_as_child(ctx, handle, in)) {
  180. OSSL_LIB_CTX_free(ctx);
  181. return NULL;
  182. }
  183. ctx->ischild = 1;
  184. return ctx;
  185. }
  186. int OSSL_LIB_CTX_load_config(OSSL_LIB_CTX *ctx, const char *config_file)
  187. {
  188. return CONF_modules_load_file_ex(ctx, config_file, NULL, 0) > 0;
  189. }
  190. #endif
  191. void OSSL_LIB_CTX_free(OSSL_LIB_CTX *ctx)
  192. {
  193. if (ossl_lib_ctx_is_default(ctx))
  194. return;
  195. context_deinit(ctx);
  196. OPENSSL_free(ctx);
  197. }
  198. #ifndef FIPS_MODULE
  199. OSSL_LIB_CTX *OSSL_LIB_CTX_get0_global_default(void)
  200. {
  201. if (!RUN_ONCE(&default_context_init, default_context_do_init))
  202. return NULL;
  203. return &default_context_int;
  204. }
  205. OSSL_LIB_CTX *OSSL_LIB_CTX_set0_default(OSSL_LIB_CTX *libctx)
  206. {
  207. OSSL_LIB_CTX *current_defctx;
  208. if ((current_defctx = get_default_context()) != NULL) {
  209. if (libctx != NULL)
  210. set_default_context(libctx);
  211. return current_defctx;
  212. }
  213. return NULL;
  214. }
  215. #endif
  216. OSSL_LIB_CTX *ossl_lib_ctx_get_concrete(OSSL_LIB_CTX *ctx)
  217. {
  218. #ifndef FIPS_MODULE
  219. if (ctx == NULL)
  220. return get_default_context();
  221. #endif
  222. return ctx;
  223. }
  224. int ossl_lib_ctx_is_default(OSSL_LIB_CTX *ctx)
  225. {
  226. #ifndef FIPS_MODULE
  227. if (ctx == NULL || ctx == get_default_context())
  228. return 1;
  229. #endif
  230. return 0;
  231. }
  232. int ossl_lib_ctx_is_global_default(OSSL_LIB_CTX *ctx)
  233. {
  234. #ifndef FIPS_MODULE
  235. if (ossl_lib_ctx_get_concrete(ctx) == &default_context_int)
  236. return 1;
  237. #endif
  238. return 0;
  239. }
  240. static void ossl_lib_ctx_generic_new(void *parent_ign, void *ptr_ign,
  241. CRYPTO_EX_DATA *ad, int index,
  242. long argl_ign, void *argp)
  243. {
  244. const OSSL_LIB_CTX_METHOD *meth = argp;
  245. OSSL_LIB_CTX *ctx = ossl_crypto_ex_data_get_ossl_lib_ctx(ad);
  246. void *ptr = meth->new_func(ctx);
  247. if (ptr != NULL) {
  248. if (!CRYPTO_THREAD_write_lock(ctx->lock))
  249. /*
  250. * Can't return something, so best to hope that something will
  251. * fail later. :(
  252. */
  253. return;
  254. CRYPTO_set_ex_data(ad, index, ptr);
  255. CRYPTO_THREAD_unlock(ctx->lock);
  256. }
  257. }
  258. static void ossl_lib_ctx_generic_free(void *parent_ign, void *ptr,
  259. CRYPTO_EX_DATA *ad, int index,
  260. long argl_ign, void *argp)
  261. {
  262. const OSSL_LIB_CTX_METHOD *meth = argp;
  263. meth->free_func(ptr);
  264. }
  265. static int ossl_lib_ctx_init_index(OSSL_LIB_CTX *ctx, int static_index,
  266. const OSSL_LIB_CTX_METHOD *meth)
  267. {
  268. int idx;
  269. ctx = ossl_lib_ctx_get_concrete(ctx);
  270. if (ctx == NULL)
  271. return 0;
  272. idx = ossl_crypto_get_ex_new_index_ex(ctx, CRYPTO_EX_INDEX_OSSL_LIB_CTX, 0,
  273. (void *)meth,
  274. ossl_lib_ctx_generic_new,
  275. NULL, ossl_lib_ctx_generic_free,
  276. meth->priority);
  277. if (idx < 0)
  278. return 0;
  279. ctx->dyn_indexes[static_index] = idx;
  280. return 1;
  281. }
  282. void *ossl_lib_ctx_get_data(OSSL_LIB_CTX *ctx, int index,
  283. const OSSL_LIB_CTX_METHOD *meth)
  284. {
  285. void *data = NULL;
  286. int dynidx;
  287. ctx = ossl_lib_ctx_get_concrete(ctx);
  288. if (ctx == NULL)
  289. return NULL;
  290. if (!CRYPTO_THREAD_read_lock(ctx->lock))
  291. return NULL;
  292. dynidx = ctx->dyn_indexes[index];
  293. CRYPTO_THREAD_unlock(ctx->lock);
  294. if (dynidx != -1) {
  295. if (!CRYPTO_THREAD_read_lock(ctx->index_locks[index]))
  296. return NULL;
  297. if (!CRYPTO_THREAD_read_lock(ctx->lock)) {
  298. CRYPTO_THREAD_unlock(ctx->index_locks[index]);
  299. return NULL;
  300. }
  301. data = CRYPTO_get_ex_data(&ctx->data, dynidx);
  302. CRYPTO_THREAD_unlock(ctx->lock);
  303. CRYPTO_THREAD_unlock(ctx->index_locks[index]);
  304. return data;
  305. }
  306. if (!CRYPTO_THREAD_write_lock(ctx->index_locks[index]))
  307. return NULL;
  308. if (!CRYPTO_THREAD_write_lock(ctx->lock)) {
  309. CRYPTO_THREAD_unlock(ctx->index_locks[index]);
  310. return NULL;
  311. }
  312. dynidx = ctx->dyn_indexes[index];
  313. if (dynidx != -1) {
  314. data = CRYPTO_get_ex_data(&ctx->data, dynidx);
  315. CRYPTO_THREAD_unlock(ctx->lock);
  316. CRYPTO_THREAD_unlock(ctx->index_locks[index]);
  317. return data;
  318. }
  319. if (!ossl_lib_ctx_init_index(ctx, index, meth)) {
  320. CRYPTO_THREAD_unlock(ctx->lock);
  321. CRYPTO_THREAD_unlock(ctx->index_locks[index]);
  322. return NULL;
  323. }
  324. CRYPTO_THREAD_unlock(ctx->lock);
  325. /*
  326. * The alloc call ensures there's a value there. We release the ctx->lock
  327. * for this, because the allocation itself may recursively call
  328. * ossl_lib_ctx_get_data for other indexes (never this one). The allocation
  329. * will itself aquire the ctx->lock when it actually comes to store the
  330. * allocated data (see ossl_lib_ctx_generic_new() above). We call
  331. * ossl_crypto_alloc_ex_data_intern() here instead of CRYPTO_alloc_ex_data().
  332. * They do the same thing except that the latter calls CRYPTO_get_ex_data()
  333. * as well - which we must not do without holding the ctx->lock.
  334. */
  335. if (ossl_crypto_alloc_ex_data_intern(CRYPTO_EX_INDEX_OSSL_LIB_CTX, NULL,
  336. &ctx->data, ctx->dyn_indexes[index])) {
  337. if (!CRYPTO_THREAD_read_lock(ctx->lock))
  338. goto end;
  339. data = CRYPTO_get_ex_data(&ctx->data, ctx->dyn_indexes[index]);
  340. CRYPTO_THREAD_unlock(ctx->lock);
  341. }
  342. end:
  343. CRYPTO_THREAD_unlock(ctx->index_locks[index]);
  344. return data;
  345. }
  346. OSSL_EX_DATA_GLOBAL *ossl_lib_ctx_get_ex_data_global(OSSL_LIB_CTX *ctx)
  347. {
  348. ctx = ossl_lib_ctx_get_concrete(ctx);
  349. if (ctx == NULL)
  350. return NULL;
  351. return &ctx->global;
  352. }
  353. int ossl_lib_ctx_run_once(OSSL_LIB_CTX *ctx, unsigned int idx,
  354. ossl_lib_ctx_run_once_fn run_once_fn)
  355. {
  356. int done = 0, ret = 0;
  357. ctx = ossl_lib_ctx_get_concrete(ctx);
  358. if (ctx == NULL)
  359. return 0;
  360. if (!CRYPTO_THREAD_read_lock(ctx->oncelock))
  361. return 0;
  362. done = ctx->run_once_done[idx];
  363. if (done)
  364. ret = ctx->run_once_ret[idx];
  365. CRYPTO_THREAD_unlock(ctx->oncelock);
  366. if (done)
  367. return ret;
  368. if (!CRYPTO_THREAD_write_lock(ctx->oncelock))
  369. return 0;
  370. if (ctx->run_once_done[idx]) {
  371. ret = ctx->run_once_ret[idx];
  372. CRYPTO_THREAD_unlock(ctx->oncelock);
  373. return ret;
  374. }
  375. ret = run_once_fn(ctx);
  376. ctx->run_once_done[idx] = 1;
  377. ctx->run_once_ret[idx] = ret;
  378. CRYPTO_THREAD_unlock(ctx->oncelock);
  379. return ret;
  380. }
  381. int ossl_lib_ctx_onfree(OSSL_LIB_CTX *ctx, ossl_lib_ctx_onfree_fn onfreefn)
  382. {
  383. struct ossl_lib_ctx_onfree_list_st *newonfree
  384. = OPENSSL_malloc(sizeof(*newonfree));
  385. if (newonfree == NULL)
  386. return 0;
  387. newonfree->fn = onfreefn;
  388. newonfree->next = ctx->onfreelist;
  389. ctx->onfreelist = newonfree;
  390. return 1;
  391. }
  392. const char *ossl_lib_ctx_get_descriptor(OSSL_LIB_CTX *libctx)
  393. {
  394. #ifdef FIPS_MODULE
  395. return "FIPS internal library context";
  396. #else
  397. if (ossl_lib_ctx_is_global_default(libctx))
  398. return "Global default library context";
  399. if (ossl_lib_ctx_is_default(libctx))
  400. return "Thread-local default library context";
  401. return "Non-default library context";
  402. #endif
  403. }