diff --git a/lib/core/context.c b/lib/core/context.c index 96eab80cf..d9518806f 100644 --- a/lib/core/context.c +++ b/lib/core/context.c @@ -568,6 +568,8 @@ lws_context_destroy3(struct lws_context *context) if (context->pt[0].fds) lws_free_set_NULL(context->pt[0].fds); #endif + lws_context_deinit_ssl_library(context); + lws_free(context); lwsl_info("%s: ctx %p freed\n", __func__, context); diff --git a/lib/core/private.h b/lib/core/private.h index 91d2d0c2b..54c9faf89 100644 --- a/lib/core/private.h +++ b/lib/core/private.h @@ -490,6 +490,7 @@ LWS_EXTERN void lwsl_emit_stderr(int level, const char *line); #define lws_ssl_remove_wsi_from_buffered_list(_a) #define __lws_ssl_remove_wsi_from_buffered_list(_a) #define lws_context_init_ssl_library(_a) + #define lws_context_deinit_ssl_library(_a) #define lws_tls_check_all_cert_lifetimes(_a) #define lws_tls_acme_sni_cert_destroy(_a) #endif diff --git a/lib/tls/mbedtls/tls.c b/lib/tls/mbedtls/tls.c index b02ca52f2..ecb094900 100644 --- a/lib/tls/mbedtls/tls.c +++ b/lib/tls/mbedtls/tls.c @@ -38,3 +38,9 @@ lws_context_init_ssl_library(const struct lws_context_creation_info *info) return 0; } + +void +lws_context_deinit_ssl_library(struct lws_context *context) +{ + +} diff --git a/lib/tls/openssl/tls.c b/lib/tls/openssl/tls.c index cf4a7ef96..d14cd83cf 100644 --- a/lib/tls/openssl/tls.c +++ b/lib/tls/openssl/tls.c @@ -81,6 +81,29 @@ lws_tls_err_describe_clear(void) lwsl_info("\n"); } +#if LWS_MAX_SMP != 1 + +static pthread_mutex_t *openssl_mutexes; + +static void +lws_openssl_lock_callback(int mode, int type, const char *file, int line) +{ + (void)file; + (void)line; + + if (mode & CRYPTO_LOCK) + pthread_mutex_lock(&openssl_mutexes[type]); + else + pthread_mutex_unlock(&openssl_mutexes[type]); +} + +static unsigned long +lws_openssl_thread_id(void) +{ + return (unsigned long)pthread_self(); +} +#endif + int lws_context_init_ssl_library(const struct lws_context_creation_info *info) @@ -123,5 +146,48 @@ lws_context_init_ssl_library(const struct lws_context_creation_info *info) NULL, NULL, NULL, NULL); #endif +#if LWS_MAX_SMP != 1 + { + int n; + + openssl_mutexes = (pthread_mutex_t *) + OPENSSL_malloc(CRYPTO_num_locks() * + sizeof(openssl_mutexes[0])); + + for (n = 0; n < CRYPTO_num_locks(); n++) + pthread_mutex_init(&openssl_mutexes[n], NULL); + + /* + * These "functions" disappeared in later OpenSSL which is + * already threadsafe. + */ + + (void)lws_openssl_thread_id; + (void)lws_openssl_lock_callback; + + CRYPTO_set_id_callback(lws_openssl_thread_id); + CRYPTO_set_locking_callback(lws_openssl_lock_callback); + } +#endif + return 0; } + +void +lws_context_deinit_ssl_library(struct lws_context *context) +{ +#if LWS_MAX_SMP != 1 + int n; + + if (!lws_check_opt(context->options, + LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT)) + return; + + CRYPTO_set_locking_callback(NULL); + + for (n = 0; n < CRYPTO_num_locks(); n++) + pthread_mutex_destroy(&openssl_mutexes[n]); + + OPENSSL_free(openssl_mutexes); +#endif +} diff --git a/lib/tls/private.h b/lib/tls/private.h index f27a8366b..16b7d667e 100644 --- a/lib/tls/private.h +++ b/lib/tls/private.h @@ -123,6 +123,8 @@ typedef X509 lws_tls_x509; LWS_EXTERN int lws_context_init_ssl_library(const struct lws_context_creation_info *info); +LWS_EXTERN void +lws_context_deinit_ssl_library(struct lws_context *context); #define LWS_SSL_ENABLED(vh) (vh && vh->tls.use_ssl) extern const struct lws_tls_ops tls_ops_openssl, tls_ops_mbedtls; diff --git a/minimal-examples/api-tests/api-test-jose/jws.c b/minimal-examples/api-tests/api-test-jose/jws.c index 181bb7dfb..2236d928a 100644 --- a/minimal-examples/api-tests/api-test-jose/jws.c +++ b/minimal-examples/api-tests/api-test-jose/jws.c @@ -535,7 +535,7 @@ bail1: lws_jose_destroy(&jose); bail: - lwsl_notice("%s: selftest %s\n", __func__, ret < 0 ? "FAIL" : "OK"); + lwsl_notice("%s: selftest %s\n", __func__, ret ? "FAIL" : "OK"); return ret; } @@ -692,7 +692,7 @@ bail1: lws_jose_destroy(&jose); bail: - lwsl_notice("%s: selftest %s\n", __func__, ret < 0 ? "FAIL" : "OK"); + lwsl_notice("%s: selftest %s\n", __func__, ret ? "FAIL" : "OK"); return ret; } diff --git a/minimal-examples/api-tests/api-test-jose/main.c b/minimal-examples/api-tests/api-test-jose/main.c index 4dc5ba11a..c2f2c7248 100644 --- a/minimal-examples/api-tests/api-test-jose/main.c +++ b/minimal-examples/api-tests/api-test-jose/main.c @@ -40,8 +40,11 @@ int main(int argc, const char **argv) } result |= test_jwk(context); + lwsl_notice("%d\n", result); result |= test_jws(context); + lwsl_notice("%d\n", result); result |= test_jwe(context); + lwsl_notice("%d\n", result); lwsl_user("Completed: %s\n", result ? "FAIL" : "PASS"); diff --git a/minimal-examples/http-server/minimal-http-server-smp/minimal-http-server-smp.c b/minimal-examples/http-server/minimal-http-server-smp/minimal-http-server-smp.c index 1fb677c81..ae07e4a8e 100644 --- a/minimal-examples/http-server/minimal-http-server-smp/minimal-http-server-smp.c +++ b/minimal-examples/http-server/minimal-http-server-smp/minimal-http-server-smp.c @@ -101,7 +101,7 @@ int main(int argc, const char **argv) info.count_threads = COUNT_THREADS; if (lws_cmdline_option(argc, argv, "-s")) { - info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; + info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT | LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT; info.ssl_cert_filepath = "localhost-100y.cert"; info.ssl_private_key_filepath = "localhost-100y.key"; } diff --git a/minimal-examples/selftests-library.sh b/minimal-examples/selftests-library.sh index 9a0847456..154e05b6c 100755 --- a/minimal-examples/selftests-library.sh +++ b/minimal-examples/selftests-library.sh @@ -63,12 +63,12 @@ dotest() { ) >/dev/null 2> /dev/null & W=$! WT=0 - while [ $WT -le 420 ] ; do + while [ $WT -le 820 ] ; do kill -0 $W 2>/dev/null if [ $? -ne 0 ] ; then WT=10000 else - if [ $WT -ge 400 ] ; then + if [ $WT -ge 800 ] ; then WT=10000 kill $W 2>/dev/null wait $W 2>/dev/null