CI: Various updates to buildAsterisk.sh
[asterisk/asterisk.git] / main / libasteriskssl.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2009-2018, Digium, Inc.
5  *
6  * Russell Bryant <russell@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*!
20  * \file
21  * \brief Common OpenSSL support code
22  *
23  * \author Russell Bryant <russell@digium.com>
24  */
25
26 #include "asterisk.h"
27
28 #include "asterisk/_private.h"   /* ast_ssl_init() */
29
30 #ifdef HAVE_OPENSSL
31 #include <openssl/opensslv.h>    /* for OPENSSL_VERSION_NUMBER */
32 #endif
33
34 #if defined(HAVE_OPENSSL) && \
35         (defined(LIBRESSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10100000L)
36
37 #include <dlfcn.h>               /* for dlerror, dlsym, RTLD_NEXT */
38 #include <openssl/crypto.h>      /* for CRYPTO_num_locks, CRYPTO_set_id_call... */
39 #include <openssl/err.h>         /* for ERR_free_strings */
40 #include <openssl/ssl.h>         /* for SSL_library_init, SSL_load_error_str... */
41 #if OPENSSL_VERSION_NUMBER < 0x10000000L
42 #include <pthread.h>             /* for pthread_self */
43 #endif
44
45 #include "asterisk/lock.h"       /* for ast_mutex_t, ast_mutex_init, ast_mut... */
46 #include "asterisk/logger.h"     /* for ast_debug, ast_log, LOG_ERROR */
47 #include "asterisk/utils.h"      /* for ast_calloc */
48
49 #define get_OpenSSL_function(func) do { real_##func = dlsym(RTLD_NEXT, __stringify(func)); } while(0)
50
51 static int startup_complete;
52
53 static ast_mutex_t *ssl_locks;
54
55 static int ssl_num_locks;
56
57 #if OPENSSL_VERSION_NUMBER < 0x10000000L
58 static unsigned long ssl_threadid(void)
59 {
60         return (unsigned long) pthread_self();
61 }
62 #endif
63
64 static void ssl_lock(int mode, int n, const char *file, int line)
65 {
66         if (n < 0 || n >= ssl_num_locks) {
67                 ast_log(LOG_ERROR, "OpenSSL is full of LIES!!! - "
68                                 "ssl_num_locks '%d' - n '%d'\n",
69                                 ssl_num_locks, n);
70                 return;
71         }
72
73         if (mode & 0x1) {
74                 ast_mutex_lock(&ssl_locks[n]);
75         } else {
76                 ast_mutex_unlock(&ssl_locks[n]);
77         }
78 }
79
80 int SSL_library_init(void)
81 {
82 #if defined(AST_DEVMODE)
83         if (startup_complete) {
84                 ast_debug(1, "Called after startup... ignoring!\n");
85         }
86 #endif
87         return 1;
88 }
89
90 void SSL_load_error_strings(void)
91 {
92 #if defined(AST_DEVMODE)
93         if (startup_complete) {
94                 ast_debug(1, "Called after startup... ignoring!\n");
95         }
96 #endif
97 }
98
99 #if OPENSSL_VERSION_NUMBER < 0x10000000L
100 void CRYPTO_set_id_callback(unsigned long (*func)(void))
101 {
102 #if defined(AST_DEVMODE)
103         if (startup_complete) {
104                 ast_debug(1, "Called after startup... ignoring!\n");
105         }
106 #endif
107 }
108 #endif
109
110 void CRYPTO_set_locking_callback(void (*func)(int mode,int type, const char *file, int line))
111 {
112 #if defined(AST_DEVMODE)
113         if (startup_complete) {
114                 ast_debug(1, "Called after startup... ignoring!\n");
115         }
116 #endif
117 }
118
119 void ERR_free_strings(void)
120 {
121         /* we can't allow this to be called, ever */
122 }
123
124 /*!
125  * \internal
126  * \brief Common OpenSSL initialization for all of Asterisk.
127  *
128  * Not needed for OpenSSL versions >= 1.1.0
129  */
130 int ast_ssl_init(void)
131 {
132         unsigned int i;
133         int (*real_SSL_library_init)(void);
134 #if OPENSSL_VERSION_NUMBER < 0x10000000L
135         void (*real_CRYPTO_set_id_callback)(unsigned long (*)(void));
136 #endif
137         void (*real_CRYPTO_set_locking_callback)(void (*)(int, int, const char *, int));
138         void (*real_SSL_load_error_strings)(void);
139         const char *errstr;
140
141         /* clear any previous dynamic linker errors */
142         dlerror();
143         get_OpenSSL_function(SSL_library_init);
144         if ((errstr = dlerror()) != NULL) {
145                 ast_debug(1, "unable to get real address of SSL_library_init: %s\n", errstr);
146                 /* there is no way to continue in this situation... SSL will
147                  * likely be broken in this process
148                  */
149                 return -1;
150         } else {
151                 real_SSL_library_init();
152         }
153
154         /* Make OpenSSL usage thread-safe. */
155
156 #if OPENSSL_VERSION_NUMBER < 0x10000000L
157         dlerror();
158         get_OpenSSL_function(CRYPTO_set_id_callback);
159         if ((errstr = dlerror()) != NULL) {
160                 ast_debug(1, "unable to get real address of CRYPTO_set_id_callback: %s\n", errstr);
161                 /* there is no way to continue in this situation... SSL will
162                  * likely be broken in this process
163                  */
164                 return -1;
165         } else {
166                 real_CRYPTO_set_id_callback(ssl_threadid);
167         }
168 #endif
169
170         dlerror();
171         get_OpenSSL_function(CRYPTO_set_locking_callback);
172         if ((errstr = dlerror()) != NULL) {
173                 ast_debug(1, "unable to get real address of CRYPTO_set_locking_callback: %s\n", errstr);
174                 /* there is no way to continue in this situation... SSL will
175                  * likely be broken in this process
176                  */
177                 return -1;
178         } else {
179                 ssl_num_locks = CRYPTO_num_locks();
180                 if (!(ssl_locks = ast_calloc(ssl_num_locks, sizeof(ssl_locks[0])))) {
181                         return -1;
182                 }
183                 for (i = 0; i < ssl_num_locks; i++) {
184                         ast_mutex_init(&ssl_locks[i]);
185                 }
186                 real_CRYPTO_set_locking_callback(ssl_lock);
187         }
188
189         /* after this point, we don't check for errors from the dlsym() calls,
190          * under the assumption that if the ones above were successful, all
191          * the rest will be too. this assumption holds as long as OpenSSL still
192          * provides all of these functions.
193          */
194
195         get_OpenSSL_function(SSL_load_error_strings);
196         real_SSL_load_error_strings();
197
198         startup_complete = 1;
199
200         return 0;
201 }
202
203 #else
204
205 int ast_ssl_init(void)
206 {
207         return 0;
208 }
209
210 #endif