dirvote: Fix memleak when computing consensus
[tor.git] / src / lib / crypt_ops / crypto_openssl_mgt.c
blob6c01cb6aa8f3568c857532366a90e4f4a4829d7b
1 /* Copyright (c) 2001, Matej Pfajfar.
2 * Copyright (c) 2001-2004, Roger Dingledine.
3 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4 * Copyright (c) 2007-2021, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
7 /**
8 * \file crypto_openssl_mgt.c
10 * \brief Block of functions related to operations from OpenSSL.
11 **/
13 #include "lib/crypt_ops/compat_openssl.h"
14 #include "lib/crypt_ops/crypto_openssl_mgt.h"
15 #include "lib/crypt_ops/crypto_rand.h"
16 #include "lib/crypt_ops/aes.h"
17 #include "lib/string/util_string.h"
18 #include "lib/lock/compat_mutex.h"
19 #include "lib/log/log.h"
20 #include "lib/log/util_bug.h"
21 #include "lib/testsupport/testsupport.h"
22 #include "lib/thread/threads.h"
24 DISABLE_GCC_WARNING("-Wredundant-decls")
26 #include <openssl/err.h>
27 #include <openssl/rsa.h>
28 #include <openssl/pem.h>
29 #include <openssl/evp.h>
30 #include <openssl/engine.h>
31 #include <openssl/rand.h>
32 #include <openssl/bn.h>
33 #include <openssl/dh.h>
34 #include <openssl/conf.h>
35 #include <openssl/hmac.h>
36 #include <openssl/crypto.h>
37 #include <openssl/ssl.h>
39 ENABLE_GCC_WARNING("-Wredundant-decls")
41 #include <string.h>
43 #ifndef NEW_THREAD_API
44 /** A number of preallocated mutexes for use by OpenSSL. */
45 static tor_mutex_t **openssl_mutexes_ = NULL;
46 /** How many mutexes have we allocated for use by OpenSSL? */
47 static int n_openssl_mutexes_ = 0;
48 #endif /* !defined(NEW_THREAD_API) */
50 /** Declare STATIC functions */
51 STATIC char * parse_openssl_version_str(const char *raw_version);
52 #ifndef NEW_THREAD_API
53 STATIC void openssl_locking_cb_(int mode, int n, const char *file, int line);
54 STATIC void tor_set_openssl_thread_id(CRYPTO_THREADID *threadid);
55 #endif
57 /** Log all pending crypto errors at level <b>severity</b>. Use
58 * <b>doing</b> to describe our current activities.
60 void
61 crypto_openssl_log_errors(int severity, const char *doing)
63 unsigned long err;
64 const char *msg, *lib, *func;
65 while ((err = ERR_get_error()) != 0) {
66 msg = (const char*)ERR_reason_error_string(err);
67 lib = (const char*)ERR_lib_error_string(err);
68 func = (const char*)ERR_func_error_string(err);
69 if (!msg) msg = "(null)";
70 if (!lib) lib = "(null)";
71 if (!func) func = "(null)";
72 if (BUG(!doing)) doing = "(null)";
73 tor_log(severity, LD_CRYPTO, "crypto error while %s: %s (in %s:%s)",
74 doing, msg, lib, func);
78 /* Returns a trimmed and human-readable version of an openssl version string
79 * <b>raw_version</b>. They are usually in the form of 'OpenSSL 1.0.0b 10
80 * May 2012' and this will parse them into a form similar to '1.0.0b' */
81 STATIC char *
82 parse_openssl_version_str(const char *raw_version)
84 const char *end_of_version = NULL;
85 /* The output should be something like "OpenSSL 1.0.0b 10 May 2012. Let's
86 trim that down. */
87 if (!strcmpstart(raw_version, "OpenSSL ")) {
88 raw_version += strlen("OpenSSL ");
89 end_of_version = strchr(raw_version, ' ');
92 if (end_of_version)
93 return tor_strndup(raw_version,
94 end_of_version-raw_version);
95 else
96 return tor_strdup(raw_version);
99 static char *crypto_openssl_version_str = NULL;
100 /* Return a human-readable version of the run-time openssl version number. */
101 const char *
102 crypto_openssl_get_version_str(void)
104 #ifdef OPENSSL_VERSION
105 const int query = OPENSSL_VERSION;
106 #else
107 /* This old name was changed around OpenSSL 1.1.0 */
108 const int query = SSLEAY_VERSION;
109 #endif /* defined(OPENSSL_VERSION) */
111 if (crypto_openssl_version_str == NULL) {
112 const char *raw_version = OpenSSL_version(query);
113 crypto_openssl_version_str = parse_openssl_version_str(raw_version);
115 return crypto_openssl_version_str;
118 #undef QUERY_OPENSSL_VERSION
120 static char *crypto_openssl_header_version_str = NULL;
121 /* Return a human-readable version of the compile-time openssl version
122 * number. */
123 const char *
124 crypto_openssl_get_header_version_str(void)
126 if (crypto_openssl_header_version_str == NULL) {
127 crypto_openssl_header_version_str =
128 parse_openssl_version_str(OPENSSL_VERSION_TEXT);
130 return crypto_openssl_header_version_str;
133 #ifndef COCCI
134 #ifndef OPENSSL_THREADS
135 #error "OpenSSL has been built without thread support. Tor requires an \
136 OpenSSL library with thread support enabled."
137 #endif
138 #endif /* !defined(COCCI) */
140 #ifndef NEW_THREAD_API
141 /** Helper: OpenSSL uses this callback to manipulate mutexes. */
142 STATIC void
143 openssl_locking_cb_(int mode, int n, const char *file, int line)
145 (void)file;
146 (void)line;
147 if (!openssl_mutexes_)
148 /* This is not a really good fix for the
149 * "release-freed-lock-from-separate-thread-on-shutdown" problem, but
150 * it can't hurt. */
151 return;
152 if (mode & CRYPTO_LOCK)
153 tor_mutex_acquire(openssl_mutexes_[n]);
154 else
155 tor_mutex_release(openssl_mutexes_[n]);
158 STATIC void
159 tor_set_openssl_thread_id(CRYPTO_THREADID *threadid)
161 CRYPTO_THREADID_set_numeric(threadid, tor_get_thread_id());
163 #endif /* !defined(NEW_THREAD_API) */
165 /** Helper: Construct mutexes, and set callbacks to help OpenSSL handle being
166 * multithreaded. Returns 0. */
167 static int
168 setup_openssl_threading(void)
170 #ifndef NEW_THREAD_API
171 int i;
172 int n = CRYPTO_num_locks();
173 n_openssl_mutexes_ = n;
174 openssl_mutexes_ = tor_calloc(n, sizeof(tor_mutex_t *));
175 for (i=0; i < n; ++i)
176 openssl_mutexes_[i] = tor_mutex_new();
177 CRYPTO_set_locking_callback(openssl_locking_cb_);
178 CRYPTO_THREADID_set_callback(tor_set_openssl_thread_id);
179 #endif /* !defined(NEW_THREAD_API) */
180 return 0;
183 /** free OpenSSL variables */
184 static void
185 crypto_openssl_free_all(void)
187 tor_free(crypto_openssl_version_str);
188 tor_free(crypto_openssl_header_version_str);
190 /* Destroying a locked mutex is undefined behaviour. This mutex may be
191 * locked, because multiple threads can access it. But we need to destroy
192 * it, otherwise re-initialisation will trigger undefined behaviour.
193 * See #31735 for details. */
194 #ifndef NEW_THREAD_API
195 if (n_openssl_mutexes_) {
196 int n = n_openssl_mutexes_;
197 tor_mutex_t **ms = openssl_mutexes_;
198 int i;
199 openssl_mutexes_ = NULL;
200 n_openssl_mutexes_ = 0;
201 for (i=0;i<n;++i) {
202 tor_mutex_free(ms[i]);
204 tor_free(ms);
206 #endif /* !defined(NEW_THREAD_API) */
209 /** Perform early (pre-configuration) initialization tasks for OpenSSL. */
210 void
211 crypto_openssl_early_init(void)
213 #ifdef OPENSSL_1_1_API
214 OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS |
215 OPENSSL_INIT_LOAD_CRYPTO_STRINGS |
216 OPENSSL_INIT_ADD_ALL_CIPHERS |
217 OPENSSL_INIT_ADD_ALL_DIGESTS, NULL);
218 #else /* !defined(OPENSSL_1_1_API) */
219 ERR_load_crypto_strings();
220 OpenSSL_add_all_algorithms();
221 #endif /* defined(OPENSSL_1_1_API) */
223 setup_openssl_threading();
225 unsigned long version_num = tor_OpenSSL_version_num();
226 const char *version_str = crypto_openssl_get_version_str();
227 if (version_num == OPENSSL_VERSION_NUMBER &&
228 !strcmp(version_str, OPENSSL_VERSION_TEXT)) {
229 log_info(LD_CRYPTO, "OpenSSL version matches version from headers "
230 "(%lx: %s).", version_num, version_str);
231 } else if ((version_num & 0xffff0000) ==
232 (OPENSSL_VERSION_NUMBER & 0xffff0000)) {
233 log_notice(LD_CRYPTO,
234 "We compiled with OpenSSL %lx: %s and we "
235 "are running with OpenSSL %lx: %s. "
236 "These two versions should be binary compatible.",
237 (unsigned long)OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT,
238 version_num, version_str);
239 } else {
240 log_warn(LD_CRYPTO, "OpenSSL version from headers does not match the "
241 "version we're running with. If you get weird crashes, that "
242 "might be why. (Compiled with %lx: %s; running with %lx: %s).",
243 (unsigned long)OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_TEXT,
244 version_num, version_str);
247 crypto_force_rand_ssleay();
250 #ifndef DISABLE_ENGINES
251 /** Try to load an engine in a shared library via fully qualified path.
253 static ENGINE *
254 try_load_engine(const char *path, const char *engine)
256 ENGINE *e = ENGINE_by_id("dynamic");
257 if (e) {
258 if (!ENGINE_ctrl_cmd_string(e, "ID", engine, 0) ||
259 !ENGINE_ctrl_cmd_string(e, "DIR_LOAD", "2", 0) ||
260 !ENGINE_ctrl_cmd_string(e, "DIR_ADD", path, 0) ||
261 !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) {
262 ENGINE_free(e);
263 e = NULL;
266 return e;
268 #endif /* !defined(DISABLE_ENGINES) */
270 #ifndef DISABLE_ENGINES
271 /** Log any OpenSSL engines we're using at NOTICE. */
272 static void
273 log_engine(const char *fn, ENGINE *e)
275 if (e) {
276 const char *name, *id;
277 name = ENGINE_get_name(e);
278 id = ENGINE_get_id(e);
279 log_notice(LD_CRYPTO, "Default OpenSSL engine for %s is %s [%s]",
280 fn, name?name:"?", id?id:"?");
281 } else {
282 log_info(LD_CRYPTO, "Using default implementation for %s", fn);
285 #endif /* !defined(DISABLE_ENGINES) */
287 /** Initialize engines for openssl (if enabled). Load all the built-in
288 * engines, along with the one called <b>accelName</b> (which may be NULL).
289 * If <b>accelName</b> is prefixed with "!", then it is required: return -1
290 * if it can't be loaded. Otherwise return 0.
292 * If <b>accelDir</b> is not NULL, it is the path from which the engine should
293 * be loaded. */
294 static int
295 crypto_openssl_init_engines(const char *accelName,
296 const char *accelDir)
298 #ifdef DISABLE_ENGINES
299 (void)accelName;
300 (void)accelDir;
301 log_warn(LD_CRYPTO, "No OpenSSL hardware acceleration support enabled.");
302 if (accelName && accelName[0] == '!') {
303 log_warn(LD_CRYPTO, "Unable to load required dynamic OpenSSL engine "
304 "\"%s\".", accelName+1);
305 return -1;
307 return 0;
308 #else /* !defined(DISABLE_ENGINES) */
309 ENGINE *e = NULL;
311 log_info(LD_CRYPTO, "Initializing OpenSSL engine support.");
312 ENGINE_load_builtin_engines();
313 ENGINE_register_all_complete();
315 if (accelName) {
316 const bool required = accelName[0] == '!';
317 if (required)
318 ++accelName;
319 if (accelDir) {
320 log_info(LD_CRYPTO, "Trying to load dynamic OpenSSL engine \"%s\""
321 " via path \"%s\".", accelName, accelDir);
322 e = try_load_engine(accelName, accelDir);
323 } else {
324 log_info(LD_CRYPTO, "Initializing dynamic OpenSSL engine \"%s\""
325 " acceleration support.", accelName);
326 e = ENGINE_by_id(accelName);
328 if (!e) {
329 log_warn(LD_CRYPTO, "Unable to load %sdynamic OpenSSL engine \"%s\".",
330 required?"required ":"",
331 accelName);
332 if (required)
333 return -1;
334 } else {
335 log_info(LD_CRYPTO, "Loaded dynamic OpenSSL engine \"%s\".",
336 accelName);
339 if (e) {
340 log_info(LD_CRYPTO, "Loaded OpenSSL hardware acceleration engine,"
341 " setting default ciphers.");
342 ENGINE_set_default(e, ENGINE_METHOD_ALL);
344 /* Log, if available, the intersection of the set of algorithms
345 used by Tor and the set of algorithms available in the engine */
346 log_engine("RSA", ENGINE_get_default_RSA());
347 log_engine("DH", ENGINE_get_default_DH());
348 #ifdef OPENSSL_1_1_API
349 log_engine("EC", ENGINE_get_default_EC());
350 #else
351 log_engine("ECDH", ENGINE_get_default_ECDH());
352 log_engine("ECDSA", ENGINE_get_default_ECDSA());
353 #endif /* defined(OPENSSL_1_1_API) */
354 log_engine("RAND", ENGINE_get_default_RAND());
355 log_engine("RAND (which we will not use)", ENGINE_get_default_RAND());
356 log_engine("SHA1", ENGINE_get_digest_engine(NID_sha1));
357 log_engine("3DES-CBC", ENGINE_get_cipher_engine(NID_des_ede3_cbc));
358 log_engine("AES-128-ECB", ENGINE_get_cipher_engine(NID_aes_128_ecb));
359 log_engine("AES-128-CBC", ENGINE_get_cipher_engine(NID_aes_128_cbc));
360 #ifdef NID_aes_128_ctr
361 log_engine("AES-128-CTR", ENGINE_get_cipher_engine(NID_aes_128_ctr));
362 #endif
363 #ifdef NID_aes_128_gcm
364 log_engine("AES-128-GCM", ENGINE_get_cipher_engine(NID_aes_128_gcm));
365 #endif
366 log_engine("AES-256-CBC", ENGINE_get_cipher_engine(NID_aes_256_cbc));
367 #ifdef NID_aes_256_gcm
368 log_engine("AES-256-GCM", ENGINE_get_cipher_engine(NID_aes_256_gcm));
369 #endif
370 return 0;
372 #endif /* defined(DISABLE_ENGINES) */
375 /** Perform late (post-init) initialization tasks for OpenSSL */
377 crypto_openssl_late_init(int useAccel, const char *accelName,
378 const char *accelDir)
380 if (useAccel > 0) {
381 if (crypto_openssl_init_engines(accelName, accelDir) < 0)
382 return -1;
383 } else {
384 log_info(LD_CRYPTO, "NOT using OpenSSL engine support.");
387 if (crypto_force_rand_ssleay()) {
388 if (crypto_seed_rng() < 0)
389 return -1;
392 evaluate_evp_for_aes(-1);
393 evaluate_ctr_for_aes();
395 return 0;
398 /** Free crypto resources held by this thread. */
399 void
400 crypto_openssl_thread_cleanup(void)
402 #ifndef NEW_THREAD_API
403 ERR_remove_thread_state(NULL);
404 #endif
407 /** Clean up global resources held by openssl. */
408 void
409 crypto_openssl_global_cleanup(void)
411 #ifndef OPENSSL_1_1_API
412 EVP_cleanup();
413 #endif
414 #ifndef NEW_THREAD_API
415 ERR_remove_thread_state(NULL);
416 #endif
417 #ifndef OPENSSL_1_1_API
418 ERR_free_strings();
419 #endif
421 #ifndef DISABLE_ENGINES
422 #ifndef OPENSSL_1_1_API
423 ENGINE_cleanup();
424 #endif
425 #endif
427 CONF_modules_unload(1);
428 #ifndef OPENSSL_1_1_API
429 CRYPTO_cleanup_all_ex_data();
430 #endif
432 crypto_openssl_free_all();