diff --git a/libretroshare/src/pqi/authssl.cc b/libretroshare/src/pqi/authssl.cc index 347a4f25a..6c0e6cc2b 100644 --- a/libretroshare/src/pqi/authssl.cc +++ b/libretroshare/src/pqi/authssl.cc @@ -57,6 +57,144 @@ // initialisation du pointeur de singleton static AuthSSL *instance_ssl = NULL; +static pthread_mutex_t *mutex_buf = NULL; + +struct CRYPTO_dynlock_value +{ + pthread_mutex_t mutex; +}; + +/** + * OpenSSL locking function. + * + * @param mode lock mode + * @param n lock number + * @param file source file name + * @param line source file line number + * @return none + */ +static void locking_function(int mode, int n, const char */*file*/, int /*line*/) +{ + if (mode & CRYPTO_LOCK) { + pthread_mutex_lock(&mutex_buf[n]); + } else { + pthread_mutex_unlock(&mutex_buf[n]); + } +} + +/** + * OpenSSL uniq id function. + * + * @return thread id + */ +static unsigned long id_function(void) +{ +#ifdef WINDOWS_SYS + return (unsigned long) pthread_self().p; +#else + return (unsigned long) pthread_self(); +#endif +} + +/** + * OpenSSL allocate and initialize dynamic crypto lock. + * + * @param file source file name + * @param line source file line number + */ +static struct CRYPTO_dynlock_value *dyn_create_function(const char */*file*/, int /*line*/) +{ + struct CRYPTO_dynlock_value *value; + + value = (struct CRYPTO_dynlock_value*) malloc(sizeof(struct CRYPTO_dynlock_value)); + if (!value) { + return NULL; + } + pthread_mutex_init(&value->mutex, NULL); + + return value; +} + +/** + * OpenSSL dynamic locking function. + * + * @param mode lock mode + * @param l lock structure pointer + * @param file source file name + * @param line source file line number + * @return none + */ +static void dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l, const char */*file*/, int /*line*/) +{ + if (mode & CRYPTO_LOCK) { + pthread_mutex_lock(&l->mutex); + } else { + pthread_mutex_unlock(&l->mutex); + } +} + +/** + * OpenSSL destroy dynamic crypto lock. + * + * @param l lock structure pointer + * @param file source file name + * @param line source file line number + * @return none + */ +static void dyn_destroy_function(struct CRYPTO_dynlock_value *l, const char */*file*/, int /*line*/) +{ + pthread_mutex_destroy(&l->mutex); + free(l); +} + +/** + * Initialize TLS library. + * + * @return true on success, false on error + */ +bool tls_init() +{ + /* static locks area */ + mutex_buf = (pthread_mutex_t*) malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t)); + if (mutex_buf == NULL) { + return false; + } + for (int i = 0; i < CRYPTO_num_locks(); i++) { + pthread_mutex_init(&mutex_buf[i], NULL); + } + /* static locks callbacks */ + CRYPTO_set_locking_callback(locking_function); + CRYPTO_set_id_callback(id_function); + /* dynamic locks callbacks */ + CRYPTO_set_dynlock_create_callback(dyn_create_function); + CRYPTO_set_dynlock_lock_callback(dyn_lock_function); + CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function); + + return true; +} + +/** + * Cleanup TLS library. + * + * @return 0 + */ +void tls_cleanup() +{ + CRYPTO_set_dynlock_create_callback(NULL); + CRYPTO_set_dynlock_lock_callback(NULL); + CRYPTO_set_dynlock_destroy_callback(NULL); + + CRYPTO_set_locking_callback(NULL); + CRYPTO_set_id_callback(NULL); + + if (mutex_buf == NULL) { + for (int i = 0; i < CRYPTO_num_locks(); i++) { + pthread_mutex_destroy(&mutex_buf[i]); + } + free(mutex_buf); + mutex_buf = NULL; + } +} /* hidden function - for testing purposes() */ void setAuthSSL(AuthSSL *newssl) @@ -148,6 +286,11 @@ static int initLib = 0; if (!initLib) { initLib = 1; + + if (!tls_init()) { + return 0; + } + SSL_load_error_strings(); SSL_library_init(); } @@ -287,6 +430,8 @@ bool AuthSSLimpl::validateOwnCertificate(X509 *x509, EVP_PKEY *pkey) bool AuthSSLimpl::CloseAuth() { + tls_cleanup(); + #ifdef AUTHSSL_DEBUG std::cerr << "AuthSSLimpl::CloseAuth()"; std::cerr << std::endl;