Add new /dev/crypto engine
[openssl.git] / crypto / init.c
1 /*
2  * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (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 #include <internal/cryptlib_int.h>
11 #include <openssl/err.h>
12 #include <internal/rand.h>
13 #include <internal/bio.h>
14 #include <openssl/evp.h>
15 #include <internal/evp_int.h>
16 #include <internal/conf.h>
17 #include <internal/async.h>
18 #include <internal/engine.h>
19 #include <internal/comp.h>
20 #include <internal/err.h>
21 #include <internal/err_int.h>
22 #include <internal/objects.h>
23 #include <stdlib.h>
24 #include <assert.h>
25 #include <internal/thread_once.h>
26 #include <internal/dso.h>
27
28 static int stopped = 0;
29
30 static void ossl_init_thread_stop(struct thread_local_inits_st *locals);
31
32 static CRYPTO_THREAD_LOCAL threadstopkey;
33
34 static void ossl_init_thread_stop_wrap(void *local)
35 {
36     ossl_init_thread_stop((struct thread_local_inits_st *)local);
37 }
38
39 static struct thread_local_inits_st *ossl_init_get_thread_local(int alloc)
40 {
41     struct thread_local_inits_st *local =
42         CRYPTO_THREAD_get_local(&threadstopkey);
43
44     if (local == NULL && alloc) {
45         local = OPENSSL_zalloc(sizeof *local);
46         if (local != NULL && !CRYPTO_THREAD_set_local(&threadstopkey, local)) {
47             OPENSSL_free(local);
48             return NULL;
49         }
50     }
51     if (!alloc) {
52         CRYPTO_THREAD_set_local(&threadstopkey, NULL);
53     }
54
55     return local;
56 }
57
58 typedef struct ossl_init_stop_st OPENSSL_INIT_STOP;
59 struct ossl_init_stop_st {
60     void (*handler)(void);
61     OPENSSL_INIT_STOP *next;
62 };
63
64 static OPENSSL_INIT_STOP *stop_handlers = NULL;
65 static CRYPTO_RWLOCK *init_lock = NULL;
66
67 static CRYPTO_ONCE base = CRYPTO_ONCE_STATIC_INIT;
68 static int base_inited = 0;
69 DEFINE_RUN_ONCE_STATIC(ossl_init_base)
70 {
71 #ifdef OPENSSL_INIT_DEBUG
72     fprintf(stderr, "OPENSSL_INIT: ossl_init_base: Setting up stop handlers\n");
73 #endif
74 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
75     ossl_malloc_setup_failures();
76 #endif
77     /*
78      * We use a dummy thread local key here. We use the destructor to detect
79      * when the thread is going to stop (where that feature is available)
80      */
81     CRYPTO_THREAD_init_local(&threadstopkey, ossl_init_thread_stop_wrap);
82 #ifndef OPENSSL_SYS_UEFI
83     atexit(OPENSSL_cleanup);
84 #endif
85     if ((init_lock = CRYPTO_THREAD_lock_new()) == NULL)
86         return 0;
87     OPENSSL_cpuid_setup();
88
89     /*
90      * BIG FAT WARNING!
91      * Everything needed to be initialized in this function before threads
92      * come along MUST happen before base_inited is set to 1, or we will
93      * see race conditions.
94      */
95     base_inited = 1;
96
97 #if !defined(OPENSSL_NO_DSO) && !defined(OPENSSL_USE_NODELETE)
98 # ifdef DSO_WIN32
99     {
100         HMODULE handle = NULL;
101         BOOL ret;
102
103         /* We don't use the DSO route for WIN32 because there is a better way */
104         ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
105                                 | GET_MODULE_HANDLE_EX_FLAG_PIN,
106                                 (void *)&base_inited, &handle);
107
108         return (ret == TRUE) ? 1 : 0;
109     }
110 # else
111     /*
112      * Deliberately leak a reference to ourselves. This will force the library
113      * to remain loaded until the atexit() handler is run at process exit.
114      */
115     {
116         DSO *dso = NULL;
117
118         ERR_set_mark();
119         dso = DSO_dsobyaddr(&base_inited, DSO_FLAG_NO_UNLOAD_ON_FREE);
120         DSO_free(dso);
121         ERR_pop_to_mark();
122     }
123 # endif
124 #endif
125
126     return 1;
127 }
128
129 static CRYPTO_ONCE load_crypto_strings = CRYPTO_ONCE_STATIC_INIT;
130 static int load_crypto_strings_inited = 0;
131 DEFINE_RUN_ONCE_STATIC(ossl_init_no_load_crypto_strings)
132 {
133     /* Do nothing in this case */
134     return 1;
135 }
136
137 DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_strings)
138 {
139     int ret = 1;
140     /*
141      * OPENSSL_NO_AUTOERRINIT is provided here to prevent at compile time
142      * pulling in all the error strings during static linking
143      */
144 #if !defined(OPENSSL_NO_ERR) && !defined(OPENSSL_NO_AUTOERRINIT)
145 # ifdef OPENSSL_INIT_DEBUG
146     fprintf(stderr, "OPENSSL_INIT: ossl_init_load_crypto_strings: "
147                     "err_load_crypto_strings_int()\n");
148 # endif
149     ret = err_load_crypto_strings_int();
150     load_crypto_strings_inited = 1;
151 #endif
152     return ret;
153 }
154
155 static CRYPTO_ONCE add_all_ciphers = CRYPTO_ONCE_STATIC_INIT;
156 DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_ciphers)
157 {
158     /*
159      * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
160      * pulling in all the ciphers during static linking
161      */
162 #ifndef OPENSSL_NO_AUTOALGINIT
163 # ifdef OPENSSL_INIT_DEBUG
164     fprintf(stderr, "OPENSSL_INIT: ossl_init_add_all_ciphers: "
165                     "openssl_add_all_ciphers_int()\n");
166 # endif
167     openssl_add_all_ciphers_int();
168 #endif
169     return 1;
170 }
171
172 static CRYPTO_ONCE add_all_digests = CRYPTO_ONCE_STATIC_INIT;
173 DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_digests)
174 {
175     /*
176      * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
177      * pulling in all the ciphers during static linking
178      */
179 #ifndef OPENSSL_NO_AUTOALGINIT
180 # ifdef OPENSSL_INIT_DEBUG
181     fprintf(stderr, "OPENSSL_INIT: ossl_init_add_all_digests: "
182                     "openssl_add_all_digests()\n");
183 # endif
184     openssl_add_all_digests_int();
185 #endif
186     return 1;
187 }
188
189 DEFINE_RUN_ONCE_STATIC(ossl_init_no_add_algs)
190 {
191     /* Do nothing */
192     return 1;
193 }
194
195 static CRYPTO_ONCE config = CRYPTO_ONCE_STATIC_INIT;
196 static int config_inited = 0;
197 static const char *appname;
198 DEFINE_RUN_ONCE_STATIC(ossl_init_config)
199 {
200 #ifdef OPENSSL_INIT_DEBUG
201     fprintf(stderr,
202             "OPENSSL_INIT: ossl_init_config: openssl_config(%s)\n",
203             appname == NULL ? "NULL" : appname);
204 #endif
205     openssl_config_int(appname);
206     config_inited = 1;
207     return 1;
208 }
209 DEFINE_RUN_ONCE_STATIC(ossl_init_no_config)
210 {
211 #ifdef OPENSSL_INIT_DEBUG
212     fprintf(stderr,
213             "OPENSSL_INIT: ossl_init_config: openssl_no_config_int()\n");
214 #endif
215     openssl_no_config_int();
216     config_inited = 1;
217     return 1;
218 }
219
220 static CRYPTO_ONCE async = CRYPTO_ONCE_STATIC_INIT;
221 static int async_inited = 0;
222 DEFINE_RUN_ONCE_STATIC(ossl_init_async)
223 {
224 #ifdef OPENSSL_INIT_DEBUG
225     fprintf(stderr, "OPENSSL_INIT: ossl_init_async: async_init()\n");
226 #endif
227     if (!async_init())
228         return 0;
229     async_inited = 1;
230     return 1;
231 }
232
233 #ifndef OPENSSL_NO_ENGINE
234 static CRYPTO_ONCE engine_openssl = CRYPTO_ONCE_STATIC_INIT;
235 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_openssl)
236 {
237 # ifdef OPENSSL_INIT_DEBUG
238     fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_openssl: "
239                     "engine_load_openssl_int()\n");
240 # endif
241     engine_load_openssl_int();
242     return 1;
243 }
244 # ifndef OPENSSL_NO_DEVCRYPTOENG
245 static CRYPTO_ONCE engine_devcrypto = CRYPTO_ONCE_STATIC_INIT;
246 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_devcrypto)
247 {
248 #  ifdef OPENSSL_INIT_DEBUG
249     fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_devcrypto: "
250                     "engine_load_devcrypto_int()\n");
251 #  endif
252     engine_load_devcrypto_int();
253     return 1;
254 }
255 # endif
256
257 # ifndef OPENSSL_NO_RDRAND
258 static CRYPTO_ONCE engine_rdrand = CRYPTO_ONCE_STATIC_INIT;
259 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_rdrand)
260 {
261 #  ifdef OPENSSL_INIT_DEBUG
262     fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_rdrand: "
263                     "engine_load_rdrand_int()\n");
264 #  endif
265     engine_load_rdrand_int();
266     return 1;
267 }
268 # endif
269 static CRYPTO_ONCE engine_dynamic = CRYPTO_ONCE_STATIC_INIT;
270 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_dynamic)
271 {
272 # ifdef OPENSSL_INIT_DEBUG
273     fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_dynamic: "
274                     "engine_load_dynamic_int()\n");
275 # endif
276     engine_load_dynamic_int();
277     return 1;
278 }
279 # ifndef OPENSSL_NO_STATIC_ENGINE
280 #  if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
281 static CRYPTO_ONCE engine_padlock = CRYPTO_ONCE_STATIC_INIT;
282 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_padlock)
283 {
284 #   ifdef OPENSSL_INIT_DEBUG
285     fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_padlock: "
286                     "engine_load_padlock_int()\n");
287 #   endif
288     engine_load_padlock_int();
289     return 1;
290 }
291 #  endif
292 #  if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
293 static CRYPTO_ONCE engine_capi = CRYPTO_ONCE_STATIC_INIT;
294 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_capi)
295 {
296 #   ifdef OPENSSL_INIT_DEBUG
297     fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_capi: "
298                     "engine_load_capi_int()\n");
299 #   endif
300     engine_load_capi_int();
301     return 1;
302 }
303 #  endif
304 #  if !defined(OPENSSL_NO_AFALGENG)
305 static CRYPTO_ONCE engine_afalg = CRYPTO_ONCE_STATIC_INIT;
306 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_afalg)
307 {
308 #   ifdef OPENSSL_INIT_DEBUG
309     fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_afalg: "
310                     "engine_load_afalg_int()\n");
311 #   endif
312     engine_load_afalg_int();
313     return 1;
314 }
315 #  endif
316 # endif
317 #endif
318
319 #ifndef OPENSSL_NO_COMP
320 static CRYPTO_ONCE zlib = CRYPTO_ONCE_STATIC_INIT;
321
322 static int zlib_inited = 0;
323 DEFINE_RUN_ONCE_STATIC(ossl_init_zlib)
324 {
325     /* Do nothing - we need to know about this for the later cleanup */
326     zlib_inited = 1;
327     return 1;
328 }
329 #endif
330
331 static void ossl_init_thread_stop(struct thread_local_inits_st *locals)
332 {
333     /* Can't do much about this */
334     if (locals == NULL)
335         return;
336
337     if (locals->async) {
338 #ifdef OPENSSL_INIT_DEBUG
339         fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: "
340                         "ASYNC_cleanup_thread()\n");
341 #endif
342         ASYNC_cleanup_thread();
343     }
344
345     if (locals->err_state) {
346 #ifdef OPENSSL_INIT_DEBUG
347         fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: "
348                         "err_delete_thread_state()\n");
349 #endif
350         err_delete_thread_state();
351     }
352
353     OPENSSL_free(locals);
354 }
355
356 void OPENSSL_thread_stop(void)
357 {
358     ossl_init_thread_stop(
359         (struct thread_local_inits_st *)ossl_init_get_thread_local(0));
360 }
361
362 int ossl_init_thread_start(uint64_t opts)
363 {
364     struct thread_local_inits_st *locals;
365
366     if (!OPENSSL_init_crypto(0, NULL))
367         return 0;
368
369     locals = ossl_init_get_thread_local(1);
370
371     if (locals == NULL)
372         return 0;
373
374     if (opts & OPENSSL_INIT_THREAD_ASYNC) {
375 #ifdef OPENSSL_INIT_DEBUG
376         fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_start: "
377                         "marking thread for async\n");
378 #endif
379         locals->async = 1;
380     }
381
382     if (opts & OPENSSL_INIT_THREAD_ERR_STATE) {
383 #ifdef OPENSSL_INIT_DEBUG
384         fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_start: "
385                         "marking thread for err_state\n");
386 #endif
387         locals->err_state = 1;
388     }
389
390     return 1;
391 }
392
393 void OPENSSL_cleanup(void)
394 {
395     OPENSSL_INIT_STOP *currhandler, *lasthandler;
396
397     /* If we've not been inited then no need to deinit */
398     if (!base_inited)
399         return;
400
401     /* Might be explicitly called and also by atexit */
402     if (stopped)
403         return;
404     stopped = 1;
405
406     /*
407      * Thread stop may not get automatically called by the thread library for
408      * the very last thread in some situations, so call it directly.
409      */
410     ossl_init_thread_stop(ossl_init_get_thread_local(0));
411
412     currhandler = stop_handlers;
413     while (currhandler != NULL) {
414         currhandler->handler();
415         lasthandler = currhandler;
416         currhandler = currhandler->next;
417         OPENSSL_free(lasthandler);
418     }
419     stop_handlers = NULL;
420
421     CRYPTO_THREAD_lock_free(init_lock);
422
423     /*
424      * We assume we are single-threaded for this function, i.e. no race
425      * conditions for the various "*_inited" vars below.
426      */
427
428 #ifndef OPENSSL_NO_COMP
429     if (zlib_inited) {
430 #ifdef OPENSSL_INIT_DEBUG
431         fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
432                         "comp_zlib_cleanup_int()\n");
433 #endif
434         comp_zlib_cleanup_int();
435     }
436 #endif
437
438     if (async_inited) {
439 # ifdef OPENSSL_INIT_DEBUG
440         fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
441                         "async_deinit()\n");
442 # endif
443         async_deinit();
444     }
445
446     if (load_crypto_strings_inited) {
447 #ifdef OPENSSL_INIT_DEBUG
448         fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
449                         "err_free_strings_int()\n");
450 #endif
451         err_free_strings_int();
452     }
453
454     CRYPTO_THREAD_cleanup_local(&threadstopkey);
455
456 #ifdef OPENSSL_INIT_DEBUG
457     fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
458                     "rand_cleanup_int()\n");
459     fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
460                     "conf_modules_free_int()\n");
461 #ifndef OPENSSL_NO_ENGINE
462     fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
463                     "engine_cleanup_int()\n");
464 #endif
465     fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
466                     "crypto_cleanup_all_ex_data_int()\n");
467     fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
468                     "bio_sock_cleanup_int()\n");
469     fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
470                     "bio_cleanup()\n");
471     fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
472                     "evp_cleanup_int()\n");
473     fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
474                     "obj_cleanup_int()\n");
475     fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: "
476                     "err_cleanup()\n");
477 #endif
478     /*
479      * Note that cleanup order is important:
480      * - rand_cleanup_int could call an ENGINE's RAND cleanup function so
481      * must be called before engine_cleanup_int()
482      * - ENGINEs use CRYPTO_EX_DATA and therefore, must be cleaned up
483      * before the ex data handlers are wiped in CRYPTO_cleanup_all_ex_data().
484      * - conf_modules_free_int() can end up in ENGINE code so must be called
485      * before engine_cleanup_int()
486      * - ENGINEs and additional EVP algorithms might use added OIDs names so
487      * obj_cleanup_int() must be called last
488      */
489     rand_cleanup_int();
490     conf_modules_free_int();
491 #ifndef OPENSSL_NO_ENGINE
492     engine_cleanup_int();
493 #endif
494     crypto_cleanup_all_ex_data_int();
495     bio_cleanup();
496     evp_cleanup_int();
497     obj_cleanup_int();
498     err_cleanup();
499
500     base_inited = 0;
501 }
502
503 /*
504  * If this function is called with a non NULL settings value then it must be
505  * called prior to any threads making calls to any OpenSSL functions,
506  * i.e. passing a non-null settings value is assumed to be single-threaded.
507  */
508 int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
509 {
510     static int stoperrset = 0;
511
512     if (stopped) {
513         if (!stoperrset) {
514             /*
515              * We only ever set this once to avoid getting into an infinite
516              * loop where the error system keeps trying to init and fails so
517              * sets an error etc
518              */
519             stoperrset = 1;
520             CRYPTOerr(CRYPTO_F_OPENSSL_INIT_CRYPTO, ERR_R_INIT_FAIL);
521         }
522         return 0;
523     }
524
525     if (!base_inited && !RUN_ONCE(&base, ossl_init_base))
526         return 0;
527
528     if ((opts & OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS)
529             && !RUN_ONCE(&load_crypto_strings,
530                          ossl_init_no_load_crypto_strings))
531         return 0;
532
533     if ((opts & OPENSSL_INIT_LOAD_CRYPTO_STRINGS)
534             && !RUN_ONCE(&load_crypto_strings, ossl_init_load_crypto_strings))
535         return 0;
536
537     if ((opts & OPENSSL_INIT_NO_ADD_ALL_CIPHERS)
538             && !RUN_ONCE(&add_all_ciphers, ossl_init_no_add_algs))
539         return 0;
540
541     if ((opts & OPENSSL_INIT_ADD_ALL_CIPHERS)
542             && !RUN_ONCE(&add_all_ciphers, ossl_init_add_all_ciphers))
543         return 0;
544
545     if ((opts & OPENSSL_INIT_NO_ADD_ALL_DIGESTS)
546             && !RUN_ONCE(&add_all_digests, ossl_init_no_add_algs))
547         return 0;
548
549     if ((opts & OPENSSL_INIT_ADD_ALL_DIGESTS)
550             && !RUN_ONCE(&add_all_digests, ossl_init_add_all_digests))
551         return 0;
552
553     if ((opts & OPENSSL_INIT_NO_LOAD_CONFIG)
554             && !RUN_ONCE(&config, ossl_init_no_config))
555         return 0;
556
557     if (opts & OPENSSL_INIT_LOAD_CONFIG) {
558         int ret;
559         CRYPTO_THREAD_write_lock(init_lock);
560         appname = (settings == NULL) ? NULL : settings->appname;
561         ret = RUN_ONCE(&config, ossl_init_config);
562         CRYPTO_THREAD_unlock(init_lock);
563         if (!ret)
564             return 0;
565     }
566
567     if ((opts & OPENSSL_INIT_ASYNC)
568             && !RUN_ONCE(&async, ossl_init_async))
569         return 0;
570
571 #ifndef OPENSSL_NO_ENGINE
572     if ((opts & OPENSSL_INIT_ENGINE_OPENSSL)
573             && !RUN_ONCE(&engine_openssl, ossl_init_engine_openssl))
574         return 0;
575 # if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_DEVCRYPTOENG)
576     if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV)
577             && !RUN_ONCE(&engine_devcrypto, ossl_init_engine_devcrypto))
578         return 0;
579 # endif
580 # ifndef OPENSSL_NO_RDRAND
581     if ((opts & OPENSSL_INIT_ENGINE_RDRAND)
582             && !RUN_ONCE(&engine_rdrand, ossl_init_engine_rdrand))
583         return 0;
584 # endif
585     if ((opts & OPENSSL_INIT_ENGINE_DYNAMIC)
586             && !RUN_ONCE(&engine_dynamic, ossl_init_engine_dynamic))
587         return 0;
588 # ifndef OPENSSL_NO_STATIC_ENGINE
589 #  if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK)
590     if ((opts & OPENSSL_INIT_ENGINE_PADLOCK)
591             && !RUN_ONCE(&engine_padlock, ossl_init_engine_padlock))
592         return 0;
593 #  endif
594 #  if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
595     if ((opts & OPENSSL_INIT_ENGINE_CAPI)
596             && !RUN_ONCE(&engine_capi, ossl_init_engine_capi))
597         return 0;
598 #  endif
599 #  if !defined(OPENSSL_NO_AFALGENG)
600     if ((opts & OPENSSL_INIT_ENGINE_AFALG)
601             && !RUN_ONCE(&engine_afalg, ossl_init_engine_afalg))
602         return 0;
603 #  endif
604 # endif
605     if (opts & (OPENSSL_INIT_ENGINE_ALL_BUILTIN
606                 | OPENSSL_INIT_ENGINE_OPENSSL
607                 | OPENSSL_INIT_ENGINE_AFALG)) {
608         ENGINE_register_all_complete();
609     }
610 #endif
611
612 #ifndef OPENSSL_NO_COMP
613     if ((opts & OPENSSL_INIT_ZLIB)
614             && !RUN_ONCE(&zlib, ossl_init_zlib))
615         return 0;
616 #endif
617
618     return 1;
619 }
620
621 int OPENSSL_atexit(void (*handler)(void))
622 {
623     OPENSSL_INIT_STOP *newhand;
624
625 #if !defined(OPENSSL_NO_DSO) && !defined(OPENSSL_USE_NODELETE)
626     {
627         union {
628             void *sym;
629             void (*func)(void);
630         } handlersym;
631
632         handlersym.func = handler;
633 # ifdef DSO_WIN32
634         {
635             HMODULE handle = NULL;
636             BOOL ret;
637
638             /*
639              * We don't use the DSO route for WIN32 because there is a better
640              * way
641              */
642             ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
643                                     | GET_MODULE_HANDLE_EX_FLAG_PIN,
644                                     handlersym.sym, &handle);
645
646             if (!ret)
647                 return 0;
648         }
649 # else
650         /*
651          * Deliberately leak a reference to the handler. This will force the
652          * library/code containing the handler to remain loaded until we run the
653          * atexit handler. If -znodelete has been used then this is
654          * unneccessary.
655          */
656         {
657             DSO *dso = NULL;
658
659             ERR_set_mark();
660             dso = DSO_dsobyaddr(handlersym.sym, DSO_FLAG_NO_UNLOAD_ON_FREE);
661             DSO_free(dso);
662             ERR_pop_to_mark();
663         }
664 # endif
665     }
666 #endif
667
668     newhand = OPENSSL_malloc(sizeof(*newhand));
669     if (newhand == NULL)
670         return 0;
671
672     newhand->handler = handler;
673     newhand->next = stop_handlers;
674     stop_handlers = newhand;
675
676     return 1;
677 }