context.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. /*
  2. * Copyright 2019-2020 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. struct openssl_ctx_onfree_list_st {
  14. openssl_ctx_onfree_fn *fn;
  15. struct openssl_ctx_onfree_list_st *next;
  16. };
  17. struct openssl_ctx_st {
  18. CRYPTO_RWLOCK *lock;
  19. CRYPTO_EX_DATA data;
  20. /*
  21. * For most data in the OPENSSL_CTX we just use ex_data to store it. But
  22. * that doesn't work for ex_data itself - so we store that directly.
  23. */
  24. OSSL_EX_DATA_GLOBAL global;
  25. /* Map internal static indexes to dynamically created indexes */
  26. int dyn_indexes[OPENSSL_CTX_MAX_INDEXES];
  27. /* Keep a separate lock for each index */
  28. CRYPTO_RWLOCK *index_locks[OPENSSL_CTX_MAX_INDEXES];
  29. CRYPTO_RWLOCK *oncelock;
  30. int run_once_done[OPENSSL_CTX_MAX_RUN_ONCE];
  31. int run_once_ret[OPENSSL_CTX_MAX_RUN_ONCE];
  32. struct openssl_ctx_onfree_list_st *onfreelist;
  33. };
  34. #ifndef FIPS_MODE
  35. static OPENSSL_CTX default_context_int;
  36. /* Always points at default_context_int if it has been initialised */
  37. static OPENSSL_CTX *default_context = NULL;
  38. #endif
  39. static int context_init(OPENSSL_CTX *ctx)
  40. {
  41. size_t i;
  42. int exdata_done = 0;
  43. ctx->lock = CRYPTO_THREAD_lock_new();
  44. if (ctx->lock == NULL)
  45. return 0;
  46. ctx->oncelock = CRYPTO_THREAD_lock_new();
  47. if (ctx->oncelock == NULL)
  48. goto err;
  49. for (i = 0; i < OPENSSL_CTX_MAX_INDEXES; i++) {
  50. ctx->index_locks[i] = CRYPTO_THREAD_lock_new();
  51. ctx->dyn_indexes[i] = -1;
  52. if (ctx->index_locks[i] == NULL)
  53. goto err;
  54. }
  55. /* OPENSSL_CTX is built on top of ex_data so we initialise that directly */
  56. if (!do_ex_data_init(ctx))
  57. goto err;
  58. exdata_done = 1;
  59. if (!crypto_new_ex_data_ex(ctx, CRYPTO_EX_INDEX_OPENSSL_CTX, NULL,
  60. &ctx->data)) {
  61. crypto_cleanup_all_ex_data_int(ctx);
  62. goto err;
  63. }
  64. /* Everything depends on properties, so we also pre-initialise that */
  65. if (!ossl_property_parse_init(ctx))
  66. goto err;
  67. return 1;
  68. err:
  69. if (exdata_done)
  70. crypto_cleanup_all_ex_data_int(ctx);
  71. CRYPTO_THREAD_lock_free(ctx->oncelock);
  72. CRYPTO_THREAD_lock_free(ctx->lock);
  73. ctx->lock = NULL;
  74. return 0;
  75. }
  76. static int context_deinit(OPENSSL_CTX *ctx)
  77. {
  78. struct openssl_ctx_onfree_list_st *tmp, *onfree;
  79. int i;
  80. if (ctx == NULL)
  81. return 1;
  82. ossl_ctx_thread_stop(ctx);
  83. onfree = ctx->onfreelist;
  84. while (onfree != NULL) {
  85. onfree->fn(ctx);
  86. tmp = onfree;
  87. onfree = onfree->next;
  88. OPENSSL_free(tmp);
  89. }
  90. CRYPTO_free_ex_data(CRYPTO_EX_INDEX_OPENSSL_CTX, NULL, &ctx->data);
  91. crypto_cleanup_all_ex_data_int(ctx);
  92. for (i = 0; i < OPENSSL_CTX_MAX_INDEXES; i++)
  93. CRYPTO_THREAD_lock_free(ctx->index_locks[i]);
  94. CRYPTO_THREAD_lock_free(ctx->oncelock);
  95. CRYPTO_THREAD_lock_free(ctx->lock);
  96. ctx->lock = NULL;
  97. return 1;
  98. }
  99. #ifndef FIPS_MODE
  100. void openssl_ctx_default_deinit(void)
  101. {
  102. context_deinit(default_context);
  103. }
  104. static CRYPTO_ONCE default_context_init = CRYPTO_ONCE_STATIC_INIT;
  105. DEFINE_RUN_ONCE_STATIC(do_default_context_init)
  106. {
  107. if (context_init(&default_context_int))
  108. default_context = &default_context_int;
  109. return 1;
  110. }
  111. #endif
  112. OPENSSL_CTX *OPENSSL_CTX_new(void)
  113. {
  114. OPENSSL_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
  115. if (ctx != NULL && !context_init(ctx)) {
  116. OPENSSL_CTX_free(ctx);
  117. ctx = NULL;
  118. }
  119. return ctx;
  120. }
  121. #ifndef FIPS_MODE
  122. int OPENSSL_CTX_load_config(OPENSSL_CTX *ctx, const char *config_file)
  123. {
  124. return CONF_modules_load_file_with_libctx(ctx, config_file, NULL, 0) > 0;
  125. }
  126. #endif
  127. void OPENSSL_CTX_free(OPENSSL_CTX *ctx)
  128. {
  129. if (ctx != NULL)
  130. context_deinit(ctx);
  131. OPENSSL_free(ctx);
  132. }
  133. OPENSSL_CTX *openssl_ctx_get_concrete(OPENSSL_CTX *ctx)
  134. {
  135. #ifndef FIPS_MODE
  136. if (ctx == NULL) {
  137. if (!RUN_ONCE(&default_context_init, do_default_context_init))
  138. return 0;
  139. return default_context;
  140. }
  141. #endif
  142. return ctx;
  143. }
  144. int openssl_ctx_is_default(OPENSSL_CTX *ctx)
  145. {
  146. #ifndef FIPS_MODE
  147. if (ctx == NULL || ctx == default_context)
  148. return 1;
  149. #endif
  150. return 0;
  151. }
  152. static void openssl_ctx_generic_new(void *parent_ign, void *ptr_ign,
  153. CRYPTO_EX_DATA *ad, int index,
  154. long argl_ign, void *argp)
  155. {
  156. const OPENSSL_CTX_METHOD *meth = argp;
  157. void *ptr = meth->new_func(crypto_ex_data_get_openssl_ctx(ad));
  158. if (ptr != NULL)
  159. CRYPTO_set_ex_data(ad, index, ptr);
  160. }
  161. static void openssl_ctx_generic_free(void *parent_ign, void *ptr,
  162. CRYPTO_EX_DATA *ad, int index,
  163. long argl_ign, void *argp)
  164. {
  165. const OPENSSL_CTX_METHOD *meth = argp;
  166. meth->free_func(ptr);
  167. }
  168. /* Non-static so we can use it in context_internal_test */
  169. static int openssl_ctx_init_index(OPENSSL_CTX *ctx, int static_index,
  170. const OPENSSL_CTX_METHOD *meth)
  171. {
  172. int idx;
  173. ctx = openssl_ctx_get_concrete(ctx);
  174. if (ctx == NULL)
  175. return 0;
  176. idx = crypto_get_ex_new_index_ex(ctx, CRYPTO_EX_INDEX_OPENSSL_CTX, 0,
  177. (void *)meth,
  178. openssl_ctx_generic_new,
  179. NULL, openssl_ctx_generic_free);
  180. if (idx < 0)
  181. return 0;
  182. ctx->dyn_indexes[static_index] = idx;
  183. return 1;
  184. }
  185. void *openssl_ctx_get_data(OPENSSL_CTX *ctx, int index,
  186. const OPENSSL_CTX_METHOD *meth)
  187. {
  188. void *data = NULL;
  189. int dynidx;
  190. ctx = openssl_ctx_get_concrete(ctx);
  191. if (ctx == NULL)
  192. return NULL;
  193. CRYPTO_THREAD_read_lock(ctx->lock);
  194. dynidx = ctx->dyn_indexes[index];
  195. CRYPTO_THREAD_unlock(ctx->lock);
  196. if (dynidx != -1) {
  197. CRYPTO_THREAD_read_lock(ctx->index_locks[index]);
  198. data = CRYPTO_get_ex_data(&ctx->data, dynidx);
  199. CRYPTO_THREAD_unlock(ctx->index_locks[index]);
  200. return data;
  201. }
  202. CRYPTO_THREAD_write_lock(ctx->index_locks[index]);
  203. CRYPTO_THREAD_write_lock(ctx->lock);
  204. dynidx = ctx->dyn_indexes[index];
  205. if (dynidx != -1) {
  206. CRYPTO_THREAD_unlock(ctx->lock);
  207. data = CRYPTO_get_ex_data(&ctx->data, dynidx);
  208. CRYPTO_THREAD_unlock(ctx->index_locks[index]);
  209. return data;
  210. }
  211. if (!openssl_ctx_init_index(ctx, index, meth)) {
  212. CRYPTO_THREAD_unlock(ctx->lock);
  213. CRYPTO_THREAD_unlock(ctx->index_locks[index]);
  214. return NULL;
  215. }
  216. CRYPTO_THREAD_unlock(ctx->lock);
  217. /* The alloc call ensures there's a value there */
  218. if (CRYPTO_alloc_ex_data(CRYPTO_EX_INDEX_OPENSSL_CTX, NULL,
  219. &ctx->data, ctx->dyn_indexes[index]))
  220. data = CRYPTO_get_ex_data(&ctx->data, ctx->dyn_indexes[index]);
  221. CRYPTO_THREAD_unlock(ctx->index_locks[index]);
  222. return data;
  223. }
  224. OSSL_EX_DATA_GLOBAL *openssl_ctx_get_ex_data_global(OPENSSL_CTX *ctx)
  225. {
  226. ctx = openssl_ctx_get_concrete(ctx);
  227. if (ctx == NULL)
  228. return NULL;
  229. return &ctx->global;
  230. }
  231. int openssl_ctx_run_once(OPENSSL_CTX *ctx, unsigned int idx,
  232. openssl_ctx_run_once_fn run_once_fn)
  233. {
  234. int done = 0, ret = 0;
  235. ctx = openssl_ctx_get_concrete(ctx);
  236. if (ctx == NULL)
  237. return 0;
  238. CRYPTO_THREAD_read_lock(ctx->oncelock);
  239. done = ctx->run_once_done[idx];
  240. if (done)
  241. ret = ctx->run_once_ret[idx];
  242. CRYPTO_THREAD_unlock(ctx->oncelock);
  243. if (done)
  244. return ret;
  245. CRYPTO_THREAD_write_lock(ctx->oncelock);
  246. if (ctx->run_once_done[idx]) {
  247. ret = ctx->run_once_ret[idx];
  248. CRYPTO_THREAD_unlock(ctx->oncelock);
  249. return ret;
  250. }
  251. ret = run_once_fn(ctx);
  252. ctx->run_once_done[idx] = 1;
  253. ctx->run_once_ret[idx] = ret;
  254. CRYPTO_THREAD_unlock(ctx->oncelock);
  255. return ret;
  256. }
  257. int openssl_ctx_onfree(OPENSSL_CTX *ctx, openssl_ctx_onfree_fn onfreefn)
  258. {
  259. struct openssl_ctx_onfree_list_st *newonfree
  260. = OPENSSL_malloc(sizeof(*newonfree));
  261. if (newonfree == NULL)
  262. return 0;
  263. newonfree->fn = onfreefn;
  264. newonfree->next = ctx->onfreelist;
  265. ctx->onfreelist = newonfree;
  266. return 1;
  267. }