1 /*
2 *
3 * Functions to enable multi-threaded use of crypto libraries.
4 *
5 * OpenSSL -- http://www.openssl.org/docs/crypto/threads.html
6 * Libgcrypt -- http://gnupg.org/documentation/manuals/gcrypt/Multi_002dThreading.html
7 *
8 * This code is based on Curl 7.21.1
9 *
10 * See <medusa-thread-ssl.h> for interface declarations.
11 *
12 */
13
14 #include "medusa.h"
15
16 /* In OpenSSL <= 1.0.2, an application had to set locking callbacks to use
17 OpenSSL in a multi-threaded environment. OpenSSL 1.1.0 now finds pthreads
18 or Windows threads, so nothing special is necessary.
19 */
20 #if defined(HAVE_LIBSSL) && (OPENSSL_VERSION_NUMBER < 0x10100005L)
21 static pthread_mutex_t *lockarray;
22
23 #include <openssl/crypto.h>
lock_callback(int mode,int type,char * file,int line)24 static void lock_callback(int mode, int type, char *file, int line)
25 {
26 (void)file;
27 (void)line;
28 if (mode & CRYPTO_LOCK) {
29 pthread_mutex_lock(&(lockarray[type]));
30 }
31 else {
32 pthread_mutex_unlock(&(lockarray[type]));
33 }
34 }
35
thread_id(void)36 static unsigned long thread_id(void)
37 {
38 unsigned long ret;
39
40 ret=(unsigned long)pthread_self();
41 return(ret);
42 }
43
init_locks_openssl(void)44 void init_locks_openssl(void)
45 {
46 int i;
47
48 lockarray=(pthread_mutex_t *)OPENSSL_malloc(CRYPTO_num_locks() *
49 sizeof(pthread_mutex_t));
50 for (i=0; i<CRYPTO_num_locks(); i++) {
51 pthread_mutex_init(&(lockarray[i]),NULL);
52
53 }
54
55 CRYPTO_set_id_callback((unsigned long (*)())thread_id);
56 CRYPTO_set_locking_callback((void (*)())lock_callback);
57 }
58
kill_locks_openssl(void)59 void kill_locks_openssl(void)
60 {
61 int i;
62
63 CRYPTO_set_locking_callback(NULL);
64 for (i=0; i<CRYPTO_num_locks(); i++)
65 pthread_mutex_destroy(&(lockarray[i]));
66
67 OPENSSL_free(lockarray);
68 }
69 #endif
70
71 #ifdef HAVE_GNUTLS
72 #include <gnutls/gnutls.h>
73 #include <gcrypt.h>
74
75 GCRY_THREAD_OPTION_PTHREAD_IMPL;
76
init_locks_gnutls(void)77 void init_locks_gnutls(void)
78 {
79 gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
80 gnutls_global_init();
81 }
82 #endif
83
init_crypto_locks(void)84 void init_crypto_locks(void)
85 {
86 #if defined(HAVE_LIBSSL) && (OPENSSL_VERSION_NUMBER < 0x10100005L)
87 init_locks_openssl();
88 #endif
89
90 #ifdef HAVE_GNUTLS
91 init_locks_gnutls();
92 #endif
93 }
94
kill_crypto_locks(void)95 void kill_crypto_locks(void)
96 {
97 #if defined(HAVE_LIBSSL) && (OPENSSL_VERSION_NUMBER < 0x10100005L)
98 kill_locks_openssl();
99 #endif
100 }
101