1 /*
2 * Copyright 2016-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 /* We need to use some engine deprecated APIs */
11 #define OPENSSL_SUPPRESS_DEPRECATED
12
13 #include "internal/e_os.h"
14 #include "crypto/cryptlib.h"
15 #include <openssl/err.h>
16 #include "crypto/rand.h"
17 #include "internal/bio.h"
18 #include <openssl/evp.h>
19 #include "crypto/evp.h"
20 #include "internal/conf.h"
21 #include "crypto/async.h"
22 #include "crypto/engine.h"
23 #include "internal/comp.h"
24 #include "internal/err.h"
25 #include "crypto/err.h"
26 #include "crypto/objects.h"
27 #include <stdlib.h>
28 #include <assert.h>
29 #include "internal/thread_once.h"
30 #include "crypto/dso_conf.h"
31 #include "internal/dso.h"
32 #include "crypto/store.h"
33 #include <openssl/cmp_util.h> /* for OSSL_CMP_log_close() */
34 #include <openssl/trace.h>
35 #include <openssl/ssl.h> /* for OPENSSL_INIT_(NO_)?LOAD_SSL_STRINGS */
36 #include "crypto/ctype.h"
37 #include "sslerr.h"
38
39 static int stopped = 0;
40 static uint64_t optsdone = 0;
41
42 typedef struct ossl_init_stop_st OPENSSL_INIT_STOP;
43 struct ossl_init_stop_st {
44 void (*handler)(void);
45 OPENSSL_INIT_STOP *next;
46 };
47
48 static OPENSSL_INIT_STOP *stop_handlers = NULL;
49 /* Guards access to the optsdone variable on platforms without atomics */
50 static CRYPTO_RWLOCK *optsdone_lock = NULL;
51 /* Guards simultaneous INIT_LOAD_CONFIG calls with non-NULL settings */
52 static CRYPTO_RWLOCK *init_lock = NULL;
53 static CRYPTO_THREAD_LOCAL in_init_config_local;
54
55 static CRYPTO_ONCE base = CRYPTO_ONCE_STATIC_INIT;
56 static int base_inited = 0;
DEFINE_RUN_ONCE_STATIC(ossl_init_base)57 DEFINE_RUN_ONCE_STATIC(ossl_init_base)
58 {
59 /* no need to init trace */
60
61 OSSL_TRACE(INIT, "ossl_init_base: setting up stop handlers\n");
62 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
63 ossl_malloc_setup_failures();
64 #endif
65
66 if ((optsdone_lock = CRYPTO_THREAD_lock_new()) == NULL
67 || (init_lock = CRYPTO_THREAD_lock_new()) == NULL)
68 goto err;
69
70 OPENSSL_cpuid_setup();
71
72 if (!ossl_init_thread())
73 goto err;
74
75 if (!CRYPTO_THREAD_init_local(&in_init_config_local, NULL))
76 goto err;
77
78 base_inited = 1;
79 return 1;
80
81 err:
82 OSSL_TRACE(INIT, "ossl_init_base failed!\n");
83 CRYPTO_THREAD_lock_free(optsdone_lock);
84 optsdone_lock = NULL;
85 CRYPTO_THREAD_lock_free(init_lock);
86 init_lock = NULL;
87
88 return 0;
89 }
90
91 static CRYPTO_ONCE register_atexit = CRYPTO_ONCE_STATIC_INIT;
92 #if !defined(OPENSSL_SYS_UEFI) && defined(_WIN32)
win32atexit(void)93 static int win32atexit(void)
94 {
95 OPENSSL_cleanup();
96 return 0;
97 }
98 #endif
99
DEFINE_RUN_ONCE_STATIC(ossl_init_register_atexit)100 DEFINE_RUN_ONCE_STATIC(ossl_init_register_atexit)
101 {
102 #ifndef OPENSSL_NO_ATEXIT
103 # ifdef OPENSSL_INIT_DEBUG
104 fprintf(stderr, "OPENSSL_INIT: ossl_init_register_atexit()\n");
105 # endif
106 # ifndef OPENSSL_SYS_UEFI
107 # if defined(_WIN32) && !defined(__BORLANDC__)
108 /* We use _onexit() in preference because it gets called on DLL unload */
109 if (_onexit(win32atexit) == NULL)
110 return 0;
111 # else
112 if (atexit(OPENSSL_cleanup) != 0)
113 return 0;
114 # endif
115 # endif
116 #endif
117
118 return 1;
119 }
120
DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_register_atexit,ossl_init_register_atexit)121 DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_register_atexit,
122 ossl_init_register_atexit)
123 {
124 #ifdef OPENSSL_INIT_DEBUG
125 fprintf(stderr, "OPENSSL_INIT: ossl_init_no_register_atexit ok!\n");
126 #endif
127 /* Do nothing in this case */
128 return 1;
129 }
130
131 static CRYPTO_ONCE load_crypto_nodelete = CRYPTO_ONCE_STATIC_INIT;
DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_nodelete)132 DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_nodelete)
133 {
134 OSSL_TRACE(INIT, "ossl_init_load_crypto_nodelete()\n");
135
136 #if !defined(OPENSSL_USE_NODELETE) \
137 && !defined(OPENSSL_NO_PINSHARED)
138 # if defined(DSO_WIN32) && !defined(_WIN32_WCE)
139 {
140 HMODULE handle = NULL;
141 BOOL ret;
142
143 /* We don't use the DSO route for WIN32 because there is a better way */
144 ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
145 | GET_MODULE_HANDLE_EX_FLAG_PIN,
146 (void *)&base_inited, &handle);
147
148 OSSL_TRACE1(INIT,
149 "ossl_init_load_crypto_nodelete: "
150 "obtained DSO reference? %s\n",
151 (ret == TRUE ? "No!" : "Yes."));
152 return (ret == TRUE) ? 1 : 0;
153 }
154 # elif !defined(DSO_NONE)
155 /*
156 * Deliberately leak a reference to ourselves. This will force the library
157 * to remain loaded until the atexit() handler is run at process exit.
158 */
159 {
160 DSO *dso;
161 void *err;
162
163 if (!err_shelve_state(&err))
164 return 0;
165
166 dso = DSO_dsobyaddr(&base_inited, DSO_FLAG_NO_UNLOAD_ON_FREE);
167 /*
168 * In case of No!, it is uncertain our exit()-handlers can still be
169 * called. After dlclose() the whole library might have been unloaded
170 * already.
171 */
172 OSSL_TRACE1(INIT, "obtained DSO reference? %s\n",
173 (dso == NULL ? "No!" : "Yes."));
174 DSO_free(dso);
175 err_unshelve_state(err);
176 }
177 # endif
178 #endif
179
180 return 1;
181 }
182
183 static CRYPTO_ONCE load_crypto_strings = CRYPTO_ONCE_STATIC_INIT;
184
DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_strings)185 DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_strings)
186 {
187 int ret = 1;
188 /*
189 * OPENSSL_NO_AUTOERRINIT is provided here to prevent at compile time
190 * pulling in all the error strings during static linking
191 */
192 #if !defined(OPENSSL_NO_ERR) && !defined(OPENSSL_NO_AUTOERRINIT)
193 void *err;
194
195 if (!err_shelve_state(&err))
196 return 0;
197
198 OSSL_TRACE(INIT, "ossl_err_load_crypto_strings()\n");
199 ret = ossl_err_load_crypto_strings();
200
201 err_unshelve_state(err);
202 #endif
203 return ret;
204 }
205
DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_load_crypto_strings,ossl_init_load_crypto_strings)206 DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_load_crypto_strings,
207 ossl_init_load_crypto_strings)
208 {
209 /* Do nothing in this case */
210 return 1;
211 }
212
213 static CRYPTO_ONCE ssl_strings = CRYPTO_ONCE_STATIC_INIT;
214
DEFINE_RUN_ONCE_STATIC(ossl_init_load_ssl_strings)215 DEFINE_RUN_ONCE_STATIC(ossl_init_load_ssl_strings)
216 {
217 /*
218 * OPENSSL_NO_AUTOERRINIT is provided here to prevent at compile time
219 * pulling in all the error strings during static linking
220 */
221 #if !defined(OPENSSL_NO_ERR) && !defined(OPENSSL_NO_AUTOERRINIT)
222 OSSL_TRACE(INIT, "ossl_init_load_ssl_strings: ossl_err_load_SSL_strings()\n");
223 ossl_err_load_SSL_strings();
224 #endif
225 return 1;
226 }
227
DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_load_ssl_strings,ossl_init_load_ssl_strings)228 DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_load_ssl_strings,
229 ossl_init_load_ssl_strings)
230 {
231 /* Do nothing in this case */
232 return 1;
233 }
234
235 static CRYPTO_ONCE add_all_ciphers = CRYPTO_ONCE_STATIC_INIT;
DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_ciphers)236 DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_ciphers)
237 {
238 /*
239 * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
240 * pulling in all the ciphers during static linking
241 */
242 #ifndef OPENSSL_NO_AUTOALGINIT
243 OSSL_TRACE(INIT, "openssl_add_all_ciphers_int()\n");
244 openssl_add_all_ciphers_int();
245 #endif
246 return 1;
247 }
248
DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_add_all_ciphers,ossl_init_add_all_ciphers)249 DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_add_all_ciphers,
250 ossl_init_add_all_ciphers)
251 {
252 /* Do nothing */
253 return 1;
254 }
255
256 static CRYPTO_ONCE add_all_digests = CRYPTO_ONCE_STATIC_INIT;
DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_digests)257 DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_digests)
258 {
259 /*
260 * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
261 * pulling in all the ciphers during static linking
262 */
263 #ifndef OPENSSL_NO_AUTOALGINIT
264 OSSL_TRACE(INIT, "openssl_add_all_digests()\n");
265 openssl_add_all_digests_int();
266 #endif
267 return 1;
268 }
269
DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_add_all_digests,ossl_init_add_all_digests)270 DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_add_all_digests,
271 ossl_init_add_all_digests)
272 {
273 /* Do nothing */
274 return 1;
275 }
276
277 static CRYPTO_ONCE config = CRYPTO_ONCE_STATIC_INIT;
278 static int config_inited = 0;
279 static const OPENSSL_INIT_SETTINGS *conf_settings = NULL;
DEFINE_RUN_ONCE_STATIC(ossl_init_config)280 DEFINE_RUN_ONCE_STATIC(ossl_init_config)
281 {
282 int ret = ossl_config_int(NULL);
283
284 config_inited = 1;
285 return ret;
286 }
DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_config_settings,ossl_init_config)287 DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_config_settings, ossl_init_config)
288 {
289 int ret = ossl_config_int(conf_settings);
290
291 config_inited = 1;
292 return ret;
293 }
DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_config,ossl_init_config)294 DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_config, ossl_init_config)
295 {
296 OSSL_TRACE(INIT, "ossl_no_config_int()\n");
297 ossl_no_config_int();
298 config_inited = 1;
299 return 1;
300 }
301
302 static CRYPTO_ONCE async = CRYPTO_ONCE_STATIC_INIT;
303 static int async_inited = 0;
DEFINE_RUN_ONCE_STATIC(ossl_init_async)304 DEFINE_RUN_ONCE_STATIC(ossl_init_async)
305 {
306 OSSL_TRACE(INIT, "async_init()\n");
307 if (!async_init())
308 return 0;
309 async_inited = 1;
310 return 1;
311 }
312
313 #ifndef OPENSSL_NO_ENGINE
314 static CRYPTO_ONCE engine_openssl = CRYPTO_ONCE_STATIC_INIT;
DEFINE_RUN_ONCE_STATIC(ossl_init_engine_openssl)315 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_openssl)
316 {
317 OSSL_TRACE(INIT, "engine_load_openssl_int()\n");
318 engine_load_openssl_int();
319 return 1;
320 }
321 # ifndef OPENSSL_NO_RDRAND
322 static CRYPTO_ONCE engine_rdrand = CRYPTO_ONCE_STATIC_INIT;
DEFINE_RUN_ONCE_STATIC(ossl_init_engine_rdrand)323 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_rdrand)
324 {
325 OSSL_TRACE(INIT, "engine_load_rdrand_int()\n");
326 engine_load_rdrand_int();
327 return 1;
328 }
329 # endif
330 static CRYPTO_ONCE engine_dynamic = CRYPTO_ONCE_STATIC_INIT;
DEFINE_RUN_ONCE_STATIC(ossl_init_engine_dynamic)331 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_dynamic)
332 {
333 OSSL_TRACE(INIT, "engine_load_dynamic_int()\n");
334 engine_load_dynamic_int();
335 return 1;
336 }
337 # ifndef OPENSSL_NO_STATIC_ENGINE
338 # ifndef OPENSSL_NO_DEVCRYPTOENG
339 static CRYPTO_ONCE engine_devcrypto = CRYPTO_ONCE_STATIC_INIT;
DEFINE_RUN_ONCE_STATIC(ossl_init_engine_devcrypto)340 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_devcrypto)
341 {
342 OSSL_TRACE(INIT, "engine_load_devcrypto_int()\n");
343 engine_load_devcrypto_int();
344 return 1;
345 }
346 # endif
347 # if !defined(OPENSSL_NO_PADLOCKENG)
348 static CRYPTO_ONCE engine_padlock = CRYPTO_ONCE_STATIC_INIT;
DEFINE_RUN_ONCE_STATIC(ossl_init_engine_padlock)349 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_padlock)
350 {
351 OSSL_TRACE(INIT, "engine_load_padlock_int()\n");
352 engine_load_padlock_int();
353 return 1;
354 }
355 # endif
356 # if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
357 static CRYPTO_ONCE engine_capi = CRYPTO_ONCE_STATIC_INIT;
DEFINE_RUN_ONCE_STATIC(ossl_init_engine_capi)358 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_capi)
359 {
360 OSSL_TRACE(INIT, "engine_load_capi_int()\n");
361 engine_load_capi_int();
362 return 1;
363 }
364 # endif
365 # if !defined(OPENSSL_NO_AFALGENG)
366 static CRYPTO_ONCE engine_afalg = CRYPTO_ONCE_STATIC_INIT;
DEFINE_RUN_ONCE_STATIC(ossl_init_engine_afalg)367 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_afalg)
368 {
369 OSSL_TRACE(INIT, "engine_load_afalg_int()\n");
370 engine_load_afalg_int();
371 return 1;
372 }
373 # endif
374 # endif
375 #endif
376
OPENSSL_cleanup(void)377 void OPENSSL_cleanup(void)
378 {
379 OPENSSL_INIT_STOP *currhandler, *lasthandler;
380
381 /*
382 * At some point we should consider looking at this function with a view to
383 * moving most/all of this into onfree handlers in OSSL_LIB_CTX.
384 */
385
386 /* If we've not been inited then no need to deinit */
387 if (!base_inited)
388 return;
389
390 /* Might be explicitly called and also by atexit */
391 if (stopped)
392 return;
393 stopped = 1;
394
395 /*
396 * Thread stop may not get automatically called by the thread library for
397 * the very last thread in some situations, so call it directly.
398 */
399 OPENSSL_thread_stop();
400
401 currhandler = stop_handlers;
402 while (currhandler != NULL) {
403 currhandler->handler();
404 lasthandler = currhandler;
405 currhandler = currhandler->next;
406 OPENSSL_free(lasthandler);
407 }
408 stop_handlers = NULL;
409
410 CRYPTO_THREAD_lock_free(optsdone_lock);
411 optsdone_lock = NULL;
412 CRYPTO_THREAD_lock_free(init_lock);
413 init_lock = NULL;
414
415 CRYPTO_THREAD_cleanup_local(&in_init_config_local);
416
417 /*
418 * We assume we are single-threaded for this function, i.e. no race
419 * conditions for the various "*_inited" vars below.
420 */
421
422 #ifndef OPENSSL_NO_COMP
423 OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_comp_zlib_cleanup()\n");
424 ossl_comp_zlib_cleanup();
425 OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_comp_brotli_cleanup()\n");
426 ossl_comp_brotli_cleanup();
427 OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_comp_zstd_cleanup()\n");
428 ossl_comp_zstd_cleanup();
429 #endif
430
431 if (async_inited) {
432 OSSL_TRACE(INIT, "OPENSSL_cleanup: async_deinit()\n");
433 async_deinit();
434 }
435
436 /*
437 * Note that cleanup order is important:
438 * - ossl_rand_cleanup_int could call an ENGINE's RAND cleanup function so
439 * must be called before engine_cleanup_int()
440 * - ENGINEs use CRYPTO_EX_DATA and therefore, must be cleaned up
441 * before the ex data handlers are wiped during default ossl_lib_ctx deinit.
442 * - ossl_config_modules_free() can end up in ENGINE code so must be called
443 * before engine_cleanup_int()
444 * - ENGINEs and additional EVP algorithms might use added OIDs names so
445 * ossl_obj_cleanup_int() must be called last
446 */
447 OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_rand_cleanup_int()\n");
448 ossl_rand_cleanup_int();
449
450 OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_config_modules_free()\n");
451 ossl_config_modules_free();
452
453 #ifndef OPENSSL_NO_ENGINE
454 OSSL_TRACE(INIT, "OPENSSL_cleanup: engine_cleanup_int()\n");
455 engine_cleanup_int();
456 #endif
457
458 #ifndef OPENSSL_NO_DEPRECATED_3_0
459 OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_store_cleanup_int()\n");
460 ossl_store_cleanup_int();
461 #endif
462
463 OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_lib_ctx_default_deinit()\n");
464 ossl_lib_ctx_default_deinit();
465
466 ossl_cleanup_thread();
467
468 OSSL_TRACE(INIT, "OPENSSL_cleanup: bio_cleanup()\n");
469 bio_cleanup();
470
471 OSSL_TRACE(INIT, "OPENSSL_cleanup: evp_cleanup_int()\n");
472 evp_cleanup_int();
473
474 OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_obj_cleanup_int()\n");
475 ossl_obj_cleanup_int();
476
477 OSSL_TRACE(INIT, "OPENSSL_cleanup: err_int()\n");
478 err_cleanup();
479
480 OSSL_TRACE(INIT, "OPENSSL_cleanup: CRYPTO_secure_malloc_done()\n");
481 CRYPTO_secure_malloc_done();
482
483 #ifndef OPENSSL_NO_CMP
484 OSSL_TRACE(INIT, "OPENSSL_cleanup: OSSL_CMP_log_close()\n");
485 OSSL_CMP_log_close();
486 #endif
487
488 OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_trace_cleanup()\n");
489 ossl_trace_cleanup();
490
491 base_inited = 0;
492 }
493
494 /*
495 * If this function is called with a non NULL settings value then it must be
496 * called prior to any threads making calls to any OpenSSL functions,
497 * i.e. passing a non-null settings value is assumed to be single-threaded.
498 */
OPENSSL_init_crypto(uint64_t opts,const OPENSSL_INIT_SETTINGS * settings)499 int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
500 {
501 uint64_t tmp;
502 int aloaddone = 0;
503
504 /* Applications depend on 0 being returned when cleanup was already done */
505 if (stopped) {
506 if (!(opts & OPENSSL_INIT_BASE_ONLY))
507 ERR_raise(ERR_LIB_CRYPTO, ERR_R_INIT_FAIL);
508 return 0;
509 }
510
511 /*
512 * We ignore failures from this function. It is probably because we are
513 * on a platform that doesn't support lockless atomic loads (we may not
514 * have created optsdone_lock yet so we can't use it). This is just an
515 * optimisation to skip the full checks in this function if we don't need
516 * to, so we carry on regardless in the event of failure.
517 *
518 * There could be a race here with other threads, so that optsdone has not
519 * been updated yet, even though the options have in fact been initialised.
520 * This doesn't matter - it just means we will run the full function
521 * unnecessarily - but all the critical code is contained in RUN_ONCE
522 * functions anyway so we are safe.
523 */
524 if (CRYPTO_atomic_load(&optsdone, &tmp, NULL)) {
525 if ((tmp & opts) == opts)
526 return 1;
527 aloaddone = 1;
528 }
529
530 /*
531 * At some point we should look at this function with a view to moving
532 * most/all of this into OSSL_LIB_CTX.
533 *
534 * When the caller specifies OPENSSL_INIT_BASE_ONLY, that should be the
535 * *only* option specified. With that option we return immediately after
536 * doing the requested limited initialization. Note that
537 * err_shelve_state() called by us via ossl_init_load_crypto_nodelete()
538 * re-enters OPENSSL_init_crypto() with OPENSSL_INIT_BASE_ONLY, but with
539 * base already initialized this is a harmless NOOP.
540 *
541 * If we remain the only caller of err_shelve_state() the recursion should
542 * perhaps be removed, but if in doubt, it can be left in place.
543 */
544 if (!RUN_ONCE(&base, ossl_init_base))
545 return 0;
546
547 if (opts & OPENSSL_INIT_BASE_ONLY)
548 return 1;
549
550 /*
551 * optsdone_lock should definitely be set up now, so we can now repeat the
552 * same check from above but be sure that it will work even on platforms
553 * without lockless CRYPTO_atomic_load
554 */
555 if (!aloaddone) {
556 if (!CRYPTO_atomic_load(&optsdone, &tmp, optsdone_lock))
557 return 0;
558 if ((tmp & opts) == opts)
559 return 1;
560 }
561
562 /*
563 * Now we don't always set up exit handlers, the INIT_BASE_ONLY calls
564 * should not have the side-effect of setting up exit handlers, and
565 * therefore, this code block is below the INIT_BASE_ONLY-conditioned early
566 * return above.
567 */
568 if ((opts & OPENSSL_INIT_NO_ATEXIT) != 0) {
569 if (!RUN_ONCE_ALT(®ister_atexit, ossl_init_no_register_atexit,
570 ossl_init_register_atexit))
571 return 0;
572 } else if (!RUN_ONCE(®ister_atexit, ossl_init_register_atexit)) {
573 return 0;
574 }
575
576 if (!RUN_ONCE(&load_crypto_nodelete, ossl_init_load_crypto_nodelete))
577 return 0;
578
579 if ((opts & OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS)
580 && !RUN_ONCE_ALT(&load_crypto_strings,
581 ossl_init_no_load_crypto_strings,
582 ossl_init_load_crypto_strings))
583 return 0;
584
585 if ((opts & OPENSSL_INIT_LOAD_CRYPTO_STRINGS)
586 && !RUN_ONCE(&load_crypto_strings, ossl_init_load_crypto_strings))
587 return 0;
588
589 if ((opts & OPENSSL_INIT_NO_LOAD_SSL_STRINGS)
590 && !RUN_ONCE_ALT(&ssl_strings, ossl_init_no_load_ssl_strings,
591 ossl_init_load_ssl_strings))
592 return 0;
593
594 if ((opts & OPENSSL_INIT_LOAD_SSL_STRINGS)
595 && !RUN_ONCE(&ssl_strings, ossl_init_load_ssl_strings))
596 return 0;
597
598 if ((opts & OPENSSL_INIT_NO_ADD_ALL_CIPHERS)
599 && !RUN_ONCE_ALT(&add_all_ciphers, ossl_init_no_add_all_ciphers,
600 ossl_init_add_all_ciphers))
601 return 0;
602
603 if ((opts & OPENSSL_INIT_ADD_ALL_CIPHERS)
604 && !RUN_ONCE(&add_all_ciphers, ossl_init_add_all_ciphers))
605 return 0;
606
607 if ((opts & OPENSSL_INIT_NO_ADD_ALL_DIGESTS)
608 && !RUN_ONCE_ALT(&add_all_digests, ossl_init_no_add_all_digests,
609 ossl_init_add_all_digests))
610 return 0;
611
612 if ((opts & OPENSSL_INIT_ADD_ALL_DIGESTS)
613 && !RUN_ONCE(&add_all_digests, ossl_init_add_all_digests))
614 return 0;
615
616 if ((opts & OPENSSL_INIT_ATFORK)
617 && !openssl_init_fork_handlers())
618 return 0;
619
620 if ((opts & OPENSSL_INIT_NO_LOAD_CONFIG)
621 && !RUN_ONCE_ALT(&config, ossl_init_no_config, ossl_init_config))
622 return 0;
623
624 if (opts & OPENSSL_INIT_LOAD_CONFIG) {
625 int loading = CRYPTO_THREAD_get_local(&in_init_config_local) != NULL;
626
627 /* If called recursively from OBJ_ calls, just skip it. */
628 if (!loading) {
629 int ret;
630
631 if (!CRYPTO_THREAD_set_local(&in_init_config_local, (void *)-1))
632 return 0;
633 if (settings == NULL) {
634 ret = RUN_ONCE(&config, ossl_init_config);
635 } else {
636 if (!CRYPTO_THREAD_write_lock(init_lock))
637 return 0;
638 conf_settings = settings;
639 ret = RUN_ONCE_ALT(&config, ossl_init_config_settings,
640 ossl_init_config);
641 conf_settings = NULL;
642 CRYPTO_THREAD_unlock(init_lock);
643 }
644
645 if (ret <= 0)
646 return 0;
647 }
648 }
649
650 if ((opts & OPENSSL_INIT_ASYNC)
651 && !RUN_ONCE(&async, ossl_init_async))
652 return 0;
653
654 #ifndef OPENSSL_NO_ENGINE
655 if ((opts & OPENSSL_INIT_ENGINE_OPENSSL)
656 && !RUN_ONCE(&engine_openssl, ossl_init_engine_openssl))
657 return 0;
658 # ifndef OPENSSL_NO_RDRAND
659 if ((opts & OPENSSL_INIT_ENGINE_RDRAND)
660 && !RUN_ONCE(&engine_rdrand, ossl_init_engine_rdrand))
661 return 0;
662 # endif
663 if ((opts & OPENSSL_INIT_ENGINE_DYNAMIC)
664 && !RUN_ONCE(&engine_dynamic, ossl_init_engine_dynamic))
665 return 0;
666 # ifndef OPENSSL_NO_STATIC_ENGINE
667 # ifndef OPENSSL_NO_DEVCRYPTOENG
668 if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV)
669 && !RUN_ONCE(&engine_devcrypto, ossl_init_engine_devcrypto))
670 return 0;
671 # endif
672 # if !defined(OPENSSL_NO_PADLOCKENG)
673 if ((opts & OPENSSL_INIT_ENGINE_PADLOCK)
674 && !RUN_ONCE(&engine_padlock, ossl_init_engine_padlock))
675 return 0;
676 # endif
677 # if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
678 if ((opts & OPENSSL_INIT_ENGINE_CAPI)
679 && !RUN_ONCE(&engine_capi, ossl_init_engine_capi))
680 return 0;
681 # endif
682 # if !defined(OPENSSL_NO_AFALGENG)
683 if ((opts & OPENSSL_INIT_ENGINE_AFALG)
684 && !RUN_ONCE(&engine_afalg, ossl_init_engine_afalg))
685 return 0;
686 # endif
687 # endif
688 if (opts & (OPENSSL_INIT_ENGINE_ALL_BUILTIN
689 | OPENSSL_INIT_ENGINE_OPENSSL
690 | OPENSSL_INIT_ENGINE_AFALG)) {
691 ENGINE_register_all_complete();
692 }
693 #endif
694
695 if (!CRYPTO_atomic_or(&optsdone, opts, &tmp, optsdone_lock))
696 return 0;
697
698 return 1;
699 }
700
OPENSSL_atexit(void (* handler)(void))701 int OPENSSL_atexit(void (*handler)(void))
702 {
703 OPENSSL_INIT_STOP *newhand;
704
705 #if !defined(OPENSSL_USE_NODELETE)\
706 && !defined(OPENSSL_NO_PINSHARED)
707 {
708 # if defined(DSO_WIN32) && !defined(_WIN32_WCE)
709 HMODULE handle = NULL;
710 BOOL ret;
711 union {
712 void *sym;
713 void (*func)(void);
714 } handlersym;
715
716 handlersym.func = handler;
717
718 /*
719 * We don't use the DSO route for WIN32 because there is a better
720 * way
721 */
722 ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
723 | GET_MODULE_HANDLE_EX_FLAG_PIN,
724 handlersym.sym, &handle);
725
726 if (!ret)
727 return 0;
728 # elif !defined(DSO_NONE)
729 /*
730 * Deliberately leak a reference to the handler. This will force the
731 * library/code containing the handler to remain loaded until we run the
732 * atexit handler. If -znodelete has been used then this is
733 * unnecessary.
734 */
735 DSO *dso = NULL;
736 union {
737 void *sym;
738 void (*func)(void);
739 } handlersym;
740
741 handlersym.func = handler;
742
743 ERR_set_mark();
744 dso = DSO_dsobyaddr(handlersym.sym, DSO_FLAG_NO_UNLOAD_ON_FREE);
745 /* See same code above in ossl_init_base() for an explanation. */
746 OSSL_TRACE1(INIT,
747 "atexit: obtained DSO reference? %s\n",
748 (dso == NULL ? "No!" : "Yes."));
749 DSO_free(dso);
750 ERR_pop_to_mark();
751 # endif
752 }
753 #endif
754
755 if ((newhand = OPENSSL_malloc(sizeof(*newhand))) == NULL)
756 return 0;
757
758 newhand->handler = handler;
759 newhand->next = stop_handlers;
760 stop_handlers = newhand;
761
762 return 1;
763 }
764
765