Files
wlan-cloud-lib-poco/Crypto/src/OpenSSLInitializer.cpp
Aleksandar Fabijanic be19dc4a2f 1.12.2 release merge (#3695)
* chore: 1.12.2 versions and notes

* chore: spelling fix

* fix(): Linking Crypto-testrunner fails #3688

* fix(Event): POSIX Event state need not be atomic #3699

* fix(OpenSSLInitializer): SIGABRT in OSSL_PROVIDER_unload with static OpenSSL3 #3698

* #3700: Release script must include build_vs170.cmd

* fix(mingw): lowercase winsock2 and iphlpapi to allow cross compile #3711

* fix(PollSet): wakeup fd is never read #3708

* fix(PollSet): wakeup fd is never read (windows portion and some other optimizations) #3708

* fix(PollSet): wakeup fd is never read #3708

* fix(PollSet): Compiling with clang_cl_x64_x64 on Visual Studio 2022 failed #3716

* fix(SpinlockMutex): VS2022 compilation issues #3693

* Only support extracting JSON fields when the SDK supports it (#3717)

* Added preprocessor defined to detect support for JSON

* Only support extracting JSON fields when the SDK supports it

* Fix version comparison

* fix(MSVC): PocoNet Project File does not support Visual Studio 2022 #3719

* Update max MSVC version information (#3720)

add visual studio 2022 support

* Added missing Crypto Header to ProGen source (#3722)

* fix(Crypto): fails to build with Visual Studio projects #3721

* Crypto: Progen again to add new files and bring back ARM64 configuration (#3724)

* Progen Crypto to re-add ARM64

* Add new files

* Add how to install using Conan section on README (#3727)

Signed-off-by: Uilian Ries <uilianries@gmail.com>

* fix(Platform): LoongArch support #3460

* fix(format): Poco::format and C++20 #3733

* fix: g++ C++20 warnings #3734

* core(CI): add c++20

* fix(CI): skip MySQL tests for c++20

* release 1.12.2

Co-authored-by: Günter Obiltschnig <guenter.obiltschnig@appinf.com>
Co-authored-by: Hernan Martinez <hernan.c.martinez@gmail.com>
Co-authored-by: Byungjun Lee <40881444+OneTop4458@users.noreply.github.com>
Co-authored-by: Hernan Martinez <hmartinez@malwarebytes.com>
Co-authored-by: Uilian Ries <uilianries@gmail.com>
2022-08-07 05:10:18 -05:00

224 lines
5.0 KiB
C++

//
// OpenSSLInitializer.cpp
//
// Library: Crypto
// Package: CryptoCore
// Module: OpenSSLInitializer
//
// Copyright (c) 2006-2009, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "Poco/Crypto/OpenSSLInitializer.h"
#include "Poco/Crypto/CryptoException.h"
#include "Poco/RandomStream.h"
#include "Poco/Thread.h"
#include <openssl/ssl.h>
#include <openssl/rand.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/conf.h>
#if defined(POCO_OS_FAMILY_WINDOWS)
#define POCO_STR_HELPER(x) #x
#define POCO_STR(x) POCO_STR_HELPER(x)
#if defined POCO_INTERNAL_OPENSSL_MSVC_VER
#define POCO_INTERNAL_OPENSSL_BUILD \
" (POCO internal build, MSVC version " \
POCO_STR(POCO_INTERNAL_OPENSSL_MSVC_VER) ")"
#else
#define POCO_INTERNAL_OPENSSL_BUILD ""
#endif
#pragma message (OPENSSL_VERSION_TEXT POCO_INTERNAL_OPENSSL_BUILD)
#endif
using Poco::RandomInputStream;
using Poco::Thread;
#if defined(_MSC_VER) && !defined(_DLL) && defined(POCO_INTERNAL_OPENSSL_MSVC_VER)
#if (POCO_MSVS_VERSION >= 2015)
FILE _iob[] = { *stdin, *stdout, *stderr };
extern "C" FILE * __cdecl __iob_func(void) { return _iob; }
#endif // (POCO_MSVS_VERSION >= 2015)
#if (POCO_MSVS_VERSION < 2012)
extern "C" __declspec(noreturn) void __cdecl __report_rangecheckfailure(void) { ::ExitProcess(1); }
#endif // (POCO_MSVS_VERSION < 2012)
#endif // _MSC_VER && _MT && !POCO_EXTERNAL_OPENSSL && (POCO_MSVS_VERSION < 2013)
namespace Poco {
namespace Crypto {
Poco::AtomicCounter OpenSSLInitializer::_rc;
#if OPENSSL_VERSION_NUMBER < 0x10100000L
Poco::FastMutex* OpenSSLInitializer::_mutexes(0);
#endif
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
OSSL_PROVIDER* OpenSSLInitializer::_defaultProvider(0);
OSSL_PROVIDER* OpenSSLInitializer::_legacyProvider(0);
#endif
OpenSSLInitializer::OpenSSLInitializer()
{
initialize();
}
OpenSSLInitializer::~OpenSSLInitializer()
{
try
{
uninitialize();
}
catch (...)
{
poco_unexpected();
}
}
void OpenSSLInitializer::initialize()
{
if (++_rc == 1)
{
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
CONF_modules_load(NULL, NULL, 0);
#else
OPENSSL_config(NULL);
#endif
#if OPENSSL_VERSION_NUMBER < 0x10100000L
SSL_library_init();
SSL_load_error_strings();
OpenSSL_add_all_algorithms();
int nMutexes = CRYPTO_num_locks();
_mutexes = new Poco::FastMutex[nMutexes];
CRYPTO_set_locking_callback(&OpenSSLInitializer::lock);
#ifndef POCO_OS_FAMILY_WINDOWS
// Not needed on Windows (see SF #110: random unhandled exceptions when linking with ssl).
// https://sourceforge.net/p/poco/bugs/110/
//
// From http://www.openssl.org/docs/crypto/threads.html :
// "If the application does not register such a callback using CRYPTO_THREADID_set_callback(),
// then a default implementation is used - on Windows and BeOS this uses the system's
// default thread identifying APIs"
CRYPTO_set_id_callback(&OpenSSLInitializer::id);
#endif
CRYPTO_set_dynlock_create_callback(&OpenSSLInitializer::dynlockCreate);
CRYPTO_set_dynlock_lock_callback(&OpenSSLInitializer::dynlock);
CRYPTO_set_dynlock_destroy_callback(&OpenSSLInitializer::dynlockDestroy);
char seed[SEEDSIZE];
RandomInputStream rnd;
rnd.read(seed, sizeof(seed));
RAND_seed(seed, SEEDSIZE);
#endif
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
if (!_defaultProvider)
{
_defaultProvider = OSSL_PROVIDER_load(NULL, "default");
if (!_defaultProvider) throw CryptoException("Failed to load OpenSSL default provider");
}
if (!_legacyProvider)
{
_legacyProvider = OSSL_PROVIDER_load(NULL, "legacy");
if (!_legacyProvider) throw CryptoException("Failed to load OpenSSL legacy provider");
}
#endif
}
}
void OpenSSLInitializer::uninitialize()
{
if (--_rc == 0)
{
#if OPENSSL_VERSION_NUMBER < 0x10100000L
EVP_cleanup();
ERR_free_strings();
CRYPTO_set_locking_callback(0);
#ifndef POCO_OS_FAMILY_WINDOWS
CRYPTO_set_id_callback(0);
#endif
delete [] _mutexes;
#endif
}
}
#if OPENSSL_VERSION_NUMBER < 0x10100000L
void OpenSSLInitializer::lock(int mode, int n, const char* file, int line)
{
if (mode & CRYPTO_LOCK)
_mutexes[n].lock();
else
_mutexes[n].unlock();
}
unsigned long OpenSSLInitializer::id()
{
// Note: we use an old-style C cast here because
// neither static_cast<> nor reinterpret_cast<>
// work uniformly across all platforms.
return (unsigned long) Poco::Thread::currentTid();
}
struct CRYPTO_dynlock_value* OpenSSLInitializer::dynlockCreate(const char* file, int line)
{
return new CRYPTO_dynlock_value;
}
void OpenSSLInitializer::dynlock(int mode, struct CRYPTO_dynlock_value* lock, const char* file, int line)
{
poco_check_ptr (lock);
if (mode & CRYPTO_LOCK)
lock->_mutex.lock();
else
lock->_mutex.unlock();
}
void OpenSSLInitializer::dynlockDestroy(struct CRYPTO_dynlock_value* lock, const char* file, int line)
{
delete lock;
}
#endif // OPENSSL_VERSION_NUMBER < 0x10100000L
void initializeCrypto()
{
OpenSSLInitializer::initialize();
}
void uninitializeCrypto()
{
OpenSSLInitializer::uninitialize();
}
} } // namespace Poco::Crypto