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