diff options
author | Martin Willi <martin@strongswan.org> | 2008-11-03 16:14:12 +0000 |
---|---|---|
committer | Martin Willi <martin@strongswan.org> | 2008-11-03 16:14:12 +0000 |
commit | 7de6da0c8809eea0a7bab31e2802411a5e7749db (patch) | |
tree | 86e8f7aa678d61d4f8b7ffff39f7ced6ad869946 | |
parent | 4d901e358456805fd59fb254075e83372533ad2e (diff) | |
download | strongswan-7de6da0c8809eea0a7bab31e2802411a5e7749db.tar.bz2 strongswan-7de6da0c8809eea0a7bab31e2802411a5e7749db.tar.xz |
added locking mechanism for multithreaded use of OpenSSL
-rw-r--r-- | src/libstrongswan/plugins/openssl/openssl_plugin.c | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/src/libstrongswan/plugins/openssl/openssl_plugin.c b/src/libstrongswan/plugins/openssl/openssl_plugin.c index d4e0f6fa9..a159cd5fa 100644 --- a/src/libstrongswan/plugins/openssl/openssl_plugin.c +++ b/src/libstrongswan/plugins/openssl/openssl_plugin.c @@ -17,6 +17,8 @@ #include <openssl/evp.h> #include <openssl/engine.h> +#include <openssl/crypto.h> +#include <pthread.h> #include "openssl_plugin.h" @@ -41,9 +43,120 @@ struct private_openssl_plugin_t { * public functions */ openssl_plugin_t public; + +}; + +/** + * Array of static mutexs, with CRYPTO_num_locks() mutex + */ +static pthread_mutex_t *mutex; + +/** + * Locking callback for static locks + */ +static void locking_function(int mode, int type, const char *file, int line) +{ + if (mode & CRYPTO_LOCK) + { + pthread_mutex_lock(&mutex[type]); + } + else + { + pthread_mutex_unlock(&mutex[type]); + } +} + +/** + * Implementation of dynlock + */ +struct CRYPTO_dynlock_value { + pthread_mutex_t mutex; }; /** + * Callback to create a dynamic lock + */ +static struct CRYPTO_dynlock_value *create_function(const char *file, int line) +{ + struct CRYPTO_dynlock_value *lock; + + lock = malloc_thing(struct CRYPTO_dynlock_value); + pthread_mutex_init(&lock->mutex, NULL); + return lock; +} + +/** + * Callback to (un-)lock a dynamic lock + */ +static void lock_function(int mode, struct CRYPTO_dynlock_value *lock, + const char *file, int line) +{ + if (mode & CRYPTO_LOCK) + { + pthread_mutex_lock(&lock->mutex); + } + else + { + pthread_mutex_unlock(&lock->mutex); + } +} + +/** + * Callback to destroy a dynamic lock + */ +static void destroy_function(struct CRYPTO_dynlock_value *lock, + const char *file, int line) +{ + pthread_mutex_destroy(&lock->mutex); + free(lock); +} + +/** + * Thread-ID callback function + */ +static unsigned long id_function(void) +{ + return pthread_self(); +} + +/** + * initialize OpenSSL for multi-threaded use + */ +static void threading_init() +{ + int i, num_locks; + + CRYPTO_set_id_callback(id_function); + CRYPTO_set_locking_callback(locking_function); + + CRYPTO_set_dynlock_create_callback(create_function); + CRYPTO_set_dynlock_lock_callback(lock_function); + CRYPTO_set_dynlock_destroy_callback(destroy_function); + + num_locks = CRYPTO_num_locks(); + mutex = malloc(sizeof(pthread_mutex_t) * num_locks); + for (i = 0; i < num_locks; i++) + { + pthread_mutex_init(&mutex[i], NULL); + } +} + +/** + * cleanup OpenSSL threading locks + */ +static void threading_cleanup() +{ + int i, num_locks; + + num_locks = CRYPTO_num_locks(); + for (i = 0; i < num_locks; i++) + { + pthread_mutex_destroy(&mutex[i]); + } + free(mutex); +} + +/** * Implementation of openssl_plugin_t.destroy */ static void destroy(private_openssl_plugin_t *this) @@ -68,6 +181,8 @@ static void destroy(private_openssl_plugin_t *this) ENGINE_cleanup(); EVP_cleanup(); + threading_cleanup(); + free(this); } @@ -80,6 +195,8 @@ plugin_t *plugin_create() this->public.plugin.destroy = (void(*)(plugin_t*))destroy; + threading_init(); + OpenSSL_add_all_algorithms(); /* activate support for hardware accelerators */ |