1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci *
4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci */
9e1051a39Sopenharmony_ci
10e1051a39Sopenharmony_ci#include "e_os.h"
11e1051a39Sopenharmony_ci
12e1051a39Sopenharmony_ci#include "internal/err.h"
13e1051a39Sopenharmony_ci#include <openssl/crypto.h>
14e1051a39Sopenharmony_ci#include <openssl/evp.h>
15e1051a39Sopenharmony_ci#include <openssl/trace.h>
16e1051a39Sopenharmony_ci#include "ssl_local.h"
17e1051a39Sopenharmony_ci#include "sslerr.h"
18e1051a39Sopenharmony_ci#include "internal/thread_once.h"
19e1051a39Sopenharmony_ci
20e1051a39Sopenharmony_cistatic int stopped;
21e1051a39Sopenharmony_ci
22e1051a39Sopenharmony_cistatic void ssl_library_stop(void);
23e1051a39Sopenharmony_ci
24e1051a39Sopenharmony_cistatic CRYPTO_ONCE ssl_base = CRYPTO_ONCE_STATIC_INIT;
25e1051a39Sopenharmony_cistatic int ssl_base_inited = 0;
26e1051a39Sopenharmony_ciDEFINE_RUN_ONCE_STATIC(ossl_init_ssl_base)
27e1051a39Sopenharmony_ci{
28e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_COMP
29e1051a39Sopenharmony_ci    OSSL_TRACE(INIT, "ossl_init_ssl_base: "
30e1051a39Sopenharmony_ci               "SSL_COMP_get_compression_methods()\n");
31e1051a39Sopenharmony_ci    /*
32e1051a39Sopenharmony_ci     * This will initialise the built-in compression algorithms. The value
33e1051a39Sopenharmony_ci     * returned is a STACK_OF(SSL_COMP), but that can be discarded safely
34e1051a39Sopenharmony_ci     */
35e1051a39Sopenharmony_ci    SSL_COMP_get_compression_methods();
36e1051a39Sopenharmony_ci#endif
37e1051a39Sopenharmony_ci    ssl_sort_cipher_list();
38e1051a39Sopenharmony_ci    OSSL_TRACE(INIT,"ossl_init_ssl_base: SSL_add_ssl_module()\n");
39e1051a39Sopenharmony_ci    /*
40e1051a39Sopenharmony_ci     * We ignore an error return here. Not much we can do - but not that bad
41e1051a39Sopenharmony_ci     * either. We can still safely continue.
42e1051a39Sopenharmony_ci     */
43e1051a39Sopenharmony_ci    OPENSSL_atexit(ssl_library_stop);
44e1051a39Sopenharmony_ci    ssl_base_inited = 1;
45e1051a39Sopenharmony_ci    return 1;
46e1051a39Sopenharmony_ci}
47e1051a39Sopenharmony_ci
48e1051a39Sopenharmony_cistatic CRYPTO_ONCE ssl_strings = CRYPTO_ONCE_STATIC_INIT;
49e1051a39Sopenharmony_ci
50e1051a39Sopenharmony_ciDEFINE_RUN_ONCE_STATIC(ossl_init_load_ssl_strings)
51e1051a39Sopenharmony_ci{
52e1051a39Sopenharmony_ci    /*
53e1051a39Sopenharmony_ci     * OPENSSL_NO_AUTOERRINIT is provided here to prevent at compile time
54e1051a39Sopenharmony_ci     * pulling in all the error strings during static linking
55e1051a39Sopenharmony_ci     */
56e1051a39Sopenharmony_ci#if !defined(OPENSSL_NO_ERR) && !defined(OPENSSL_NO_AUTOERRINIT)
57e1051a39Sopenharmony_ci    OSSL_TRACE(INIT, "ossl_init_load_ssl_strings: ossl_err_load_SSL_strings()\n");
58e1051a39Sopenharmony_ci    ossl_err_load_SSL_strings();
59e1051a39Sopenharmony_ci#endif
60e1051a39Sopenharmony_ci    return 1;
61e1051a39Sopenharmony_ci}
62e1051a39Sopenharmony_ci
63e1051a39Sopenharmony_ciDEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_load_ssl_strings,
64e1051a39Sopenharmony_ci                           ossl_init_load_ssl_strings)
65e1051a39Sopenharmony_ci{
66e1051a39Sopenharmony_ci    /* Do nothing in this case */
67e1051a39Sopenharmony_ci    return 1;
68e1051a39Sopenharmony_ci}
69e1051a39Sopenharmony_ci
70e1051a39Sopenharmony_cistatic void ssl_library_stop(void)
71e1051a39Sopenharmony_ci{
72e1051a39Sopenharmony_ci    /* Might be explicitly called and also by atexit */
73e1051a39Sopenharmony_ci    if (stopped)
74e1051a39Sopenharmony_ci        return;
75e1051a39Sopenharmony_ci    stopped = 1;
76e1051a39Sopenharmony_ci
77e1051a39Sopenharmony_ci    if (ssl_base_inited) {
78e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_COMP
79e1051a39Sopenharmony_ci        OSSL_TRACE(INIT, "ssl_library_stop: "
80e1051a39Sopenharmony_ci                   "ssl_comp_free_compression_methods_int()\n");
81e1051a39Sopenharmony_ci        ssl_comp_free_compression_methods_int();
82e1051a39Sopenharmony_ci#endif
83e1051a39Sopenharmony_ci    }
84e1051a39Sopenharmony_ci}
85e1051a39Sopenharmony_ci
86e1051a39Sopenharmony_ci/*
87e1051a39Sopenharmony_ci * If this function is called with a non NULL settings value then it must be
88e1051a39Sopenharmony_ci * called prior to any threads making calls to any OpenSSL functions,
89e1051a39Sopenharmony_ci * i.e. passing a non-null settings value is assumed to be single-threaded.
90e1051a39Sopenharmony_ci */
91e1051a39Sopenharmony_ciint OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS * settings)
92e1051a39Sopenharmony_ci{
93e1051a39Sopenharmony_ci    static int stoperrset = 0;
94e1051a39Sopenharmony_ci
95e1051a39Sopenharmony_ci    if (stopped) {
96e1051a39Sopenharmony_ci        if (!stoperrset) {
97e1051a39Sopenharmony_ci            /*
98e1051a39Sopenharmony_ci             * We only ever set this once to avoid getting into an infinite
99e1051a39Sopenharmony_ci             * loop where the error system keeps trying to init and fails so
100e1051a39Sopenharmony_ci             * sets an error etc
101e1051a39Sopenharmony_ci             */
102e1051a39Sopenharmony_ci            stoperrset = 1;
103e1051a39Sopenharmony_ci            ERR_raise(ERR_LIB_SSL, ERR_R_INIT_FAIL);
104e1051a39Sopenharmony_ci        }
105e1051a39Sopenharmony_ci        return 0;
106e1051a39Sopenharmony_ci    }
107e1051a39Sopenharmony_ci
108e1051a39Sopenharmony_ci    opts |= OPENSSL_INIT_ADD_ALL_CIPHERS
109e1051a39Sopenharmony_ci         |  OPENSSL_INIT_ADD_ALL_DIGESTS;
110e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_AUTOLOAD_CONFIG
111e1051a39Sopenharmony_ci    if ((opts & OPENSSL_INIT_NO_LOAD_CONFIG) == 0)
112e1051a39Sopenharmony_ci        opts |= OPENSSL_INIT_LOAD_CONFIG;
113e1051a39Sopenharmony_ci#endif
114e1051a39Sopenharmony_ci
115e1051a39Sopenharmony_ci    if (!OPENSSL_init_crypto(opts, settings))
116e1051a39Sopenharmony_ci        return 0;
117e1051a39Sopenharmony_ci
118e1051a39Sopenharmony_ci    if (!RUN_ONCE(&ssl_base, ossl_init_ssl_base))
119e1051a39Sopenharmony_ci        return 0;
120e1051a39Sopenharmony_ci
121e1051a39Sopenharmony_ci    if ((opts & OPENSSL_INIT_NO_LOAD_SSL_STRINGS)
122e1051a39Sopenharmony_ci        && !RUN_ONCE_ALT(&ssl_strings, ossl_init_no_load_ssl_strings,
123e1051a39Sopenharmony_ci                         ossl_init_load_ssl_strings))
124e1051a39Sopenharmony_ci        return 0;
125e1051a39Sopenharmony_ci
126e1051a39Sopenharmony_ci    if ((opts & OPENSSL_INIT_LOAD_SSL_STRINGS)
127e1051a39Sopenharmony_ci        && !RUN_ONCE(&ssl_strings, ossl_init_load_ssl_strings))
128e1051a39Sopenharmony_ci        return 0;
129e1051a39Sopenharmony_ci
130e1051a39Sopenharmony_ci    return 1;
131e1051a39Sopenharmony_ci}
132