From: Russell Bryant Date: Wed, 8 Jul 2009 15:54:21 +0000 (+0000) Subject: Make OpenSSL usage thread-safe. X-Git-Tag: 1.4.26-rc6~16 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=33f54353ba17375052863a050f568bbb85f33cd6;p=thirdparty%2Fasterisk.git Make OpenSSL usage thread-safe. OpenSSL is not thread-safe by default. However, making it thread safe is very easy. We just have to provide a couple of callbacks. One callback returns a thread ID. The other handles locking. For more information, start with the "Is OpenSSL thread-safe?" question on the FAQ page of openssl.org. git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@205149 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- diff --git a/res/res_crypto.c b/res/res_crypto.c index 8fd78c498a..4e958f91e3 100644 --- a/res/res_crypto.c +++ b/res/res_crypto.c @@ -102,6 +102,30 @@ struct ast_key { static struct ast_key *keys = NULL; +static ast_mutex_t *ssl_locks; + +static int ssl_num_locks; + +static unsigned long ssl_threadid(void) +{ + return pthread_self(); +} + +static void ssl_lock(int mode, int n, const char *file, int line) +{ + if (n < 0 || n >= ssl_num_locks) { + ast_log(LOG_ERROR, "OpenSSL is full of LIES!!! - " + "ssl_num_locks '%d' - n '%d'\n", + ssl_num_locks, n); + return; + } + + if (mode & CRYPTO_LOCK) { + ast_mutex_lock(&ssl_locks[n]); + } else { + ast_mutex_unlock(&ssl_locks[n]); + } +} #if 0 static int fdprint(int fd, char *s) @@ -586,8 +610,27 @@ static struct ast_cli_entry cli_crypto[] = { static int crypto_init(void) { + unsigned int i; + SSL_library_init(); + SSL_load_error_strings(); ERR_load_crypto_strings(); + ERR_load_BIO_strings(); + OpenSSL_add_all_algorithms(); + + /* Make OpenSSL thread-safe. */ + + CRYPTO_set_id_callback(ssl_threadid); + + ssl_num_locks = CRYPTO_num_locks(); + if (!(ssl_locks = ast_calloc(ssl_num_locks, sizeof(ssl_locks[0])))) { + return AST_MODULE_LOAD_DECLINE; + } + for (i = 0; i < ssl_num_locks; i++) { + ast_mutex_init(&ssl_locks[i]); + } + CRYPTO_set_locking_callback(ssl_lock); + ast_cli_register_multiple(cli_crypto, sizeof(cli_crypto) / sizeof(struct ast_cli_entry)); /* Install ourselves into stubs */ @@ -598,7 +641,8 @@ static int crypto_init(void) ast_sign_bin = __ast_sign_bin; ast_encrypt_bin = __ast_encrypt_bin; ast_decrypt_bin = __ast_decrypt_bin; - return 0; + + return AST_MODULE_LOAD_SUCCESS; } static int reload(void)