From 2f09686f6b22c4e8064ac17cdbb708b6ebc898ce Mon Sep 17 00:00:00 2001 From: Juan Lang Date: Wed, 7 Oct 2009 08:36:04 -0700 Subject: [PATCH] winhttp: Set callbacks needed by OpenSSL for multithreaded use. --- dlls/winhttp/net.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/dlls/winhttp/net.c b/dlls/winhttp/net.c index 7ab9944e8e..6e54348623 100644 --- a/dlls/winhttp/net.c +++ b/dlls/winhttp/net.c @@ -111,11 +111,29 @@ MAKE_FUNCPTR( SSL_get_peer_certificate ); MAKE_FUNCPTR( SSL_CTX_set_default_verify_paths ); MAKE_FUNCPTR( BIO_new_fp ); +MAKE_FUNCPTR( CRYPTO_num_locks ); +MAKE_FUNCPTR( CRYPTO_set_id_callback ); +MAKE_FUNCPTR( CRYPTO_set_locking_callback ); MAKE_FUNCPTR( ERR_get_error ); MAKE_FUNCPTR( ERR_error_string ); MAKE_FUNCPTR( i2d_X509 ); #undef MAKE_FUNCPTR +static CRITICAL_SECTION *ssl_locks; + +static unsigned long ssl_thread_id(void) +{ + return GetCurrentThreadId(); +} + +static void ssl_lock_callback(int mode, int type, const char *file, int line) +{ + if (mode & CRYPTO_LOCK) + EnterCriticalSection( &ssl_locks[type] ); + else + LeaveCriticalSection( &ssl_locks[type] ); +} + #endif /* translate a unix error code into a winsock error code */ @@ -187,6 +205,10 @@ static int sock_get_error( int err ) BOOL netconn_init( netconn_t *conn, BOOL secure ) { +#if defined(SONAME_LIBSSL) && defined(SONAME_LIBCRYPTO) + int i; +#endif + conn->socket = -1; if (!secure) return TRUE; @@ -245,6 +267,9 @@ BOOL netconn_init( netconn_t *conn, BOOL secure ) return FALSE; \ } LOAD_FUNCPTR( BIO_new_fp ); + LOAD_FUNCPTR( CRYPTO_num_locks ); + LOAD_FUNCPTR( CRYPTO_set_id_callback ); + LOAD_FUNCPTR( CRYPTO_set_locking_callback ); LOAD_FUNCPTR( ERR_get_error ); LOAD_FUNCPTR( ERR_error_string ); LOAD_FUNCPTR( i2d_X509 ); @@ -263,6 +288,20 @@ BOOL netconn_init( netconn_t *conn, BOOL secure ) LeaveCriticalSection( &init_ssl_cs ); return FALSE; } + + pCRYPTO_set_id_callback(ssl_thread_id); + ssl_locks = HeapAlloc(GetProcessHeap(), 0, + pCRYPTO_num_locks() * sizeof(HANDLE)); + if (!ssl_locks) + { + set_last_error( ERROR_OUTOFMEMORY ); + LeaveCriticalSection( &init_ssl_cs ); + return FALSE; + } + for (i = 0; i < pCRYPTO_num_locks(); i++) + InitializeCriticalSection( &ssl_locks[i] ); + pCRYPTO_set_locking_callback(ssl_lock_callback); + LeaveCriticalSection( &init_ssl_cs ); #else WARN("SSL support not compiled in.\n"); @@ -276,7 +315,17 @@ void netconn_unload( void ) { #if defined(SONAME_LIBSSL) && defined(SONAME_LIBCRYPTO) if (libcrypto_handle) + { + if (ssl_locks) + { + int i; + + for (i = 0; i < pCRYPTO_num_locks(); i++) + DeleteCriticalSection( &ssl_locks[i] ); + HeapFree( GetProcessHeap(), 0, ssl_locks ); + } wine_dlclose( libcrypto_handle, NULL, 0 ); + } if (libssl_handle) { if (ctx)