2014-07-28 23:55:57 +04:00
|
|
|
/**
|
|
|
|
* WinPR: Windows Portable Runtime
|
|
|
|
* OpenSSL Library Initialization
|
|
|
|
*
|
|
|
|
* Copyright 2014 Thincast Technologies GmbH
|
|
|
|
* Copyright 2014 Norbert Federa <norbert.federa@thincast.com>
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2022-02-16 12:08:00 +03:00
|
|
|
#include <winpr/config.h>
|
2015-10-05 23:23:44 +03:00
|
|
|
|
2014-07-28 23:55:57 +04:00
|
|
|
#include <winpr/crt.h>
|
|
|
|
#include <winpr/synch.h>
|
|
|
|
#include <winpr/ssl.h>
|
2014-07-31 13:22:46 +04:00
|
|
|
#include <winpr/thread.h>
|
2017-01-09 18:43:28 +03:00
|
|
|
#include <winpr/crypto.h>
|
2014-07-28 23:55:57 +04:00
|
|
|
|
2015-10-05 23:23:44 +03:00
|
|
|
#ifdef WITH_OPENSSL
|
|
|
|
|
2014-07-28 23:55:57 +04:00
|
|
|
#include <openssl/ssl.h>
|
|
|
|
#include <openssl/err.h>
|
|
|
|
|
2021-11-16 18:12:33 +03:00
|
|
|
#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
|
|
|
|
#include <openssl/provider.h>
|
|
|
|
#endif
|
|
|
|
|
2014-08-18 19:11:40 +04:00
|
|
|
#include "../log.h"
|
2014-08-18 20:57:08 +04:00
|
|
|
#define TAG WINPR_TAG("utils.ssl")
|
2014-08-18 19:11:40 +04:00
|
|
|
|
2016-11-21 19:28:54 +03:00
|
|
|
static BOOL g_winpr_openssl_initialized_by_winpr = FALSE;
|
|
|
|
|
2022-10-19 09:38:57 +03:00
|
|
|
#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
|
|
|
|
static OSSL_PROVIDER* s_winpr_openssl_provider_fips = NULL;
|
|
|
|
static OSSL_PROVIDER* s_winpr_openssl_provider_legacy = NULL;
|
|
|
|
static OSSL_PROVIDER* s_winpr_openssl_provider_default = NULL;
|
|
|
|
#endif
|
|
|
|
|
2016-11-21 19:28:54 +03:00
|
|
|
/**
|
|
|
|
* Note from OpenSSL 1.1.0 "CHANGES":
|
|
|
|
* OpenSSL now uses a new threading API. It is no longer necessary to
|
|
|
|
* set locking callbacks to use OpenSSL in a multi-threaded environment.
|
|
|
|
*/
|
|
|
|
|
2017-03-19 23:58:24 +03:00
|
|
|
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
|
2016-11-21 19:28:54 +03:00
|
|
|
|
|
|
|
#define WINPR_OPENSSL_LOCKING_REQUIRED 1
|
|
|
|
|
2014-07-28 23:55:57 +04:00
|
|
|
static int g_winpr_openssl_num_locks = 0;
|
2014-08-18 21:34:47 +04:00
|
|
|
static HANDLE* g_winpr_openssl_locks = NULL;
|
2014-07-28 23:55:57 +04:00
|
|
|
|
|
|
|
struct CRYPTO_dynlock_value
|
|
|
|
{
|
|
|
|
HANDLE mutex;
|
|
|
|
};
|
|
|
|
|
2018-05-01 16:43:36 +03:00
|
|
|
#if (OPENSSL_VERSION_NUMBER < 0x10000000L) || defined(LIBRESSL_VERSION_NUMBER)
|
2014-07-31 13:22:46 +04:00
|
|
|
static unsigned long _winpr_openssl_id(void)
|
2014-07-28 23:55:57 +04:00
|
|
|
{
|
|
|
|
return (unsigned long)GetCurrentThreadId();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2014-08-18 21:34:47 +04:00
|
|
|
static void _winpr_openssl_locking(int mode, int type, const char* file, int line)
|
2014-07-28 23:55:57 +04:00
|
|
|
{
|
|
|
|
if (mode & CRYPTO_LOCK)
|
|
|
|
{
|
|
|
|
WaitForSingleObject(g_winpr_openssl_locks[type], INFINITE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ReleaseMutex(g_winpr_openssl_locks[type]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-18 21:34:47 +04:00
|
|
|
static struct CRYPTO_dynlock_value* _winpr_openssl_dynlock_create(const char* file, int line)
|
2014-07-28 23:55:57 +04:00
|
|
|
{
|
2015-05-05 18:25:17 +03:00
|
|
|
struct CRYPTO_dynlock_value* dynlock;
|
2014-07-28 23:55:57 +04:00
|
|
|
|
2019-11-06 17:24:51 +03:00
|
|
|
if (!(dynlock = (struct CRYPTO_dynlock_value*)malloc(sizeof(struct CRYPTO_dynlock_value))))
|
2015-05-05 18:25:17 +03:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (!(dynlock->mutex = CreateMutex(NULL, FALSE, NULL)))
|
2014-08-18 19:11:40 +04:00
|
|
|
{
|
2015-05-05 18:25:17 +03:00
|
|
|
free(dynlock);
|
|
|
|
return NULL;
|
2014-07-28 23:55:57 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return dynlock;
|
|
|
|
}
|
|
|
|
|
2017-11-14 15:52:52 +03:00
|
|
|
static void _winpr_openssl_dynlock_lock(int mode, struct CRYPTO_dynlock_value* dynlock,
|
|
|
|
const char* file, int line)
|
2014-07-28 23:55:57 +04:00
|
|
|
{
|
|
|
|
if (mode & CRYPTO_LOCK)
|
|
|
|
{
|
|
|
|
WaitForSingleObject(dynlock->mutex, INFINITE);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ReleaseMutex(dynlock->mutex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-14 15:52:52 +03:00
|
|
|
static void _winpr_openssl_dynlock_destroy(struct CRYPTO_dynlock_value* dynlock, const char* file,
|
2019-11-06 17:24:51 +03:00
|
|
|
int line)
|
2014-07-28 23:55:57 +04:00
|
|
|
{
|
|
|
|
CloseHandle(dynlock->mutex);
|
|
|
|
free(dynlock);
|
|
|
|
}
|
|
|
|
|
2014-07-31 13:22:46 +04:00
|
|
|
static BOOL _winpr_openssl_initialize_locking(void)
|
2014-07-28 23:55:57 +04:00
|
|
|
{
|
|
|
|
int i, count;
|
|
|
|
|
|
|
|
/* OpenSSL static locking */
|
|
|
|
|
|
|
|
if (CRYPTO_get_locking_callback())
|
|
|
|
{
|
2014-08-18 19:11:40 +04:00
|
|
|
WLog_WARN(TAG, "OpenSSL static locking callback is already set");
|
2014-07-28 23:55:57 +04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ((count = CRYPTO_num_locks()) > 0)
|
|
|
|
{
|
2014-08-18 21:34:47 +04:00
|
|
|
HANDLE* locks;
|
2014-08-18 19:11:40 +04:00
|
|
|
|
2014-07-28 23:55:57 +04:00
|
|
|
if (!(locks = calloc(count, sizeof(HANDLE))))
|
|
|
|
{
|
2014-08-18 19:11:40 +04:00
|
|
|
WLog_ERR(TAG, "error allocating lock table");
|
2014-07-28 23:55:57 +04:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
if (!(locks[i] = CreateMutex(NULL, FALSE, NULL)))
|
|
|
|
{
|
2014-08-18 19:11:40 +04:00
|
|
|
WLog_ERR(TAG, "error creating lock #%d", i);
|
|
|
|
|
2014-07-28 23:55:57 +04:00
|
|
|
while (i--)
|
|
|
|
{
|
2015-03-23 19:25:23 +03:00
|
|
|
if (locks[i])
|
|
|
|
CloseHandle(locks[i]);
|
2014-07-28 23:55:57 +04:00
|
|
|
}
|
2014-08-18 19:11:40 +04:00
|
|
|
|
2014-07-28 23:55:57 +04:00
|
|
|
free(locks);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
g_winpr_openssl_locks = locks;
|
|
|
|
g_winpr_openssl_num_locks = count;
|
|
|
|
CRYPTO_set_locking_callback(_winpr_openssl_locking);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* OpenSSL dynamic locking */
|
|
|
|
|
2019-11-06 17:24:51 +03:00
|
|
|
if (CRYPTO_get_dynlock_create_callback() || CRYPTO_get_dynlock_lock_callback() ||
|
2017-11-14 15:52:52 +03:00
|
|
|
CRYPTO_get_dynlock_destroy_callback())
|
2014-07-28 23:55:57 +04:00
|
|
|
{
|
2014-08-18 19:11:40 +04:00
|
|
|
WLog_WARN(TAG, "dynamic locking callbacks are already set");
|
2014-07-28 23:55:57 +04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
CRYPTO_set_dynlock_create_callback(_winpr_openssl_dynlock_create);
|
|
|
|
CRYPTO_set_dynlock_lock_callback(_winpr_openssl_dynlock_lock);
|
|
|
|
CRYPTO_set_dynlock_destroy_callback(_winpr_openssl_dynlock_destroy);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Use the deprecated CRYPTO_get_id_callback() if building against OpenSSL < 1.0.0 */
|
2018-05-01 16:43:36 +03:00
|
|
|
#if (OPENSSL_VERSION_NUMBER < 0x10000000L) || defined(LIBRESSL_VERSION_NUMBER)
|
2014-08-18 19:11:40 +04:00
|
|
|
|
2014-07-28 23:55:57 +04:00
|
|
|
if (CRYPTO_get_id_callback())
|
|
|
|
{
|
2014-08-18 19:11:40 +04:00
|
|
|
WLog_WARN(TAG, "OpenSSL id_callback is already set");
|
2014-07-28 23:55:57 +04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
CRYPTO_set_id_callback(_winpr_openssl_id);
|
|
|
|
}
|
|
|
|
|
2014-08-18 19:11:40 +04:00
|
|
|
#endif
|
2014-07-28 23:55:57 +04:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2014-07-31 13:22:46 +04:00
|
|
|
static BOOL _winpr_openssl_cleanup_locking(void)
|
2014-07-28 23:55:57 +04:00
|
|
|
{
|
|
|
|
/* undo our static locking modifications */
|
|
|
|
if (CRYPTO_get_locking_callback() == _winpr_openssl_locking)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
CRYPTO_set_locking_callback(NULL);
|
|
|
|
|
|
|
|
for (i = 0; i < g_winpr_openssl_num_locks; i++)
|
|
|
|
{
|
|
|
|
CloseHandle(g_winpr_openssl_locks[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_winpr_openssl_num_locks = 0;
|
|
|
|
free(g_winpr_openssl_locks);
|
|
|
|
g_winpr_openssl_locks = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* unset our dynamic locking callbacks */
|
|
|
|
|
|
|
|
if (CRYPTO_get_dynlock_create_callback() == _winpr_openssl_dynlock_create)
|
|
|
|
{
|
|
|
|
CRYPTO_set_dynlock_create_callback(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (CRYPTO_get_dynlock_lock_callback() == _winpr_openssl_dynlock_lock)
|
|
|
|
{
|
|
|
|
CRYPTO_set_dynlock_lock_callback(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (CRYPTO_get_dynlock_destroy_callback() == _winpr_openssl_dynlock_destroy)
|
|
|
|
{
|
|
|
|
CRYPTO_set_dynlock_destroy_callback(NULL);
|
|
|
|
}
|
|
|
|
|
2018-05-01 16:43:36 +03:00
|
|
|
#if (OPENSSL_VERSION_NUMBER < 0x10000000L) || defined(LIBRESSL_VERSION_NUMBER)
|
2014-08-18 19:11:40 +04:00
|
|
|
|
2014-07-28 23:55:57 +04:00
|
|
|
if (CRYPTO_get_id_callback() == _winpr_openssl_id)
|
|
|
|
{
|
|
|
|
CRYPTO_set_id_callback(NULL);
|
|
|
|
}
|
|
|
|
|
2014-08-18 19:11:40 +04:00
|
|
|
#endif
|
2014-07-28 23:55:57 +04:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2016-11-21 19:28:54 +03:00
|
|
|
#endif /* OpenSSL < 1.1.0 */
|
|
|
|
|
2019-02-25 12:37:30 +03:00
|
|
|
static BOOL winpr_enable_fips(DWORD flags)
|
|
|
|
{
|
|
|
|
if (flags & WINPR_SSL_INIT_ENABLE_FIPS)
|
|
|
|
{
|
|
|
|
#if (OPENSSL_VERSION_NUMBER < 0x10001000L) || defined(LIBRESSL_VERSION_NUMBER)
|
|
|
|
WLog_ERR(TAG, "Openssl fips mode not available on openssl versions less than 1.0.1!");
|
|
|
|
return FALSE;
|
|
|
|
#else
|
2021-11-16 18:31:36 +03:00
|
|
|
WLog_DBG(TAG, "Ensuring openssl fips mode is enabled");
|
2019-02-25 12:37:30 +03:00
|
|
|
|
2021-05-12 13:48:15 +03:00
|
|
|
#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
|
2022-10-19 09:38:57 +03:00
|
|
|
s_winpr_openssl_provider_fips = OSSL_PROVIDER_load(NULL, "fips");
|
|
|
|
if (s_winpr_openssl_provider_fips == NULL)
|
|
|
|
{
|
|
|
|
WLog_WARN(TAG, "OpenSSL FIPS provider failled to load");
|
|
|
|
}
|
2021-05-12 13:48:15 +03:00
|
|
|
if (!EVP_default_properties_is_fips_enabled(NULL))
|
|
|
|
#else
|
2019-02-25 12:37:30 +03:00
|
|
|
if (FIPS_mode() != 1)
|
2021-05-12 13:48:15 +03:00
|
|
|
#endif
|
2019-02-25 12:37:30 +03:00
|
|
|
{
|
2021-05-12 13:48:15 +03:00
|
|
|
#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
|
|
|
|
if (EVP_set_default_properties(NULL, "fips=yes"))
|
|
|
|
#else
|
2019-02-25 12:37:30 +03:00
|
|
|
if (FIPS_mode_set(1))
|
2021-05-12 13:48:15 +03:00
|
|
|
#endif
|
2021-11-16 18:31:36 +03:00
|
|
|
WLog_INFO(TAG, "Openssl fips mode enabled!");
|
2019-02-25 12:37:30 +03:00
|
|
|
else
|
|
|
|
{
|
2021-11-16 18:31:36 +03:00
|
|
|
WLog_ERR(TAG, "Openssl fips mode enable failed!");
|
2019-02-25 12:37:30 +03:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
2016-11-21 19:28:54 +03:00
|
|
|
|
2023-05-30 11:01:03 +03:00
|
|
|
static void winpr_openssl_cleanup(void)
|
|
|
|
{
|
|
|
|
winpr_CleanupSSL(WINPR_SSL_INIT_DEFAULT);
|
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL CALLBACK winpr_openssl_initialize(PINIT_ONCE once, PVOID param, PVOID* context)
|
2014-07-28 23:55:57 +04:00
|
|
|
{
|
|
|
|
DWORD flags = param ? *(PDWORD)param : WINPR_SSL_INIT_DEFAULT;
|
|
|
|
|
|
|
|
if (flags & WINPR_SSL_INIT_ALREADY_INITIALIZED)
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2016-11-21 19:28:54 +03:00
|
|
|
#ifdef WINPR_OPENSSL_LOCKING_REQUIRED
|
2017-11-14 15:52:52 +03:00
|
|
|
|
2014-07-28 23:55:57 +04:00
|
|
|
if (flags & WINPR_SSL_INIT_ENABLE_LOCKING)
|
|
|
|
{
|
2014-07-31 13:22:46 +04:00
|
|
|
if (!_winpr_openssl_initialize_locking())
|
2014-07-28 23:55:57 +04:00
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
2017-11-14 15:52:52 +03:00
|
|
|
|
2016-11-21 19:28:54 +03:00
|
|
|
#endif
|
2014-07-28 23:55:57 +04:00
|
|
|
/* SSL_load_error_strings() is void */
|
2017-07-26 17:12:14 +03:00
|
|
|
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
|
2014-07-28 23:55:57 +04:00
|
|
|
SSL_load_error_strings();
|
|
|
|
/* SSL_library_init() always returns "1" */
|
|
|
|
SSL_library_init();
|
Winpr/openssl: Fix digests initialization in multi-thread
SSL functions like OpenSSL_add_all_digests should be invoked at very beginning as they are not MT safe.
If not we might meet double free exception as following:
#0 0x00007f23ddd71c37 in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007f23ddd75028 in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00007f23dddae2a4 in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#3 0x00007f23dddba55e in ?? () from /lib/x86_64-linux-gnu/libc.so.6
#4 0x00007f23dc6ecfcd in CRYPTO_free () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
#5 0x00007f23dc6ef8d1 in OBJ_NAME_add () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
#6 0x00007f23dc77dcd8 in EVP_add_digest () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
#7 0x00007f23dc782321 in OpenSSL_add_all_digests () from /lib/x86_64-linux-gnu/libcrypto.so.1.0.0
#8 0x00007f23c781da28 in winpr_openssl_get_evp_md (md=4) at /home/zihao/workspace/zihao_FreeRDP/winpr/libwinpr/crypto/hash.c:52
#9 0x00007f23c781dccb in winpr_Digest_Init (ctx=0x7f22d064d470, md=<optimized out>) at /home/zihao/workspace/zihao_FreeRDP/winpr/libwinpr/crypto/hash.c:344
#10 0x00007f23d486139b in security_salted_mac_signature (rdp=0x7f23859f5a20, data=0x7f238542d4fb "\004\204\022\004", length=4743, encryption=<optimized out>, output=0x7
at /home/zihao/workspace/zihao_FreeRDP/libfreerdp/core/security.c:378
#11 0x00007f23d488d73f in fastpath_send_update_pdu (fastpath=<optimized out>, updateCode=4 '\004', s=0x7f23859f5f40, skipCompression=true)
at /home/zihao/workspace/zihao_FreeRDP/libfreerdp/core/fastpath.c:1076
#12 0x00007f23d4891c4f in update_send_surface_frame_bits (context=0x7f23859f5540, cmd=0x7f22b2ffcc80, first=true, last=true, frameId=6)
at /home/zihao/workspace/zihao_FreeRDP/libfreerdp/core/update.c:1041
Related reports: https://rt.openssl.org/Ticket/Display.html?id=2216&user=guest&pass=guest
2016-12-26 17:21:36 +03:00
|
|
|
OpenSSL_add_all_digests();
|
|
|
|
OpenSSL_add_all_ciphers();
|
2017-04-06 11:37:28 +03:00
|
|
|
#else
|
2017-11-14 15:52:52 +03:00
|
|
|
|
2019-11-06 17:24:51 +03:00
|
|
|
if (OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS | OPENSSL_INIT_LOAD_CRYPTO_STRINGS |
|
|
|
|
OPENSSL_INIT_ADD_ALL_CIPHERS | OPENSSL_INIT_ADD_ALL_DIGESTS |
|
|
|
|
OPENSSL_INIT_ENGINE_ALL_BUILTIN,
|
|
|
|
NULL) != 1)
|
2017-04-06 11:37:28 +03:00
|
|
|
return FALSE;
|
2017-11-14 15:52:52 +03:00
|
|
|
|
2017-04-06 11:37:28 +03:00
|
|
|
#endif
|
2021-11-16 18:12:33 +03:00
|
|
|
|
|
|
|
#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
|
|
|
|
/* The legacy provider is needed for MD4. */
|
2022-10-19 09:38:57 +03:00
|
|
|
s_winpr_openssl_provider_legacy = OSSL_PROVIDER_load(NULL, "legacy");
|
|
|
|
if (s_winpr_openssl_provider_legacy == NULL)
|
|
|
|
{
|
|
|
|
WLog_WARN(TAG, "OpenSSL LEGACY provider failed to load, no md4 support available!");
|
|
|
|
}
|
|
|
|
s_winpr_openssl_provider_default = OSSL_PROVIDER_load(NULL, "default");
|
|
|
|
if (s_winpr_openssl_provider_default == NULL)
|
|
|
|
{
|
|
|
|
WLog_WARN(TAG, "OpenSSL DEFAULT provider failed to load");
|
|
|
|
}
|
2021-11-16 18:12:33 +03:00
|
|
|
#endif
|
|
|
|
|
2023-05-30 11:01:03 +03:00
|
|
|
atexit(winpr_openssl_cleanup);
|
2014-07-28 23:55:57 +04:00
|
|
|
g_winpr_openssl_initialized_by_winpr = TRUE;
|
2021-11-16 18:22:55 +03:00
|
|
|
return TRUE;
|
2014-07-28 23:55:57 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
/* exported functions */
|
|
|
|
|
|
|
|
BOOL winpr_InitializeSSL(DWORD flags)
|
|
|
|
{
|
|
|
|
static INIT_ONCE once = INIT_ONCE_STATIC_INIT;
|
2019-02-25 12:37:30 +03:00
|
|
|
|
2023-05-30 11:01:03 +03:00
|
|
|
if (!InitOnceExecuteOnce(&once, winpr_openssl_initialize, &flags, NULL))
|
2019-02-25 12:37:30 +03:00
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
return winpr_enable_fips(flags);
|
2014-07-28 23:55:57 +04:00
|
|
|
}
|
|
|
|
|
2023-05-30 11:01:03 +03:00
|
|
|
#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
|
|
|
|
static int unload(OSSL_PROVIDER* provider, void* data)
|
|
|
|
{
|
|
|
|
if (!provider)
|
|
|
|
return 1;
|
|
|
|
const char* name = OSSL_PROVIDER_get0_name(provider);
|
|
|
|
if (!name)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
OSSL_LIB_CTX* ctx = OSSL_LIB_CTX_get0_global_default();
|
|
|
|
const int rc = OSSL_PROVIDER_available(ctx, name);
|
|
|
|
if (rc < 1)
|
|
|
|
return 1;
|
|
|
|
OSSL_PROVIDER_unload(provider);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2014-07-28 23:55:57 +04:00
|
|
|
BOOL winpr_CleanupSSL(DWORD flags)
|
|
|
|
{
|
|
|
|
if (flags & WINPR_SSL_CLEANUP_GLOBAL)
|
|
|
|
{
|
|
|
|
if (!g_winpr_openssl_initialized_by_winpr)
|
|
|
|
{
|
2014-08-18 19:11:40 +04:00
|
|
|
WLog_WARN(TAG, "ssl was not initialized by winpr");
|
2014-07-28 23:55:57 +04:00
|
|
|
return FALSE;
|
|
|
|
}
|
2014-08-18 19:11:40 +04:00
|
|
|
|
2014-07-28 23:55:57 +04:00
|
|
|
g_winpr_openssl_initialized_by_winpr = FALSE;
|
2016-11-21 19:28:54 +03:00
|
|
|
#ifdef WINPR_OPENSSL_LOCKING_REQUIRED
|
2014-07-28 23:55:57 +04:00
|
|
|
_winpr_openssl_cleanup_locking();
|
2016-11-21 19:28:54 +03:00
|
|
|
#endif
|
2017-07-26 17:12:14 +03:00
|
|
|
#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER)
|
2014-07-28 23:55:57 +04:00
|
|
|
CRYPTO_cleanup_all_ex_data();
|
|
|
|
ERR_free_strings();
|
|
|
|
EVP_cleanup();
|
2017-04-06 11:37:28 +03:00
|
|
|
#endif
|
2017-11-14 15:52:52 +03:00
|
|
|
#ifdef WINPR_OPENSSL_LOCKING_REQUIRED
|
2014-07-28 23:55:57 +04:00
|
|
|
flags |= WINPR_SSL_CLEANUP_THREAD;
|
2017-11-14 15:52:52 +03:00
|
|
|
#endif
|
2014-07-28 23:55:57 +04:00
|
|
|
}
|
|
|
|
|
2016-11-25 12:39:20 +03:00
|
|
|
#ifdef WINPR_OPENSSL_LOCKING_REQUIRED
|
2017-11-14 15:52:52 +03:00
|
|
|
|
2014-07-28 23:55:57 +04:00
|
|
|
if (flags & WINPR_SSL_CLEANUP_THREAD)
|
|
|
|
{
|
2017-07-26 17:12:14 +03:00
|
|
|
#if (OPENSSL_VERSION_NUMBER < 0x10000000L) || defined(LIBRESSL_VERSION_NUMBER)
|
2014-07-28 23:55:57 +04:00
|
|
|
ERR_remove_state(0);
|
|
|
|
#else
|
|
|
|
ERR_remove_thread_state(NULL);
|
|
|
|
#endif
|
|
|
|
}
|
2017-11-14 15:52:52 +03:00
|
|
|
|
2022-10-19 09:38:57 +03:00
|
|
|
#endif
|
|
|
|
#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
|
2023-05-30 11:01:03 +03:00
|
|
|
OSSL_LIB_CTX* ctx = OSSL_LIB_CTX_get0_global_default();
|
|
|
|
OSSL_PROVIDER_do_all(ctx, unload, NULL);
|
2016-11-25 12:39:20 +03:00
|
|
|
#endif
|
2023-05-30 11:01:03 +03:00
|
|
|
|
2014-07-28 23:55:57 +04:00
|
|
|
return TRUE;
|
|
|
|
}
|
2015-10-05 23:23:44 +03:00
|
|
|
|
2017-11-22 21:25:32 +03:00
|
|
|
BOOL winpr_FIPSMode(void)
|
|
|
|
{
|
2017-12-01 18:34:48 +03:00
|
|
|
#if (OPENSSL_VERSION_NUMBER < 0x10001000L) || defined(LIBRESSL_VERSION_NUMBER)
|
2017-11-22 21:25:32 +03:00
|
|
|
return FALSE;
|
2021-08-01 19:14:43 +03:00
|
|
|
#elif defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3)
|
|
|
|
return (EVP_default_properties_is_fips_enabled(NULL) == 1);
|
2017-11-22 21:25:32 +03:00
|
|
|
#else
|
|
|
|
return (FIPS_mode() == 1);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2015-10-05 23:23:44 +03:00
|
|
|
#else
|
|
|
|
|
|
|
|
BOOL winpr_InitializeSSL(DWORD flags)
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL winpr_CleanupSSL(DWORD flags)
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2017-11-22 21:25:32 +03:00
|
|
|
BOOL winpr_FIPSMode(void)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2015-10-05 23:23:44 +03:00
|
|
|
#endif
|