/src/libwebsockets/lib/tls/openssl/openssl-tls.c
Line | Count | Source |
1 | | /* |
2 | | * libwebsockets - small server side websockets and web server implementation |
3 | | * |
4 | | * Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com> |
5 | | * |
6 | | * Permission is hereby granted, free of charge, to any person obtaining a copy |
7 | | * of this software and associated documentation files (the "Software"), to |
8 | | * deal in the Software without restriction, including without limitation the |
9 | | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
10 | | * sell copies of the Software, and to permit persons to whom the Software is |
11 | | * furnished to do so, subject to the following conditions: |
12 | | * |
13 | | * The above copyright notice and this permission notice shall be included in |
14 | | * all copies or substantial portions of the Software. |
15 | | * |
16 | | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
17 | | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
18 | | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
19 | | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
20 | | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
21 | | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
22 | | * IN THE SOFTWARE. |
23 | | */ |
24 | | |
25 | | #include "private-lib-core.h" |
26 | | #include "private-lib-tls-openssl.h" |
27 | | |
28 | | extern int openssl_websocket_private_data_index, |
29 | | openssl_SSL_CTX_private_data_index; |
30 | | #if defined(LWS_WITH_NETWORK) |
31 | | static char openssl_ex_indexes_acquired; |
32 | | #endif |
33 | | static int openssl_contexts_using_global_init; |
34 | | |
35 | | void |
36 | | lws_tls_err_describe_clear(void) |
37 | 0 | { |
38 | 0 | char buf[160]; |
39 | 0 | unsigned long l; |
40 | |
|
41 | 0 | do { |
42 | 0 | l = ERR_peek_error(); |
43 | 0 | if (!l) |
44 | 0 | break; |
45 | | |
46 | 0 | ERR_error_string_n(LWS_TLS_ERR_CAST(ERR_get_error()), buf, sizeof(buf)); |
47 | 0 | lwsl_info(" openssl error: %s\n", buf); |
48 | 0 | } while (l); |
49 | 0 | lwsl_info("\n"); |
50 | 0 | } |
51 | | |
52 | | #if LWS_MAX_SMP != 1 |
53 | | |
54 | | static pthread_mutex_t *openssl_mutexes = NULL; |
55 | | |
56 | | static void |
57 | | lws_openssl_lock_callback(int mode, int type, const char *file, int line) |
58 | | { |
59 | | (void)file; |
60 | | (void)line; |
61 | | |
62 | | if (mode & CRYPTO_LOCK) |
63 | | pthread_mutex_lock(&openssl_mutexes[type]); |
64 | | else |
65 | | pthread_mutex_unlock(&openssl_mutexes[type]); |
66 | | } |
67 | | |
68 | | static unsigned long |
69 | | lws_openssl_thread_id(void) |
70 | | { |
71 | | #ifdef __PTW32_H |
72 | | return (unsigned long)(intptr_t)(pthread_self()).p; |
73 | | #else |
74 | | return (unsigned long)pthread_self(); |
75 | | #endif |
76 | | } |
77 | | #endif |
78 | | |
79 | | int |
80 | | lws_context_init_ssl_library(struct lws_context *cx, |
81 | | const struct lws_context_creation_info *info) |
82 | 0 | { |
83 | 0 | if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT)) { |
84 | 0 | #if !defined(LWS_WITH_MBEDTLS) && defined(LWS_WITH_NETWORK) |
85 | 0 | if (!info->provided_client_ssl_ctx) |
86 | 0 | #endif |
87 | 0 | lwsl_cx_info(cx, " SSL disabled: no " |
88 | 0 | "LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT"); |
89 | 0 | return 0; |
90 | 0 | } |
91 | | |
92 | | /* basic openssl init */ |
93 | | |
94 | 0 | if (!openssl_contexts_using_global_init++) { |
95 | |
|
96 | | #if OPENSSL_VERSION_NUMBER < 0x10100000L |
97 | | SSL_library_init(); |
98 | | OpenSSL_add_all_algorithms(); |
99 | | SSL_load_error_strings(); |
100 | | #else |
101 | 0 | OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL); |
102 | 0 | #endif |
103 | 0 | } |
104 | 0 | #if defined(LWS_WITH_NETWORK) |
105 | 0 | if (!openssl_ex_indexes_acquired) { |
106 | 0 | openssl_websocket_private_data_index = |
107 | 0 | SSL_get_ex_new_index(0, "lws", NULL, NULL, NULL); |
108 | |
|
109 | 0 | openssl_SSL_CTX_private_data_index = |
110 | 0 | SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL); |
111 | |
|
112 | 0 | openssl_ex_indexes_acquired = 1; |
113 | 0 | } |
114 | 0 | #endif |
115 | |
|
116 | | #if LWS_MAX_SMP != 1 |
117 | | { |
118 | | int n; |
119 | | |
120 | | openssl_mutexes = (pthread_mutex_t *) |
121 | | OPENSSL_malloc((size_t)((unsigned long)CRYPTO_num_locks() * |
122 | | (unsigned long)sizeof(openssl_mutexes[0]))); |
123 | | |
124 | | for (n = 0; n < CRYPTO_num_locks(); n++) |
125 | | pthread_mutex_init(&openssl_mutexes[n], NULL); |
126 | | |
127 | | /* |
128 | | * These "functions" disappeared in later OpenSSL which is |
129 | | * already threadsafe. |
130 | | */ |
131 | | |
132 | | (void)lws_openssl_thread_id; |
133 | | (void)lws_openssl_lock_callback; |
134 | | |
135 | | CRYPTO_set_id_callback(lws_openssl_thread_id); |
136 | | CRYPTO_set_locking_callback(lws_openssl_lock_callback); |
137 | | } |
138 | | #endif |
139 | |
|
140 | 0 | return 0; |
141 | 0 | } |
142 | | |
143 | | void |
144 | | lws_context_deinit_ssl_library(struct lws_context *context) |
145 | 0 | { |
146 | 0 | if (!lws_check_opt(context->options, |
147 | 0 | LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT)) |
148 | 0 | return; |
149 | | |
150 | | #if LWS_MAX_SMP != 1 |
151 | | int n; |
152 | | |
153 | | CRYPTO_set_locking_callback(NULL); |
154 | | |
155 | | if (openssl_mutexes) { |
156 | | for (n = 0; n < CRYPTO_num_locks(); n++) |
157 | | pthread_mutex_destroy(&openssl_mutexes[n]); |
158 | | |
159 | | OPENSSL_free(openssl_mutexes); |
160 | | openssl_mutexes = NULL; |
161 | | } |
162 | | #endif |
163 | | |
164 | 0 | --openssl_contexts_using_global_init; |
165 | 0 | } |